Compare commits
115 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5db6a6819d | ||
|
|
f448279b14 | ||
|
|
ded5a504b4 | ||
|
|
c0d0fe86d8 | ||
|
|
a81a8c137b | ||
|
|
02f7bcdbd1 | ||
|
|
5ced1f590b | ||
|
|
b98ee19241 | ||
|
|
ad8330af72 | ||
|
|
b25adabcfa | ||
|
|
875e873f26 | ||
|
|
2a9e3bd743 | ||
|
|
f37b7c1f96 | ||
|
|
509c2680aa | ||
|
|
ec5adb83dd | ||
|
|
c8e52741fd | ||
|
|
6399d0a699 | ||
|
|
aa9db61677 | ||
|
|
2b05d47bc2 | ||
|
|
7bc9fca430 | ||
|
|
bb16b94455 | ||
|
|
33011754e6 | ||
|
|
bce58f487e | ||
|
|
ce067a6cd1 | ||
|
|
d3a3a73f64 | ||
|
|
58a3975e93 | ||
|
|
5857929f95 | ||
|
|
709477274e | ||
|
|
1af712c101 | ||
|
|
ec90cd0f90 | ||
|
|
ce76ffac4c | ||
|
|
500b5ecec3 | ||
|
|
87ab3360d0 | ||
|
|
b46af82cc1 | ||
|
|
a4aa30d9a0 | ||
|
|
0d7818d1b6 | ||
|
|
4b67db4d9b | ||
|
|
f70a7e1ee1 | ||
|
|
6a8421fb44 | ||
|
|
031e16ecff | ||
|
|
75be88cfbd | ||
|
|
e2442e0707 | ||
|
|
1c2d3cfaaf | ||
|
|
2d0b675adf | ||
|
|
90e2d7f3fd | ||
|
|
5308c1a03b | ||
|
|
ce90ab5d44 | ||
|
|
1ee87a9e2e | ||
|
|
479501b07c | ||
|
|
9bc8eb6449 | ||
|
|
0fa5ae6b54 | ||
|
|
1ff90822f1 | ||
|
|
f8cca819a4 | ||
|
|
beefb62a6f | ||
|
|
3d9c64e9f8 | ||
|
|
23e8e0ff83 | ||
|
|
c868e41b22 | ||
|
|
0696b0a451 | ||
|
|
aa829dcf50 | ||
|
|
43ce78e032 | ||
|
|
bb3d325624 | ||
|
|
c701014dce | ||
|
|
950580eb0c | ||
|
|
2b1c9c6887 | ||
|
|
07e304c3bf | ||
|
|
5ea77d8b77 | ||
|
|
504a295cde | ||
|
|
d00d7d8c19 | ||
|
|
aaffc14f65 | ||
|
|
d5f281b734 | ||
|
|
f2729c983a | ||
|
|
c1f07a9fc4 | ||
|
|
4f943644e5 | ||
|
|
3bef88f6ec | ||
|
|
2260b66e16 | ||
|
|
a861cc2f31 | ||
|
|
43c58ff983 | ||
|
|
574f3a772c | ||
|
|
ad6c316146 | ||
|
|
8d95be3afb | ||
|
|
a62895265f | ||
|
|
9ab569e616 | ||
|
|
9c78a04df4 | ||
|
|
0fa7850aeb | ||
|
|
0c8eb5b4dd | ||
|
|
84893085cf | ||
|
|
f4b8a5cf03 | ||
|
|
6d8caa9f88 | ||
|
|
398c1e9acc | ||
|
|
26f109290d | ||
|
|
43e84cff1b | ||
|
|
696e754ecf | ||
|
|
909a8cfc7b | ||
|
|
3041cf67ff | ||
|
|
1a85fc497d | ||
|
|
eb8bba627f | ||
|
|
53bb941845 | ||
|
|
2401e4d10c | ||
|
|
34e9d7e340 | ||
|
|
dc9bdf143a | ||
|
|
b2d000e64b | ||
|
|
bfc3ce3157 | ||
|
|
269e84c971 | ||
|
|
b628d6934f | ||
|
|
450306a84b | ||
|
|
ed3c527386 | ||
|
|
4a275cf080 | ||
|
|
13e4803e6a | ||
|
|
a74655af45 | ||
|
|
58cb10ee5f | ||
|
|
7b3c0f0109 | ||
|
|
72964b8633 | ||
|
|
3270768736 | ||
|
|
51f94caba1 | ||
|
|
9a12cf7ab5 |
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -2,3 +2,4 @@
|
||||
/appveyor.yml export-ignore
|
||||
/ci export-ignore
|
||||
/.gitattributes export-ignore
|
||||
/.github export-ignore
|
||||
|
||||
95
.github/CONTRIBUTING.md
vendored
Normal file
95
.github/CONTRIBUTING.md
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
Contributing to libjpeg-turbo
|
||||
=============================
|
||||
|
||||
libjpeg-turbo is a stable and mature product with a worldwide reach, it is an
|
||||
ISO/ITU-T reference implementation of the JPEG standard, and its maintainer
|
||||
does not earn a salary for maintaining it. Thus, not every code contribution
|
||||
can or will be accepted into the libjpeg-turbo code base. In order to maximize
|
||||
the chances that a code contribution is acceptable, please adhere to the
|
||||
following guidelines:
|
||||
|
||||
1. If the code contribution is a bug fix, then please ensure that enough
|
||||
information is provided so that the maintainer can readily reproduce and
|
||||
document the bug. That information should include:
|
||||
- A clear and concise description of the bug
|
||||
- The steps and (if applicable) images necessary to reproduce the bug
|
||||
- The compilers, operating systems, and CPUs with which the bug was
|
||||
observed
|
||||
- The versions of libjpeg-turbo with which the bug was observed
|
||||
- If the bug is a regression, the specific commit that introduced the bug
|
||||
(use `git bisect` to determine this)
|
||||
|
||||
2. If the code contribution will implement a major new feature, then please
|
||||
contact the project maintainer (through a
|
||||
[GitHub issue](https://github.com/libjpeg-turbo/libjpeg-turbo/issues/new),
|
||||
[direct e-mail](https://libjpeg-turbo.org/About/Contact), or the
|
||||
[libjpeg-turbo-devel mailing list](https://libjpeg-turbo.org/About/MailingLists))
|
||||
prior to implementing the feature. In general, major new features that are
|
||||
potentially disruptive to the quality of libjpeg-turbo are unlikely to be
|
||||
accepted unless:
|
||||
- The new feature is within the existing scope of libjpeg-turbo.
|
||||
- The new feature has been thoroughly regression tested and benchmarked on
|
||||
all of the supported platforms that are potentially affected by it.
|
||||
- The new feature has been documented clearly and concisely in the change
|
||||
log and (if applicable) the libjpeg and TurboJPEG API documentation and
|
||||
man pages.
|
||||
- The code implementing the new feature is formatted consistently with the
|
||||
rest of the libjpeg-turbo code base (use
|
||||
[checkstyle](https://github.com/libjpeg-turbo/checkstyle) to validate
|
||||
this.)
|
||||
- The new feature does not introduce new members into the exposed libjpeg
|
||||
API structures (doing so would break backward ABI compatibility.)
|
||||
- The new feature does not alter existing libjpeg-turbo usage or
|
||||
development workflows.
|
||||
- The code implementing the new feature is elegant, easily maintainable,
|
||||
and causes the least possible amount of disruption to the libjpeg-turbo
|
||||
code base.
|
||||
- The new feature is based on the dev branch of the libjpeg-turbo
|
||||
repository.
|
||||
|
||||
... OR ...
|
||||
|
||||
- Your organization is prepared to pay for the labor necessary to ensure
|
||||
all of the above. Even the most well-written patches can still require
|
||||
a significant amount of labor to clean up, test, and integrate. (See
|
||||
above RE: the maintainer not earning a salary.)
|
||||
|
||||
Specific types of features that *will not* be accepted:
|
||||
|
||||
- Features that extend the scope of libjpeg-turbo to support image formats
|
||||
other than DCT-based JPEG and JFIF
|
||||
- Features that extend the scope of libjpeg-turbo to support image
|
||||
processing algorithms that are not necessary for JPEG compression or
|
||||
decompression
|
||||
- Extensions to the JPEG format that have not been approved by the
|
||||
appropriate standards bodies
|
||||
- Non-trivial performance enhancements that have less than a 5% overall
|
||||
impact on performance
|
||||
|
||||
3. If the code contribution is a build system enhancement, then please be
|
||||
prepared to justify the enhancement. In general, build system enhancements
|
||||
are unlikely to be accepted unless:
|
||||
- The enhancement is potentially beneficial to a significant number of
|
||||
upstream libjpeg-turbo users/developers. (If the enhancement is only
|
||||
beneficial to a downstream project, then it does not belong here.)
|
||||
- The enhancement has been tested with the following CMake versions:
|
||||
- The earliest version of CMake that libjpeg-turbo currently supports
|
||||
(refer to CMakeLists.txt)
|
||||
- The most recent major version of CMake
|
||||
- (if applicable) The earliest version of CMake with which the
|
||||
enhancement can be used
|
||||
- The enhancement has been tested on all of the major platforms (Mac,
|
||||
Linux, Windows/Visual C++, Windows/MinGW) that are potentially affected
|
||||
by it.
|
||||
- The enhancement does not introduce new build system requirements or CMake
|
||||
variables unless absolutely necessary.
|
||||
- The enhancement does not alter existing libjpeg-turbo development
|
||||
workflows.
|
||||
|
||||
Specific types of build system enhancements that *will not* be accepted:
|
||||
|
||||
- Enhancements that allow libjpeg-turbo to be built from a subdirectory
|
||||
of a downstream repository. These enhancements are not maintainable in
|
||||
the upstream libjpeg-turbo build system. Use the CMake
|
||||
`ExternalProject_Add()` function instead.
|
||||
- Enhancements that introduce new (non-CMake-based) build systems
|
||||
40
.github/ISSUE_TEMPLATE/bug-report.md
vendored
Normal file
40
.github/ISSUE_TEMPLATE/bug-report.md
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: Inform the libjpeg-turbo maintainer about unexpected, reproducible behavior
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: dcommander
|
||||
|
||||
---
|
||||
|
||||
**Have you searched the existing issues (both open and closed) in the libjpeg-turbo issue tracker to ensure that this bug report is not a duplicate?**
|
||||
|
||||
|
||||
**Does this bug report describe one of the [two known and unsolvable issues with the JPEG format](https://libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf)?**
|
||||
|
||||
|
||||
**Clear and concise description of the bug:**
|
||||
|
||||
|
||||
**Steps to reproduce the bug (using *only* libjpeg-turbo):**
|
||||
|
||||
|
||||
**Image(s) needed in order to reproduce the bug (if applicable):**
|
||||
|
||||
|
||||
**Expected behavior:**
|
||||
|
||||
|
||||
**Observed behavior:**
|
||||
|
||||
|
||||
**Platform(s) (compiler version, operating system version, CPU) on which the bug was observed:**
|
||||
|
||||
|
||||
**libjpeg-turbo release(s), commit(s), or branch(es) in which the bug was observed (always test the tip of the master branch or the latest [stable pre-release](https://libjpeg-turbo.org/DeveloperInfo/PreReleases) to verify that the bug hasn't already been fixed):**
|
||||
|
||||
|
||||
**If the bug is a regression, the specific commit that introduced the regression (use `git bisect` to determine this):**
|
||||
|
||||
|
||||
**Additional information:**
|
||||
8
.github/ISSUE_TEMPLATE/feature-request.md
vendored
Normal file
8
.github/ISSUE_TEMPLATE/feature-request.md
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
name: Feature Request
|
||||
about: Suggest new libjpeg-turbo functionality
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: dcommander
|
||||
|
||||
---
|
||||
53
.travis.yml
53
.travis.yml
@@ -14,49 +14,64 @@ matrix:
|
||||
- docker
|
||||
- os: osx
|
||||
env: BUILD_OFFICIAL=1
|
||||
osx_image: xcode7.3
|
||||
osx_image: xcode8.3
|
||||
- os: linux
|
||||
dist: trusty
|
||||
compiler: clang
|
||||
env:
|
||||
CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
CFLAGS_RELWITHDEBINFO="-O1 -g -fsanitize=address -fno-omit-frame-pointer"
|
||||
CFLAGS_RELWITHDEBINFO="-O1 -g -fsanitize=address,undefined -fno-omit-frame-pointer"
|
||||
CMAKE_FLAGS="-DENABLE_SHARED=0"
|
||||
ASAN_OPTIONS="detect_leaks=1 symbolize=1"
|
||||
CTEST_OUTPUT_ON_FAILURE=1
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- nasm
|
||||
- os: linux
|
||||
dist: trusty
|
||||
compiler: gcc
|
||||
env: CMAKE_FLAGS="-DWITH_12BIT=1"
|
||||
env:
|
||||
CMAKE_FLAGS="-DWITH_12BIT=1"
|
||||
CTEST_OUTPUT_ON_FAILURE=1
|
||||
- os: linux
|
||||
dist: trusty
|
||||
compiler: gcc
|
||||
env: CMAKE_FLAGS="-DWITH_JPEG7=1"
|
||||
env:
|
||||
CMAKE_FLAGS="-DWITH_JPEG7=1"
|
||||
CTEST_OUTPUT_ON_FAILURE=1
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- nasm
|
||||
- os: linux
|
||||
dist: trusty
|
||||
compiler: gcc
|
||||
env: CMAKE_FLAGS="-DWITH_JPEG8=1"
|
||||
env:
|
||||
CMAKE_FLAGS="-DWITH_JPEG8=1"
|
||||
CTEST_OUTPUT_ON_FAILURE=1
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- nasm
|
||||
- os: linux
|
||||
dist: trusty
|
||||
compiler: gcc
|
||||
env: CMAKE_FLAGS="-DWITH_SIMD=0"
|
||||
compiler: clang
|
||||
env:
|
||||
CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
CFLAGS_RELWITHDEBINFO="-O3 -g -fsanitize=memory -fPIE"
|
||||
CMAKE_FLAGS="-DWITH_SIMD=0"
|
||||
CTEST_OUTPUT_ON_FAILURE=1
|
||||
|
||||
addons:
|
||||
homebrew:
|
||||
brewfile: true
|
||||
update: true
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/Library/Caches/Homebrew
|
||||
|
||||
before_cache:
|
||||
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then brew cleanup; fi
|
||||
|
||||
before_install:
|
||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
brew update &&
|
||||
brew bundle &&
|
||||
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
|
||||
@@ -70,7 +85,7 @@ before_install:
|
||||
tar xf ci/keys &&
|
||||
rm ci/keys &&
|
||||
mv ci/gpgsign ~/src/buildscripts &&
|
||||
gpg --import ci/sign_ljt &&
|
||||
gpg --batch --import ci/sign_ljt &&
|
||||
rm ci/sign_ljt;
|
||||
fi
|
||||
fi
|
||||
@@ -79,7 +94,9 @@ script:
|
||||
- if [ "${BUILD_OFFICIAL:-}" != "" ]; then
|
||||
mkdir -p ~/src/ljt.nightly &&
|
||||
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 -d /root/src/libjpeg-turbo -v" &&
|
||||
mkdir $HOME/rpmkeys &&
|
||||
wget --no-check-certificate "http://www.libjpeg-turbo.org/key/LJTPR-GPG-KEY" -O $HOME/rpmkeys/LJTPR-GPG-KEY &&
|
||||
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 -v $HOME/rpmkeys:/rpmkeys -t dcommander/buildljt:latest bash -c "rpm --import /rpmkeys/LJTPR-GPG-KEY && ~/src/buildscripts/buildljt -d /root/src/libjpeg-turbo -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
|
||||
@@ -121,6 +138,7 @@ deploy:
|
||||
local-dir: $HOME/src/ljt.nightly/latest/files
|
||||
upload-dir: $TRAVIS_BRANCH/$TRAVIS_OS_NAME
|
||||
on:
|
||||
repo: libjpeg-turbo/libjpeg-turbo
|
||||
branch: master
|
||||
condition: -n "$BUILD_OFFICIAL"
|
||||
- provider: s3
|
||||
@@ -133,5 +151,6 @@ deploy:
|
||||
local-dir: $HOME/src/ljt.nightly/latest/files
|
||||
upload-dir: $TRAVIS_BRANCH/$TRAVIS_OS_NAME
|
||||
on:
|
||||
repo: libjpeg-turbo/libjpeg-turbo
|
||||
branch: dev
|
||||
condition: -n "$BUILD_OFFICIAL"
|
||||
|
||||
166
BUILDING.md
166
BUILDING.md
@@ -48,8 +48,9 @@ Build Requirements
|
||||
install the Java Developer Package, which can be downloaded from
|
||||
<http://developer.apple.com/downloads> (Apple ID required.) For other
|
||||
systems, you can obtain the Oracle Java Development Kit from
|
||||
<http://www.java.com>.
|
||||
<http://www.oracle.com/technetwork/java/javase/downloads>.
|
||||
|
||||
* If using JDK 11 or later, CMake 3.10.x or later must also be used.
|
||||
|
||||
### Windows
|
||||
|
||||
@@ -83,7 +84,10 @@ Build Requirements
|
||||
appropriate compiler paths automatically set.
|
||||
|
||||
- If building the TurboJPEG Java wrapper, JDK 1.5 or later is required. This
|
||||
can be downloaded from <http://www.java.com>.
|
||||
can be downloaded from
|
||||
<http://www.oracle.com/technetwork/java/javase/downloads>.
|
||||
|
||||
* If using JDK 11 or later, CMake 3.10.x or later must also be used.
|
||||
|
||||
|
||||
Out-of-Tree Builds
|
||||
@@ -416,13 +420,14 @@ iPhone 3GS-4S/iPad 1st-3rd Generation and newer:
|
||||
IOS_SYSROOT=($IOS_PLATFORMDIR/Developer/SDKs/iPhoneOS*.sdk)
|
||||
export CFLAGS="-mfloat-abi=softfp -march=armv7 -mcpu=cortex-a8 -mtune=cortex-a8 -mfpu=neon -miphoneos-version-min=3.0"
|
||||
|
||||
cd {build_directory}
|
||||
|
||||
cat <<EOF >toolchain.cmake
|
||||
set(CMAKE_SYSTEM_NAME Darwin)
|
||||
set(CMAKE_SYSTEM_PROCESSOR arm)
|
||||
set(CMAKE_C_COMPILER ${IOS_PLATFORMDIR}/Developer/usr/bin/arm-apple-darwin10-llvm-gcc-4.2)
|
||||
EOF
|
||||
|
||||
cd {build_directory}
|
||||
cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake \
|
||||
-DCMAKE_OSX_SYSROOT=${IOS_SYSROOT[0]} \
|
||||
[additional CMake flags] {source_directory}
|
||||
@@ -441,13 +446,14 @@ Same as above, but replace the first line with:
|
||||
export CFLAGS="-mfloat-abi=softfp -arch armv7 -miphoneos-version-min=3.0"
|
||||
export ASMFLAGS="-no-integrated-as"
|
||||
|
||||
cd {build_directory}
|
||||
|
||||
cat <<EOF >toolchain.cmake
|
||||
set(CMAKE_SYSTEM_NAME Darwin)
|
||||
set(CMAKE_SYSTEM_PROCESSOR arm)
|
||||
set(CMAKE_C_COMPILER /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang)
|
||||
EOF
|
||||
|
||||
cd {build_directory}
|
||||
cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake \
|
||||
-DCMAKE_OSX_SYSROOT=${IOS_SYSROOT[0]} \
|
||||
[additional CMake flags] {source_directory}
|
||||
@@ -467,13 +473,14 @@ iPhone 5/iPad 4th Generation and newer:
|
||||
IOS_SYSROOT=($IOS_PLATFORMDIR/Developer/SDKs/iPhoneOS*.sdk)
|
||||
export CFLAGS="-Wall -mfloat-abi=softfp -march=armv7s -mcpu=swift -mtune=swift -mfpu=neon -miphoneos-version-min=6.0"
|
||||
|
||||
cd {build_directory}
|
||||
|
||||
cat <<EOF >toolchain.cmake
|
||||
set(CMAKE_SYSTEM_NAME Darwin)
|
||||
set(CMAKE_SYSTEM_PROCESSOR arm)
|
||||
set(CMAKE_C_COMPILER ${IOS_PLATFORMDIR}/Developer/usr/bin/arm-apple-darwin10-llvm-gcc-4.2)
|
||||
EOF
|
||||
|
||||
cd {build_directory}
|
||||
cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake \
|
||||
-DCMAKE_OSX_SYSROOT=${IOS_SYSROOT[0]} \
|
||||
[additional CMake flags] {source_directory}
|
||||
@@ -498,13 +505,14 @@ iPhone 5S/iPad Mini 2/iPad Air and newer.
|
||||
IOS_SYSROOT=($IOS_PLATFORMDIR/Developer/SDKs/iPhoneOS*.sdk)
|
||||
export CFLAGS="-Wall -arch arm64 -miphoneos-version-min=7.0 -funwind-tables"
|
||||
|
||||
cd {build_directory}
|
||||
|
||||
cat <<EOF >toolchain.cmake
|
||||
set(CMAKE_SYSTEM_NAME Darwin)
|
||||
set(CMAKE_SYSTEM_PROCESSOR aarch64)
|
||||
set(CMAKE_C_COMPILER /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang)
|
||||
EOF
|
||||
|
||||
cd {build_directory}
|
||||
cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake \
|
||||
-DCMAKE_OSX_SYSROOT=${IOS_SYSROOT[0]} \
|
||||
[additional CMake flags] {source_directory}
|
||||
@@ -517,7 +525,7 @@ a universal library.
|
||||
Building libjpeg-turbo for Android
|
||||
----------------------------------
|
||||
|
||||
Building libjpeg-turbo for Android platforms requires the
|
||||
Building libjpeg-turbo for Android platforms requires v13b or later of the
|
||||
[Android NDK](https://developer.android.com/tools/sdk/ndk).
|
||||
|
||||
|
||||
@@ -527,34 +535,21 @@ 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/sdk/ndk-bundle}
|
||||
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,
|
||||
NDK_PATH={full path to the NDK directory-- for example,
|
||||
/opt/android/android-ndk-r16b}
|
||||
TOOLCHAIN={"gcc" or "clang"-- "gcc" must be used with NDK r16b and earlier,
|
||||
and "clang" must be used with NDK r17c and later}
|
||||
ANDROID_VERSION={the minimum version of Android to support-- for example,
|
||||
"16", "19", etc.}
|
||||
|
||||
# It should not be necessary to modify the rest
|
||||
HOST=arm-linux-androideabi
|
||||
SYSROOT=${NDK_PATH}/platforms/android-${ANDROID_VERSION}/arch-arm
|
||||
export CFLAGS="-march=armv7-a -mfloat-abi=softfp -fprefetch-loop-arrays \
|
||||
-D__ANDROID_API__=${ANDROID_VERSION} --sysroot=${SYSROOT} \
|
||||
-isystem ${NDK_PATH}/sysroot/usr/include \
|
||||
-isystem ${NDK_PATH}/sysroot/usr/include/${HOST}"
|
||||
export LDFLAGS=-pie
|
||||
TOOLCHAIN=${NDK_PATH}/toolchains/${HOST}-${TOOLCHAIN_VERSION}/prebuilt/${BUILD_PLATFORM}
|
||||
|
||||
cat <<EOF >toolchain.cmake
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(CMAKE_SYSTEM_PROCESSOR arm)
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${HOST}-gcc)
|
||||
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/${HOST})
|
||||
EOF
|
||||
|
||||
cd {build_directory}
|
||||
cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake \
|
||||
-DCMAKE_POSITION_INDEPENDENT_CODE=1 \
|
||||
cmake -G"Unix Makefiles" \
|
||||
-DANDROID_ABI=armeabi-v7a \
|
||||
-DANDROID_ARM_MODE=arm \
|
||||
-DANDROID_PLATFORM=android-${ANDROID_VERSION} \
|
||||
-DANDROID_TOOLCHAIN=${TOOLCHAIN} \
|
||||
-DCMAKE_ASM_FLAGS="--target=arm-linux-androideabi${ANDROID_VERSION}" \
|
||||
-DCMAKE_TOOLCHAIN_FILE=${NDK_PATH}/build/cmake/android.toolchain.cmake \
|
||||
[additional CMake flags] {source_directory}
|
||||
make
|
||||
|
||||
@@ -565,33 +560,21 @@ 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/sdk/ndk-bundle}
|
||||
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. "21" or later
|
||||
NDK_PATH={full path to the NDK directory-- for example,
|
||||
/opt/android/android-ndk-r16b}
|
||||
TOOLCHAIN={"gcc" or "clang"-- "gcc" must be used with NDK r14b and earlier,
|
||||
and "clang" must be used with NDK r17c and later}
|
||||
ANDROID_VERSION={the minimum version of Android to support. "21" or later
|
||||
is required for a 64-bit build.}
|
||||
|
||||
# It should not be necessary to modify the rest
|
||||
HOST=aarch64-linux-android
|
||||
SYSROOT=${NDK_PATH}/platforms/android-${ANDROID_VERSION}/arch-arm64
|
||||
export CFLAGS="-D__ANDROID_API__=${ANDROID_VERSION} --sysroot=${SYSROOT} \
|
||||
-isystem ${NDK_PATH}/sysroot/usr/include \
|
||||
-isystem ${NDK_PATH}/sysroot/usr/include/${HOST}"
|
||||
export LDFLAGS=-pie
|
||||
TOOLCHAIN=${NDK_PATH}/toolchains/${HOST}-${TOOLCHAIN_VERSION}/prebuilt/${BUILD_PLATFORM}
|
||||
|
||||
cat <<EOF >toolchain.cmake
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(CMAKE_SYSTEM_PROCESSOR aarch64)
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${HOST}-gcc)
|
||||
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/${HOST})
|
||||
EOF
|
||||
|
||||
cd {build_directory}
|
||||
cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake \
|
||||
-DCMAKE_POSITION_INDEPENDENT_CODE=1 \
|
||||
cmake -G"Unix Makefiles" \
|
||||
-DANDROID_ABI=arm64-v8a \
|
||||
-DANDROID_ARM_MODE=arm \
|
||||
-DANDROID_PLATFORM=android-${ANDROID_VERSION} \
|
||||
-DANDROID_TOOLCHAIN=${TOOLCHAIN} \
|
||||
-DCMAKE_ASM_FLAGS="--target=aarch64-linux-android${ANDROID_VERSION}" \
|
||||
-DCMAKE_TOOLCHAIN_FILE=${NDK_PATH}/build/cmake/android.toolchain.cmake \
|
||||
[additional CMake flags] {source_directory}
|
||||
make
|
||||
|
||||
@@ -602,33 +585,19 @@ 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/sdk/ndk-bundle}
|
||||
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/.}
|
||||
NDK_PATH={full path to the NDK directory-- for example,
|
||||
/opt/android/android-ndk-r16b}
|
||||
TOOLCHAIN={"gcc" or "clang"-- "gcc" must be used with NDK r14b and earlier,
|
||||
and "clang" must be used with NDK r17c and later}
|
||||
ANDROID_VERSION={The minimum version of Android to support-- for example,
|
||||
"16", "19", etc.}
|
||||
|
||||
# It should not be necessary to modify the rest
|
||||
HOST=i686-linux-android
|
||||
SYSROOT=${NDK_PATH}/platforms/android-${ANDROID_VERSION}/arch-x86
|
||||
export CFLAGS="-D__ANDROID_API__=${ANDROID_VERSION} --sysroot=${SYSROOT} \
|
||||
-isystem ${NDK_PATH}/sysroot/usr/include \
|
||||
-isystem ${NDK_PATH}/sysroot/usr/include/${HOST}"
|
||||
export LDFLAGS=-pie
|
||||
TOOLCHAIN=${NDK_PATH}/toolchains/x86-${TOOLCHAIN_VERSION}/prebuilt/${BUILD_PLATFORM}
|
||||
|
||||
cat <<EOF >toolchain.cmake
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(CMAKE_SYSTEM_PROCESSOR i386)
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${HOST}-gcc)
|
||||
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/${HOST})
|
||||
EOF
|
||||
|
||||
cd {build_directory}
|
||||
cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake \
|
||||
-DCMAKE_POSITION_INDEPENDENT_CODE=1 \
|
||||
cmake -G"Unix Makefiles" \
|
||||
-DANDROID_ABI=x86 \
|
||||
-DANDROID_PLATFORM=android-${ANDROID_VERSION} \
|
||||
-DANDROID_TOOLCHAIN=${TOOLCHAIN} \
|
||||
-DCMAKE_TOOLCHAIN_FILE=${NDK_PATH}/build/cmake/android.toolchain.cmake \
|
||||
[additional CMake flags] {source_directory}
|
||||
make
|
||||
|
||||
@@ -639,42 +608,23 @@ 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/sdk/ndk-bundle}
|
||||
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. "21" or later
|
||||
NDK_PATH={full path to the NDK directory-- for example,
|
||||
/opt/android/android-ndk-r16b}
|
||||
TOOLCHAIN={"gcc" or "clang"-- "gcc" must be used with NDK r14b and earlier,
|
||||
and "clang" must be used with NDK r17c and later}
|
||||
ANDROID_VERSION={the minimum version of Android to support. "21" or later
|
||||
is required for a 64-bit build.}
|
||||
|
||||
# It should not be necessary to modify the rest
|
||||
HOST=x86_64-linux-android
|
||||
SYSROOT=${NDK_PATH}/platforms/android-${ANDROID_VERSION}/arch-x86_64
|
||||
export CFLAGS="-D__ANDROID_API__=${ANDROID_VERSION} --sysroot=${SYSROOT} \
|
||||
-isystem ${NDK_PATH}/sysroot/usr/include \
|
||||
-isystem ${NDK_PATH}/sysroot/usr/include/${HOST}"
|
||||
export LDFLAGS=-pie
|
||||
TOOLCHAIN=${NDK_PATH}/toolchains/x86_64-${TOOLCHAIN_VERSION}/prebuilt/${BUILD_PLATFORM}
|
||||
|
||||
cat <<EOF >toolchain.cmake
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(CMAKE_SYSTEM_PROCESSOR x86_64)
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${HOST}-gcc)
|
||||
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/${HOST})
|
||||
EOF
|
||||
|
||||
cd {build_directory}
|
||||
cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake \
|
||||
-DCMAKE_POSITION_INDEPENDENT_CODE=1 \
|
||||
cmake -G"Unix Makefiles" \
|
||||
-DANDROID_ABI=x86_64 \
|
||||
-DANDROID_PLATFORM=android-${ANDROID_VERSION} \
|
||||
-DANDROID_TOOLCHAIN=${TOOLCHAIN} \
|
||||
-DCMAKE_TOOLCHAIN_FILE=${NDK_PATH}/build/cmake/android.toolchain.cmake \
|
||||
[additional CMake flags] {source_directory}
|
||||
make
|
||||
|
||||
|
||||
If building for Android 4.0.x (API level < 16) or earlier, remove
|
||||
`-DCMAKE_POSITION_INDEPENDENT_CODE=1` from the CMake arguments and `-pie` from
|
||||
`LDFLAGS`.
|
||||
|
||||
|
||||
Advanced CMake Options
|
||||
----------------------
|
||||
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
if(CMAKE_EXECUTABLE_SUFFIX)
|
||||
set(CMAKE_EXECUTABLE_SUFFIX_TMP ${CMAKE_EXECUTABLE_SUFFIX})
|
||||
endif()
|
||||
|
||||
project(libjpeg-turbo C)
|
||||
set(VERSION 1.5.90)
|
||||
set(VERSION 2.0.3)
|
||||
string(REPLACE "." ";" VERSION_TRIPLET ${VERSION})
|
||||
list(GET VERSION_TRIPLET 0 VERSION_MAJOR)
|
||||
list(GET VERSION_TRIPLET 1 VERSION_MINOR)
|
||||
@@ -105,8 +109,6 @@ endif()
|
||||
|
||||
include(cmakescripts/GNUInstallDirs.cmake)
|
||||
|
||||
set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR})
|
||||
|
||||
macro(report_directory var)
|
||||
if(CMAKE_INSTALL_${var} STREQUAL CMAKE_INSTALL_FULL_${var})
|
||||
message(STATUS "CMAKE_INSTALL_${var} = ${CMAKE_INSTALL_${var}}")
|
||||
@@ -187,6 +189,10 @@ endif()
|
||||
report_option(ENABLE_SHARED "Shared libraries")
|
||||
report_option(ENABLE_STATIC "Static libraries")
|
||||
|
||||
if(ENABLE_SHARED)
|
||||
set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR})
|
||||
endif()
|
||||
|
||||
if(WITH_12BIT)
|
||||
set(WITH_ARITH_DEC 0)
|
||||
set(WITH_ARITH_ENC 0)
|
||||
@@ -351,6 +357,9 @@ if(SIZE_T EQUAL UNSIGNED_LONG)
|
||||
check_c_source_compiles("int main(int argc, char **argv) { unsigned long a = argc; return __builtin_ctzl(a); }"
|
||||
HAVE_BUILTIN_CTZL)
|
||||
endif()
|
||||
if(MSVC)
|
||||
check_include_files("intrin.h" HAVE_INTRIN_H)
|
||||
endif()
|
||||
|
||||
if(UNIX)
|
||||
# Check for headers
|
||||
@@ -360,9 +369,9 @@ if(UNIX)
|
||||
check_include_files(sys/types.h NEED_SYS_TYPES_H)
|
||||
|
||||
# Check for functions
|
||||
include(CheckFunctionExists)
|
||||
check_function_exists(memset HAVE_MEMSET)
|
||||
check_function_exists(memcpy HAVE_MEMCPY)
|
||||
include(CheckSymbolExists)
|
||||
check_symbol_exists(memset string.h HAVE_MEMSET)
|
||||
check_symbol_exists(memcpy string.h HAVE_MEMCPY)
|
||||
if(NOT HAVE_MEMSET AND NOT HAVE_MEMCPY)
|
||||
set(NEED_BSD_STRINGS 1)
|
||||
endif()
|
||||
@@ -372,7 +381,7 @@ if(UNIX)
|
||||
check_type_size("unsigned short" UNSIGNED_SHORT)
|
||||
|
||||
# Check for compiler features
|
||||
check_c_source_compiles("int main(void) { typedef struct undefined_structure *undef_struct_ptr; }"
|
||||
check_c_source_compiles("int main(void) { typedef struct undefined_structure *undef_struct_ptr; undef_struct_ptr ptr = 0; return ptr != 0; }"
|
||||
INCOMPLETE_TYPES)
|
||||
if(INCOMPLETE_TYPES)
|
||||
message(STATUS "Compiler supports pointers to undefined structures.")
|
||||
@@ -415,7 +424,6 @@ if(UNIX)
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
check_include_files("intrin.h" HAVE_INTRIN_H)
|
||||
set(INLINE_OPTIONS "__inline;inline")
|
||||
else()
|
||||
set(INLINE_OPTIONS "__inline__;inline")
|
||||
@@ -431,7 +439,7 @@ if(FORCE_INLINE)
|
||||
endif()
|
||||
endif()
|
||||
foreach(inline ${INLINE_OPTIONS})
|
||||
check_c_source_compiles("${inline} static void foo(void) {} int main(void) { foo(); }"
|
||||
check_c_source_compiles("${inline} static int foo(void) { return 0; } int main(void) { return foo(); }"
|
||||
INLINE_WORKS)
|
||||
if(INLINE_WORKS)
|
||||
set(INLINE ${inline})
|
||||
@@ -462,8 +470,8 @@ if(UNIX AND NOT APPLE)
|
||||
# still work.
|
||||
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/conftest.map
|
||||
"VERS_1 { global: foo; local: *; }; VERS_2 { global: foo2; } VERS_1;")
|
||||
set(CMAKE_REQUIRED_FLAGS "-Wl,-M,${CMAKE_CURRENT_BINARY_DIR}/conftest.map")
|
||||
check_c_source_compiles("void foo() {} void foo2() {} int main(void) { return 0; }"
|
||||
set(CMAKE_REQUIRED_FLAGS "-Wl,-M,${CMAKE_CURRENT_BINARY_DIR}/conftest.map -shared")
|
||||
check_c_source_compiles("int foo() { return 0; } int foo2() { return 2; }"
|
||||
HAVE_MAPFILE)
|
||||
set(CMAKE_REQUIRED_FLAGS)
|
||||
file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/conftest.map)
|
||||
@@ -496,6 +504,11 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
# TARGETS
|
||||
###############################################################################
|
||||
|
||||
if(CMAKE_EXECUTABLE_SUFFIX_TMP)
|
||||
set(CMAKE_EXECUTABLE_SUFFIX ${CMAKE_EXECUTABLE_SUFFIX_TMP})
|
||||
endif()
|
||||
message(STATUS "CMAKE_EXECUTABLE_SUFFIX = ${CMAKE_EXECUTABLE_SUFFIX}")
|
||||
|
||||
set(JPEG_SOURCES jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c
|
||||
jcicc.c jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c
|
||||
jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c jdatadst.c
|
||||
@@ -523,7 +536,7 @@ elseif(NOT WITH_12BIT)
|
||||
endif()
|
||||
if(WITH_SIMD)
|
||||
message(STATUS "SIMD extensions: ${CPU_TYPE} (WITH_SIMD = ${WITH_SIMD})")
|
||||
if(MSVC_IDE)
|
||||
if(MSVC_IDE OR XCODE)
|
||||
set_source_files_properties(${SIMD_OBJS} PROPERTIES GENERATED 1)
|
||||
endif()
|
||||
else()
|
||||
@@ -566,7 +579,8 @@ if(WITH_TURBOJPEG)
|
||||
if(MINGW)
|
||||
set_target_properties(turbojpeg PROPERTIES LINK_FLAGS -Wl,--kill-at)
|
||||
endif()
|
||||
if(APPLE)
|
||||
if(APPLE AND (NOT CMAKE_OSX_DEPLOYMENT_TARGET OR
|
||||
CMAKE_OSX_DEPLOYMENT_TARGET VERSION_GREATER 10.4))
|
||||
if(NOT CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG)
|
||||
set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,")
|
||||
endif()
|
||||
@@ -652,7 +666,7 @@ add_executable(wrjpgcom wrjpgcom.c)
|
||||
|
||||
add_subdirectory(md5)
|
||||
|
||||
if(MSVC_IDE)
|
||||
if(MSVC_IDE OR XCODE)
|
||||
set(OBJDIR "\${CTEST_CONFIGURATION_TYPE}/")
|
||||
else()
|
||||
set(OBJDIR "")
|
||||
@@ -668,7 +682,7 @@ if(WITH_12BIT)
|
||||
set(MD5_JPEG_422_IFAST_OPT 7322e3bd2f127f7de4b40d4480ce60e4)
|
||||
set(MD5_PPM_422_IFAST 79807fa552899e66a04708f533e16950)
|
||||
set(MD5_PPM_422M_IFAST 07737bfe8a7c1c87aaa393a0098d16b0)
|
||||
set(MD5_JPEG_420_IFAST_Q100_PROG a1da220b5604081863a504297ed59e55)
|
||||
set(MD5_JPEG_420_IFAST_Q100_PROG 008ab68d6ddbba04a8f01deee4e0f9f8)
|
||||
set(MD5_PPM_420_Q100_IFAST 1b3730122709f53d007255e8dfd3305e)
|
||||
set(MD5_PPM_420M_Q100_IFAST 980a1a3c5bf9510022869d30b7d26566)
|
||||
set(MD5_JPEG_GRAY_ISLOW 235c90707b16e2e069f37c888b2636d9)
|
||||
@@ -718,7 +732,7 @@ else()
|
||||
set(MD5_PPM_422M_IFAST 8dbc65323d62cca7c91ba02dd1cfa81d)
|
||||
set(MD5_BMP_422M_IFAST_565 3294bd4d9a1f2b3d08ea6020d0db7065)
|
||||
set(MD5_BMP_422M_IFAST_565D da98c9c7b6039511be4a79a878a9abc1)
|
||||
set(MD5_JPEG_420_IFAST_Q100_PROG 990cbe0329c882420a2094da7e5adade)
|
||||
set(MD5_JPEG_420_IFAST_Q100_PROG e59bb462016a8d9a748c330a3474bb55)
|
||||
set(MD5_PPM_420_Q100_IFAST 5a732542015c278ff43635e473a8a294)
|
||||
set(MD5_PPM_420M_Q100_IFAST ff692ee9323a3b424894862557c092f1)
|
||||
set(MD5_JPEG_GRAY_ISLOW 72b51f894b8f4a10b3ee3066770aa38d)
|
||||
@@ -985,6 +999,8 @@ foreach(libtype ${TEST_LIBTYPES})
|
||||
|
||||
add_test(djpeg-${libtype}-rgb-islow-icc-cmp
|
||||
${MD5CMP} b06a39d730129122e85c1363ed1bbc9e testout_rgb_islow.icc)
|
||||
set_tests_properties(djpeg-${libtype}-rgb-islow-icc-cmp PROPERTIES
|
||||
DEPENDS djpeg-${libtype}-rgb-islow)
|
||||
|
||||
add_bittest(jpegtran icc "-copy;all;-icc;${TESTIMAGES}/test2.icc"
|
||||
testout_rgb_islow2.jpg testout_rgb_islow.jpg ${MD5_JPEG_RGB_ISLOW2})
|
||||
@@ -1031,7 +1047,7 @@ foreach(libtype ${TEST_LIBTYPES})
|
||||
|
||||
# CC: RGB->YCC SAMP: fullsize/h2v2 FDCT: ifast ENT: prog huff
|
||||
add_bittest(cjpeg 420-q100-ifast-prog
|
||||
"-sample;2x2;-quality;100;-dct;fast;-prog"
|
||||
"-sample;2x2;-quality;100;-dct;fast;-scans;${TESTIMAGES}/test.scan"
|
||||
testout_420_q100_ifast_prog.jpg ${TESTIMAGES}/testorig.ppm
|
||||
${MD5_JPEG_420_IFAST_Q100_PROG})
|
||||
|
||||
@@ -1274,6 +1290,8 @@ if(WITH_TURBOJPEG)
|
||||
COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/tjbenchtest -yuv -alloc
|
||||
COMMAND echo tjbenchtest -progressive
|
||||
COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/tjbenchtest -progressive
|
||||
COMMAND echo tjbenchtest -progressive -yuv
|
||||
COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/tjbenchtest -progressive -yuv
|
||||
COMMAND echo tjexampletest
|
||||
COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/tjexampletest
|
||||
COMMAND echo tjbenchtest.java
|
||||
@@ -1282,6 +1300,9 @@ if(WITH_TURBOJPEG)
|
||||
COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/tjbenchtest.java -yuv
|
||||
COMMAND echo tjbenchtest.java -progressive
|
||||
COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/tjbenchtest.java -progressive
|
||||
COMMAND echo tjexampletest.java -progressive -yuv
|
||||
COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/tjbenchtest.java
|
||||
-progressive -yuv
|
||||
COMMAND echo tjexampletest.java
|
||||
COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/tjexampletest.java
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/tjbenchtest
|
||||
@@ -1297,6 +1318,10 @@ if(WITH_TURBOJPEG)
|
||||
COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/tjbenchtest -yuv
|
||||
COMMAND echo tjbenchtest -yuv -alloc
|
||||
COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/tjbenchtest -yuv -alloc
|
||||
COMMAND echo tjbenchtest -progressive
|
||||
COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/tjbenchtest -progressive
|
||||
COMMAND echo tjbenchtest -progressive -yuv
|
||||
COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/tjbenchtest -progressive -yuv
|
||||
COMMAND echo tjexampletest
|
||||
COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/tjexampletest
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/tjbenchtest)
|
||||
@@ -1308,9 +1333,7 @@ endif()
|
||||
# INSTALLATION
|
||||
###############################################################################
|
||||
|
||||
if(WIN32)
|
||||
set(EXE ".exe")
|
||||
endif()
|
||||
set(EXE ${CMAKE_EXECUTABLE_SUFFIX})
|
||||
|
||||
if(WITH_TURBOJPEG)
|
||||
if(ENABLE_SHARED)
|
||||
@@ -1318,12 +1341,22 @@ if(WITH_TURBOJPEG)
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
if(NOT CMAKE_VERSION VERSION_LESS "3.1" AND MSVC AND
|
||||
CMAKE_C_LINKER_SUPPORTS_PDB)
|
||||
install(FILES "$<TARGET_PDB_FILE:turbojpeg>"
|
||||
DESTINATION ${CMAKE_INSTALL_BINDIR} OPTIONAL)
|
||||
endif()
|
||||
endif()
|
||||
if(ENABLE_STATIC)
|
||||
install(TARGETS turbojpeg-static ARCHIVE
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
if(NOT ENABLE_SHARED)
|
||||
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/tjbench-static${EXE}
|
||||
if(MSVC_IDE OR XCODE)
|
||||
set(DIR "${CMAKE_CURRENT_BINARY_DIR}/\${CMAKE_INSTALL_CONFIG_NAME}")
|
||||
else()
|
||||
set(DIR ${CMAKE_CURRENT_BINARY_DIR})
|
||||
endif()
|
||||
install(PROGRAMS ${DIR}/tjbench-static${EXE}
|
||||
DESTINATION ${CMAKE_INSTALL_BINDIR} RENAME tjbench${EXE})
|
||||
endif()
|
||||
endif()
|
||||
@@ -1334,11 +1367,16 @@ endif()
|
||||
if(ENABLE_STATIC)
|
||||
install(TARGETS jpeg-static ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
if(NOT ENABLE_SHARED)
|
||||
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/cjpeg-static${EXE}
|
||||
if(MSVC_IDE OR XCODE)
|
||||
set(DIR "${CMAKE_CURRENT_BINARY_DIR}/\${CMAKE_INSTALL_CONFIG_NAME}")
|
||||
else()
|
||||
set(DIR ${CMAKE_CURRENT_BINARY_DIR})
|
||||
endif()
|
||||
install(PROGRAMS ${DIR}/cjpeg-static${EXE}
|
||||
DESTINATION ${CMAKE_INSTALL_BINDIR} RENAME cjpeg${EXE})
|
||||
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/djpeg-static${EXE}
|
||||
install(PROGRAMS ${DIR}/djpeg-static${EXE}
|
||||
DESTINATION ${CMAKE_INSTALL_BINDIR} RENAME djpeg${EXE})
|
||||
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/jpegtran-static${EXE}
|
||||
install(PROGRAMS ${DIR}/jpegtran-static${EXE}
|
||||
DESTINATION ${CMAKE_INSTALL_BINDIR} RENAME jpegtran${EXE})
|
||||
endif()
|
||||
endif()
|
||||
@@ -1363,10 +1401,10 @@ if(UNIX OR MINGW)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rdjpgcom.1
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wrjpgcom.1
|
||||
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pkgscripts/libjpeg.pc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/pkgscripts/libturbojpeg.pc
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||
endif()
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pkgscripts/libjpeg.pc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/pkgscripts/libturbojpeg.pc
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/jconfig.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/jerror.h ${CMAKE_CURRENT_SOURCE_DIR}/jmorecfg.h
|
||||
|
||||
173
ChangeLog.md
173
ChangeLog.md
@@ -1,3 +1,172 @@
|
||||
2.0.3
|
||||
=====
|
||||
|
||||
### Significant changes relative to 2.0.2:
|
||||
|
||||
1. Fixed "using JNI after critical get" errors that occurred on Android
|
||||
platforms when passing invalid arguments to certain methods in the TurboJPEG
|
||||
Java API.
|
||||
|
||||
2. Fixed a regression in the SIMD feature detection code, introduced by
|
||||
the AVX2 SIMD extensions (2.0 beta1[1]), that was known to cause an illegal
|
||||
instruction exception, in rare cases, on CPUs that lack support for CPUID leaf
|
||||
07H (or on which the maximum CPUID leaf has been limited by way of a BIOS
|
||||
setting.)
|
||||
|
||||
3. The 4:4:0 (h1v2) fancy (smooth) chroma upsampling algorithm in the
|
||||
decompressor now uses a similar bias pattern to that of the 4:2:2 (h2v1) fancy
|
||||
chroma upsampling algorithm, rounding up or down the upsampled result for
|
||||
alternate pixels rather than always rounding down. This ensures that,
|
||||
regardless of whether a 4:2:2 JPEG image is rotated or transposed prior to
|
||||
decompression (in the frequency domain) or after decompression (in the spatial
|
||||
domain), the final image will be similar.
|
||||
|
||||
4. Fixed an integer overflow and subsequent segfault that occurred when
|
||||
attempting to compress or decompress images with more than 1 billion pixels
|
||||
using the TurboJPEG API.
|
||||
|
||||
5. Fixed a regression introduced by 2.0 beta1[15] whereby attempting to
|
||||
generate a progressive JPEG image on an SSE2-capable CPU using a scan script
|
||||
containing one or more scans with lengths divisible by 16 would result in an
|
||||
error ("Missing Huffman code table entry") and an invalid JPEG image.
|
||||
|
||||
6. Fixed an issue whereby `tjDecodeYUV()` and `tjDecodeYUVPlanes()` would throw
|
||||
an error ("Invalid progressive parameters") or a warning ("Inconsistent
|
||||
progression sequence") if passed a TurboJPEG instance that was previously used
|
||||
to decompress a progressive JPEG image.
|
||||
|
||||
|
||||
2.0.2
|
||||
=====
|
||||
|
||||
### Significant changes relative to 2.0.1:
|
||||
|
||||
1. Fixed a regression introduced by 2.0.1[5] that prevented a runtime search
|
||||
path (rpath) from being embedded in the libjpeg-turbo shared libraries and
|
||||
executables for macOS and iOS. This caused a fatal error of the form
|
||||
"dyld: Library not loaded" when attempting to use one of the executables,
|
||||
unless `DYLD_LIBRARY_PATH` was explicitly set to the location of the
|
||||
libjpeg-turbo shared libraries.
|
||||
|
||||
2. Fixed an integer overflow and subsequent segfault (CVE-2018-20330) that
|
||||
occurred when attempting to load a BMP file with more than 1 billion pixels
|
||||
using the `tjLoadImage()` function.
|
||||
|
||||
3. Fixed a buffer overrun (CVE-2018-19664) that occurred when attempting to
|
||||
decompress a specially-crafted malformed JPEG image to a 256-color BMP using
|
||||
djpeg.
|
||||
|
||||
4. Fixed a floating point exception that occurred when attempting to
|
||||
decompress a specially-crafted malformed JPEG image with a specified image
|
||||
width or height of 0 using the C version of TJBench.
|
||||
|
||||
5. The TurboJPEG API will now decompress 4:4:4 JPEG images with 2x1, 1x2, 3x1,
|
||||
or 1x3 luminance and chrominance sampling factors. This is a non-standard way
|
||||
of specifying 1x subsampling (normally 4:4:4 JPEGs have 1x1 luminance and
|
||||
chrominance sampling factors), but the JPEG format and the libjpeg API both
|
||||
allow it.
|
||||
|
||||
6. Fixed a regression introduced by 2.0 beta1[7] that caused djpeg to generate
|
||||
incorrect PPM images when used with the `-colors` option.
|
||||
|
||||
7. Fixed an issue whereby a static build of libjpeg-turbo (a build in which
|
||||
`ENABLE_SHARED` is `0`) could not be installed using the Visual Studio IDE.
|
||||
|
||||
8. Fixed a severe performance issue in the Loongson MMI SIMD extensions that
|
||||
occurred when compressing RGB images whose image rows were not 64-bit-aligned.
|
||||
|
||||
|
||||
2.0.1
|
||||
=====
|
||||
|
||||
### Significant changes relative to 2.0.0:
|
||||
|
||||
1. Fixed a regression introduced with the new CMake-based Un*x build system,
|
||||
whereby jconfig.h could cause compiler warnings of the form
|
||||
`"HAVE_*_H" redefined` if it was included by downstream Autotools-based
|
||||
projects that used `AC_CHECK_HEADERS()` to check for the existence of locale.h,
|
||||
stddef.h, or stdlib.h.
|
||||
|
||||
2. The `jsimd_quantize_float_dspr2()` and `jsimd_convsamp_float_dspr2()`
|
||||
functions in the MIPS DSPr2 SIMD extensions are now disabled at compile time
|
||||
if the soft float ABI is enabled. Those functions use instructions that are
|
||||
incompatible with the soft float ABI.
|
||||
|
||||
3. Fixed a regression in the SIMD feature detection code, introduced by
|
||||
the AVX2 SIMD extensions (2.0 beta1[1]), that caused libjpeg-turbo to crash on
|
||||
Windows 7 if Service Pack 1 was not installed.
|
||||
|
||||
4. Fixed out-of-bounds read in cjpeg that occurred when attempting to compress
|
||||
a specially-crafted malformed color-index (8-bit-per-sample) Targa file in
|
||||
which some of the samples (color indices) exceeded the bounds of the Targa
|
||||
file's color table.
|
||||
|
||||
5. Fixed an issue whereby installing a fully static build of libjpeg-turbo
|
||||
(a build in which `CFLAGS` contains `-static` and `ENABLE_SHARED` is `0`) would
|
||||
fail with "No valid ELF RPATH or RUNPATH entry exists in the file."
|
||||
|
||||
|
||||
2.0.0
|
||||
=====
|
||||
|
||||
### Significant changes relative to 2.0 beta1:
|
||||
|
||||
1. The TurboJPEG API can now decompress CMYK JPEG images that have subsampled M
|
||||
and Y components (not to be confused with YCCK JPEG images, in which the C/M/Y
|
||||
components have been transformed into luma and chroma.) Previously, an error
|
||||
was generated ("Could not determine subsampling type for JPEG image") when such
|
||||
an image was passed to `tjDecompressHeader3()`, `tjTransform()`,
|
||||
`tjDecompressToYUVPlanes()`, `tjDecompressToYUV2()`, or the equivalent Java
|
||||
methods.
|
||||
|
||||
2. Fixed an issue (CVE-2018-11813) whereby a specially-crafted malformed input
|
||||
file (specifically, a file with a valid Targa header but incomplete pixel data)
|
||||
would cause cjpeg to generate a JPEG file that was potentially thousands of
|
||||
times larger than the input file. The Targa reader in cjpeg was not properly
|
||||
detecting that the end of the input file had been reached prematurely, so after
|
||||
all valid pixels had been read from the input, the reader injected dummy pixels
|
||||
with values of 255 into the JPEG compressor until the number of pixels
|
||||
specified in the Targa header had been compressed. The Targa reader in cjpeg
|
||||
now behaves like the PPM reader and aborts compression if the end of the input
|
||||
file is reached prematurely. Because this issue only affected cjpeg and not
|
||||
the underlying library, and because it did not involve any out-of-bounds reads
|
||||
or other exploitable behaviors, it was not believed to represent a security
|
||||
threat.
|
||||
|
||||
3. Fixed an issue whereby the `tjLoadImage()` and `tjSaveImage()` functions
|
||||
would produce a "Bogus message code" error message if the underlying bitmap and
|
||||
PPM readers/writers threw an error that was specific to the readers/writers
|
||||
(as opposed to a general libjpeg API error.)
|
||||
|
||||
4. Fixed an issue whereby a specially-crafted malformed BMP file, one in which
|
||||
the header specified an image width of 1073741824 pixels, would trigger a
|
||||
floating point exception (division by zero) in the `tjLoadImage()` function
|
||||
when attempting to load the BMP file into a 4-component image buffer.
|
||||
|
||||
5. Fixed an issue whereby certain combinations of calls to
|
||||
`jpeg_skip_scanlines()` and `jpeg_read_scanlines()` could trigger an infinite
|
||||
loop when decompressing progressive JPEG images that use vertical chroma
|
||||
subsampling (for instance, 4:2:0 or 4:4:0.)
|
||||
|
||||
6. Fixed a segfault in `jpeg_skip_scanlines()` that occurred when decompressing
|
||||
a 4:2:2 or 4:2:0 JPEG image using the merged (non-fancy) upsampling algorithms
|
||||
(that is, when setting `cinfo.do_fancy_upsampling` to `FALSE`.)
|
||||
|
||||
7. The new CMake-based build system will now disable the MIPS DSPr2 SIMD
|
||||
extensions if it detects that the compiler does not support DSPr2 instructions.
|
||||
|
||||
8. Fixed out-of-bounds read in cjpeg that occurred when attempting to compress
|
||||
a specially-crafted malformed color-index (8-bit-per-sample) BMP file in which
|
||||
some of the samples (color indices) exceeded the bounds of the BMP file's color
|
||||
table.
|
||||
|
||||
9. Fixed a signed integer overflow in the progressive Huffman decoder, detected
|
||||
by the Clang and GCC undefined behavior sanitizers, that could be triggered by
|
||||
attempting to decompress a specially-crafted malformed JPEG image. This issue
|
||||
did not pose a security threat, but removing the warning made it easier to
|
||||
detect actual security issues, should they arise in the future.
|
||||
|
||||
|
||||
1.5.90 (2.0 beta1)
|
||||
==================
|
||||
|
||||
@@ -305,8 +474,8 @@ specified.)
|
||||
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.
|
||||
1x2 luminance and 1x1 chrominance sampling factors), but the JPEG format 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
|
||||
|
||||
36
LICENSE.md
36
LICENSE.md
@@ -14,7 +14,7 @@ libjpeg-turbo is covered by three compatible BSD-style open source licenses:
|
||||
This license covers the TurboJPEG API library and associated programs, as
|
||||
well as the build system.
|
||||
|
||||
- The zlib License, which is listed below
|
||||
- The [zlib License](https://opensource.org/licenses/Zlib)
|
||||
|
||||
This license is a subset of the other two, and it covers the libjpeg-turbo
|
||||
SIMD extensions.
|
||||
@@ -66,7 +66,7 @@ best of our understanding.
|
||||
|
||||
2. If your binary distribution includes or uses the TurboJPEG API, then
|
||||
your product documentation must include the text of the Modified BSD
|
||||
License.
|
||||
License (see below.)
|
||||
|
||||
**Origin**
|
||||
- Clause 2 of the Modified BSD License
|
||||
@@ -91,7 +91,8 @@ best of our understanding.
|
||||
The Modified (3-clause) BSD License
|
||||
===================================
|
||||
|
||||
Copyright (C)\<YEAR\> \<AUTHOR\>. All Rights Reserved.
|
||||
Copyright (C)2009-2019 D. R. Commander. All Rights Reserved.
|
||||
Copyright (C)2015 Viktor Szathmáry. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
@@ -118,23 +119,14 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
The zlib License
|
||||
================
|
||||
Why Three Licenses?
|
||||
===================
|
||||
|
||||
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.
|
||||
The zlib License could have been used instead of the Modified (3-clause) BSD
|
||||
License, and since the IJG License effectively subsumes the distribution
|
||||
conditions of the zlib License, this would have effectively placed
|
||||
libjpeg-turbo binary distributions under the IJG License. However, the IJG
|
||||
License specifically refers to the Independent JPEG Group and does not extend
|
||||
attribution and endorsement protections to other entities. Thus, it was
|
||||
desirable to choose a license that granted us the same protections for new code
|
||||
that were granted to the IJG for code derived from their software.
|
||||
|
||||
42
README.ijg
42
README.ijg
@@ -214,14 +214,14 @@ Continuous-tone Still Images, Part 2: Compliance testing" and has document
|
||||
numbers ISO/IEC IS 10918-2, ITU-T T.83.
|
||||
|
||||
The JPEG standard does not specify all details of an interchangeable file
|
||||
format. For the omitted details we follow the "JFIF" conventions, revision
|
||||
1.02. JFIF 1.02 has been adopted as an Ecma International Technical Report
|
||||
and thus received a formal publication status. It is available as a free
|
||||
download in PDF format from
|
||||
http://www.ecma-international.org/publications/techreports/E-TR-098.htm.
|
||||
A PostScript version of the JFIF document is available at
|
||||
http://www.ijg.org/files/jfif.ps.gz. There is also a plain text version at
|
||||
http://www.ijg.org/files/jfif.txt.gz, but it is missing the figures.
|
||||
format. For the omitted details, we follow the "JFIF" conventions, revision
|
||||
1.02. JFIF version 1 has been adopted as ISO/IEC 10918-5 (05/2013) and
|
||||
Recommendation ITU-T T.871 (05/2011): Information technology - Digital
|
||||
compression and coding of continuous-tone still images: JPEG File Interchange
|
||||
Format (JFIF). It is available as a free download in PDF file format from
|
||||
https://www.iso.org/standard/54989.html and http://www.itu.int/rec/T-REC-T.871.
|
||||
A PDF file of the older JFIF 1.02 specification is available at
|
||||
http://www.w3.org/Graphics/JPEG/jfif3.pdf.
|
||||
|
||||
The TIFF 6.0 file format specification can be obtained by FTP from
|
||||
ftp://ftp.sgi.com/graphics/tiff/TIFF6.ps.gz. The JPEG incorporation scheme
|
||||
@@ -253,18 +253,22 @@ with body
|
||||
send usenet/news.answers/jpeg-faq/part2
|
||||
|
||||
|
||||
FILE FORMAT WARS
|
||||
================
|
||||
FILE FORMAT COMPATIBILITY
|
||||
=========================
|
||||
|
||||
The ISO/IEC JTC1/SC29/WG1 standards committee (also known as JPEG, together
|
||||
with ITU-T SG16) currently promotes different formats containing the name
|
||||
"JPEG" which are incompatible with original DCT-based JPEG. IJG therefore does
|
||||
not support these formats (see REFERENCES). Indeed, one of the original
|
||||
reasons for developing this free software was to help force convergence on
|
||||
common, interoperable format standards for JPEG files.
|
||||
Don't use an incompatible file format!
|
||||
(In any case, our decoder will remain capable of reading existing JPEG
|
||||
image files indefinitely.)
|
||||
This software implements ITU T.81 | ISO/IEC 10918 with some extensions from
|
||||
ITU T.871 | ISO/IEC 10918-5 (JPEG File Interchange Format-- see REFERENCES).
|
||||
Informally, the term "JPEG image" or "JPEG file" most often refers to JFIF or
|
||||
a subset thereof, but there are other formats containing the name "JPEG" that
|
||||
are incompatible with the DCT-based JPEG standard or with JFIF (for instance,
|
||||
JPEG 2000 and JPEG XR). This software therefore does not support these
|
||||
formats. Indeed, one of the original reasons for developing this free software
|
||||
was to help force convergence on a common, interoperable format standard for
|
||||
JPEG files.
|
||||
|
||||
JFIF is a minimal or "low end" representation. TIFF/JPEG (TIFF revision 6.0 as
|
||||
modified by TIFF Technical Note #2) can be used for "high end" applications
|
||||
that need to record a lot of additional data about an image.
|
||||
|
||||
|
||||
TO DO
|
||||
|
||||
31
README.md
31
README.md
@@ -3,7 +3,8 @@ Background
|
||||
|
||||
libjpeg-turbo is a JPEG image codec that uses SIMD instructions (MMX, SSE2,
|
||||
AVX2, NEON, AltiVec) to accelerate baseline JPEG compression and decompression
|
||||
on x86, x86-64, ARM, and PowerPC systems. On such systems, libjpeg-turbo is
|
||||
on x86, x86-64, ARM, and PowerPC systems, as well as progressive JPEG
|
||||
compression on x86 and x86-64 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
|
||||
@@ -134,12 +135,11 @@ 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.
|
||||
By passing 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
|
||||
|
||||
@@ -246,9 +246,8 @@ 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
|
||||
v6b or v7 API can pass 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.
|
||||
|
||||
@@ -343,3 +342,15 @@ 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.
|
||||
|
||||
|
||||
Memory Debugger Pitfalls
|
||||
========================
|
||||
|
||||
Valgrind and Memory Sanitizer (MSan) can generate false positives
|
||||
(specifically, incorrect reports of uninitialized memory accesses) when used
|
||||
with libjpeg-turbo's SIMD extensions. It is generally recommended that the
|
||||
SIMD extensions be disabled, either by passing an argument of `-DWITH_SIMD=0`
|
||||
to `cmake` when configuring the build or by setting the environment variable
|
||||
`JSIMD_FORCENONE` to `1` at run time, when testing libjpeg-turbo with Valgrind,
|
||||
MSan, or other memory debuggers.
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
install:
|
||||
- cmd: >-
|
||||
mkdir c:\installers
|
||||
if not exist c:\installers 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
|
||||
if not exist c:\installers\nasm-2.10.01-win32.zip 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
|
||||
|
||||
@@ -22,6 +22,9 @@ install:
|
||||
|
||||
git clone --depth=1 https://github.com/libjpeg-turbo/buildscripts.git -b %APPVEYOR_REPO_BRANCH% c:/buildscripts
|
||||
|
||||
cache:
|
||||
- c:\installers\nasm-2.10.01-win32.zip -> appveyor.yml
|
||||
|
||||
build_script:
|
||||
- cmd: >-
|
||||
for /f %%i in ('"cygpath %CD%"') do set MINGWPATH=%%i
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* cderror.h
|
||||
*
|
||||
* Copyright (C) 1994-1997, Thomas G. Lane.
|
||||
* Modified 2009 by Guido Vollbeding.
|
||||
* Modified 2009-2017 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
@@ -49,6 +49,7 @@ JMESSAGE(JERR_BMP_COLORSPACE, "BMP output must be grayscale or RGB")
|
||||
JMESSAGE(JERR_BMP_COMPRESSED, "Sorry, compressed BMPs not yet supported")
|
||||
JMESSAGE(JERR_BMP_EMPTY, "Empty BMP image")
|
||||
JMESSAGE(JERR_BMP_NOT, "Not a BMP file - does not start with BM")
|
||||
JMESSAGE(JERR_BMP_OUTOFRANGE, "Numeric value out of range in BMP file")
|
||||
JMESSAGE(JTRC_BMP, "%ux%u 24-bit BMP image")
|
||||
JMESSAGE(JTRC_BMP_MAPPED, "%ux%u 8-bit colormapped BMP image")
|
||||
JMESSAGE(JTRC_BMP_OS2, "%ux%u 24-bit OS2 BMP image")
|
||||
@@ -75,8 +76,8 @@ JMESSAGE(JWRN_GIF_NOMOREDATA, "Ran out of GIF bits")
|
||||
#ifdef PPM_SUPPORTED
|
||||
JMESSAGE(JERR_PPM_COLORSPACE, "PPM output must be grayscale or RGB")
|
||||
JMESSAGE(JERR_PPM_NONNUMERIC, "Nonnumeric data in PPM file")
|
||||
JMESSAGE(JERR_PPM_TOOLARGE, "Integer value too large in PPM file")
|
||||
JMESSAGE(JERR_PPM_NOT, "Not a PPM/PGM file")
|
||||
JMESSAGE(JERR_PPM_OUTOFRANGE, "Numeric value out of range in PPM file")
|
||||
JMESSAGE(JTRC_PGM, "%ux%u PGM image")
|
||||
JMESSAGE(JTRC_PGM_TEXT, "%ux%u text PGM image")
|
||||
JMESSAGE(JTRC_PPM, "%ux%u PPM image")
|
||||
|
||||
@@ -145,6 +145,11 @@ set(DEFAULT_IOS_ARMV8_BUILD ${CMAKE_SOURCE_DIR}/iosarmv8)
|
||||
set(IOS_ARMV8_BUILD ${DEFAULT_IOS_ARMV8_BUILD} CACHE PATH
|
||||
"Directory containing ARMv8 iOS build to include in universal binaries (default: ${DEFAULT_IOS_ARMV8_BUILD})")
|
||||
|
||||
set(OSX_APP_CERT_NAME "" CACHE STRING
|
||||
"Name of the Developer ID Application certificate (in the macOS keychain) that should be used to sign the libjpeg-turbo DMG. Leave this blank to generate an unsigned DMG.")
|
||||
set(OSX_INST_CERT_NAME "" CACHE STRING
|
||||
"Name of the Developer ID Installer certificate (in the macOS keychain) that should be used to sign the libjpeg-turbo installer package. Leave this blank to generate an unsigned package.")
|
||||
|
||||
configure_file(release/makemacpkg.in pkgscripts/makemacpkg)
|
||||
configure_file(release/Distribution.xml.in pkgscripts/Distribution.xml)
|
||||
configure_file(release/uninstall.in pkgscripts/uninstall)
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
# absolute paths where necessary, using the same logic.
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2016 D. R. Commander
|
||||
# Copyright 2016, 2019 D. R. Commander
|
||||
# Copyright 2016 Dmitry Marakasov
|
||||
# Copyright 2016 Roger Leigh
|
||||
# Copyright 2015 Alex Turbov
|
||||
@@ -184,7 +184,7 @@ macro(GNUInstallDirs_set_install_dir var docstring)
|
||||
"${docstring} (Default: ${CMAKE_INSTALL_DEFAULT_${var}})"
|
||||
${_GNUInstallDirs_CMAKE_INSTALL_FORCE_${var}})
|
||||
|
||||
if(NOT "${CMAKE_INSTALL_${var}}" STREQUAL "${CMAKE_INSTALL_DEFAULT_${var}}")
|
||||
if(NOT CMAKE_INSTALL_${var} STREQUAL CMAKE_INSTALL_DEFAULT_${var})
|
||||
unset(_GNUInstallDirs_CMAKE_INSTALL_DEFAULT_${var} CACHE)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -4,16 +4,16 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Developed 1997-2009 by Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2015, D. R. Commander.
|
||||
* Copyright (C) 2015, 2018, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
* This file contains probability estimation tables for common use in
|
||||
* arithmetic entropy encoding and decoding routines.
|
||||
*
|
||||
* This data represents Table D.2 in the JPEG spec (ISO/IEC IS 10918-1
|
||||
* and CCITT Recommendation ITU-T T.81) and Table 24 in the JBIG spec
|
||||
* (ISO/IEC IS 11544 and CCITT Recommendation ITU-T T.82).
|
||||
* This data represents Table D.2 in
|
||||
* Recommendation ITU-T T.81 (1992) | ISO/IEC 10918-1:1994 and Table 24 in
|
||||
* Recommendation ITU-T T.82 (1993) | ISO/IEC 11544:1993.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
|
||||
@@ -58,11 +58,21 @@ endif()
|
||||
add_custom_target(javadoc COMMAND
|
||||
javadoc -notimestamp -d ${CMAKE_CURRENT_SOURCE_DIR}/doc -sourcepath ${CMAKE_CURRENT_SOURCE_DIR} org.libjpegturbo.turbojpeg)
|
||||
set(JAVACLASSPATH ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/turbojpeg-java.dir)
|
||||
add_custom_target(javah
|
||||
COMMAND javah -d ${CMAKE_CURRENT_SOURCE_DIR} -classpath ${JAVACLASSPATH} org.libjpegturbo.turbojpeg.TJ
|
||||
COMMAND javah -d ${CMAKE_CURRENT_SOURCE_DIR} -classpath ${JAVACLASSPATH} org.libjpegturbo.turbojpeg.TJCompressor
|
||||
COMMAND javah -d ${CMAKE_CURRENT_SOURCE_DIR} -classpath ${JAVACLASSPATH} org.libjpegturbo.turbojpeg.TJDecompressor
|
||||
COMMAND javah -d ${CMAKE_CURRENT_SOURCE_DIR} -classpath ${JAVACLASSPATH} org.libjpegturbo.turbojpeg.TJTransformer)
|
||||
if(Java_VERSION_MAJOR GREATER 9)
|
||||
add_custom_target(javah
|
||||
COMMAND javac -h ${CMAKE_CURRENT_SOURCE_DIR} -classpath ${JAVACLASSPATH}
|
||||
-d ${CMAKE_CURRENT_BINARY_DIR}/__unused
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/org/libjpegturbo/turbojpeg/TJ.java
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/org/libjpegturbo/turbojpeg/TJCompressor.java
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/org/libjpegturbo/turbojpeg/TJDecompressor.java
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/org/libjpegturbo/turbojpeg/TJTransformer.java)
|
||||
else()
|
||||
add_custom_target(javah
|
||||
COMMAND javah -d ${CMAKE_CURRENT_SOURCE_DIR} -classpath ${JAVACLASSPATH} org.libjpegturbo.turbojpeg.TJ
|
||||
COMMAND javah -d ${CMAKE_CURRENT_SOURCE_DIR} -classpath ${JAVACLASSPATH} org.libjpegturbo.turbojpeg.TJCompressor
|
||||
COMMAND javah -d ${CMAKE_CURRENT_SOURCE_DIR} -classpath ${JAVACLASSPATH} org.libjpegturbo.turbojpeg.TJDecompressor
|
||||
COMMAND javah -d ${CMAKE_CURRENT_SOURCE_DIR} -classpath ${JAVACLASSPATH} org.libjpegturbo.turbojpeg.TJTransformer)
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_DEFAULT_JAVADIR)
|
||||
set(CMAKE_INSTALL_DEFAULT_JAVADIR "<CMAKE_INSTALL_DATAROOTDIR>/java")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C)2009-2014, 2016-2017 D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C)2009-2014, 2016-2019 D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -32,51 +32,53 @@ import javax.imageio.*;
|
||||
import java.util.*;
|
||||
import org.libjpegturbo.turbojpeg.*;
|
||||
|
||||
class TJBench {
|
||||
final class TJBench {
|
||||
|
||||
static int flags = 0, quiet = 0, pf = TJ.PF_BGR, yuvPad = 1;
|
||||
static boolean compOnly, decompOnly, doTile, doYUV, write = true;
|
||||
private TJBench() {}
|
||||
|
||||
static final String[] pixFormatStr = {
|
||||
private static int flags = 0, quiet = 0, pf = TJ.PF_BGR, yuvPad = 1;
|
||||
private static boolean compOnly, decompOnly, doTile, doYUV, write = true;
|
||||
|
||||
static final String[] PIXFORMATSTR = {
|
||||
"RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "GRAY"
|
||||
};
|
||||
|
||||
static final String[] subNameLong = {
|
||||
static final String[] SUBNAME_LONG = {
|
||||
"4:4:4", "4:2:2", "4:2:0", "GRAY", "4:4:0", "4:1:1"
|
||||
};
|
||||
|
||||
static final String[] subName = {
|
||||
static final String[] SUBNAME = {
|
||||
"444", "422", "420", "GRAY", "440", "411"
|
||||
};
|
||||
|
||||
static final String[] csName = {
|
||||
static final String[] CSNAME = {
|
||||
"RGB", "YCbCr", "GRAY", "CMYK", "YCCK"
|
||||
};
|
||||
|
||||
static TJScalingFactor sf;
|
||||
static int xformOp = TJTransform.OP_NONE, xformOpt = 0;
|
||||
static double benchTime = 5.0, warmup = 1.0;
|
||||
private static TJScalingFactor sf;
|
||||
private static int xformOp = TJTransform.OP_NONE, xformOpt = 0;
|
||||
private static double benchTime = 5.0, warmup = 1.0;
|
||||
|
||||
|
||||
static final double getTime() {
|
||||
static double getTime() {
|
||||
return (double)System.nanoTime() / 1.0e9;
|
||||
}
|
||||
|
||||
|
||||
static String tjErrorMsg;
|
||||
static int tjErrorCode = -1;
|
||||
private static String tjErrorMsg;
|
||||
private static int tjErrorCode = -1;
|
||||
|
||||
static void handleTJException(TJException e) throws TJException {
|
||||
String _tjErrorMsg = e.getMessage();
|
||||
int _tjErrorCode = e.getErrorCode();
|
||||
String errorMsg = e.getMessage();
|
||||
int errorCode = e.getErrorCode();
|
||||
|
||||
if ((flags & TJ.FLAG_STOPONWARNING) == 0 &&
|
||||
_tjErrorCode == TJ.ERR_WARNING) {
|
||||
if (tjErrorMsg == null || !tjErrorMsg.equals(_tjErrorMsg) ||
|
||||
tjErrorCode != _tjErrorCode) {
|
||||
tjErrorMsg = _tjErrorMsg;
|
||||
tjErrorCode = _tjErrorCode;
|
||||
System.out.println("WARNING: " + _tjErrorMsg);
|
||||
errorCode == TJ.ERR_WARNING) {
|
||||
if (tjErrorMsg == null || !tjErrorMsg.equals(errorMsg) ||
|
||||
tjErrorCode != errorCode) {
|
||||
tjErrorMsg = errorMsg;
|
||||
tjErrorCode = errorCode;
|
||||
System.out.println("WARNING: " + errorMsg);
|
||||
}
|
||||
} else
|
||||
throw e;
|
||||
@@ -85,11 +87,11 @@ class TJBench {
|
||||
|
||||
static String formatName(int subsamp, int cs) {
|
||||
if (cs == TJ.CS_YCbCr)
|
||||
return subNameLong[subsamp];
|
||||
return SUBNAME_LONG[subsamp];
|
||||
else if (cs == TJ.CS_YCCK)
|
||||
return csName[cs] + " " + subNameLong[subsamp];
|
||||
return CSNAME[cs] + " " + SUBNAME_LONG[subsamp];
|
||||
else
|
||||
return csName[cs];
|
||||
return CSNAME[cs];
|
||||
}
|
||||
|
||||
|
||||
@@ -119,6 +121,8 @@ class TJBench {
|
||||
int rindex = TJ.getRedOffset(pixelFormat);
|
||||
int gindex = TJ.getGreenOffset(pixelFormat);
|
||||
int bindex = TJ.getBlueOffset(pixelFormat);
|
||||
if ((long)w[0] * (long)h[0] * (long)ps > (long)Integer.MAX_VALUE)
|
||||
throw new Exception("Image is too large");
|
||||
byte[] dstBuf = new byte[w[0] * h[0] * ps];
|
||||
int pixels = w[0] * h[0], dstPtr = 0, rgbPtr = 0;
|
||||
|
||||
@@ -173,8 +177,11 @@ class TJBench {
|
||||
|
||||
tjd = new TJDecompressor();
|
||||
|
||||
if (dstBuf == null)
|
||||
if (dstBuf == null) {
|
||||
if ((long)pitch * (long)scaledh > (long)Integer.MAX_VALUE)
|
||||
throw new Exception("Image is too large");
|
||||
dstBuf = new byte[pitch * scaledh];
|
||||
}
|
||||
|
||||
/* Set the destination buffer to gray so we know whether the decompressor
|
||||
attempted to write to it */
|
||||
@@ -200,7 +207,9 @@ class TJBench {
|
||||
int width = doTile ? Math.min(tilew, w - x) : scaledw;
|
||||
int height = doTile ? Math.min(tileh, h - y) : scaledh;
|
||||
|
||||
tjd.setSourceImage(jpegBuf[tile], jpegSize[tile]);
|
||||
try {
|
||||
tjd.setSourceImage(jpegBuf[tile], jpegSize[tile]);
|
||||
} catch (TJException e) { handleTJException(e); }
|
||||
if (doYUV) {
|
||||
yuvImage.setBuf(yuvImage.getBuf(), width, yuvPad, height, subsamp);
|
||||
try {
|
||||
@@ -276,7 +285,7 @@ class TJBench {
|
||||
if (decompOnly)
|
||||
tempStr = new String(fileName + "_" + sizeStr + ".bmp");
|
||||
else
|
||||
tempStr = new String(fileName + "_" + subName[subsamp] + qualStr +
|
||||
tempStr = new String(fileName + "_" + SUBNAME[subsamp] + qualStr +
|
||||
"_" + sizeStr + ".bmp");
|
||||
|
||||
saveImage(tempStr, dstBuf, scaledw, scaledh, pf);
|
||||
@@ -324,16 +333,18 @@ class TJBench {
|
||||
int totalJpegSize = 0, tilew, tileh, i, iter;
|
||||
int ps = TJ.getPixelSize(pf);
|
||||
int ntilesw = 1, ntilesh = 1, pitch = w * ps;
|
||||
String pfStr = pixFormatStr[pf];
|
||||
String pfStr = PIXFORMATSTR[pf];
|
||||
YUVImage yuvImage = null;
|
||||
|
||||
if ((long)pitch * (long)h > (long)Integer.MAX_VALUE)
|
||||
throw new Exception("Image is too large");
|
||||
tmpBuf = new byte[pitch * h];
|
||||
|
||||
if (quiet == 0)
|
||||
System.out.format(">>>>> %s (%s) <--> JPEG %s Q%d <<<<<\n", pfStr,
|
||||
(flags & TJ.FLAG_BOTTOMUP) != 0 ?
|
||||
"Bottom-up" : "Top-down",
|
||||
subNameLong[subsamp], jpegQual);
|
||||
SUBNAME_LONG[subsamp], jpegQual);
|
||||
|
||||
tjc = new TJCompressor();
|
||||
|
||||
@@ -353,7 +364,7 @@ class TJBench {
|
||||
if (quiet == 1)
|
||||
System.out.format("%-4s (%s) %-5s %-3d ", pfStr,
|
||||
(flags & TJ.FLAG_BOTTOMUP) != 0 ? "BU" : "TD",
|
||||
subNameLong[subsamp], jpegQual);
|
||||
SUBNAME_LONG[subsamp], jpegQual);
|
||||
for (i = 0; i < h; i++)
|
||||
System.arraycopy(srcBuf, w * ps * i, tmpBuf, pitch * i, w * ps);
|
||||
tjc.setJPEGQuality(jpegQual);
|
||||
@@ -453,7 +464,7 @@ class TJBench {
|
||||
(double)iter / elapsed);
|
||||
}
|
||||
if (tilew == w && tileh == h && write) {
|
||||
String tempStr = fileName + "_" + subName[subsamp] + "_" + "Q" +
|
||||
String tempStr = fileName + "_" + SUBNAME[subsamp] + "_" + "Q" +
|
||||
jpegQual + ".jpg";
|
||||
FileOutputStream fos = new FileOutputStream(tempStr);
|
||||
|
||||
@@ -479,13 +490,16 @@ class TJBench {
|
||||
byte[] srcBuf;
|
||||
int[] jpegSize = null;
|
||||
int totalJpegSize;
|
||||
int w = 0, h = 0, subsamp = -1, cs = -1, _w, _h, _tilew, _tileh,
|
||||
_ntilesw, _ntilesh, _subsamp, x, y, iter;
|
||||
int ntilesw = 1, ntilesh = 1;
|
||||
double start, elapsed;
|
||||
int ps = TJ.getPixelSize(pf), tile;
|
||||
int ps = TJ.getPixelSize(pf), tile, x, y, iter;
|
||||
// Original image
|
||||
int w = 0, h = 0, ntilesw = 1, ntilesh = 1, subsamp = -1, cs = -1;
|
||||
// Transformed image
|
||||
int tw, th, ttilew, ttileh, tntilesw, tntilesh, tsubsamp;
|
||||
|
||||
FileInputStream fis = new FileInputStream(fileName);
|
||||
if (fis.getChannel().size() > (long)Integer.MAX_VALUE)
|
||||
throw new Exception("Image is too large");
|
||||
int srcSize = (int)fis.getChannel().size();
|
||||
srcBuf = new byte[srcSize];
|
||||
fis.read(srcBuf, 0, srcSize);
|
||||
@@ -497,7 +511,9 @@ class TJBench {
|
||||
|
||||
tjt = new TJTransformer();
|
||||
|
||||
tjt.setSourceImage(srcBuf, srcSize);
|
||||
try {
|
||||
tjt.setSourceImage(srcBuf, srcSize);
|
||||
} catch (TJException e) { handleTJException(e); }
|
||||
w = tjt.getWidth();
|
||||
h = tjt.getHeight();
|
||||
subsamp = tjt.getSubsamp();
|
||||
@@ -517,7 +533,7 @@ class TJBench {
|
||||
System.out.println("\n");
|
||||
} else if (quiet == 0)
|
||||
System.out.format(">>>>> JPEG %s --> %s (%s) <<<<<\n",
|
||||
formatName(subsamp, cs), pixFormatStr[pf],
|
||||
formatName(subsamp, cs), PIXFORMATSTR[pf],
|
||||
(flags & TJ.FLAG_BOTTOMUP) != 0 ?
|
||||
"Bottom-up" : "Top-down");
|
||||
|
||||
@@ -530,66 +546,66 @@ class TJBench {
|
||||
ntilesw = (w + tilew - 1) / tilew;
|
||||
ntilesh = (h + tileh - 1) / tileh;
|
||||
|
||||
_w = w; _h = h; _tilew = tilew; _tileh = tileh;
|
||||
tw = w; th = h; ttilew = tilew; ttileh = tileh;
|
||||
if (quiet == 0) {
|
||||
System.out.format("\n%s size: %d x %d", (doTile ? "Tile" : "Image"),
|
||||
_tilew, _tileh);
|
||||
ttilew, ttileh);
|
||||
if (sf.getNum() != 1 || sf.getDenom() != 1)
|
||||
System.out.format(" --> %d x %d", sf.getScaled(_w),
|
||||
sf.getScaled(_h));
|
||||
System.out.format(" --> %d x %d", sf.getScaled(tw),
|
||||
sf.getScaled(th));
|
||||
System.out.println("");
|
||||
} else if (quiet == 1) {
|
||||
System.out.format("%-4s (%s) %-5s %-5s ", pixFormatStr[pf],
|
||||
System.out.format("%-4s (%s) %-5s %-5s ", PIXFORMATSTR[pf],
|
||||
(flags & TJ.FLAG_BOTTOMUP) != 0 ? "BU" : "TD",
|
||||
csName[cs], subNameLong[subsamp]);
|
||||
CSNAME[cs], SUBNAME_LONG[subsamp]);
|
||||
System.out.format("%-5d %-5d ", tilew, tileh);
|
||||
}
|
||||
|
||||
_subsamp = subsamp;
|
||||
tsubsamp = subsamp;
|
||||
if (doTile || xformOp != TJTransform.OP_NONE || xformOpt != 0) {
|
||||
if (xformOp == TJTransform.OP_TRANSPOSE ||
|
||||
xformOp == TJTransform.OP_TRANSVERSE ||
|
||||
xformOp == TJTransform.OP_ROT90 ||
|
||||
xformOp == TJTransform.OP_ROT270) {
|
||||
_w = h; _h = w; _tilew = tileh; _tileh = tilew;
|
||||
tw = h; th = w; ttilew = tileh; ttileh = tilew;
|
||||
}
|
||||
|
||||
if ((xformOpt & TJTransform.OPT_GRAY) != 0)
|
||||
_subsamp = TJ.SAMP_GRAY;
|
||||
tsubsamp = TJ.SAMP_GRAY;
|
||||
if (xformOp == TJTransform.OP_HFLIP ||
|
||||
xformOp == TJTransform.OP_ROT180)
|
||||
_w = _w - (_w % TJ.getMCUWidth(_subsamp));
|
||||
tw = tw - (tw % TJ.getMCUWidth(tsubsamp));
|
||||
if (xformOp == TJTransform.OP_VFLIP ||
|
||||
xformOp == TJTransform.OP_ROT180)
|
||||
_h = _h - (_h % TJ.getMCUHeight(_subsamp));
|
||||
th = th - (th % TJ.getMCUHeight(tsubsamp));
|
||||
if (xformOp == TJTransform.OP_TRANSVERSE ||
|
||||
xformOp == TJTransform.OP_ROT90)
|
||||
_w = _w - (_w % TJ.getMCUHeight(_subsamp));
|
||||
tw = tw - (tw % TJ.getMCUHeight(tsubsamp));
|
||||
if (xformOp == TJTransform.OP_TRANSVERSE ||
|
||||
xformOp == TJTransform.OP_ROT270)
|
||||
_h = _h - (_h % TJ.getMCUWidth(_subsamp));
|
||||
_ntilesw = (_w + _tilew - 1) / _tilew;
|
||||
_ntilesh = (_h + _tileh - 1) / _tileh;
|
||||
th = th - (th % TJ.getMCUWidth(tsubsamp));
|
||||
tntilesw = (tw + ttilew - 1) / ttilew;
|
||||
tntilesh = (th + ttileh - 1) / ttileh;
|
||||
|
||||
if (xformOp == TJTransform.OP_TRANSPOSE ||
|
||||
xformOp == TJTransform.OP_TRANSVERSE ||
|
||||
xformOp == TJTransform.OP_ROT90 ||
|
||||
xformOp == TJTransform.OP_ROT270) {
|
||||
if (_subsamp == TJ.SAMP_422)
|
||||
_subsamp = TJ.SAMP_440;
|
||||
else if (_subsamp == TJ.SAMP_440)
|
||||
_subsamp = TJ.SAMP_422;
|
||||
if (tsubsamp == TJ.SAMP_422)
|
||||
tsubsamp = TJ.SAMP_440;
|
||||
else if (tsubsamp == TJ.SAMP_440)
|
||||
tsubsamp = TJ.SAMP_422;
|
||||
}
|
||||
|
||||
TJTransform[] t = new TJTransform[_ntilesw * _ntilesh];
|
||||
TJTransform[] t = new TJTransform[tntilesw * tntilesh];
|
||||
jpegBuf =
|
||||
new byte[_ntilesw * _ntilesh][TJ.bufSize(_tilew, _tileh, subsamp)];
|
||||
new byte[tntilesw * tntilesh][TJ.bufSize(ttilew, ttileh, subsamp)];
|
||||
|
||||
for (y = 0, tile = 0; y < _h; y += _tileh) {
|
||||
for (x = 0; x < _w; x += _tilew, tile++) {
|
||||
for (y = 0, tile = 0; y < th; y += ttileh) {
|
||||
for (x = 0; x < tw; x += ttilew, tile++) {
|
||||
t[tile] = new TJTransform();
|
||||
t[tile].width = Math.min(_tilew, _w - x);
|
||||
t[tile].height = Math.min(_tileh, _h - y);
|
||||
t[tile].width = Math.min(ttilew, tw - x);
|
||||
t[tile].height = Math.min(ttileh, th - y);
|
||||
t[tile].x = x;
|
||||
t[tile].y = y;
|
||||
t[tile].op = xformOp;
|
||||
@@ -604,7 +620,9 @@ class TJBench {
|
||||
elapsed = 0.;
|
||||
while (true) {
|
||||
start = getTime();
|
||||
tjt.transform(jpegBuf, t, flags);
|
||||
try {
|
||||
tjt.transform(jpegBuf, t, flags);
|
||||
} catch (TJException e) { handleTJException(e); }
|
||||
jpegSize = tjt.getTransformedSizes();
|
||||
elapsed += getTime() - start;
|
||||
if (iter >= 0) {
|
||||
@@ -618,7 +636,7 @@ class TJBench {
|
||||
}
|
||||
t = null;
|
||||
|
||||
for (tile = 0, totalJpegSize = 0; tile < _ntilesw * _ntilesh; tile++)
|
||||
for (tile = 0, totalJpegSize = 0; tile < tntilesw * tntilesh; tile++)
|
||||
totalJpegSize += jpegSize[tile];
|
||||
|
||||
if (quiet != 0) {
|
||||
@@ -643,19 +661,19 @@ class TJBench {
|
||||
} else {
|
||||
if (quiet == 1)
|
||||
System.out.print("N/A N/A ");
|
||||
jpegBuf = new byte[1][TJ.bufSize(_tilew, _tileh, subsamp)];
|
||||
jpegBuf = new byte[1][TJ.bufSize(ttilew, ttileh, subsamp)];
|
||||
jpegSize = new int[1];
|
||||
jpegBuf[0] = srcBuf;
|
||||
jpegSize[0] = srcSize;
|
||||
}
|
||||
|
||||
if (w == tilew)
|
||||
_tilew = _w;
|
||||
ttilew = tw;
|
||||
if (h == tileh)
|
||||
_tileh = _h;
|
||||
ttileh = th;
|
||||
if ((xformOpt & TJTransform.OPT_NOOUTPUT) == 0)
|
||||
decomp(null, jpegBuf, jpegSize, null, _w, _h, _subsamp, 0,
|
||||
fileName, _tilew, _tileh);
|
||||
decomp(null, jpegBuf, jpegSize, null, tw, th, tsubsamp, 0,
|
||||
fileName, ttilew, ttileh);
|
||||
else if (quiet == 1)
|
||||
System.out.println("N/A");
|
||||
|
||||
@@ -702,7 +720,7 @@ class TJBench {
|
||||
System.out.println(" bytes to which each row of each plane in the intermediate YUV image is");
|
||||
System.out.println(" padded (default = 1)");
|
||||
System.out.println("-scale M/N = Scale down the width/height of the decompressed JPEG image by a");
|
||||
System.out.print (" factor of M/N (M/N = ");
|
||||
System.out.print(" factor of M/N (M/N = ");
|
||||
for (i = 0; i < nsf; i++) {
|
||||
System.out.format("%d/%d", scalingFactors[i].getNum(),
|
||||
scalingFactors[i].getDenom());
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C)2011-2012, 2014-2015, 2017 D. R. Commander.
|
||||
* All Rights Reserved.
|
||||
* Copyright (C)2011-2012, 2014-2015, 2017-2018 D. R. Commander.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -41,25 +41,28 @@ import javax.swing.*;
|
||||
import org.libjpegturbo.turbojpeg.*;
|
||||
|
||||
|
||||
public class TJExample implements TJCustomFilter {
|
||||
@SuppressWarnings("checkstyle:JavadocType")
|
||||
class TJExample implements TJCustomFilter {
|
||||
|
||||
private static final String classname = new TJExample().getClass().getName();
|
||||
static final String CLASS_NAME =
|
||||
new TJExample().getClass().getName();
|
||||
|
||||
private static final int DEFAULT_SUBSAMP = TJ.SAMP_444;
|
||||
private static final int DEFAULT_QUALITY = 95;
|
||||
static final int DEFAULT_SUBSAMP = TJ.SAMP_444;
|
||||
static final int DEFAULT_QUALITY = 95;
|
||||
|
||||
|
||||
private static final String[] subsampName = {
|
||||
static final String[] SUBSAMP_NAME = {
|
||||
"4:4:4", "4:2:2", "4:2:0", "Grayscale", "4:4:0", "4:1:1"
|
||||
};
|
||||
|
||||
private static final String[] colorspaceName = {
|
||||
static final String[] COLORSPACE_NAME = {
|
||||
"RGB", "YCbCr", "GRAY", "CMYK", "YCCK"
|
||||
};
|
||||
|
||||
|
||||
/* DCT filter example. This produces a negative of the image. */
|
||||
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
public void customFilter(ShortBuffer coeffBuffer, Rectangle bufferRegion,
|
||||
Rectangle planeRegion, int componentIndex,
|
||||
int transformIndex, TJTransform transform)
|
||||
@@ -70,8 +73,8 @@ public class TJExample implements TJCustomFilter {
|
||||
}
|
||||
|
||||
|
||||
private static void usage() throws Exception {
|
||||
System.out.println("\nUSAGE: java [Java options] " + classname +
|
||||
static void usage() throws Exception {
|
||||
System.out.println("\nUSAGE: java [Java options] " + CLASS_NAME +
|
||||
" <Input image> <Output image> [options]\n");
|
||||
|
||||
System.out.println("Input and output images can be in any image format that the Java Image I/O");
|
||||
@@ -85,7 +88,9 @@ public class TJExample implements TJCustomFilter {
|
||||
System.out.println(" compressing the output image. The default is to use the same level of");
|
||||
System.out.println(" subsampling as in the input image, if the input image is also a JPEG");
|
||||
System.out.println(" image, or to use grayscale if the input image is a grayscale non-JPEG");
|
||||
System.out.println(" image, or to use " + subsampName[DEFAULT_SUBSAMP] + " subsampling otherwise.\n");
|
||||
System.out.println(" image, or to use " +
|
||||
SUBSAMP_NAME[DEFAULT_SUBSAMP] +
|
||||
" subsampling otherwise.\n");
|
||||
|
||||
System.out.println("-q <1-100> = Compress the output image with this JPEG quality level");
|
||||
System.out.println(" (default = " + DEFAULT_QUALITY + ").\n");
|
||||
@@ -95,15 +100,15 @@ public class TJExample implements TJCustomFilter {
|
||||
|
||||
System.out.println("-scale M/N = Scale the input image by a factor of M/N when decompressing it.");
|
||||
System.out.print("(M/N = ");
|
||||
for (int i = 0; i < scalingFactors.length; i++) {
|
||||
System.out.print(scalingFactors[i].getNum() + "/" +
|
||||
scalingFactors[i].getDenom());
|
||||
if (scalingFactors.length == 2 && i != scalingFactors.length - 1)
|
||||
for (int i = 0; i < SCALING_FACTORS.length; i++) {
|
||||
System.out.print(SCALING_FACTORS[i].getNum() + "/" +
|
||||
SCALING_FACTORS[i].getDenom());
|
||||
if (SCALING_FACTORS.length == 2 && i != SCALING_FACTORS.length - 1)
|
||||
System.out.print(" or ");
|
||||
else if (scalingFactors.length > 2) {
|
||||
if (i != scalingFactors.length - 1)
|
||||
else if (SCALING_FACTORS.length > 2) {
|
||||
if (i != SCALING_FACTORS.length - 1)
|
||||
System.out.print(", ");
|
||||
if (i == scalingFactors.length - 2)
|
||||
if (i == SCALING_FACTORS.length - 2)
|
||||
System.out.print("or ");
|
||||
}
|
||||
}
|
||||
@@ -177,9 +182,9 @@ public class TJExample implements TJCustomFilter {
|
||||
TJScalingFactor tempsf =
|
||||
new TJScalingFactor(Integer.parseInt(scaleArg[0]),
|
||||
Integer.parseInt(scaleArg[1]));
|
||||
for (int j = 0; j < scalingFactors.length; j++) {
|
||||
if (tempsf.equals(scalingFactors[j])) {
|
||||
scalingFactor = scalingFactors[j];
|
||||
for (int j = 0; j < SCALING_FACTORS.length; j++) {
|
||||
if (tempsf.equals(SCALING_FACTORS[j])) {
|
||||
scalingFactor = SCALING_FACTORS[j];
|
||||
match = 1;
|
||||
break;
|
||||
}
|
||||
@@ -302,8 +307,8 @@ public class TJExample implements TJCustomFilter {
|
||||
|
||||
System.out.println((doTransform ? "Transformed" : "Input") +
|
||||
" Image (jpg): " + width + " x " + height +
|
||||
" pixels, " + subsampName[inSubsamp] +
|
||||
" subsampling, " + colorspaceName[inColorspace]);
|
||||
" pixels, " + SUBSAMP_NAME[inSubsamp] +
|
||||
" subsampling, " + COLORSPACE_NAME[inColorspace]);
|
||||
|
||||
if (outFormat.equalsIgnoreCase("jpg") && doTransform &&
|
||||
scalingFactor.isOne() && outSubsamp < 0 && outQual < 0) {
|
||||
@@ -362,7 +367,7 @@ public class TJExample implements TJCustomFilter {
|
||||
/* Output image format is JPEG. Compress the uncompressed image. */
|
||||
if (outQual < 0)
|
||||
outQual = DEFAULT_QUALITY;
|
||||
System.out.println(", " + subsampName[outSubsamp] +
|
||||
System.out.println(", " + SUBSAMP_NAME[outSubsamp] +
|
||||
" subsampling, quality = " + outQual);
|
||||
|
||||
TJCompressor tjc = new TJCompressor();
|
||||
@@ -395,5 +400,6 @@ public class TJExample implements TJCustomFilter {
|
||||
}
|
||||
}
|
||||
|
||||
private static final TJScalingFactor[] scalingFactors = TJ.getScalingFactors();
|
||||
static final TJScalingFactor[] SCALING_FACTORS =
|
||||
TJ.getScalingFactors();
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C)2011-2017 D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C)2011-2018 D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -37,13 +37,16 @@ import javax.imageio.*;
|
||||
import java.nio.*;
|
||||
import org.libjpegturbo.turbojpeg.*;
|
||||
|
||||
public class TJUnitTest {
|
||||
@SuppressWarnings("checkstyle:JavadocType")
|
||||
final class TJUnitTest {
|
||||
|
||||
private static final String classname =
|
||||
private TJUnitTest() {}
|
||||
|
||||
static final String CLASS_NAME =
|
||||
new TJUnitTest().getClass().getName();
|
||||
|
||||
private static void usage() {
|
||||
System.out.println("\nUSAGE: java " + classname + " [options]\n");
|
||||
static void usage() {
|
||||
System.out.println("\nUSAGE: java " + CLASS_NAME + " [options]\n");
|
||||
System.out.println("Options:");
|
||||
System.out.println("-yuv = test YUV encoding/decoding support");
|
||||
System.out.println("-noyuvpad = do not pad each line of each Y, U, and V plane to the nearest");
|
||||
@@ -52,39 +55,39 @@ public class TJUnitTest {
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
private static final String[] subNameLong = {
|
||||
static final String[] SUBNAME_LONG = {
|
||||
"4:4:4", "4:2:2", "4:2:0", "GRAY", "4:4:0", "4:1:1"
|
||||
};
|
||||
private static final String[] subName = {
|
||||
static final String[] SUBNAME = {
|
||||
"444", "422", "420", "GRAY", "440", "411"
|
||||
};
|
||||
|
||||
private static final String[] pixFormatStr = {
|
||||
static final String[] PIXFORMATSTR = {
|
||||
"RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "Grayscale",
|
||||
"RGBA", "BGRA", "ABGR", "ARGB", "CMYK"
|
||||
};
|
||||
|
||||
private static final int[] _3byteFormats = {
|
||||
static final int[] FORMATS_3BYTE = {
|
||||
TJ.PF_RGB, TJ.PF_BGR
|
||||
};
|
||||
private static final int[] _3byteFormatsBI = {
|
||||
static final int[] FORMATS_3BYTEBI = {
|
||||
BufferedImage.TYPE_3BYTE_BGR
|
||||
};
|
||||
private static final int[] _4byteFormats = {
|
||||
static final int[] FORMATS_4BYTE = {
|
||||
TJ.PF_RGBX, TJ.PF_BGRX, TJ.PF_XBGR, TJ.PF_XRGB, TJ.PF_CMYK
|
||||
};
|
||||
private static final int[] _4byteFormatsBI = {
|
||||
static final int[] FORMATS_4BYTEBI = {
|
||||
BufferedImage.TYPE_INT_BGR, BufferedImage.TYPE_INT_RGB,
|
||||
BufferedImage.TYPE_4BYTE_ABGR, BufferedImage.TYPE_4BYTE_ABGR_PRE,
|
||||
BufferedImage.TYPE_INT_ARGB, BufferedImage.TYPE_INT_ARGB_PRE
|
||||
};
|
||||
private static final int[] onlyGray = {
|
||||
static final int[] FORMATS_GRAY = {
|
||||
TJ.PF_GRAY
|
||||
};
|
||||
private static final int[] onlyGrayBI = {
|
||||
static final int[] FORMATS_GRAYBI = {
|
||||
BufferedImage.TYPE_BYTE_GRAY
|
||||
};
|
||||
private static final int[] onlyRGB = {
|
||||
static final int[] FORMATS_RGB = {
|
||||
TJ.PF_RGB
|
||||
};
|
||||
|
||||
@@ -94,7 +97,7 @@ public class TJUnitTest {
|
||||
|
||||
private static int exitStatus = 0;
|
||||
|
||||
private static int biTypePF(int biType) {
|
||||
static int biTypePF(int biType) {
|
||||
ByteOrder byteOrder = ByteOrder.nativeOrder();
|
||||
switch (biType) {
|
||||
case BufferedImage.TYPE_3BYTE_BGR:
|
||||
@@ -111,11 +114,12 @@ public class TJUnitTest {
|
||||
case BufferedImage.TYPE_INT_ARGB:
|
||||
case BufferedImage.TYPE_INT_ARGB_PRE:
|
||||
return TJ.PF_BGRA;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static String biTypeStr(int biType) {
|
||||
static String biTypeStr(int biType) {
|
||||
switch (biType) {
|
||||
case BufferedImage.TYPE_3BYTE_BGR:
|
||||
return "3BYTE_BGR";
|
||||
@@ -133,12 +137,13 @@ public class TJUnitTest {
|
||||
return "INT_ARGB";
|
||||
case BufferedImage.TYPE_INT_ARGB_PRE:
|
||||
return "INT_ARGB_PRE";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
private static void initBuf(byte[] buf, int w, int pitch, int h, int pf,
|
||||
int flags) throws Exception {
|
||||
static void initBuf(byte[] buf, int w, int pitch, int h, int pf, int flags)
|
||||
throws Exception {
|
||||
int roffset = TJ.getRedOffset(pf);
|
||||
int goffset = TJ.getGreenOffset(pf);
|
||||
int boffset = TJ.getBlueOffset(pf);
|
||||
@@ -206,8 +211,8 @@ public class TJUnitTest {
|
||||
}
|
||||
}
|
||||
|
||||
private static void initIntBuf(int[] buf, int w, int pitch, int h, int pf,
|
||||
int flags) throws Exception {
|
||||
static void initIntBuf(int[] buf, int w, int pitch, int h, int pf, int flags)
|
||||
throws Exception {
|
||||
int rshift = TJ.getRedOffset(pf) * 8;
|
||||
int gshift = TJ.getGreenOffset(pf) * 8;
|
||||
int bshift = TJ.getBlueOffset(pf) * 8;
|
||||
@@ -238,8 +243,7 @@ public class TJUnitTest {
|
||||
}
|
||||
}
|
||||
|
||||
private static void initImg(BufferedImage img, int pf, int flags)
|
||||
throws Exception {
|
||||
static void initImg(BufferedImage img, int pf, int flags) throws Exception {
|
||||
WritableRaster wr = img.getRaster();
|
||||
int imgType = img.getType();
|
||||
|
||||
@@ -262,8 +266,8 @@ public class TJUnitTest {
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkVal(int row, int col, int v, String vname, int cv)
|
||||
throws Exception {
|
||||
static void checkVal(int row, int col, int v, String vname, int cv)
|
||||
throws Exception {
|
||||
v = (v < 0) ? v + 256 : v;
|
||||
if (v < cv - 1 || v > cv + 1) {
|
||||
throw new Exception("Comp. " + vname + " at " + row + "," + col +
|
||||
@@ -271,8 +275,8 @@ public class TJUnitTest {
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkVal0(int row, int col, int v, String vname)
|
||||
throws Exception {
|
||||
static void checkVal0(int row, int col, int v, String vname)
|
||||
throws Exception {
|
||||
v = (v < 0) ? v + 256 : v;
|
||||
if (v > 1) {
|
||||
throw new Exception("Comp. " + vname + " at " + row + "," + col +
|
||||
@@ -280,8 +284,8 @@ public class TJUnitTest {
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkVal255(int row, int col, int v, String vname)
|
||||
throws Exception {
|
||||
static void checkVal255(int row, int col, int v, String vname)
|
||||
throws Exception {
|
||||
v = (v < 0) ? v + 256 : v;
|
||||
if (v < 254) {
|
||||
throw new Exception("Comp. " + vname + " at " + row + "," + col +
|
||||
@@ -289,9 +293,8 @@ public class TJUnitTest {
|
||||
}
|
||||
}
|
||||
|
||||
private static int checkBuf(byte[] buf, int w, int pitch, int h, int pf,
|
||||
int subsamp, TJScalingFactor sf, int flags)
|
||||
throws Exception {
|
||||
static int checkBuf(byte[] buf, int w, int pitch, int h, int pf, int subsamp,
|
||||
TJScalingFactor sf, int flags) throws Exception {
|
||||
int roffset = TJ.getRedOffset(pf);
|
||||
int goffset = TJ.getGreenOffset(pf);
|
||||
int boffset = TJ.getBlueOffset(pf);
|
||||
@@ -416,9 +419,9 @@ public class TJUnitTest {
|
||||
return retval;
|
||||
}
|
||||
|
||||
private static int checkIntBuf(int[] buf, int w, int pitch, int h, int pf,
|
||||
int subsamp, TJScalingFactor sf, int flags)
|
||||
throws Exception {
|
||||
static int checkIntBuf(int[] buf, int w, int pitch, int h, int pf,
|
||||
int subsamp, TJScalingFactor sf, int flags)
|
||||
throws Exception {
|
||||
int rshift = TJ.getRedOffset(pf) * 8;
|
||||
int gshift = TJ.getGreenOffset(pf) * 8;
|
||||
int bshift = TJ.getBlueOffset(pf) * 8;
|
||||
@@ -494,8 +497,8 @@ public class TJUnitTest {
|
||||
return retval;
|
||||
}
|
||||
|
||||
private static int checkImg(BufferedImage img, int pf, int subsamp,
|
||||
TJScalingFactor sf, int flags) throws Exception {
|
||||
static int checkImg(BufferedImage img, int pf, int subsamp,
|
||||
TJScalingFactor sf, int flags) throws Exception {
|
||||
WritableRaster wr = img.getRaster();
|
||||
int imgType = img.getType();
|
||||
if (imgType == BufferedImage.TYPE_INT_RGB ||
|
||||
@@ -519,18 +522,17 @@ public class TJUnitTest {
|
||||
}
|
||||
}
|
||||
|
||||
private static int PAD(int v, int p) {
|
||||
static int pad(int v, int p) {
|
||||
return ((v + (p) - 1) & (~((p) - 1)));
|
||||
}
|
||||
|
||||
private static int checkBufYUV(byte[] buf, int size, int w, int h,
|
||||
int subsamp, TJScalingFactor sf)
|
||||
throws Exception {
|
||||
static int checkBufYUV(byte[] buf, int size, int w, int h, int subsamp,
|
||||
TJScalingFactor sf) throws Exception {
|
||||
int row, col;
|
||||
int hsf = TJ.getMCUWidth(subsamp) / 8, vsf = TJ.getMCUHeight(subsamp) / 8;
|
||||
int pw = PAD(w, hsf), ph = PAD(h, vsf);
|
||||
int pw = pad(w, hsf), ph = pad(h, vsf);
|
||||
int cw = pw / hsf, ch = ph / vsf;
|
||||
int ypitch = PAD(pw, pad), uvpitch = PAD(cw, pad);
|
||||
int ypitch = pad(pw, pad), uvpitch = pad(cw, pad);
|
||||
int retval = 1;
|
||||
int correctsize = ypitch * ph +
|
||||
(subsamp == TJ.SAMP_GRAY ? 0 : uvpitch * ch * 2);
|
||||
@@ -616,17 +618,17 @@ public class TJUnitTest {
|
||||
return retval;
|
||||
}
|
||||
|
||||
private static void writeJPEG(byte[] jpegBuf, int jpegBufSize,
|
||||
String filename) throws Exception {
|
||||
static void writeJPEG(byte[] jpegBuf, int jpegBufSize, String filename)
|
||||
throws Exception {
|
||||
File file = new File(filename);
|
||||
FileOutputStream fos = new FileOutputStream(file);
|
||||
fos.write(jpegBuf, 0, jpegBufSize);
|
||||
fos.close();
|
||||
}
|
||||
|
||||
private static int compTest(TJCompressor tjc, byte[] dstBuf, int w,
|
||||
int h, int pf, String baseName, int subsamp,
|
||||
int jpegQual, int flags) throws Exception {
|
||||
static int compTest(TJCompressor tjc, byte[] dstBuf, int w, int h, int pf,
|
||||
String baseName, int subsamp, int jpegQual, int flags)
|
||||
throws Exception {
|
||||
String tempStr;
|
||||
byte[] srcBuf = null;
|
||||
BufferedImage img = null;
|
||||
@@ -639,9 +641,9 @@ public class TJUnitTest {
|
||||
if (bi) {
|
||||
pf = biTypePF(imgType);
|
||||
pfStr = biTypeStr(imgType);
|
||||
pfStrLong = pfStr + " (" + pixFormatStr[pf] + ")";
|
||||
pfStrLong = pfStr + " (" + PIXFORMATSTR[pf] + ")";
|
||||
} else {
|
||||
pfStr = pixFormatStr[pf];
|
||||
pfStr = PIXFORMATSTR[pf];
|
||||
pfStrLong = pfStr;
|
||||
}
|
||||
ps = TJ.getPixelSize(pf);
|
||||
@@ -650,7 +652,7 @@ public class TJUnitTest {
|
||||
img = new BufferedImage(w, h, imgType);
|
||||
initImg(img, pf, flags);
|
||||
tempStr = baseName + "_enc_" + pfStr + "_" + buStr + "_" +
|
||||
subName[subsamp] + "_Q" + jpegQual + ".png";
|
||||
SUBNAME[subsamp] + "_Q" + jpegQual + ".png";
|
||||
File file = new File(tempStr);
|
||||
ImageIO.write(img, "png", file);
|
||||
tjc.setSourceImage(img, 0, 0, 0, 0);
|
||||
@@ -665,7 +667,7 @@ public class TJUnitTest {
|
||||
tjc.setJPEGQuality(jpegQual);
|
||||
if (doYUV) {
|
||||
System.out.format("%s %s -> YUV %s ... ", pfStrLong, buStrLong,
|
||||
subNameLong[subsamp]);
|
||||
SUBNAME_LONG[subsamp]);
|
||||
YUVImage yuvImage = tjc.encodeYUV(pad, flags);
|
||||
if (checkBufYUV(yuvImage.getBuf(), yuvImage.getSize(), w, h, subsamp,
|
||||
new TJScalingFactor(1, 1)) == 1)
|
||||
@@ -675,28 +677,27 @@ public class TJUnitTest {
|
||||
exitStatus = -1;
|
||||
}
|
||||
|
||||
System.out.format("YUV %s %s -> JPEG Q%d ... ", subNameLong[subsamp],
|
||||
System.out.format("YUV %s %s -> JPEG Q%d ... ", SUBNAME_LONG[subsamp],
|
||||
buStrLong, jpegQual);
|
||||
tjc.setSourceImage(yuvImage);
|
||||
} else {
|
||||
System.out.format("%s %s -> %s Q%d ... ", pfStrLong, buStrLong,
|
||||
subNameLong[subsamp], jpegQual);
|
||||
SUBNAME_LONG[subsamp], jpegQual);
|
||||
}
|
||||
tjc.compress(dstBuf, flags);
|
||||
size = tjc.getCompressedSize();
|
||||
|
||||
tempStr = baseName + "_enc_" + pfStr + "_" + buStr + "_" +
|
||||
subName[subsamp] + "_Q" + jpegQual + ".jpg";
|
||||
SUBNAME[subsamp] + "_Q" + jpegQual + ".jpg";
|
||||
writeJPEG(dstBuf, size, tempStr);
|
||||
System.out.println("Done.\n Result in " + tempStr);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
private static void decompTest(TJDecompressor tjd, byte[] jpegBuf,
|
||||
int jpegSize, int w, int h, int pf,
|
||||
String baseName, int subsamp, int flags,
|
||||
TJScalingFactor sf) throws Exception {
|
||||
static void decompTest(TJDecompressor tjd, byte[] jpegBuf, int jpegSize,
|
||||
int w, int h, int pf, String baseName, int subsamp,
|
||||
int flags, TJScalingFactor sf) throws Exception {
|
||||
String pfStr, pfStrLong, tempStr;
|
||||
String buStrLong = (flags & TJ.FLAG_BOTTOMUP) != 0 ?
|
||||
"Bottom-Up" : "Top-Down ";
|
||||
@@ -709,9 +710,9 @@ public class TJUnitTest {
|
||||
if (bi) {
|
||||
pf = biTypePF(imgType);
|
||||
pfStr = biTypeStr(imgType);
|
||||
pfStrLong = pfStr + " (" + pixFormatStr[pf] + ")";
|
||||
pfStrLong = pfStr + " (" + PIXFORMATSTR[pf] + ")";
|
||||
} else {
|
||||
pfStr = pixFormatStr[pf];
|
||||
pfStr = PIXFORMATSTR[pf];
|
||||
pfStrLong = pfStr;
|
||||
}
|
||||
|
||||
@@ -728,7 +729,7 @@ public class TJUnitTest {
|
||||
throw new Exception("Scaled size mismatch");
|
||||
|
||||
if (doYUV) {
|
||||
System.out.format("JPEG -> YUV %s ", subNameLong[subsamp]);
|
||||
System.out.format("JPEG -> YUV %s ", SUBNAME_LONG[subsamp]);
|
||||
if (!sf.isOne())
|
||||
System.out.format("%d/%d ... ", sf.getNum(), sf.getDenom());
|
||||
else System.out.print("... ");
|
||||
@@ -741,7 +742,7 @@ public class TJUnitTest {
|
||||
System.out.print("FAILED!\n"); exitStatus = -1;
|
||||
}
|
||||
|
||||
System.out.format("YUV %s -> %s %s ... ", subNameLong[subsamp],
|
||||
System.out.format("YUV %s -> %s %s ... ", SUBNAME_LONG[subsamp],
|
||||
pfStrLong, buStrLong);
|
||||
tjd.setSourceImage(yuvImage);
|
||||
} else {
|
||||
@@ -758,7 +759,7 @@ public class TJUnitTest {
|
||||
if (bi) {
|
||||
tempStr = baseName + "_dec_" + pfStr + "_" +
|
||||
(((flags & TJ.FLAG_BOTTOMUP) != 0) ? "BU" : "TD") + "_" +
|
||||
subName[subsamp] + "_" +
|
||||
SUBNAME[subsamp] + "_" +
|
||||
(double)sf.getNum() / (double)sf.getDenom() + "x" + ".png";
|
||||
File file = new File(tempStr);
|
||||
ImageIO.write(img, "png", file);
|
||||
@@ -775,10 +776,9 @@ public class TJUnitTest {
|
||||
}
|
||||
}
|
||||
|
||||
private static void decompTest(TJDecompressor tjd, byte[] jpegBuf,
|
||||
int jpegSize, int w, int h, int pf,
|
||||
String baseName, int subsamp,
|
||||
int flags) throws Exception {
|
||||
static void decompTest(TJDecompressor tjd, byte[] jpegBuf, int jpegSize,
|
||||
int w, int h, int pf, String baseName, int subsamp,
|
||||
int flags) throws Exception {
|
||||
int i;
|
||||
TJScalingFactor[] sf = TJ.getScalingFactors();
|
||||
for (i = 0; i < sf.length; i++) {
|
||||
@@ -794,8 +794,8 @@ public class TJUnitTest {
|
||||
}
|
||||
}
|
||||
|
||||
private static void doTest(int w, int h, int[] formats, int subsamp,
|
||||
String baseName) throws Exception {
|
||||
static void doTest(int w, int h, int[] formats, int subsamp, String baseName)
|
||||
throws Exception {
|
||||
TJCompressor tjc = null;
|
||||
TJDecompressor tjd = null;
|
||||
int size;
|
||||
@@ -837,7 +837,7 @@ public class TJUnitTest {
|
||||
if (tjd != null) tjd.close();
|
||||
}
|
||||
|
||||
private static void bufSizeTest() throws Exception {
|
||||
static void bufSizeTest() throws Exception {
|
||||
int w, h, i, subsamp;
|
||||
byte[] srcBuf, dstBuf = null;
|
||||
YUVImage dstImage = null;
|
||||
@@ -911,44 +911,45 @@ public class TJUnitTest {
|
||||
usage();
|
||||
}
|
||||
if (doYUV)
|
||||
_4byteFormats[4] = -1;
|
||||
doTest(35, 39, bi ? _3byteFormatsBI : _3byteFormats, TJ.SAMP_444,
|
||||
FORMATS_4BYTE[4] = -1;
|
||||
doTest(35, 39, bi ? FORMATS_3BYTEBI : FORMATS_3BYTE, TJ.SAMP_444,
|
||||
testName);
|
||||
doTest(39, 41, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_444,
|
||||
doTest(39, 41, bi ? FORMATS_4BYTEBI : FORMATS_4BYTE, TJ.SAMP_444,
|
||||
testName);
|
||||
doTest(41, 35, bi ? _3byteFormatsBI : _3byteFormats, TJ.SAMP_422,
|
||||
doTest(41, 35, bi ? FORMATS_3BYTEBI : FORMATS_3BYTE, TJ.SAMP_422,
|
||||
testName);
|
||||
doTest(35, 39, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_422,
|
||||
doTest(35, 39, bi ? FORMATS_4BYTEBI : FORMATS_4BYTE, TJ.SAMP_422,
|
||||
testName);
|
||||
doTest(39, 41, bi ? _3byteFormatsBI : _3byteFormats, TJ.SAMP_420,
|
||||
doTest(39, 41, bi ? FORMATS_3BYTEBI : FORMATS_3BYTE, TJ.SAMP_420,
|
||||
testName);
|
||||
doTest(41, 35, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_420,
|
||||
doTest(41, 35, bi ? FORMATS_4BYTEBI : FORMATS_4BYTE, TJ.SAMP_420,
|
||||
testName);
|
||||
doTest(35, 39, bi ? _3byteFormatsBI : _3byteFormats, TJ.SAMP_440,
|
||||
doTest(35, 39, bi ? FORMATS_3BYTEBI : FORMATS_3BYTE, TJ.SAMP_440,
|
||||
testName);
|
||||
doTest(39, 41, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_440,
|
||||
doTest(39, 41, bi ? FORMATS_4BYTEBI : FORMATS_4BYTE, TJ.SAMP_440,
|
||||
testName);
|
||||
doTest(41, 35, bi ? _3byteFormatsBI : _3byteFormats, TJ.SAMP_411,
|
||||
doTest(41, 35, bi ? FORMATS_3BYTEBI : FORMATS_3BYTE, TJ.SAMP_411,
|
||||
testName);
|
||||
doTest(35, 39, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_411,
|
||||
doTest(35, 39, bi ? FORMATS_4BYTEBI : FORMATS_4BYTE, TJ.SAMP_411,
|
||||
testName);
|
||||
doTest(39, 41, bi ? onlyGrayBI : onlyGray, TJ.SAMP_GRAY, testName);
|
||||
doTest(41, 35, bi ? _3byteFormatsBI : _3byteFormats, TJ.SAMP_GRAY,
|
||||
doTest(39, 41, bi ? FORMATS_GRAYBI : FORMATS_GRAY, TJ.SAMP_GRAY,
|
||||
testName);
|
||||
_4byteFormats[4] = -1;
|
||||
doTest(35, 39, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_GRAY,
|
||||
doTest(41, 35, bi ? FORMATS_3BYTEBI : FORMATS_3BYTE, TJ.SAMP_GRAY,
|
||||
testName);
|
||||
FORMATS_4BYTE[4] = -1;
|
||||
doTest(35, 39, bi ? FORMATS_4BYTEBI : FORMATS_4BYTE, TJ.SAMP_GRAY,
|
||||
testName);
|
||||
if (!bi)
|
||||
bufSizeTest();
|
||||
if (doYUV && !bi) {
|
||||
System.out.print("\n--------------------\n\n");
|
||||
doTest(48, 48, onlyRGB, TJ.SAMP_444, "javatest_yuv0");
|
||||
doTest(48, 48, onlyRGB, TJ.SAMP_422, "javatest_yuv0");
|
||||
doTest(48, 48, onlyRGB, TJ.SAMP_420, "javatest_yuv0");
|
||||
doTest(48, 48, onlyRGB, TJ.SAMP_440, "javatest_yuv0");
|
||||
doTest(48, 48, onlyRGB, TJ.SAMP_411, "javatest_yuv0");
|
||||
doTest(48, 48, onlyRGB, TJ.SAMP_GRAY, "javatest_yuv0");
|
||||
doTest(48, 48, onlyGray, TJ.SAMP_GRAY, "javatest_yuv0");
|
||||
doTest(48, 48, FORMATS_RGB, TJ.SAMP_444, "javatest_yuv0");
|
||||
doTest(48, 48, FORMATS_RGB, TJ.SAMP_422, "javatest_yuv0");
|
||||
doTest(48, 48, FORMATS_RGB, TJ.SAMP_420, "javatest_yuv0");
|
||||
doTest(48, 48, FORMATS_RGB, TJ.SAMP_440, "javatest_yuv0");
|
||||
doTest(48, 48, FORMATS_RGB, TJ.SAMP_411, "javatest_yuv0");
|
||||
doTest(48, 48, FORMATS_RGB, TJ.SAMP_GRAY, "javatest_yuv0");
|
||||
doTest(48, 48, FORMATS_GRAY, TJ.SAMP_GRAY, "javatest_yuv0");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
@@ -810,8 +810,6 @@
|
||||
<dd>
|
||||
<div class="block">TurboJPEG utility class (cannot be instantiated)</div>
|
||||
</dd>
|
||||
<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#TJ()">TJ()</a></span> - Constructor for class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
|
||||
<dd> </dd>
|
||||
<dt><a href="./org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">TJCompressor</span></a> - Class in <a href="./org/libjpegturbo/turbojpeg/package-summary.html">org.libjpegturbo.turbojpeg</a></dt>
|
||||
<dd>
|
||||
<div class="block">TurboJPEG compressor</div>
|
||||
@@ -885,7 +883,9 @@
|
||||
<div class="block">Fractional scaling factor</div>
|
||||
</dd>
|
||||
<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJScalingFactor.html#TJScalingFactor(int,%20int)">TJScalingFactor(int, int)</a></span> - Constructor for class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg">TJScalingFactor</a></dt>
|
||||
<dd> </dd>
|
||||
<dd>
|
||||
<div class="block">Create a TurboJPEG scaling factor instance.</div>
|
||||
</dd>
|
||||
<dt><a href="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">TJTransform</span></a> - Class in <a href="./org/libjpegturbo/turbojpeg/package-summary.html">org.libjpegturbo.turbojpeg</a></dt>
|
||||
<dd>
|
||||
<div class="block">Lossless transform parameters</div>
|
||||
|
||||
@@ -63,13 +63,13 @@
|
||||
<li>Summary: </li>
|
||||
<li>Nested | </li>
|
||||
<li><a href="#field_summary">Field</a> | </li>
|
||||
<li><a href="#constructor_summary">Constr</a> | </li>
|
||||
<li>Constr | </li>
|
||||
<li><a href="#method_summary">Method</a></li>
|
||||
</ul>
|
||||
<ul class="subNavList">
|
||||
<li>Detail: </li>
|
||||
<li><a href="#field_detail">Field</a> | </li>
|
||||
<li><a href="#constructor_detail">Constr</a> | </li>
|
||||
<li>Constr | </li>
|
||||
<li><a href="#method_detail">Method</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -361,23 +361,6 @@ extends java.lang.Object</pre>
|
||||
</table>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- ======== CONSTRUCTOR SUMMARY ======== -->
|
||||
<ul class="blockList">
|
||||
<li class="blockList"><a name="constructor_summary">
|
||||
<!-- -->
|
||||
</a>
|
||||
<h3>Constructor Summary</h3>
|
||||
<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Constructor Summary table, listing constructors, and an explanation">
|
||||
<caption><span>Constructors</span><span class="tabEnd"> </span></caption>
|
||||
<tr>
|
||||
<th class="colOne" scope="col">Constructor and Description</th>
|
||||
</tr>
|
||||
<tr class="altColor">
|
||||
<td class="colOne"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#TJ()">TJ</a></strong>()</code> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- ========== METHOD SUMMARY =========== -->
|
||||
<ul class="blockList">
|
||||
<li class="blockList"><a name="method_summary">
|
||||
@@ -1070,23 +1053,6 @@ public static final int FLAG_FORCESSE3</pre>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- ========= CONSTRUCTOR DETAIL ======== -->
|
||||
<ul class="blockList">
|
||||
<li class="blockList"><a name="constructor_detail">
|
||||
<!-- -->
|
||||
</a>
|
||||
<h3>Constructor Detail</h3>
|
||||
<a name="TJ()">
|
||||
<!-- -->
|
||||
</a>
|
||||
<ul class="blockListLast">
|
||||
<li class="blockList">
|
||||
<h4>TJ</h4>
|
||||
<pre>public TJ()</pre>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- ============ METHOD DETAIL ========== -->
|
||||
<ul class="blockList">
|
||||
<li class="blockList"><a name="method_detail">
|
||||
@@ -1372,13 +1338,13 @@ public static int bufSizeYUV(int width,
|
||||
<li>Summary: </li>
|
||||
<li>Nested | </li>
|
||||
<li><a href="#field_summary">Field</a> | </li>
|
||||
<li><a href="#constructor_summary">Constr</a> | </li>
|
||||
<li>Constr | </li>
|
||||
<li><a href="#method_summary">Method</a></li>
|
||||
</ul>
|
||||
<ul class="subNavList">
|
||||
<li>Detail: </li>
|
||||
<li><a href="#field_detail">Field</a> | </li>
|
||||
<li><a href="#constructor_detail">Constr</a> | </li>
|
||||
<li>Constr | </li>
|
||||
<li><a href="#method_detail">Method</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -579,8 +579,8 @@ public void setSourceImage(byte[] srcImage,
|
||||
<p>
|
||||
NOTE: This method has no effect when compressing a JPEG image from a YUV
|
||||
planar source. In that case, the level of chrominance subsampling in
|
||||
the JPEG image is determined by the source. Further, this method has no
|
||||
effect when encoding to a pre-allocated <a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg"><code>YUVImage</code></a> instance. In
|
||||
the JPEG image is determined by the source. Furthermore, this method has
|
||||
no effect when encoding to a pre-allocated <a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg"><code>YUVImage</code></a> instance. In
|
||||
that case, the level of chrominance subsampling is determined by the
|
||||
destination.</div>
|
||||
<dl><dt><span class="strong">Parameters:</span></dt><dd><code>newSubsamp</code> - the level of chrominance subsampling to use in
|
||||
|
||||
@@ -118,7 +118,9 @@ extends java.lang.Object</pre>
|
||||
</tr>
|
||||
<tr class="altColor">
|
||||
<td class="colOne"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJScalingFactor.html#TJScalingFactor(int,%20int)">TJScalingFactor</a></strong>(int num,
|
||||
int denom)</code> </td>
|
||||
int denom)</code>
|
||||
<div class="block">Create a TurboJPEG scaling factor instance.</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</li>
|
||||
@@ -197,6 +199,8 @@ extends java.lang.Object</pre>
|
||||
<h4>TJScalingFactor</h4>
|
||||
<pre>public TJScalingFactor(int num,
|
||||
int denom)</pre>
|
||||
<div class="block">Create a TurboJPEG scaling factor instance.</div>
|
||||
<dl><dt><span class="strong">Parameters:</span></dt><dd><code>num</code> - numerator</dd><dd><code>denom</code> - denominator</dd></dl>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
@@ -239,7 +243,8 @@ extends java.lang.Object</pre>
|
||||
<div class="block">Returns the scaled value of <code>dimension</code>. This function
|
||||
performs the integer equivalent of
|
||||
<code>ceil(dimension * scalingFactor)</code>.</div>
|
||||
<dl><dt><span class="strong">Returns:</span></dt><dd>the scaled value of <code>dimension</code>.</dd></dl>
|
||||
<dl><dt><span class="strong">Parameters:</span></dt><dd><code>dimension</code> - width or height to multiply by this scaling factor</dd>
|
||||
<dt><span class="strong">Returns:</span></dt><dd>the scaled value of <code>dimension</code>.</dd></dl>
|
||||
</li>
|
||||
</ul>
|
||||
<a name="equals(org.libjpegturbo.turbojpeg.TJScalingFactor)">
|
||||
@@ -251,7 +256,8 @@ extends java.lang.Object</pre>
|
||||
<pre>public boolean equals(<a href="../../../org/libjpegturbo/turbojpeg/TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg">TJScalingFactor</a> other)</pre>
|
||||
<div class="block">Returns true or false, depending on whether this instance and
|
||||
<code>other</code> have the same numerator and denominator.</div>
|
||||
<dl><dt><span class="strong">Returns:</span></dt><dd>true or false, depending on whether this instance and
|
||||
<dl><dt><span class="strong">Parameters:</span></dt><dd><code>other</code> - the scaling factor against which to compare this one</dd>
|
||||
<dt><span class="strong">Returns:</span></dt><dd>true or false, depending on whether this instance and
|
||||
<code>other</code> have the same numerator and denominator.</dd></dl>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C)2011-2013, 2017 D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C)2011-2013, 2017-2018 D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C)2015 Viktor Szathmáry. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -34,6 +34,8 @@ package org.libjpegturbo.turbojpeg;
|
||||
*/
|
||||
public final class TJ {
|
||||
|
||||
private TJ() {}
|
||||
|
||||
/**
|
||||
* The number of chrominance subsampling options
|
||||
*/
|
||||
@@ -89,10 +91,10 @@ public final class TJ {
|
||||
*/
|
||||
public static int getMCUWidth(int subsamp) {
|
||||
checkSubsampling(subsamp);
|
||||
return mcuWidth[subsamp];
|
||||
return MCU_WIDTH[subsamp];
|
||||
}
|
||||
|
||||
private static final int[] mcuWidth = {
|
||||
private static final int[] MCU_WIDTH = {
|
||||
8, 16, 16, 8, 8, 32
|
||||
};
|
||||
|
||||
@@ -109,10 +111,10 @@ public final class TJ {
|
||||
*/
|
||||
public static int getMCUHeight(int subsamp) {
|
||||
checkSubsampling(subsamp);
|
||||
return mcuHeight[subsamp];
|
||||
return MCU_HEIGHT[subsamp];
|
||||
}
|
||||
|
||||
private static final int[] mcuHeight = {
|
||||
private static final int[] MCU_HEIGHT = {
|
||||
8, 8, 16, 8, 16, 8
|
||||
};
|
||||
|
||||
@@ -217,10 +219,10 @@ public final class TJ {
|
||||
*/
|
||||
public static int getPixelSize(int pixelFormat) {
|
||||
checkPixelFormat(pixelFormat);
|
||||
return pixelSize[pixelFormat];
|
||||
return PIXEL_SIZE[pixelFormat];
|
||||
}
|
||||
|
||||
private static final int[] pixelSize = {
|
||||
private static final int[] PIXEL_SIZE = {
|
||||
3, 3, 4, 4, 4, 4, 1, 4, 4, 4, 4, 4
|
||||
};
|
||||
|
||||
@@ -239,10 +241,10 @@ public final class TJ {
|
||||
*/
|
||||
public static int getRedOffset(int pixelFormat) {
|
||||
checkPixelFormat(pixelFormat);
|
||||
return redOffset[pixelFormat];
|
||||
return RED_OFFSET[pixelFormat];
|
||||
}
|
||||
|
||||
private static final int[] redOffset = {
|
||||
private static final int[] RED_OFFSET = {
|
||||
0, 2, 0, 2, 3, 1, -1, 0, 2, 3, 1, -1
|
||||
};
|
||||
|
||||
@@ -261,10 +263,10 @@ public final class TJ {
|
||||
*/
|
||||
public static int getGreenOffset(int pixelFormat) {
|
||||
checkPixelFormat(pixelFormat);
|
||||
return greenOffset[pixelFormat];
|
||||
return GREEN_OFFSET[pixelFormat];
|
||||
}
|
||||
|
||||
private static final int[] greenOffset = {
|
||||
private static final int[] GREEN_OFFSET = {
|
||||
1, 1, 1, 1, 2, 2, -1, 1, 1, 2, 2, -1
|
||||
};
|
||||
|
||||
@@ -283,10 +285,10 @@ public final class TJ {
|
||||
*/
|
||||
public static int getBlueOffset(int pixelFormat) {
|
||||
checkPixelFormat(pixelFormat);
|
||||
return blueOffset[pixelFormat];
|
||||
return BLUE_OFFSET[pixelFormat];
|
||||
}
|
||||
|
||||
private static final int[] blueOffset = {
|
||||
private static final int[] BLUE_OFFSET = {
|
||||
2, 0, 2, 0, 1, 3, -1, 2, 0, 1, 3, -1
|
||||
};
|
||||
|
||||
@@ -305,10 +307,10 @@ public final class TJ {
|
||||
*/
|
||||
public static int getAlphaOffset(int pixelFormat) {
|
||||
checkPixelFormat(pixelFormat);
|
||||
return alphaOffset[pixelFormat];
|
||||
return ALPHA_OFFSET[pixelFormat];
|
||||
}
|
||||
|
||||
private static final int[] alphaOffset = {
|
||||
private static final int[] ALPHA_OFFSET = {
|
||||
-1, -1, -1, -1, -1, -1, -1, 3, 3, 0, 0, -1
|
||||
};
|
||||
|
||||
@@ -340,6 +342,7 @@ public final class TJ {
|
||||
* can be compressed from and decompressed to any of the extended RGB pixel
|
||||
* formats or grayscale, or they can be decompressed to YUV planar images.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:ConstantName")
|
||||
public static final int CS_YCbCr = 1;
|
||||
/**
|
||||
* Grayscale colorspace. The JPEG image retains only the luminance data (Y
|
||||
@@ -374,12 +377,16 @@ public final class TJ {
|
||||
*/
|
||||
public static final int FLAG_BOTTOMUP = 2;
|
||||
|
||||
@SuppressWarnings("checkstyle:JavadocVariable")
|
||||
@Deprecated
|
||||
public static final int FLAG_FORCEMMX = 8;
|
||||
@SuppressWarnings("checkstyle:JavadocVariable")
|
||||
@Deprecated
|
||||
public static final int FLAG_FORCESSE = 16;
|
||||
@SuppressWarnings("checkstyle:JavadocVariable")
|
||||
@Deprecated
|
||||
public static final int FLAG_FORCESSE2 = 32;
|
||||
@SuppressWarnings("checkstyle:JavadocVariable")
|
||||
@Deprecated
|
||||
public static final int FLAG_FORCESSE3 = 128;
|
||||
|
||||
@@ -490,6 +497,7 @@ public final class TJ {
|
||||
/**
|
||||
* @deprecated Use {@link #bufSizeYUV(int, int, int, int)} instead.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
@Deprecated
|
||||
public static native int bufSizeYUV(int width, int height, int subsamp);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C)2011-2015 D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C)2011-2015, 2018 D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C)2015 Viktor Szathmáry. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -77,6 +77,7 @@ public class TJCompressor implements Closeable {
|
||||
* @deprecated Use
|
||||
* {@link #TJCompressor(byte[], int, int, int, int, int, int)} instead.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
@Deprecated
|
||||
public TJCompressor(byte[] srcImage, int width, int pitch, int height,
|
||||
int pixelFormat) throws TJException {
|
||||
@@ -164,6 +165,7 @@ public class TJCompressor implements Closeable {
|
||||
* @deprecated Use
|
||||
* {@link #setSourceImage(byte[], int, int, int, int, int, int)} instead.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
@Deprecated
|
||||
public void setSourceImage(byte[] srcImage, int width, int pitch,
|
||||
int height, int pixelFormat) throws TJException {
|
||||
@@ -285,8 +287,8 @@ public class TJCompressor implements Closeable {
|
||||
* <p>
|
||||
* NOTE: This method has no effect when compressing a JPEG image from a YUV
|
||||
* planar source. In that case, the level of chrominance subsampling in
|
||||
* the JPEG image is determined by the source. Further, this method has no
|
||||
* effect when encoding to a pre-allocated {@link YUVImage} instance. In
|
||||
* the JPEG image is determined by the source. Furthermore, this method has
|
||||
* no effect when encoding to a pre-allocated {@link YUVImage} instance. In
|
||||
* that case, the level of chrominance subsampling is determined by the
|
||||
* destination.
|
||||
*
|
||||
@@ -386,6 +388,7 @@ public class TJCompressor implements Closeable {
|
||||
* {@link #setSourceImage(BufferedImage, int, int, int, int)} and
|
||||
* {@link #compress(byte[], int)} instead.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
@Deprecated
|
||||
public void compress(BufferedImage srcImage, byte[] dstBuf, int flags)
|
||||
throws TJException {
|
||||
@@ -398,6 +401,7 @@ public class TJCompressor implements Closeable {
|
||||
* {@link #setSourceImage(BufferedImage, int, int, int, int)} and
|
||||
* {@link #compress(int)} instead.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
@Deprecated
|
||||
public byte[] compress(BufferedImage srcImage, int flags)
|
||||
throws TJException {
|
||||
@@ -445,14 +449,16 @@ public class TJCompressor implements Closeable {
|
||||
/**
|
||||
* @deprecated Use {@link #encodeYUV(YUVImage, int)} instead.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
@Deprecated
|
||||
public void encodeYUV(byte[] dstBuf, int flags) throws TJException {
|
||||
if (dstBuf == null)
|
||||
throw new IllegalArgumentException("Invalid argument in encodeYUV()");
|
||||
checkSourceImage();
|
||||
checkSubsampling();
|
||||
YUVImage yuvImage = new YUVImage(dstBuf, srcWidth, 4, srcHeight, subsamp);
|
||||
encodeYUV(yuvImage, flags);
|
||||
YUVImage dstYUVImage = new YUVImage(dstBuf, srcWidth, 4, srcHeight,
|
||||
subsamp);
|
||||
encodeYUV(dstYUVImage, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -477,9 +483,9 @@ public class TJCompressor implements Closeable {
|
||||
checkSubsampling();
|
||||
if (pad < 1 || ((pad & (pad - 1)) != 0))
|
||||
throw new IllegalStateException("Invalid argument in encodeYUV()");
|
||||
YUVImage yuvImage = new YUVImage(srcWidth, pad, srcHeight, subsamp);
|
||||
encodeYUV(yuvImage, flags);
|
||||
return yuvImage;
|
||||
YUVImage dstYUVImage = new YUVImage(srcWidth, pad, srcHeight, subsamp);
|
||||
encodeYUV(dstYUVImage, flags);
|
||||
return dstYUVImage;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -506,21 +512,22 @@ public class TJCompressor implements Closeable {
|
||||
public YUVImage encodeYUV(int[] strides, int flags) throws TJException {
|
||||
checkSourceImage();
|
||||
checkSubsampling();
|
||||
YUVImage yuvImage = new YUVImage(srcWidth, strides, srcHeight, subsamp);
|
||||
encodeYUV(yuvImage, flags);
|
||||
return yuvImage;
|
||||
YUVImage dstYUVImage = new YUVImage(srcWidth, strides, srcHeight, subsamp);
|
||||
encodeYUV(dstYUVImage, flags);
|
||||
return dstYUVImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #encodeYUV(int, int)} instead.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
@Deprecated
|
||||
public byte[] encodeYUV(int flags) throws TJException {
|
||||
checkSourceImage();
|
||||
checkSubsampling();
|
||||
YUVImage yuvImage = new YUVImage(srcWidth, 4, srcHeight, subsamp);
|
||||
encodeYUV(yuvImage, flags);
|
||||
return yuvImage.getBuf();
|
||||
YUVImage dstYUVImage = new YUVImage(srcWidth, 4, srcHeight, subsamp);
|
||||
encodeYUV(dstYUVImage, flags);
|
||||
return dstYUVImage.getBuf();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -528,6 +535,7 @@ public class TJCompressor implements Closeable {
|
||||
* {@link #setSourceImage(BufferedImage, int, int, int, int)} and
|
||||
* {@link #encodeYUV(byte[], int)} instead.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
@Deprecated
|
||||
public void encodeYUV(BufferedImage srcImage, byte[] dstBuf, int flags)
|
||||
throws TJException {
|
||||
@@ -540,6 +548,7 @@ public class TJCompressor implements Closeable {
|
||||
* {@link #setSourceImage(BufferedImage, int, int, int, int)} and
|
||||
* {@link #encodeYUV(int, int)} instead.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
@Deprecated
|
||||
public byte[] encodeYUV(BufferedImage srcImage, int flags)
|
||||
throws TJException {
|
||||
@@ -567,6 +576,7 @@ public class TJCompressor implements Closeable {
|
||||
destroy();
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:DesignForExtension")
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
@@ -582,44 +592,53 @@ public class TJCompressor implements Closeable {
|
||||
private native void destroy() throws TJException;
|
||||
|
||||
// JPEG size in bytes is returned
|
||||
@SuppressWarnings("checkstyle:HiddenField")
|
||||
@Deprecated
|
||||
private native int compress(byte[] srcBuf, int width, int pitch,
|
||||
int height, int pixelFormat, byte[] dstBuf, int jpegSubsamp, int jpegQual,
|
||||
int height, int pixelFormat, byte[] jpegBuf, int jpegSubsamp, int jpegQual,
|
||||
int flags) throws TJException;
|
||||
|
||||
@SuppressWarnings("checkstyle:HiddenField")
|
||||
private native int compress(byte[] srcBuf, int x, int y, int width,
|
||||
int pitch, int height, int pixelFormat, byte[] dstBuf, int jpegSubsamp,
|
||||
int pitch, int height, int pixelFormat, byte[] jpegBuf, int jpegSubsamp,
|
||||
int jpegQual, int flags) throws TJException;
|
||||
|
||||
@SuppressWarnings("checkstyle:HiddenField")
|
||||
@Deprecated
|
||||
private native int compress(int[] srcBuf, int width, int stride,
|
||||
int height, int pixelFormat, byte[] dstBuf, int jpegSubsamp, int jpegQual,
|
||||
int height, int pixelFormat, byte[] jpegBuf, int jpegSubsamp, int jpegQual,
|
||||
int flags) throws TJException;
|
||||
|
||||
@SuppressWarnings("checkstyle:HiddenField")
|
||||
private native int compress(int[] srcBuf, int x, int y, int width,
|
||||
int stride, int height, int pixelFormat, byte[] dstBuf, int jpegSubsamp,
|
||||
int stride, int height, int pixelFormat, byte[] jpegBuf, int jpegSubsamp,
|
||||
int jpegQual, int flags) throws TJException;
|
||||
|
||||
@SuppressWarnings("checkstyle:HiddenField")
|
||||
private native int compressFromYUV(byte[][] srcPlanes, int[] srcOffsets,
|
||||
int width, int[] srcStrides, int height, int subsamp, byte[] dstBuf,
|
||||
int width, int[] srcStrides, int height, int subsamp, byte[] jpegBuf,
|
||||
int jpegQual, int flags)
|
||||
throws TJException;
|
||||
|
||||
@SuppressWarnings("checkstyle:HiddenField")
|
||||
@Deprecated
|
||||
private native void encodeYUV(byte[] srcBuf, int width, int pitch,
|
||||
int height, int pixelFormat, byte[] dstBuf, int subsamp, int flags)
|
||||
throws TJException;
|
||||
|
||||
@SuppressWarnings("checkstyle:HiddenField")
|
||||
private native void encodeYUV(byte[] srcBuf, int x, int y, int width,
|
||||
int pitch, int height, int pixelFormat, byte[][] dstPlanes,
|
||||
int[] dstOffsets, int[] dstStrides, int subsamp, int flags)
|
||||
throws TJException;
|
||||
|
||||
@SuppressWarnings("checkstyle:HiddenField")
|
||||
@Deprecated
|
||||
private native void encodeYUV(int[] srcBuf, int width, int stride,
|
||||
int height, int pixelFormat, byte[] dstBuf, int subsamp, int flags)
|
||||
throws TJException;
|
||||
|
||||
@SuppressWarnings("checkstyle:HiddenField")
|
||||
private native void encodeYUV(int[] srcBuf, int x, int y, int width,
|
||||
int srcStride, int height, int pixelFormat, byte[][] dstPlanes,
|
||||
int[] dstOffsets, int[] dstStrides, int subsamp, int flags)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C)2011-2015 D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C)2011-2015, 2018 D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C)2015 Viktor Szathmáry. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -82,6 +82,7 @@ public class TJDecompressor implements Closeable {
|
||||
* @param yuvImage {@link YUVImage} instance containing a YUV planar
|
||||
* image to be decoded. This image is not modified.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:HiddenField")
|
||||
public TJDecompressor(YUVImage yuvImage) throws TJException {
|
||||
init();
|
||||
setSourceImage(yuvImage);
|
||||
@@ -109,6 +110,7 @@ public class TJDecompressor implements Closeable {
|
||||
/**
|
||||
* @deprecated Use {@link #setSourceImage(byte[], int)} instead.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
@Deprecated
|
||||
public void setJPEGImage(byte[] jpegImage, int imageSize)
|
||||
throws TJException {
|
||||
@@ -400,6 +402,7 @@ public class TJDecompressor implements Closeable {
|
||||
* @deprecated Use
|
||||
* {@link #decompress(byte[], int, int, int, int, int, int, int)} instead.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
@Deprecated
|
||||
public void decompress(byte[] dstBuf, int desiredWidth, int pitch,
|
||||
int desiredHeight, int pixelFormat, int flags)
|
||||
@@ -494,11 +497,12 @@ public class TJDecompressor implements Closeable {
|
||||
/**
|
||||
* @deprecated Use {@link #decompressToYUV(YUVImage, int)} instead.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
@Deprecated
|
||||
public void decompressToYUV(byte[] dstBuf, int flags) throws TJException {
|
||||
YUVImage dstImage = new YUVImage(dstBuf, jpegWidth, 4, jpegHeight,
|
||||
jpegSubsamp);
|
||||
decompressToYUV(dstImage, flags);
|
||||
YUVImage dstYUVImage = new YUVImage(dstBuf, jpegWidth, 4, jpegHeight,
|
||||
jpegSubsamp);
|
||||
decompressToYUV(dstYUVImage, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -553,10 +557,10 @@ public class TJDecompressor implements Closeable {
|
||||
|
||||
int scaledWidth = getScaledWidth(desiredWidth, desiredHeight);
|
||||
int scaledHeight = getScaledHeight(desiredWidth, desiredHeight);
|
||||
YUVImage yuvImage = new YUVImage(scaledWidth, null, scaledHeight,
|
||||
jpegSubsamp);
|
||||
decompressToYUV(yuvImage, flags);
|
||||
return yuvImage;
|
||||
YUVImage dstYUVImage = new YUVImage(scaledWidth, null, scaledHeight,
|
||||
jpegSubsamp);
|
||||
decompressToYUV(dstYUVImage, flags);
|
||||
return dstYUVImage;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -606,20 +610,21 @@ public class TJDecompressor implements Closeable {
|
||||
|
||||
int scaledWidth = getScaledWidth(desiredWidth, desiredHeight);
|
||||
int scaledHeight = getScaledHeight(desiredWidth, desiredHeight);
|
||||
YUVImage yuvImage = new YUVImage(scaledWidth, pad, scaledHeight,
|
||||
jpegSubsamp);
|
||||
decompressToYUV(yuvImage, flags);
|
||||
return yuvImage;
|
||||
YUVImage dstYUVImage = new YUVImage(scaledWidth, pad, scaledHeight,
|
||||
jpegSubsamp);
|
||||
decompressToYUV(dstYUVImage, flags);
|
||||
return dstYUVImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #decompressToYUV(int, int, int, int)} instead.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
@Deprecated
|
||||
public byte[] decompressToYUV(int flags) throws TJException {
|
||||
YUVImage dstImage = new YUVImage(jpegWidth, 4, jpegHeight, jpegSubsamp);
|
||||
decompressToYUV(dstImage, flags);
|
||||
return dstImage.getBuf();
|
||||
YUVImage dstYUVImage = new YUVImage(jpegWidth, 4, jpegHeight, jpegSubsamp);
|
||||
decompressToYUV(dstYUVImage, flags);
|
||||
return dstYUVImage.getBuf();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -858,6 +863,7 @@ public class TJDecompressor implements Closeable {
|
||||
destroy();
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:DesignForExtension")
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C)2015 Viktor Szathmáry. All Rights Reserved.
|
||||
* Copyright (C)2017 D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C)2017-2018 D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -31,28 +31,34 @@ package org.libjpegturbo.turbojpeg;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@SuppressWarnings("checkstyle:JavadocType")
|
||||
public class TJException extends IOException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
public TJException() {
|
||||
super();
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
public TJException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
public TJException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
public TJException(String message, int code) {
|
||||
super(message);
|
||||
if (errorCode >= 0 && errorCode < TJ.NUMERR)
|
||||
errorCode = code;
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
public TJException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C)2011 D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C)2011, 2018 D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C)2015 Viktor Szathmáry. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -34,6 +34,13 @@ package org.libjpegturbo.turbojpeg;
|
||||
*/
|
||||
public class TJScalingFactor {
|
||||
|
||||
/**
|
||||
* Create a TurboJPEG scaling factor instance.
|
||||
*
|
||||
* @param num numerator
|
||||
* @param denom denominator
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:HiddenField")
|
||||
public TJScalingFactor(int num, int denom) {
|
||||
if (num < 1 || denom < 1)
|
||||
throw new IllegalArgumentException("Numerator and denominator must be >= 1");
|
||||
@@ -64,6 +71,8 @@ public class TJScalingFactor {
|
||||
* performs the integer equivalent of
|
||||
* <code>ceil(dimension * scalingFactor)</code>.
|
||||
*
|
||||
* @param dimension width or height to multiply by this scaling factor
|
||||
*
|
||||
* @return the scaled value of <code>dimension</code>.
|
||||
*/
|
||||
public int getScaled(int dimension) {
|
||||
@@ -74,6 +83,8 @@ public class TJScalingFactor {
|
||||
* Returns true or false, depending on whether this instance and
|
||||
* <code>other</code> have the same numerator and denominator.
|
||||
*
|
||||
* @param other the scaling factor against which to compare this one
|
||||
*
|
||||
* @return true or false, depending on whether this instance and
|
||||
* <code>other</code> have the same numerator and denominator.
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C)2011, 2013 D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C)2011, 2013, 2018 D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -173,6 +173,7 @@ public class TJTransform extends Rectangle {
|
||||
* @param cf an instance of an object that implements the {@link
|
||||
* TJCustomFilter} interface, or null if no custom filter is needed
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:HiddenField")
|
||||
public TJTransform(int x, int y, int w, int h, int op, int options,
|
||||
TJCustomFilter cf) {
|
||||
super(x, y, w, h);
|
||||
@@ -197,6 +198,7 @@ public class TJTransform extends Rectangle {
|
||||
* @param cf an instance of an object that implements the {@link
|
||||
* TJCustomFilter} interface, or null if no custom filter is needed
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:HiddenField")
|
||||
public TJTransform(Rectangle r, int op, int options,
|
||||
TJCustomFilter cf) {
|
||||
super(r);
|
||||
@@ -208,15 +210,18 @@ public class TJTransform extends Rectangle {
|
||||
/**
|
||||
* Transform operation (one of <code>OP_*</code>)
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:VisibilityModifier")
|
||||
public int op = 0;
|
||||
|
||||
/**
|
||||
* Transform options (bitwise OR of one or more of <code>OPT_*</code>)
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:VisibilityModifier")
|
||||
public int options = 0;
|
||||
|
||||
/**
|
||||
* Custom filter instance
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:VisibilityModifier")
|
||||
public TJCustomFilter cf = null;
|
||||
}
|
||||
|
||||
@@ -111,11 +111,11 @@ public class TJTransformer extends TJDecompressor {
|
||||
* which specifies the transform parameters and/or cropping region for the
|
||||
* corresponding transformed output image
|
||||
*
|
||||
* @return an array of {@link TJDecompressor} instances, each of
|
||||
* which has a transformed JPEG image associated with it.
|
||||
*
|
||||
* @param flags the bitwise OR of one or more of
|
||||
* {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
|
||||
*
|
||||
* @return an array of {@link TJDecompressor} instances, each of
|
||||
* which has a transformed JPEG image associated with it.
|
||||
*/
|
||||
public TJDecompressor[] transform(TJTransform[] transforms, int flags)
|
||||
throws TJException {
|
||||
|
||||
@@ -247,9 +247,11 @@ public class YUVImage {
|
||||
if (planes[i] == null || offsets[i] < 0)
|
||||
throw new IllegalArgumentException("Invalid argument in YUVImage::setBuf()");
|
||||
if (strides[i] < 0 && offsets[i] - planeSize + pw < 0)
|
||||
throw new IllegalArgumentException("Stride for plane " + i + " would cause memory to be accessed below plane boundary");
|
||||
throw new IllegalArgumentException("Stride for plane " + i +
|
||||
" would cause memory to be accessed below plane boundary");
|
||||
if (planes[i].length < offsets[i] + planeSize)
|
||||
throw new IllegalArgumentException("Image plane " + i + " is not large enough");
|
||||
throw new IllegalArgumentException("Image plane " + i +
|
||||
" is not large enough");
|
||||
}
|
||||
|
||||
yuvPlanes = planes;
|
||||
@@ -294,9 +296,9 @@ public class YUVImage {
|
||||
int[] offsets = new int[nc];
|
||||
|
||||
planes[0] = yuvImage;
|
||||
strides[0] = PAD(TJ.planeWidth(0, width, subsamp), pad);
|
||||
strides[0] = pad(TJ.planeWidth(0, width, subsamp), pad);
|
||||
if (subsamp != TJ.SAMP_GRAY) {
|
||||
strides[1] = strides[2] = PAD(TJ.planeWidth(1, width, subsamp), pad);
|
||||
strides[1] = strides[2] = pad(TJ.planeWidth(1, width, subsamp), pad);
|
||||
planes[1] = planes[2] = yuvImage;
|
||||
offsets[1] = offsets[0] +
|
||||
strides[0] * TJ.planeHeight(0, height, subsamp);
|
||||
@@ -428,7 +430,7 @@ public class YUVImage {
|
||||
return TJ.bufSizeYUV(yuvWidth, yuvPad, yuvHeight, yuvSubsamp);
|
||||
}
|
||||
|
||||
private static int PAD(int v, int p) {
|
||||
private static int pad(int v, int p) {
|
||||
return (v + p - 1) & (~(p - 1));
|
||||
}
|
||||
|
||||
|
||||
11
jcarith.c
11
jcarith.c
@@ -4,16 +4,19 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Developed 1997-2009 by Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2015, D. R. Commander.
|
||||
* Copyright (C) 2015, 2018, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
* This file contains portable arithmetic entropy encoding routines for JPEG
|
||||
* (implementing the ISO/IEC IS 10918-1 and CCITT Recommendation ITU-T T.81).
|
||||
* (implementing Recommendation ITU-T T.81 | ISO/IEC 10918-1).
|
||||
*
|
||||
* Both sequential and progressive modes are supported in this single module.
|
||||
*
|
||||
* Suspension is not currently supported in this module.
|
||||
*
|
||||
* NOTE: All referenced figures are from
|
||||
* Recommendation ITU-T T.81 (1992) | ISO/IEC 10918-1:1994.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
@@ -142,13 +145,13 @@ finish_pass(j_compress_ptr cinfo)
|
||||
|
||||
/* Find the e->c in the coding interval with the largest
|
||||
* number of trailing zero bits */
|
||||
if ((temp = (e->a - 1 + e->c) & 0xFFFF0000L) < e->c)
|
||||
if ((temp = (e->a - 1 + e->c) & 0xFFFF0000UL) < e->c)
|
||||
e->c = temp + 0x8000L;
|
||||
else
|
||||
e->c = temp;
|
||||
/* Send remaining bytes to output */
|
||||
e->c <<= e->ct;
|
||||
if (e->c & 0xF8000000L) {
|
||||
if (e->c & 0xF8000000UL) {
|
||||
/* One final overflow has to be handled */
|
||||
if (e->buffer >= 0) {
|
||||
if (e->zc)
|
||||
|
||||
41
jchuff.c
41
jchuff.c
@@ -4,7 +4,7 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2009-2011, 2014-2016, D. R. Commander.
|
||||
* Copyright (C) 2009-2011, 2014-2016, 2018-2019, D. R. Commander.
|
||||
* Copyright (C) 2015, Matthieu Darbois.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
@@ -16,6 +16,9 @@
|
||||
* back up to the start of the current MCU. To do this, we copy state
|
||||
* variables into local working storage, and update them back to the
|
||||
* permanent JPEG objects only upon successful completion of an MCU.
|
||||
*
|
||||
* NOTE: All referenced figures are from
|
||||
* Recommendation ITU-T T.81 (1992) | ISO/IEC 10918-1:1994.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
@@ -353,6 +356,8 @@ dump_buffer(working_state *state)
|
||||
put_buffer = (put_buffer << size) | code; \
|
||||
}
|
||||
|
||||
#if SIZEOF_SIZE_T != 8 && !defined(_WIN64)
|
||||
|
||||
#define CHECKBUF15() { \
|
||||
if (put_bits > 15) { \
|
||||
EMIT_BYTE() \
|
||||
@@ -360,6 +365,8 @@ dump_buffer(working_state *state)
|
||||
} \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define CHECKBUF31() { \
|
||||
if (put_bits > 31) { \
|
||||
EMIT_BYTE() \
|
||||
@@ -859,13 +866,14 @@ encode_mcu_gather(j_compress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
* one bits (so that padding bits added at the end of a compressed segment
|
||||
* can't look like a valid code). Because of the canonical ordering of
|
||||
* codewords, this just means that there must be an unused slot in the
|
||||
* longest codeword length category. Section K.2 of the JPEG spec suggests
|
||||
* reserving such a slot by pretending that symbol 256 is a valid symbol
|
||||
* with count 1. In theory that's not optimal; giving it count zero but
|
||||
* including it in the symbol set anyway should give a better Huffman code.
|
||||
* But the theoretically better code actually seems to come out worse in
|
||||
* practice, because it produces more all-ones bytes (which incur stuffed
|
||||
* zero bytes in the final file). In any case the difference is tiny.
|
||||
* longest codeword length category. Annex K (Clause K.2) of
|
||||
* Rec. ITU-T T.81 (1992) | ISO/IEC 10918-1:1994 suggests reserving such a slot
|
||||
* by pretending that symbol 256 is a valid symbol with count 1. In theory
|
||||
* that's not optimal; giving it count zero but including it in the symbol set
|
||||
* anyway should give a better Huffman code. But the theoretically better code
|
||||
* actually seems to come out worse in practice, because it produces more
|
||||
* all-ones bytes (which incur stuffed zero bytes in the final file). In any
|
||||
* case the difference is tiny.
|
||||
*
|
||||
* The JPEG standard requires Huffman codes to be no more than 16 bits long.
|
||||
* If some symbols have a very small but nonzero probability, the Huffman tree
|
||||
@@ -967,13 +975,13 @@ jpeg_gen_optimal_table(j_compress_ptr cinfo, JHUFF_TBL *htbl, long freq[])
|
||||
|
||||
/* JPEG doesn't allow symbols with code lengths over 16 bits, so if the pure
|
||||
* Huffman procedure assigned any such lengths, we must adjust the coding.
|
||||
* Here is what the JPEG spec says about how this next bit works:
|
||||
* Since symbols are paired for the longest Huffman code, the symbols are
|
||||
* removed from this length category two at a time. The prefix for the pair
|
||||
* (which is one bit shorter) is allocated to one of the pair; then,
|
||||
* skipping the BITS entry for that prefix length, a code word from the next
|
||||
* shortest nonzero BITS entry is converted into a prefix for two code words
|
||||
* one bit longer.
|
||||
* Here is what Rec. ITU-T T.81 | ISO/IEC 10918-1 says about how this next
|
||||
* bit works: Since symbols are paired for the longest Huffman code, the
|
||||
* symbols are removed from this length category two at a time. The prefix
|
||||
* for the pair (which is one bit shorter) is allocated to one of the pair;
|
||||
* then, skipping the BITS entry for that prefix length, a code word from the
|
||||
* next shortest nonzero BITS entry is converted into a prefix for two code
|
||||
* words one bit longer.
|
||||
*/
|
||||
|
||||
for (i = MAX_CLEN; i > 16; i--) {
|
||||
@@ -999,7 +1007,8 @@ jpeg_gen_optimal_table(j_compress_ptr cinfo, JHUFF_TBL *htbl, long freq[])
|
||||
|
||||
/* Return a list of the symbols sorted by code length */
|
||||
/* It's not real clear to me why we don't need to consider the codelength
|
||||
* changes made above, but the JPEG spec seems to think this works.
|
||||
* changes made above, but Rec. ITU-T T.81 | ISO/IEC 10918-1 seems to think
|
||||
* this works.
|
||||
*/
|
||||
p = 0;
|
||||
for (i = 1; i <= MAX_CLEN; i++) {
|
||||
|
||||
10
jcmaster.c
10
jcmaster.c
@@ -5,7 +5,7 @@
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Modified 2003-2010 by Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2010, 2016, D. R. Commander.
|
||||
* Copyright (C) 2010, 2016, 2018, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -234,9 +234,9 @@ validate_script(j_compress_ptr cinfo)
|
||||
Al = scanptr->Al;
|
||||
if (cinfo->progressive_mode) {
|
||||
#ifdef C_PROGRESSIVE_SUPPORTED
|
||||
/* The JPEG spec simply gives the ranges 0..13 for Ah and Al, but that
|
||||
* seems wrong: the upper bound ought to depend on data precision.
|
||||
* Perhaps they really meant 0..N+1 for N-bit precision.
|
||||
/* Rec. ITU-T T.81 | ISO/IEC 10918-1 simply gives the ranges 0..13 for Ah
|
||||
* and Al, but that seems wrong: the upper bound ought to depend on data
|
||||
* precision. Perhaps they really meant 0..N+1 for N-bit precision.
|
||||
* Here we allow 0..10 for 8-bit data; Al larger than 10 results in
|
||||
* out-of-range reconstructed DC values during the first DC scan,
|
||||
* which might cause problems for some decoders.
|
||||
@@ -492,8 +492,8 @@ prepare_for_pass(j_compress_ptr cinfo)
|
||||
*/
|
||||
master->pass_type = output_pass;
|
||||
master->pass_number++;
|
||||
/*FALLTHROUGH*/
|
||||
#endif
|
||||
/*FALLTHROUGH*/
|
||||
case output_pass:
|
||||
/* Do a data-output pass. */
|
||||
/* We need not repeat per-scan setup if prior optimization pass did it. */
|
||||
|
||||
28
jconfig.h.in
28
jconfig.h.in
@@ -10,16 +10,16 @@
|
||||
#define LIBJPEG_TURBO_VERSION_NUMBER @LIBJPEG_TURBO_VERSION_NUMBER@
|
||||
|
||||
/* Support arithmetic encoding */
|
||||
#cmakedefine C_ARITH_CODING_SUPPORTED
|
||||
#cmakedefine C_ARITH_CODING_SUPPORTED 1
|
||||
|
||||
/* Support arithmetic decoding */
|
||||
#cmakedefine D_ARITH_CODING_SUPPORTED
|
||||
#cmakedefine D_ARITH_CODING_SUPPORTED 1
|
||||
|
||||
/* Support in-memory source/destination managers */
|
||||
#cmakedefine MEM_SRCDST_SUPPORTED
|
||||
#cmakedefine MEM_SRCDST_SUPPORTED 1
|
||||
|
||||
/* Use accelerated SIMD routines. */
|
||||
#cmakedefine WITH_SIMD
|
||||
#cmakedefine WITH_SIMD 1
|
||||
|
||||
/*
|
||||
* Define BITS_IN_JSAMPLE as either
|
||||
@@ -33,37 +33,37 @@
|
||||
#define BITS_IN_JSAMPLE @BITS_IN_JSAMPLE@ /* use 8 or 12 */
|
||||
|
||||
/* Define to 1 if you have the <locale.h> header file. */
|
||||
#cmakedefine HAVE_LOCALE_H
|
||||
#cmakedefine HAVE_LOCALE_H 1
|
||||
|
||||
/* Define to 1 if you have the <stddef.h> header file. */
|
||||
#cmakedefine HAVE_STDDEF_H
|
||||
#cmakedefine HAVE_STDDEF_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#cmakedefine HAVE_STDLIB_H
|
||||
#cmakedefine HAVE_STDLIB_H 1
|
||||
|
||||
/* Define if you need to include <sys/types.h> to get size_t. */
|
||||
#cmakedefine NEED_SYS_TYPES_H
|
||||
#cmakedefine NEED_SYS_TYPES_H 1
|
||||
|
||||
/* Define if you have BSD-like bzero and bcopy in <strings.h> rather than
|
||||
memset/memcpy in <string.h>. */
|
||||
#cmakedefine NEED_BSD_STRINGS
|
||||
#cmakedefine NEED_BSD_STRINGS 1
|
||||
|
||||
/* Define to 1 if the system has the type `unsigned char'. */
|
||||
#cmakedefine HAVE_UNSIGNED_CHAR
|
||||
#cmakedefine HAVE_UNSIGNED_CHAR 1
|
||||
|
||||
/* Define to 1 if the system has the type `unsigned short'. */
|
||||
#cmakedefine HAVE_UNSIGNED_SHORT
|
||||
#cmakedefine HAVE_UNSIGNED_SHORT 1
|
||||
|
||||
/* Compiler does not support pointers to undefined structures. */
|
||||
#cmakedefine INCOMPLETE_TYPES_BROKEN
|
||||
#cmakedefine INCOMPLETE_TYPES_BROKEN 1
|
||||
|
||||
/* Define if your (broken) compiler shifts signed values as if they were
|
||||
unsigned. */
|
||||
#cmakedefine RIGHT_SHIFT_IS_UNSIGNED
|
||||
#cmakedefine RIGHT_SHIFT_IS_UNSIGNED 1
|
||||
|
||||
/* Define to 1 if type `char' is unsigned and you are not using gcc. */
|
||||
#ifndef __CHAR_UNSIGNED__
|
||||
#cmakedefine __CHAR_UNSIGNED__
|
||||
#cmakedefine __CHAR_UNSIGNED__ 1
|
||||
#endif
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
|
||||
@@ -128,7 +128,7 @@ typedef unsigned char boolean;
|
||||
*/
|
||||
#undef TWO_FILE_COMMANDLINE
|
||||
|
||||
/* By default, we open image files with fopen(...,"rb") or fopen(...,"wb").
|
||||
/* By default, we open image files with fopen(..., "rb") or fopen(..., "wb").
|
||||
* This is necessary on systems that distinguish text files from binary files,
|
||||
* and is harmless on most systems that don't. If you have one of the rare
|
||||
* systems that complains about the "b" spec, define this symbol.
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Copyright (C) 1991-1998, Thomas G. Lane.
|
||||
* Modified 2003-2008 by Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2009-2011, D. R. Commander.
|
||||
* Copyright (C) 2009-2011, 2018, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -65,7 +65,8 @@ jpeg_add_quant_table(j_compress_ptr cinfo, int which_tbl,
|
||||
}
|
||||
|
||||
|
||||
/* These are the sample quantization tables given in JPEG spec section K.1.
|
||||
/* These are the sample quantization tables given in Annex K (Clause K.1) of
|
||||
* Recommendation ITU-T T.81 (1992) | ISO/IEC 10918-1:1994.
|
||||
* The spec says that the values given produce "good" quality, and
|
||||
* when divided by 2, "very good" quality.
|
||||
*/
|
||||
|
||||
12
jcsample.c
12
jcsample.c
@@ -280,7 +280,7 @@ h2v2_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
||||
(JSAMPLE)((GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
|
||||
GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]) + bias) >> 2);
|
||||
bias ^= 3; /* 1=>2, 2=>1 */
|
||||
inptr0 += 2; inptr1 += 2;
|
||||
inptr0 += 2; inptr1 += 2;
|
||||
}
|
||||
inrow += 2;
|
||||
}
|
||||
@@ -348,7 +348,7 @@ h2v2_smooth_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
||||
GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[2]);
|
||||
membersum = membersum * memberscale + neighsum * neighscale;
|
||||
*outptr++ = (JSAMPLE)((membersum + 32768) >> 16);
|
||||
inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2;
|
||||
inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2;
|
||||
|
||||
for (colctr = output_cols - 2; colctr > 0; colctr--) {
|
||||
/* sum of pixels directly mapped to this output element */
|
||||
@@ -368,7 +368,7 @@ h2v2_smooth_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
||||
membersum = membersum * memberscale + neighsum * neighscale;
|
||||
/* round, descale and output it */
|
||||
*outptr++ = (JSAMPLE)((membersum + 32768) >> 16);
|
||||
inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2;
|
||||
inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2;
|
||||
}
|
||||
|
||||
/* Special case for last column */
|
||||
@@ -437,17 +437,17 @@ fullsize_smooth_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
||||
neighsum = colsum + (colsum - membersum) + nextcolsum;
|
||||
membersum = membersum * memberscale + neighsum * neighscale;
|
||||
*outptr++ = (JSAMPLE)((membersum + 32768) >> 16);
|
||||
lastcolsum = colsum; colsum = nextcolsum;
|
||||
lastcolsum = colsum; colsum = nextcolsum;
|
||||
|
||||
for (colctr = output_cols - 2; colctr > 0; colctr--) {
|
||||
membersum = GETJSAMPLE(*inptr++);
|
||||
above_ptr++; below_ptr++;
|
||||
above_ptr++; below_ptr++;
|
||||
nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) +
|
||||
GETJSAMPLE(*inptr);
|
||||
neighsum = lastcolsum + (colsum - membersum) + nextcolsum;
|
||||
membersum = membersum * memberscale + neighsum * neighscale;
|
||||
*outptr++ = (JSAMPLE)((membersum + 32768) >> 16);
|
||||
lastcolsum = colsum; colsum = nextcolsum;
|
||||
lastcolsum = colsum; colsum = nextcolsum;
|
||||
}
|
||||
|
||||
/* Special case for last column */
|
||||
|
||||
17
jdapistd.c
17
jdapistd.c
@@ -4,7 +4,7 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2010, 2015-2017, D. R. Commander.
|
||||
* Copyright (C) 2010, 2015-2018, D. R. Commander.
|
||||
* Copyright (C) 2015, Google, Inc.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
@@ -318,12 +318,15 @@ read_and_discard_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
|
||||
JDIMENSION n;
|
||||
void (*color_convert) (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf,
|
||||
int num_rows);
|
||||
int num_rows) = NULL;
|
||||
void (*color_quantize) (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPARRAY output_buf, int num_rows) = NULL;
|
||||
|
||||
color_convert = cinfo->cconvert->color_convert;
|
||||
cinfo->cconvert->color_convert = noop_convert;
|
||||
if (cinfo->cconvert && cinfo->cconvert->color_convert) {
|
||||
color_convert = cinfo->cconvert->color_convert;
|
||||
cinfo->cconvert->color_convert = noop_convert;
|
||||
}
|
||||
|
||||
if (cinfo->cquantize && cinfo->cquantize->color_quantize) {
|
||||
color_quantize = cinfo->cquantize->color_quantize;
|
||||
cinfo->cquantize->color_quantize = noop_quantize;
|
||||
@@ -332,7 +335,9 @@ read_and_discard_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
|
||||
for (n = 0; n < num_lines; n++)
|
||||
jpeg_read_scanlines(cinfo, NULL, 1);
|
||||
|
||||
cinfo->cconvert->color_convert = color_convert;
|
||||
if (color_convert)
|
||||
cinfo->cconvert->color_convert = color_convert;
|
||||
|
||||
if (color_quantize)
|
||||
cinfo->cquantize->color_quantize = color_quantize;
|
||||
}
|
||||
@@ -479,7 +484,7 @@ jpeg_skip_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
|
||||
if (cinfo->upsample->need_context_rows) {
|
||||
cinfo->output_scanline += lines_to_skip;
|
||||
cinfo->output_iMCU_row += lines_to_skip / lines_per_iMCU_row;
|
||||
main_ptr->iMCU_row_ctr += lines_after_iMCU_row / lines_per_iMCU_row;
|
||||
main_ptr->iMCU_row_ctr += lines_to_skip / lines_per_iMCU_row;
|
||||
/* It is complex to properly move to the middle of a context block, so
|
||||
* read the remaining lines instead of skipping them.
|
||||
*/
|
||||
|
||||
@@ -4,16 +4,19 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Developed 1997-2015 by Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2015-2017, D. R. Commander.
|
||||
* Copyright (C) 2015-2018, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
* This file contains portable arithmetic entropy decoding routines for JPEG
|
||||
* (implementing the ISO/IEC IS 10918-1 and CCITT Recommendation ITU-T T.81).
|
||||
* This file contains portable arithmetic entropy encoding routines for JPEG
|
||||
* (implementing Recommendation ITU-T T.81 | ISO/IEC 10918-1).
|
||||
*
|
||||
* Both sequential and progressive modes are supported in this single module.
|
||||
*
|
||||
* Suspension is not currently supported in this module.
|
||||
*
|
||||
* NOTE: All referenced figures are from
|
||||
* Recommendation ITU-T T.81 (1992) | ISO/IEC 10918-1:1994.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* Modified 2009-2012 by Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2011, 2014, 2016, D. R. Commander.
|
||||
* Copyright (C) 2011, 2014, 2016, 2019, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -27,6 +27,8 @@
|
||||
extern void *malloc(size_t size);
|
||||
extern void free(void *ptr);
|
||||
#endif
|
||||
void jpeg_mem_dest_tj(j_compress_ptr cinfo, unsigned char **outbuffer,
|
||||
unsigned long *outsize, boolean alloc);
|
||||
|
||||
|
||||
#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* Modified 2009-2011 by Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2011, 2016, D. R. Commander.
|
||||
* Copyright (C) 2011, 2016, 2019, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -23,6 +23,9 @@
|
||||
#include "jpeglib.h"
|
||||
#include "jerror.h"
|
||||
|
||||
void jpeg_mem_src_tj(j_decompress_ptr cinfo, const unsigned char *inbuffer,
|
||||
unsigned long insize);
|
||||
|
||||
|
||||
/*
|
||||
* Initialize source --- called by jpeg_read_header
|
||||
|
||||
@@ -592,7 +592,7 @@ ycck_cmyk_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
/* Declarations for ordered dithering
|
||||
*
|
||||
* We use a 4x4 ordered dither array packed into 32 bits. This array is
|
||||
* sufficent for dithering RGB888 to RGB565.
|
||||
* sufficient for dithering RGB888 to RGB565.
|
||||
*/
|
||||
|
||||
#define DITHER_MASK 0x3
|
||||
|
||||
15
jdhuff.c
15
jdhuff.c
@@ -4,7 +4,7 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2009-2011, 2016, D. R. Commander.
|
||||
* Copyright (C) 2009-2011, 2016, 2018-2019, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -15,6 +15,9 @@
|
||||
* up to the start of the current MCU. To do this, we copy state variables
|
||||
* into local working storage, and update them back to the permanent
|
||||
* storage only upon successful completion of an MCU.
|
||||
*
|
||||
* NOTE: All referenced figures are from
|
||||
* Recommendation ITU-T T.81 (1992) | ISO/IEC 10918-1:1994.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
@@ -459,7 +462,7 @@ jpeg_huff_decode(bitread_working_state *state,
|
||||
code = GET_BITS(l);
|
||||
|
||||
/* Collect the rest of the Huffman code one bit at a time. */
|
||||
/* This is per Figure F.16 in the JPEG spec. */
|
||||
/* This is per Figure F.16. */
|
||||
|
||||
while (code > htbl->maxcode[l]) {
|
||||
code <<= 1;
|
||||
@@ -586,7 +589,11 @@ decode_mcu_slow(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
if (entropy->dc_needed[blkn]) {
|
||||
/* Convert DC difference to actual value, update last_dc_val */
|
||||
int ci = cinfo->MCU_membership[blkn];
|
||||
s += state.last_dc_val[ci];
|
||||
/* This is really just
|
||||
* s += state.last_dc_val[ci];
|
||||
* It is written this way in order to shut up UBSan.
|
||||
*/
|
||||
s = (int)((unsigned int)s + (unsigned int)state.last_dc_val[ci]);
|
||||
state.last_dc_val[ci] = s;
|
||||
if (block) {
|
||||
/* Output the DC coefficient (assumes jpeg_natural_order[0] = 0) */
|
||||
@@ -681,7 +688,7 @@ decode_mcu_fast(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
|
||||
if (entropy->dc_needed[blkn]) {
|
||||
int ci = cinfo->MCU_membership[blkn];
|
||||
s += state.last_dc_val[ci];
|
||||
s = (int)((unsigned int)s + (unsigned int)state.last_dc_val[ci]);
|
||||
state.last_dc_val[ci] = s;
|
||||
if (block)
|
||||
(*block)[0] = (JCOEF)s;
|
||||
|
||||
8
jdhuff.h
8
jdhuff.h
@@ -152,7 +152,7 @@ typedef struct { /* Bitreading working state within an MCU */
|
||||
if (bits_left < (nbits)) { \
|
||||
if (!jpeg_fill_bit_buffer(&(state), get_buffer, bits_left, nbits)) \
|
||||
{ action; } \
|
||||
get_buffer = (state).get_buffer; bits_left = (state).bits_left; \
|
||||
get_buffer = (state).get_buffer; bits_left = (state).bits_left; \
|
||||
} \
|
||||
}
|
||||
|
||||
@@ -193,9 +193,9 @@ EXTERN(boolean) jpeg_fill_bit_buffer(bitread_working_state *state,
|
||||
if (bits_left < HUFF_LOOKAHEAD) { \
|
||||
if (!jpeg_fill_bit_buffer(&state, get_buffer, bits_left, 0)) \
|
||||
{ failaction; } \
|
||||
get_buffer = state.get_buffer; bits_left = state.bits_left; \
|
||||
get_buffer = state.get_buffer; bits_left = state.bits_left; \
|
||||
if (bits_left < HUFF_LOOKAHEAD) { \
|
||||
nb = 1; goto slowlabel; \
|
||||
nb = 1; goto slowlabel; \
|
||||
} \
|
||||
} \
|
||||
look = PEEK_BITS(HUFF_LOOKAHEAD); \
|
||||
@@ -207,7 +207,7 @@ slowlabel: \
|
||||
if ((result = \
|
||||
jpeg_huff_decode(&state, get_buffer, bits_left, htbl, nb)) < 0) \
|
||||
{ failaction; } \
|
||||
get_buffer = state.get_buffer; bits_left = state.bits_left; \
|
||||
get_buffer = state.get_buffer; bits_left = state.bits_left; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
10
jdinput.c
10
jdinput.c
@@ -4,7 +4,7 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2010, 2016, D. R. Commander.
|
||||
* Copyright (C) 2010, 2016, 2018, D. R. Commander.
|
||||
* Copyright (C) 2015, Google, Inc.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
@@ -234,10 +234,10 @@ per_scan_setup(j_decompress_ptr cinfo)
|
||||
* means that we have to save away the table actually used for each component.
|
||||
* We do this by copying the table at the start of the first scan containing
|
||||
* the component.
|
||||
* The JPEG spec prohibits the encoder from changing the contents of a Q-table
|
||||
* slot between scans of a component using that slot. If the encoder does so
|
||||
* anyway, this decoder will simply use the Q-table values that were current
|
||||
* at the start of the first scan for the component.
|
||||
* Rec. ITU-T T.81 | ISO/IEC 10918-1 prohibits the encoder from changing the
|
||||
* contents of a Q-table slot between scans of a component using that slot. If
|
||||
* the encoder does so anyway, this decoder will simply use the Q-table values
|
||||
* that were current at the start of the first scan for the component.
|
||||
*
|
||||
* The decompressor output side looks only at the saved quant tables,
|
||||
* not at the current Q-table slots.
|
||||
|
||||
@@ -429,8 +429,6 @@ h2v2_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
#define PACK_TWO_PIXELS_LE(l, r) ((r << 16) | l)
|
||||
#define PACK_TWO_PIXELS_BE(l, r) ((l << 16) | r)
|
||||
|
||||
#define PACK_NEED_ALIGNMENT(ptr) (((size_t)(ptr)) & 3)
|
||||
|
||||
#define WRITE_TWO_PIXELS_LE(addr, pixels) { \
|
||||
((INT16 *)(addr))[0] = (INT16)(pixels); \
|
||||
((INT16 *)(addr))[1] = (INT16)((pixels) >> 16); \
|
||||
@@ -448,7 +446,7 @@ h2v2_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
/* Declarations for ordered dithering
|
||||
*
|
||||
* We use a 4x4 ordered dither array packed into 32 bits. This array is
|
||||
* sufficent for dithering RGB888 to RGB565.
|
||||
* sufficient for dithering RGB888 to RGB565.
|
||||
*/
|
||||
|
||||
#define DITHER_MASK 0x3
|
||||
|
||||
10
jdphuff.c
10
jdphuff.c
@@ -4,7 +4,7 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1995-1997, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2015-2016, D. R. Commander.
|
||||
* Copyright (C) 2015-2016, 2018, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -15,12 +15,16 @@
|
||||
* up to the start of the current MCU. To do this, we copy state variables
|
||||
* into local working storage, and update them back to the permanent
|
||||
* storage only upon successful completion of an MCU.
|
||||
*
|
||||
* NOTE: All referenced figures are from
|
||||
* Recommendation ITU-T T.81 (1992) | ISO/IEC 10918-1:1994.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jdhuff.h" /* Declarations shared with jdhuff.c */
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
#ifdef D_PROGRESSIVE_SUPPORTED
|
||||
@@ -340,6 +344,10 @@ decode_mcu_DC_first(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
}
|
||||
|
||||
/* Convert DC difference to actual value, update last_dc_val */
|
||||
if ((state.last_dc_val[ci] >= 0 &&
|
||||
s > INT_MAX - state.last_dc_val[ci]) ||
|
||||
(state.last_dc_val[ci] < 0 && s < INT_MIN - state.last_dc_val[ci]))
|
||||
ERREXIT(cinfo, JERR_BAD_DCT_COEF);
|
||||
s += state.last_dc_val[ci];
|
||||
state.last_dc_val[ci] = s;
|
||||
/* Scale and output the coefficient (assumes jpeg_natural_order[0]=0) */
|
||||
|
||||
14
jdsample.c
14
jdsample.c
@@ -8,6 +8,7 @@
|
||||
* Copyright (C) 2010, 2015-2016, D. R. Commander.
|
||||
* Copyright (C) 2014, MIPS Technologies, Inc., California.
|
||||
* Copyright (C) 2015, Google, Inc.
|
||||
* Copyright (C) 2019, Arm Limited.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -315,9 +316,9 @@ h1v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY output_data = *output_data_ptr;
|
||||
JSAMPROW inptr0, inptr1, outptr;
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
int thiscolsum;
|
||||
int thiscolsum, bias;
|
||||
#else
|
||||
JLONG thiscolsum;
|
||||
JLONG thiscolsum, bias;
|
||||
#endif
|
||||
JDIMENSION colctr;
|
||||
int inrow, outrow, v;
|
||||
@@ -327,15 +328,18 @@ h1v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
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 */
|
||||
if (v == 0) { /* next nearest is row above */
|
||||
inptr1 = input_data[inrow - 1];
|
||||
else /* next nearest is row below */
|
||||
bias = 1;
|
||||
} else { /* next nearest is row below */
|
||||
inptr1 = input_data[inrow + 1];
|
||||
bias = 2;
|
||||
}
|
||||
outptr = output_data[outrow++];
|
||||
|
||||
for (colctr = 0; colctr < compptr->downsampled_width; colctr++) {
|
||||
thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
|
||||
*outptr++ = (JSAMPLE)((thiscolsum + 1) >> 2);
|
||||
*outptr++ = (JSAMPLE)((thiscolsum + bias) >> 2);
|
||||
}
|
||||
}
|
||||
inrow++;
|
||||
|
||||
10
jerror.h
10
jerror.h
@@ -288,24 +288,24 @@ JMESSAGE(JWRN_BOGUS_ICC, "Corrupt JPEG data: bad ICC marker")
|
||||
(*(cinfo)->err->emit_message) ((j_common_ptr)(cinfo), (lvl)))
|
||||
#define TRACEMS3(cinfo, lvl, code, p1, p2, p3) \
|
||||
MAKESTMT(int *_mp = (cinfo)->err->msg_parm.i; \
|
||||
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \
|
||||
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \
|
||||
(cinfo)->err->msg_code = (code); \
|
||||
(*(cinfo)->err->emit_message) ((j_common_ptr)(cinfo), (lvl)); )
|
||||
#define TRACEMS4(cinfo, lvl, code, p1, p2, p3, p4) \
|
||||
MAKESTMT(int *_mp = (cinfo)->err->msg_parm.i; \
|
||||
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
|
||||
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
|
||||
(cinfo)->err->msg_code = (code); \
|
||||
(*(cinfo)->err->emit_message) ((j_common_ptr)(cinfo), (lvl)); )
|
||||
#define TRACEMS5(cinfo, lvl, code, p1, p2, p3, p4, p5) \
|
||||
MAKESTMT(int *_mp = (cinfo)->err->msg_parm.i; \
|
||||
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
|
||||
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
|
||||
_mp[4] = (p5); \
|
||||
(cinfo)->err->msg_code = (code); \
|
||||
(*(cinfo)->err->emit_message) ((j_common_ptr)(cinfo), (lvl)); )
|
||||
#define TRACEMS8(cinfo, lvl, code, p1, p2, p3, p4, p5, p6, p7, p8) \
|
||||
MAKESTMT(int *_mp = (cinfo)->err->msg_parm.i; \
|
||||
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
|
||||
_mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \
|
||||
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
|
||||
_mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \
|
||||
(cinfo)->err->msg_code = (code); \
|
||||
(*(cinfo)->err->emit_message) ((j_common_ptr)(cinfo), (lvl)); )
|
||||
#define TRACEMSS(cinfo, lvl, code, str) \
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1992-1996, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2017, D. R. Commander.
|
||||
* Copyright (C) 2017-2018, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -72,7 +72,7 @@ jpeg_mem_available(j_common_ptr cinfo, size_t min_bytes_needed,
|
||||
size_t max_bytes_needed, size_t already_allocated)
|
||||
{
|
||||
if (cinfo->mem->max_memory_to_use) {
|
||||
if (cinfo->mem->max_memory_to_use > already_allocated)
|
||||
if ((size_t)cinfo->mem->max_memory_to_use > already_allocated)
|
||||
return cinfo->mem->max_memory_to_use - already_allocated;
|
||||
else
|
||||
return 0;
|
||||
|
||||
16
jmorecfg.h
16
jmorecfg.h
@@ -5,7 +5,7 @@
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Modified 1997-2009 by Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2009, 2011, 2014-2015, D. R. Commander.
|
||||
* Copyright (C) 2009, 2011, 2014-2015, 2018, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -17,9 +17,9 @@
|
||||
|
||||
/*
|
||||
* Maximum number of components (color channels) allowed in JPEG image.
|
||||
* To meet the letter of the JPEG spec, set this to 255. However, darn
|
||||
* few applications need more than 4 channels (maybe 5 for CMYK + alpha
|
||||
* mask). We recommend 10 as a reasonable compromise; use 4 if you are
|
||||
* To meet the letter of Rec. ITU-T T.81 | ISO/IEC 10918-1, set this to 255.
|
||||
* However, darn few applications need more than 4 channels (maybe 5 for CMYK +
|
||||
* alpha mask). We recommend 10 as a reasonable compromise; use 4 if you are
|
||||
* really short on memory. (Each allowed component costs a hundred or so
|
||||
* bytes of storage, whether actually used in an image or not.)
|
||||
*/
|
||||
@@ -315,10 +315,10 @@ typedef int boolean;
|
||||
* with it. In reality, few people ever did this, because there were some
|
||||
* severe restrictions involved (cjpeg and djpeg no longer worked properly,
|
||||
* compressing/decompressing RGB JPEGs no longer worked properly, and the color
|
||||
* quantizer wouldn't work with pixel sizes other than 3.) Further, since all
|
||||
* of the O/S-supplied versions of libjpeg were built with the default values
|
||||
* of RGB_RED, RGB_GREEN, RGB_BLUE, and RGB_PIXELSIZE, many applications have
|
||||
* come to regard these values as immutable.
|
||||
* quantizer wouldn't work with pixel sizes other than 3.) Furthermore, since
|
||||
* all of the O/S-supplied versions of libjpeg were built with the default
|
||||
* values of RGB_RED, RGB_GREEN, RGB_BLUE, and RGB_PIXELSIZE, many applications
|
||||
* have come to regard these values as immutable.
|
||||
*
|
||||
* The libjpeg-turbo colorspace extensions provide a much cleaner way of
|
||||
* compressing from/decompressing to buffers with arbitrary component orders
|
||||
|
||||
@@ -154,7 +154,7 @@ typedef struct {
|
||||
*/
|
||||
boolean is_padded; /* is the colorindex padded for odither? */
|
||||
|
||||
int Ncolors[MAX_Q_COMPS]; /* # of values alloced to each component */
|
||||
int Ncolors[MAX_Q_COMPS]; /* # of values allocated to each component */
|
||||
|
||||
/* Variables for ordered dithering */
|
||||
int row_index; /* cur row's vertical index in dither matrix */
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-2012, Thomas G. Lane, Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2010, 2012-2017, D. R. Commander.
|
||||
* Copyright (C) 2010, 2012-2019, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -36,9 +36,9 @@
|
||||
*/
|
||||
|
||||
#define JCOPYRIGHT \
|
||||
"Copyright (C) 2009-2017 D. R. Commander\n" \
|
||||
"Copyright (C) 2009-2019 D. R. Commander\n" \
|
||||
"Copyright (C) 2011-2016 Siarhei Siamashka\n" \
|
||||
"Copyright (C) 2015-2016 Matthieu Darbois\n" \
|
||||
"Copyright (C) 2015-2016, 2018 Matthieu Darbois\n" \
|
||||
"Copyright (C) 2015 Intel Corporation\n" \
|
||||
"Copyright (C) 2015 Google, Inc.\n" \
|
||||
"Copyright (C) 2013-2014 MIPS Technologies, Inc.\n" \
|
||||
@@ -49,4 +49,4 @@
|
||||
"Copyright (C) 1991-2016 Thomas G. Lane, Guido Vollbeding"
|
||||
|
||||
#define JCOPYRIGHT_SHORT \
|
||||
"Copyright (C) 1991-2017 The libjpeg-turbo Project and many others"
|
||||
"Copyright (C) 1991-2019 The libjpeg-turbo Project and many others"
|
||||
|
||||
19
libjpeg.txt
19
libjpeg.txt
@@ -3,7 +3,7 @@ USING THE IJG JPEG LIBRARY
|
||||
This file was part of the Independent JPEG Group's software:
|
||||
Copyright (C) 1994-2013, Thomas G. Lane, Guido Vollbeding.
|
||||
libjpeg-turbo Modifications:
|
||||
Copyright (C) 2010, 2014-2017, D. R. Commander.
|
||||
Copyright (C) 2010, 2014-2018, D. R. Commander.
|
||||
Copyright (C) 2015, Google, Inc.
|
||||
For conditions of distribution and use, see the accompanying README.ijg file.
|
||||
|
||||
@@ -388,13 +388,13 @@ to the total image height. In most applications it is convenient to pass
|
||||
just one or a few scanlines at a time. The expected format for the passed
|
||||
data is discussed under "Data formats", above.
|
||||
|
||||
Image data should be written in top-to-bottom scanline order. The JPEG spec
|
||||
contains some weasel wording about how top and bottom are application-defined
|
||||
terms (a curious interpretation of the English language...) but if you want
|
||||
your files to be compatible with everyone else's, you WILL use top-to-bottom
|
||||
order. If the source data must be read in bottom-to-top order, you can use
|
||||
the JPEG library's virtual array mechanism to invert the data efficiently.
|
||||
Examples of this can be found in the sample application cjpeg.
|
||||
Image data should be written in top-to-bottom scanline order.
|
||||
Rec. ITU-T T.81 | ISO/IEC 10918-1 says, "Applications determine which edges of
|
||||
a source image are defined as top, bottom, left, and right." However, if you
|
||||
want your files to be compatible with everyone else's, then top-to-bottom order
|
||||
must be used. If the source data must be read in bottom-to-top order, then you
|
||||
can use the JPEG library's virtual array mechanism to invert the data
|
||||
efficiently. Examples of this can be found in the sample application cjpeg.
|
||||
|
||||
The library maintains a count of the number of scanlines written so far
|
||||
in the next_scanline field of the JPEG object. Usually you can just use
|
||||
@@ -917,7 +917,8 @@ jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline)
|
||||
jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
|
||||
boolean force_baseline)
|
||||
Same as jpeg_set_quality() except that the generated tables are the
|
||||
sample tables given in the JPEC spec section K.1, multiplied by the
|
||||
sample tables given in Annex K (Clause K.1) of
|
||||
Rec. ITU-T T.81 (1992) | ISO/IEC 10918-1:1994, multiplied by the
|
||||
specified scale factor (which is expressed as a percentage; thus
|
||||
scale_factor = 100 reproduces the spec's tables). Note that larger
|
||||
scale factors give lower quality. This entry point is useful for
|
||||
|
||||
489
md5/md5.c
489
md5/md5.c
@@ -1,322 +1,275 @@
|
||||
/*
|
||||
* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
|
||||
* This code implements the MD5 message-digest algorithm.
|
||||
* The algorithm is due to Ron Rivest. This code was
|
||||
* written by Colin Plumb in 1993, no copyright is claimed.
|
||||
* This code is in the public domain; do with it what you wish.
|
||||
*
|
||||
* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991.
|
||||
* All rights reserved.
|
||||
* Equivalent code is available from RSA Data Security, Inc.
|
||||
* This code has been tested against that, and is equivalent,
|
||||
* except that you don't need to include two pages of legalese
|
||||
* with every copy.
|
||||
*
|
||||
* License to copy and use this software is granted provided that it
|
||||
* is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||
* Algorithm" in all material mentioning or referencing this software
|
||||
* or this function.
|
||||
* To compute the message digest of a chunk of bytes, declare an
|
||||
* MD5Context structure, pass it to MD5Init, call MD5Update as
|
||||
* needed on buffers full of bytes, and then call MD5Final, which
|
||||
* will fill a supplied 16-byte array with the digest.
|
||||
* ----------------------------------------------------------------------------
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C)2018, D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* License is also granted to make and use derivative works provided
|
||||
* that such works are identified as "derived from the RSA Data
|
||||
* Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||
* mentioning or referencing the derived work.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* RSA Data Security, Inc. makes no representations concerning either
|
||||
* the merchantability of this software or the suitability of this
|
||||
* software for any particular purpose. It is provided "as is"
|
||||
* without express or implied warranty of any kind.
|
||||
* - 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.
|
||||
*
|
||||
* These notices must be retained in any copies of any part of this
|
||||
* documentation and/or software.
|
||||
*
|
||||
* This code is the same as the code published by RSA Inc. It has been
|
||||
* edited for clarity and style only.
|
||||
* 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.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]);
|
||||
#include <string.h> /* for memcpy() */
|
||||
#include "md5.h"
|
||||
|
||||
#if (BYTE_ORDER == LITTLE_ENDIAN)
|
||||
#define Encode memcpy
|
||||
#define Decode memcpy
|
||||
#define byteReverse(buf, len) /* Nothing */
|
||||
#else
|
||||
|
||||
/*
|
||||
* OS X doesn't have le32toh() or htole32()
|
||||
* Note: this code is harmless on little-endian machines.
|
||||
*/
|
||||
#ifdef __APPLE__
|
||||
#include <libkern/OSByteOrder.h>
|
||||
#define le32toh(x) OSSwapLittleToHostInt32(x)
|
||||
#define htole32(x) OSSwapHostToLittleInt32(x)
|
||||
static void byteReverse(unsigned char *buf, unsigned int longs)
|
||||
{
|
||||
uint32 t;
|
||||
do {
|
||||
t = (uint32)((unsigned int)buf[3] << 8 | buf[2]) << 16 |
|
||||
((unsigned int)buf[1] << 8 | buf[0]);
|
||||
*(uint32 *)buf = t;
|
||||
buf += 4;
|
||||
} while (--longs);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Encodes input (unsigned int) into output (unsigned char). Assumes len is
|
||||
* a multiple of 4.
|
||||
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
|
||||
* initialization constants.
|
||||
*/
|
||||
|
||||
static void Encode(unsigned char *output, unsigned int *input,
|
||||
unsigned int len)
|
||||
void MD5Init(struct MD5Context *ctx)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int *op = (unsigned int *)output;
|
||||
ctx->buf[0] = 0x67452301;
|
||||
ctx->buf[1] = 0xefcdab89;
|
||||
ctx->buf[2] = 0x98badcfe;
|
||||
ctx->buf[3] = 0x10325476;
|
||||
|
||||
for (i = 0; i < len / 4; i++)
|
||||
op[i] = htole32(input[i]);
|
||||
ctx->bits[0] = 0;
|
||||
ctx->bits[1] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decodes input (unsigned char) into output (unsigned int). Assumes len is
|
||||
* a multiple of 4.
|
||||
* Update context to reflect the concatenation of another buffer full
|
||||
* of bytes.
|
||||
*/
|
||||
|
||||
static void Decode(unsigned int *output, const unsigned char *input,
|
||||
unsigned int len)
|
||||
void MD5Update(struct MD5Context *ctx, unsigned char *buf, unsigned int len)
|
||||
{
|
||||
unsigned int i;
|
||||
const unsigned int *ip = (const unsigned int *)input;
|
||||
uint32 t;
|
||||
|
||||
for (i = 0; i < len / 4; i++)
|
||||
output[i] = le32toh(ip[i]);
|
||||
}
|
||||
#endif
|
||||
/* Update bitcount */
|
||||
|
||||
static unsigned char PADDING[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
t = ctx->bits[0];
|
||||
if ((ctx->bits[0] = t + ((uint32)len << 3)) < t)
|
||||
ctx->bits[1]++; /* Carry from low to high */
|
||||
ctx->bits[1] += len >> 29;
|
||||
|
||||
/* F, G, H and I are basic MD5 functions. */
|
||||
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
||||
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define I(x, y, z) ((y) ^ ((x) | (~z)))
|
||||
t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
|
||||
|
||||
/* ROTATE_LEFT rotates x left n bits. */
|
||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
|
||||
/* Handle any leading odd-sized chunks */
|
||||
|
||||
/*
|
||||
* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
|
||||
* Rotation is separate from addition to prevent recomputation.
|
||||
*/
|
||||
#define FF(a, b, c, d, x, s, ac) { \
|
||||
(a) += F((b), (c), (d)) + (x) + (unsigned int)(ac); \
|
||||
(a) = ROTATE_LEFT((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define GG(a, b, c, d, x, s, ac) { \
|
||||
(a) += G((b), (c), (d)) + (x) + (unsigned int)(ac); \
|
||||
(a) = ROTATE_LEFT((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define HH(a, b, c, d, x, s, ac) { \
|
||||
(a) += H((b), (c), (d)) + (x) + (unsigned int)(ac); \
|
||||
(a) = ROTATE_LEFT((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define II(a, b, c, d, x, s, ac) { \
|
||||
(a) += I((b), (c), (d)) + (x) + (unsigned int)(ac); \
|
||||
(a) = ROTATE_LEFT((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
if (t) {
|
||||
unsigned char *p = (unsigned char *)ctx->in + t;
|
||||
|
||||
/* MD5 initialization. Begins an MD5 operation, writing a new context. */
|
||||
t = 64 - t;
|
||||
if (len < t) {
|
||||
memcpy(p, buf, len);
|
||||
return;
|
||||
}
|
||||
memcpy(p, buf, t);
|
||||
byteReverse(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, (uint32 *)ctx->in);
|
||||
buf += t;
|
||||
len -= t;
|
||||
}
|
||||
/* Process data in 64-byte chunks */
|
||||
|
||||
void MD5Init(MD5_CTX *context)
|
||||
{
|
||||
context->count[0] = context->count[1] = 0;
|
||||
while (len >= 64) {
|
||||
memcpy(ctx->in, buf, 64);
|
||||
byteReverse(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, (uint32 *)ctx->in);
|
||||
buf += 64;
|
||||
len -= 64;
|
||||
}
|
||||
|
||||
/* Load magic initialization constants. */
|
||||
context->state[0] = 0x67452301;
|
||||
context->state[1] = 0xefcdab89;
|
||||
context->state[2] = 0x98badcfe;
|
||||
context->state[3] = 0x10325476;
|
||||
/* Handle any remaining bytes of data. */
|
||||
|
||||
memcpy(ctx->in, buf, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* MD5 block update operation. Continues an MD5 message-digest
|
||||
* operation, processing another message block, and updating the
|
||||
* context.
|
||||
* Final wrapup - pad to 64-byte boundary with the bit pattern
|
||||
* 1 0* (64-bit count of bits processed, MSB-first)
|
||||
*/
|
||||
|
||||
void MD5Update(MD5_CTX *context, const void *in, unsigned int inputLen)
|
||||
void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
|
||||
{
|
||||
unsigned int i, idx, partLen;
|
||||
const unsigned char *input = in;
|
||||
unsigned int count;
|
||||
unsigned char *p;
|
||||
uint32 *in32 = (uint32 *)ctx->in;
|
||||
|
||||
/* Compute number of bytes mod 64 */
|
||||
idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
|
||||
count = (ctx->bits[0] >> 3) & 0x3F;
|
||||
|
||||
/* Update number of bits */
|
||||
if ((context->count[0] += ((unsigned int)inputLen << 3)) <
|
||||
((unsigned int)inputLen << 3))
|
||||
context->count[1]++;
|
||||
context->count[1] += ((unsigned int)inputLen >> 29);
|
||||
/* Set the first char of padding to 0x80. This is safe since there is
|
||||
always at least one byte free */
|
||||
p = ctx->in + count;
|
||||
*p++ = 0x80;
|
||||
|
||||
partLen = 64 - idx;
|
||||
/* Bytes of padding needed to make 64 bytes */
|
||||
count = 64 - 1 - count;
|
||||
|
||||
/* Transform as many times as possible. */
|
||||
if (inputLen >= partLen) {
|
||||
memcpy((void *)&context->buffer[idx], (const void *)input, partLen);
|
||||
MD5Transform(context->state, context->buffer);
|
||||
/* Pad out to 56 mod 64 */
|
||||
if (count < 8) {
|
||||
/* Two lots of padding: Pad the first block to 64 bytes */
|
||||
memset(p, 0, count);
|
||||
byteReverse(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, (uint32 *)ctx->in);
|
||||
|
||||
for (i = partLen; i + 63 < inputLen; i += 64)
|
||||
MD5Transform(context->state, &input[i]);
|
||||
/* Now fill the next block with 56 bytes */
|
||||
memset(ctx->in, 0, 56);
|
||||
} else {
|
||||
/* Pad block to 56 bytes */
|
||||
memset(p, 0, count - 8);
|
||||
}
|
||||
byteReverse(ctx->in, 14);
|
||||
|
||||
idx = 0;
|
||||
} else
|
||||
i = 0;
|
||||
/* Append length in bits and transform */
|
||||
in32[14] = ctx->bits[0];
|
||||
in32[15] = ctx->bits[1];
|
||||
|
||||
/* Buffer remaining input */
|
||||
memcpy((void *)&context->buffer[idx], (const void *)&input[i], inputLen - i);
|
||||
MD5Transform(ctx->buf, (uint32 *)ctx->in);
|
||||
byteReverse((unsigned char *)ctx->buf, 4);
|
||||
memcpy(digest, ctx->buf, 16);
|
||||
memset(ctx, 0, sizeof(struct MD5Context)); /* In case it's sensitive */
|
||||
}
|
||||
|
||||
|
||||
/* The four core functions - F1 is optimized somewhat */
|
||||
|
||||
/* #define F1(x, y, z) (x & y | ~x & z) */
|
||||
#define F1(x, y, z) (z ^ (x & (y ^ z)))
|
||||
#define F2(x, y, z) F1(z, x, y)
|
||||
#define F3(x, y, z) (x ^ y ^ z)
|
||||
#define F4(x, y, z) (y ^ (x | ~z))
|
||||
|
||||
/* This is the central step in the MD5 algorithm. */
|
||||
#define MD5STEP(f, w, x, y, z, data, s) \
|
||||
( w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x )
|
||||
|
||||
/*
|
||||
* MD5 padding. Adds padding followed by original length.
|
||||
* The core of the MD5 algorithm, this alters an existing MD5 hash to
|
||||
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
||||
* the data and converts bytes into longwords for this routine.
|
||||
*/
|
||||
|
||||
void MD5Pad(MD5_CTX *context)
|
||||
void MD5Transform(uint32 buf[4], uint32 in[16])
|
||||
{
|
||||
unsigned char bits[8];
|
||||
unsigned int idx, padLen;
|
||||
register uint32 a, b, c, d;
|
||||
|
||||
/* Save number of bits */
|
||||
Encode(bits, context->count, 8);
|
||||
a = buf[0];
|
||||
b = buf[1];
|
||||
c = buf[2];
|
||||
d = buf[3];
|
||||
|
||||
/* Pad out to 56 mod 64. */
|
||||
idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
|
||||
padLen = (idx < 56) ? (56 - idx) : (120 - idx);
|
||||
MD5Update(context, PADDING, padLen);
|
||||
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
|
||||
|
||||
/* Append length (before padding) */
|
||||
MD5Update(context, bits, 8);
|
||||
}
|
||||
|
||||
/*
|
||||
* MD5 finalization. Ends an MD5 message-digest operation, writing the
|
||||
* the message digest and zeroizing the context.
|
||||
*/
|
||||
|
||||
void MD5Final(unsigned char digest[16], MD5_CTX *context)
|
||||
{
|
||||
/* Do padding. */
|
||||
MD5Pad(context);
|
||||
|
||||
/* Store state in digest */
|
||||
Encode(digest, context->state, 16);
|
||||
|
||||
/* Zeroize sensitive information. */
|
||||
memset((void *)context, 0, sizeof(*context));
|
||||
}
|
||||
|
||||
/* MD5 basic transformation. Transforms state based on block. */
|
||||
|
||||
static void MD5Transform(unsigned int state[4], const unsigned char block[64])
|
||||
{
|
||||
unsigned int a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
||||
|
||||
Decode(x, block, 64);
|
||||
|
||||
/* Round 1 */
|
||||
#define S11 7
|
||||
#define S12 12
|
||||
#define S13 17
|
||||
#define S14 22
|
||||
FF(a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
|
||||
FF(d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
|
||||
FF(c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
|
||||
FF(b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
|
||||
FF(a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
|
||||
FF(d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
|
||||
FF(c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
|
||||
FF(b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
|
||||
FF(a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
|
||||
FF(d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
|
||||
FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
|
||||
FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
|
||||
FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
|
||||
FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
|
||||
FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
|
||||
FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
|
||||
|
||||
/* Round 2 */
|
||||
#define S21 5
|
||||
#define S22 9
|
||||
#define S23 14
|
||||
#define S24 20
|
||||
GG(a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
|
||||
GG(d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
|
||||
GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
|
||||
GG(b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
|
||||
GG(a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
|
||||
GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
|
||||
GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
|
||||
GG(b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
|
||||
GG(a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
|
||||
GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
|
||||
GG(c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
|
||||
GG(b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
|
||||
GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
|
||||
GG(d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
|
||||
GG(c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
|
||||
GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
|
||||
|
||||
/* Round 3 */
|
||||
#define S31 4
|
||||
#define S32 11
|
||||
#define S33 16
|
||||
#define S34 23
|
||||
HH(a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
|
||||
HH(d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
|
||||
HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
|
||||
HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
|
||||
HH(a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
|
||||
HH(d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
|
||||
HH(c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
|
||||
HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
|
||||
HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
|
||||
HH(d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
|
||||
HH(c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
|
||||
HH(b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
|
||||
HH(a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
|
||||
HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
|
||||
HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
|
||||
HH(b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
|
||||
|
||||
/* Round 4 */
|
||||
#define S41 6
|
||||
#define S42 10
|
||||
#define S43 15
|
||||
#define S44 21
|
||||
II(a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
|
||||
II(d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
|
||||
II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
|
||||
II(b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
|
||||
II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
|
||||
II(d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
|
||||
II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
|
||||
II(b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
|
||||
II(a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
|
||||
II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
|
||||
II(c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
|
||||
II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
|
||||
II(a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
|
||||
II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
|
||||
II(c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
|
||||
II(b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
|
||||
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
|
||||
/* Zeroize sensitive information. */
|
||||
memset((void *)x, 0, sizeof(x));
|
||||
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
|
||||
|
||||
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
|
||||
|
||||
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
|
||||
|
||||
buf[0] += a;
|
||||
buf[1] += b;
|
||||
buf[2] += c;
|
||||
buf[3] += d;
|
||||
}
|
||||
|
||||
90
md5/md5.h
90
md5/md5.h
@@ -1,51 +1,57 @@
|
||||
/* MD5.H - header file for MD5C.C
|
||||
* $FreeBSD$
|
||||
/*
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C)2018 D. R. Commander. 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.
|
||||
*/
|
||||
|
||||
/*-
|
||||
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991.
|
||||
All rights reserved.
|
||||
|
||||
License to copy and use this software is granted provided that it
|
||||
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||
Algorithm" in all material mentioning or referencing this software
|
||||
or this function.
|
||||
|
||||
License is also granted to make and use derivative works provided
|
||||
that such works are identified as "derived from the RSA Data
|
||||
Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||
mentioning or referencing the derived work.
|
||||
|
||||
RSA Data Security, Inc. makes no representations concerning either
|
||||
the merchantability of this software or the suitability of this
|
||||
software for any particular purpose. It is provided "as is"
|
||||
without express or implied warranty of any kind.
|
||||
|
||||
These notices must be retained in any copies of any part of this
|
||||
documentation and/or software.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_MD5_H_
|
||||
#define _SYS_MD5_H_
|
||||
#ifndef MD5_H
|
||||
#define MD5_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef __amigaos4__
|
||||
#include <machine/endian.h>
|
||||
#endif
|
||||
|
||||
#define MD5_BLOCK_LENGTH 64
|
||||
#define MD5_DIGEST_LENGTH 16
|
||||
#define MD5_DIGEST_STRING_LENGTH (MD5_DIGEST_LENGTH * 2 + 1)
|
||||
/* On machines where "long" is 64 bits, we need to declare
|
||||
uint32 as something guaranteed to be 32 bits. */
|
||||
|
||||
typedef unsigned int uint32;
|
||||
|
||||
/* MD5 context. */
|
||||
typedef struct MD5Context {
|
||||
unsigned int state[4]; /* state (ABCD) */
|
||||
unsigned int count[2]; /* number of bits, modulo 2^64 (lsb first) */
|
||||
unsigned char buffer[64]; /* input buffer */
|
||||
uint32 buf[4];
|
||||
uint32 bits[2];
|
||||
unsigned char in[64];
|
||||
} MD5_CTX;
|
||||
|
||||
void MD5Init(MD5_CTX *);
|
||||
void MD5Update(MD5_CTX *, const void *, unsigned int);
|
||||
void MD5Final(unsigned char [16], MD5_CTX *);
|
||||
char *MD5End(MD5_CTX *, char *);
|
||||
char *MD5File(const char *, char *);
|
||||
char *MD5FileChunk(const char *, char *, off_t, off_t);
|
||||
char *MD5Data(const void *, unsigned int, char *);
|
||||
#endif /* _SYS_MD5_H_ */
|
||||
extern void MD5Init(struct MD5Context *ctx);
|
||||
extern void MD5Update(struct MD5Context *ctx, unsigned char *buf,
|
||||
unsigned int len);
|
||||
extern void MD5Final(unsigned char digest[16], struct MD5Context *ctx);
|
||||
extern void MD5Transform(uint32 buf[4], uint32 in[16]);
|
||||
extern char *MD5File(const char *, char *);
|
||||
extern char *MD5FileChunk(const char *, char *, off_t, off_t);
|
||||
|
||||
#endif /* !MD5_H */
|
||||
|
||||
40
md5/md5hl.c
40
md5/md5hl.c
@@ -6,8 +6,31 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2016, D. R. Commander.
|
||||
* Modifications are under the same license as the original code (see above)
|
||||
* Copyright (C)2016, 2018-2019 D. R. Commander. 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@@ -33,7 +56,7 @@
|
||||
|
||||
#include "./md5.h"
|
||||
|
||||
char *MD5End(MD5_CTX *ctx, char *buf)
|
||||
static char *MD5End(MD5_CTX *ctx, char *buf)
|
||||
{
|
||||
int i;
|
||||
unsigned char digest[LENGTH];
|
||||
@@ -66,7 +89,7 @@ char *MD5FileChunk(const char *filename, char *buf, off_t ofs, off_t len)
|
||||
off_t n;
|
||||
|
||||
MD5Init(&ctx);
|
||||
#if _WIN32
|
||||
#ifdef _WIN32
|
||||
f = _open(filename, O_RDONLY | O_BINARY);
|
||||
#else
|
||||
f = open(filename, O_RDONLY);
|
||||
@@ -100,12 +123,3 @@ char *MD5FileChunk(const char *filename, char *buf, off_t ofs, off_t len)
|
||||
return 0;
|
||||
return (MD5End(&ctx, buf));
|
||||
}
|
||||
|
||||
char *MD5Data(const void *data, unsigned int len, char *buf)
|
||||
{
|
||||
MD5_CTX ctx;
|
||||
|
||||
MD5Init(&ctx);
|
||||
MD5Update(&ctx, data, len);
|
||||
return (MD5End(&ctx, buf));
|
||||
}
|
||||
|
||||
21
rdbmp.c
21
rdbmp.c
@@ -3,10 +3,10 @@
|
||||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* Modified 2009-2010 by Guido Vollbeding.
|
||||
* Modified 2009-2017 by Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Modified 2011 by Siarhei Siamashka.
|
||||
* Copyright (C) 2015, 2017, D. R. Commander.
|
||||
* Copyright (C) 2015, 2017-2018, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -72,6 +72,7 @@ typedef struct _bmp_source_struct {
|
||||
JDIMENSION row_width; /* Physical width of scanlines in file */
|
||||
|
||||
int bits_per_pixel; /* remembers 8- or 24-bit format */
|
||||
int cmap_length; /* colormap length */
|
||||
|
||||
boolean use_inversion_array; /* TRUE = preload the whole image, which is
|
||||
stored in bottom-up order, and feed it to
|
||||
@@ -155,6 +156,7 @@ get_8bit_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
|
||||
{
|
||||
bmp_source_ptr source = (bmp_source_ptr)sinfo;
|
||||
register JSAMPARRAY colormap = source->colormap;
|
||||
int cmaplen = source->cmap_length;
|
||||
JSAMPARRAY image_ptr;
|
||||
register int t;
|
||||
register JSAMPROW inptr, outptr;
|
||||
@@ -178,11 +180,15 @@ get_8bit_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
|
||||
if (cinfo->in_color_space == JCS_GRAYSCALE) {
|
||||
for (col = cinfo->image_width; col > 0; col--) {
|
||||
t = GETJSAMPLE(*inptr++);
|
||||
if (t >= cmaplen)
|
||||
ERREXIT(cinfo, JERR_BMP_OUTOFRANGE);
|
||||
*outptr++ = colormap[0][t];
|
||||
}
|
||||
} else if (cinfo->in_color_space == JCS_CMYK) {
|
||||
for (col = cinfo->image_width; col > 0; col--) {
|
||||
t = GETJSAMPLE(*inptr++);
|
||||
if (t >= cmaplen)
|
||||
ERREXIT(cinfo, JERR_BMP_OUTOFRANGE);
|
||||
rgb_to_cmyk(colormap[0][t], colormap[1][t], colormap[2][t], outptr,
|
||||
outptr + 1, outptr + 2, outptr + 3);
|
||||
outptr += 4;
|
||||
@@ -197,6 +203,8 @@ get_8bit_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
|
||||
if (aindex >= 0) {
|
||||
for (col = cinfo->image_width; col > 0; col--) {
|
||||
t = GETJSAMPLE(*inptr++);
|
||||
if (t >= cmaplen)
|
||||
ERREXIT(cinfo, JERR_BMP_OUTOFRANGE);
|
||||
outptr[rindex] = colormap[0][t];
|
||||
outptr[gindex] = colormap[1][t];
|
||||
outptr[bindex] = colormap[2][t];
|
||||
@@ -206,6 +214,8 @@ get_8bit_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
|
||||
} else {
|
||||
for (col = cinfo->image_width; col > 0; col--) {
|
||||
t = GETJSAMPLE(*inptr++);
|
||||
if (t >= cmaplen)
|
||||
ERREXIT(cinfo, JERR_BMP_OUTOFRANGE);
|
||||
outptr[rindex] = colormap[0][t];
|
||||
outptr[gindex] = colormap[1][t];
|
||||
outptr[bindex] = colormap[2][t];
|
||||
@@ -539,6 +549,7 @@ start_input_bmp(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
|
||||
/* Allocate space to store the colormap */
|
||||
source->colormap = (*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr)cinfo, JPOOL_IMAGE, (JDIMENSION)biClrUsed, (JDIMENSION)3);
|
||||
source->cmap_length = (int)biClrUsed;
|
||||
/* and read it from the file */
|
||||
read_colormap(source, (int)biClrUsed, mapentrysize);
|
||||
/* account for size of colormap */
|
||||
@@ -623,6 +634,12 @@ start_input_bmp(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure that biWidth * cinfo->input_components doesn't exceed the maximum
|
||||
value of the JDIMENSION type. This is only a danger with BMP files, since
|
||||
their width and height fields are 32-bit integers. */
|
||||
if ((unsigned long long)biWidth *
|
||||
(unsigned long long)cinfo->input_components > 0xFFFFFFFFULL)
|
||||
ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
|
||||
/* Allocate one-row buffer for returned data */
|
||||
source->pub.buffer = (*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
|
||||
@@ -118,7 +118,6 @@ read_2_bytes(void)
|
||||
#define M_SOI 0xD8 /* Start Of Image (beginning of datastream) */
|
||||
#define M_EOI 0xD9 /* End Of Image (end of datastream) */
|
||||
#define M_SOS 0xDA /* Start Of Scan (begins compressed data) */
|
||||
#define M_APP0 0xE0 /* Application-specific marker, type N */
|
||||
#define M_APP12 0xEC /* (we don't bother to list all 16 APPn's) */
|
||||
#define M_COM 0xFE /* COMment */
|
||||
|
||||
@@ -301,7 +300,8 @@ process_SOFn(int marker)
|
||||
case M_SOF10: process = "Progressive, arithmetic coding"; break;
|
||||
case M_SOF11: process = "Lossless, arithmetic coding"; break;
|
||||
case M_SOF13: process = "Differential sequential, arithmetic coding"; break;
|
||||
case M_SOF14: process = "Differential progressive, arithmetic coding"; break;
|
||||
case M_SOF14:
|
||||
process = "Differential progressive, arithmetic coding"; break;
|
||||
case M_SOF15: process = "Differential lossless, arithmetic coding"; break;
|
||||
default: process = "Unknown"; break;
|
||||
}
|
||||
|
||||
12
rdppm.c
12
rdppm.c
@@ -75,7 +75,7 @@ typedef struct {
|
||||
JSAMPROW pixrow; /* compressor input buffer */
|
||||
size_t buffer_width; /* width of I/O buffer */
|
||||
JSAMPLE *rescale; /* => maxval-remapping array, or NULL */
|
||||
int maxval;
|
||||
unsigned int maxval;
|
||||
} ppm_source_struct;
|
||||
|
||||
typedef ppm_source_struct *ppm_source_ptr;
|
||||
@@ -125,7 +125,7 @@ read_pbm_integer(j_compress_ptr cinfo, FILE *infile, unsigned int maxval)
|
||||
}
|
||||
|
||||
if (val > maxval)
|
||||
ERREXIT(cinfo, JERR_PPM_TOOLARGE);
|
||||
ERREXIT(cinfo, JERR_PPM_OUTOFRANGE);
|
||||
|
||||
return val;
|
||||
}
|
||||
@@ -509,7 +509,7 @@ get_word_gray_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
|
||||
temp = UCH(*bufferptr++) << 8;
|
||||
temp |= UCH(*bufferptr++);
|
||||
if (temp > maxval)
|
||||
ERREXIT(cinfo, JERR_PPM_TOOLARGE);
|
||||
ERREXIT(cinfo, JERR_PPM_OUTOFRANGE);
|
||||
*ptr++ = rescale[temp];
|
||||
}
|
||||
return 1;
|
||||
@@ -536,17 +536,17 @@ get_word_rgb_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
|
||||
temp = UCH(*bufferptr++) << 8;
|
||||
temp |= UCH(*bufferptr++);
|
||||
if (temp > maxval)
|
||||
ERREXIT(cinfo, JERR_PPM_TOOLARGE);
|
||||
ERREXIT(cinfo, JERR_PPM_OUTOFRANGE);
|
||||
*ptr++ = rescale[temp];
|
||||
temp = UCH(*bufferptr++) << 8;
|
||||
temp |= UCH(*bufferptr++);
|
||||
if (temp > maxval)
|
||||
ERREXIT(cinfo, JERR_PPM_TOOLARGE);
|
||||
ERREXIT(cinfo, JERR_PPM_OUTOFRANGE);
|
||||
*ptr++ = rescale[temp];
|
||||
temp = UCH(*bufferptr++) << 8;
|
||||
temp |= UCH(*bufferptr++);
|
||||
if (temp > maxval)
|
||||
ERREXIT(cinfo, JERR_PPM_TOOLARGE);
|
||||
ERREXIT(cinfo, JERR_PPM_OUTOFRANGE);
|
||||
*ptr++ = rescale[temp];
|
||||
}
|
||||
return 1;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1996, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2010, D. R. Commander.
|
||||
* Copyright (C) 2010, 2018, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -276,7 +276,8 @@ bogus:
|
||||
|
||||
|
||||
#if JPEG_LIB_VERSION < 70
|
||||
/* These are the sample quantization tables given in JPEG spec section K.1.
|
||||
/* These are the sample quantization tables given in Annex K (Clause K.1) of
|
||||
* Recommendation ITU-T T.81 (1992) | ISO/IEC 10918-1:1994.
|
||||
* The spec says that the values given produce "good" quality, and
|
||||
* when divided by 2, "very good" quality.
|
||||
*/
|
||||
|
||||
17
rdtarga.c
17
rdtarga.c
@@ -3,8 +3,9 @@
|
||||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1996, Thomas G. Lane.
|
||||
* It was modified by The libjpeg-turbo Project to include only code relevant
|
||||
* to libjpeg-turbo.
|
||||
* Modified 2017 by Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2018, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -66,6 +67,7 @@ typedef struct _tga_source_struct {
|
||||
U_CHAR tga_pixel[4];
|
||||
|
||||
int pixel_size; /* Bytes per Targa pixel (1 to 4) */
|
||||
int cmap_length; /* colormap length */
|
||||
|
||||
/* State info for reading RLE-coded pixels; both counts must be init to 0 */
|
||||
int block_count; /* # of pixels remaining in RLE block */
|
||||
@@ -126,11 +128,10 @@ METHODDEF(void)
|
||||
read_non_rle_pixel(tga_source_ptr sinfo)
|
||||
/* Read one Targa pixel from the input file; no RLE expansion */
|
||||
{
|
||||
register FILE *infile = sinfo->pub.input_file;
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < sinfo->pixel_size; i++) {
|
||||
sinfo->tga_pixel[i] = (U_CHAR)getc(infile);
|
||||
sinfo->tga_pixel[i] = (U_CHAR)read_byte(sinfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +140,6 @@ METHODDEF(void)
|
||||
read_rle_pixel(tga_source_ptr sinfo)
|
||||
/* Read one Targa pixel from the input file, expanding RLE data as needed */
|
||||
{
|
||||
register FILE *infile = sinfo->pub.input_file;
|
||||
register int i;
|
||||
|
||||
/* Duplicate previously read pixel? */
|
||||
@@ -161,7 +161,7 @@ read_rle_pixel(tga_source_ptr sinfo)
|
||||
|
||||
/* Read next pixel */
|
||||
for (i = 0; i < sinfo->pixel_size; i++) {
|
||||
sinfo->tga_pixel[i] = (U_CHAR)getc(infile);
|
||||
sinfo->tga_pixel[i] = (U_CHAR)read_byte(sinfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,11 +198,14 @@ get_8bit_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
|
||||
register JSAMPROW ptr;
|
||||
register JDIMENSION col;
|
||||
register JSAMPARRAY colormap = source->colormap;
|
||||
int cmaplen = source->cmap_length;
|
||||
|
||||
ptr = source->pub.buffer[0];
|
||||
for (col = cinfo->image_width; col > 0; col--) {
|
||||
(*source->read_pixel) (source); /* Load next pixel into tga_pixel */
|
||||
t = UCH(source->tga_pixel[0]);
|
||||
if (t >= cmaplen)
|
||||
ERREXIT(cinfo, JERR_TGA_BADPARMS);
|
||||
*ptr++ = colormap[0][t];
|
||||
*ptr++ = colormap[1][t];
|
||||
*ptr++ = colormap[2][t];
|
||||
@@ -454,12 +457,14 @@ start_input_tga(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
|
||||
/* Allocate space to store the colormap */
|
||||
source->colormap = (*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr)cinfo, JPOOL_IMAGE, (JDIMENSION)maplen, (JDIMENSION)3);
|
||||
source->cmap_length = (int)maplen;
|
||||
/* and read it from the file */
|
||||
read_colormap(source, (int)maplen, UCH(targaheader[7]));
|
||||
} else {
|
||||
if (cmaptype) /* but you promised a cmap! */
|
||||
ERREXIT(cinfo, JERR_TGA_BADPARMS);
|
||||
source->colormap = NULL;
|
||||
source->cmap_length = 0;
|
||||
}
|
||||
|
||||
cinfo->input_components = components;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
libjpeg-turbo is a JPEG image codec that uses SIMD instructions (MMX, SSE2, AVX2, 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 is a JPEG image codec that uses SIMD instructions (MMX, SSE2, AVX2, NEON, AltiVec) to accelerate baseline JPEG compression and decompression on x86, x86-64, ARM, and PowerPC systems, as well as progressive JPEG compression on x86 and x86-64 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.
|
||||
|
||||
|
||||
@@ -10,7 +10,8 @@ Installed-Size: {__SIZE}
|
||||
Description: A SIMD-accelerated JPEG codec that provides both the libjpeg and TurboJPEG APIs
|
||||
libjpeg-turbo is a JPEG image codec that uses SIMD instructions (MMX, SSE2,
|
||||
AVX2, NEON, AltiVec) to accelerate baseline JPEG compression and decompression
|
||||
on x86, x86-64, ARM, and PowerPC systems. On such systems, libjpeg-turbo is
|
||||
on x86, x86-64, ARM, and PowerPC systems, as well as progressive JPEG
|
||||
compression on x86 and x86-64 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
|
||||
|
||||
@@ -62,15 +62,15 @@ Section "@CMAKE_PROJECT_NAME@ SDK for @INST_PLATFORM@ (required)"
|
||||
File "@CMAKE_CURRENT_BINARY_DIR@\libturbojpeg.a"
|
||||
File "@CMAKE_CURRENT_BINARY_DIR@\libjpeg.dll.a"
|
||||
File "@CMAKE_CURRENT_BINARY_DIR@\libjpeg.a"
|
||||
SetOutPath $INSTDIR\lib\pkgconfig
|
||||
File "@CMAKE_CURRENT_BINARY_DIR@\pkgscripts\libjpeg.pc"
|
||||
File "@CMAKE_CURRENT_BINARY_DIR@\pkgscripts\libturbojpeg.pc"
|
||||
!else
|
||||
File "@CMAKE_CURRENT_BINARY_DIR@\${BUILDDIR}turbojpeg.lib"
|
||||
File "@CMAKE_CURRENT_BINARY_DIR@\${BUILDDIR}turbojpeg-static.lib"
|
||||
File "@CMAKE_CURRENT_BINARY_DIR@\${BUILDDIR}jpeg.lib"
|
||||
File "@CMAKE_CURRENT_BINARY_DIR@\${BUILDDIR}jpeg-static.lib"
|
||||
!endif
|
||||
SetOutPath $INSTDIR\lib\pkgconfig
|
||||
File "@CMAKE_CURRENT_BINARY_DIR@\pkgscripts\libjpeg.pc"
|
||||
File "@CMAKE_CURRENT_BINARY_DIR@\pkgscripts\libturbojpeg.pc"
|
||||
!ifdef JAVA
|
||||
SetOutPath $INSTDIR\classes
|
||||
File "@CMAKE_CURRENT_BINARY_DIR@\java\turbojpeg.jar"
|
||||
@@ -130,8 +130,6 @@ Section "Uninstall"
|
||||
Delete $INSTDIR\lib\libturbojpeg.a
|
||||
Delete $INSTDIR\lib\libjpeg.dll.a
|
||||
Delete $INSTDIR\lib\libjpeg.a
|
||||
Delete $INSTDIR\lib\pkgconfig\libjpeg.pc
|
||||
Delete $INSTDIR\lib\pkgconfig\libturbojpeg.pc
|
||||
!else
|
||||
Delete $INSTDIR\bin\jpeg@SO_MAJOR_VERSION@.dll
|
||||
Delete $INSTDIR\bin\turbojpeg.dll
|
||||
@@ -141,6 +139,8 @@ Section "Uninstall"
|
||||
Delete $INSTDIR\lib\turbojpeg.lib
|
||||
Delete $INSTDIR\lib\turbojpeg-static.lib
|
||||
!endif
|
||||
Delete $INSTDIR\lib\pkgconfig\libjpeg.pc
|
||||
Delete $INSTDIR\lib\pkgconfig\libturbojpeg.pc
|
||||
!ifdef JAVA
|
||||
Delete $INSTDIR\classes\turbojpeg.jar
|
||||
!endif
|
||||
@@ -175,9 +175,7 @@ Section "Uninstall"
|
||||
!endif
|
||||
|
||||
RMDir "$INSTDIR\include"
|
||||
!ifdef GCC
|
||||
RMDir "$INSTDIR\lib\pkgconfig"
|
||||
!endif
|
||||
RMDir "$INSTDIR\lib"
|
||||
RMDir "$INSTDIR\doc"
|
||||
!ifdef GCC
|
||||
|
||||
@@ -58,6 +58,8 @@ BUILDDIRARMV7=@IOS_ARMV7_BUILD@
|
||||
BUILDDIRARMV7S=@IOS_ARMV7S_BUILD@
|
||||
BUILDDIRARMV8=@IOS_ARMV8_BUILD@
|
||||
WITH_JAVA=@WITH_JAVA@
|
||||
OSX_APP_CERT_NAME="@OSX_APP_CERT_NAME@"
|
||||
OSX_INST_CERT_NAME="@OSX_INST_CERT_NAME@"
|
||||
LIPO=lipo
|
||||
|
||||
PREFIX=@CMAKE_INSTALL_PREFIX@
|
||||
@@ -258,11 +260,25 @@ cp $SRCDIR/release/License.rtf $SRCDIR/release/Welcome.rtf $SRCDIR/release/ReadM
|
||||
mkdir $TMPDIR/dmg
|
||||
pkgbuild --root $PKGROOT --version $VERSION.$BUILD --identifier @PKGID@ \
|
||||
$TMPDIR/pkg/$PKGNAME.pkg
|
||||
SUFFIX=
|
||||
if [ "$OSX_INST_CERT_NAME" != "" ]; then
|
||||
SUFFIX=-unsigned
|
||||
fi
|
||||
productbuild --distribution pkgscripts/Distribution.xml \
|
||||
--package-path $TMPDIR/pkg/ --resources $TMPDIR/pkg/ \
|
||||
$TMPDIR/dmg/$PKGNAME.pkg
|
||||
$TMPDIR/dmg/$PKGNAME$SUFFIX.pkg
|
||||
if [ "$OSX_INST_CERT_NAME" != "" ]; then
|
||||
productsign --sign "$OSX_INST_CERT_NAME" --timestamp \
|
||||
$TMPDIR/dmg/$PKGNAME$SUFFIX.pkg $TMPDIR/dmg/$PKGNAME.pkg
|
||||
rm -r $TMPDIR/dmg/$PKGNAME$SUFFIX.pkg
|
||||
pkgutil --check-signature $TMPDIR/dmg/$PKGNAME.pkg
|
||||
fi
|
||||
hdiutil create -fs HFS+ -volname $PKGNAME-$VERSION \
|
||||
-srcfolder "$TMPDIR/dmg" $TMPDIR/$PKGNAME-$VERSION.dmg
|
||||
if [ "$OSX_APP_CERT_NAME" != "" ]; then
|
||||
codesign -s "$OSX_APP_CERT_NAME" --timestamp $TMPDIR/$PKGNAME-$VERSION.dmg
|
||||
codesign -vv $TMPDIR/$PKGNAME-$VERSION.dmg
|
||||
fi
|
||||
cp $TMPDIR/$PKGNAME-$VERSION.dmg .
|
||||
|
||||
exit
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
%global _docdir %{_defaultdocdir}/%{name}-%{version}
|
||||
%define _prefix @CMAKE_INSTALL_PREFIX@
|
||||
%define _bindir @CMAKE_INSTALL_FULL_BINDIR@
|
||||
%define _datarootdir @CMAKE_INSTALL_FULL_DATAROOTDIR@
|
||||
%define _docdir %{_defaultdocdir}/%{name}-%{version}
|
||||
%define _includedir @CMAKE_INSTALL_FULL_INCLUDEDIR@
|
||||
%define _javadir @CMAKE_INSTALL_FULL_JAVADIR@
|
||||
%define _mandir @CMAKE_INSTALL_FULL_MANDIR@
|
||||
@@ -43,7 +43,7 @@ Group: System Environment/Libraries
|
||||
Release: @BUILD@
|
||||
License: BSD-style
|
||||
BuildRoot: %{_blddir}/%{name}-buildroot-%{version}-%{release}
|
||||
Prereq: /sbin/ldconfig
|
||||
Requires: /sbin/ldconfig
|
||||
%if "%{_bits}" == "64"
|
||||
Provides: %{name} = %{version}-%{release}, @CMAKE_PROJECT_NAME@ = %{version}-%{release}, libturbojpeg.so()(64bit)
|
||||
%else
|
||||
@@ -53,7 +53,8 @@ Provides: %{name} = %{version}-%{release}, @CMAKE_PROJECT_NAME@ = %{version}-%{r
|
||||
%description
|
||||
libjpeg-turbo is a JPEG image codec that uses SIMD instructions (MMX, SSE2,
|
||||
AVX2, NEON, AltiVec) to accelerate baseline JPEG compression and decompression
|
||||
on x86, x86-64, ARM, and PowerPC systems. On such systems, libjpeg-turbo is
|
||||
on x86, x86-64, ARM, and PowerPC systems, as well as progressive JPEG
|
||||
compression on x86 and x86-64 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
|
||||
@@ -182,7 +183,7 @@ rm -rf $RPM_BUILD_ROOT
|
||||
%if "%{_enable_static}" == "1"
|
||||
%{_libdir}/libjpeg.a
|
||||
%endif
|
||||
%{_libdir}/pkgconfig
|
||||
%dir %{_libdir}/pkgconfig
|
||||
%{_libdir}/pkgconfig/libjpeg.pc
|
||||
%if "%{_with_turbojpeg}" == "1"
|
||||
%if "%{_enable_shared}" == "1" || "%{_with_java}" == "1"
|
||||
|
||||
@@ -23,7 +23,7 @@ foreach(src ${JPEG_SOURCES})
|
||||
set(JPEG_SRCS ${JPEG_SRCS} ../${src})
|
||||
endforeach()
|
||||
|
||||
if(WITH_SIMD AND MSVC_IDE)
|
||||
if(WITH_SIMD AND (MSVC_IDE OR XCODE))
|
||||
# This tells CMake that the "source" files haven't been generated yet
|
||||
set_source_files_properties(${SIMD_OBJS} PROPERTIES GENERATED 1)
|
||||
endif()
|
||||
@@ -40,7 +40,8 @@ add_library(jpeg SHARED ${JPEG_SRCS} ${DEFFILE} $<TARGET_OBJECTS:simd>
|
||||
|
||||
set_target_properties(jpeg PROPERTIES SOVERSION ${SO_MAJOR_VERSION}
|
||||
VERSION ${SO_MAJOR_VERSION}.${SO_AGE}.${SO_MINOR_VERSION})
|
||||
if(APPLE)
|
||||
if(APPLE AND (NOT CMAKE_OSX_DEPLOYMENT_TARGET OR
|
||||
CMAKE_OSX_DEPLOYMENT_TARGET VERSION_GREATER 10.4))
|
||||
if(NOT CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG)
|
||||
set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,")
|
||||
endif()
|
||||
@@ -51,7 +52,8 @@ if(MAPFLAG)
|
||||
LINK_FLAGS "${MAPFLAG}${CMAKE_CURRENT_BINARY_DIR}/../libjpeg.map")
|
||||
endif()
|
||||
if(MSVC)
|
||||
set_target_properties(jpeg PROPERTIES SUFFIX ${SO_MAJOR_VERSION}.dll)
|
||||
set_target_properties(jpeg PROPERTIES
|
||||
RUNTIME_OUTPUT_NAME jpeg${SO_MAJOR_VERSION})
|
||||
# The jsimd_*.c file is built using /MT, so this prevents a linker warning.
|
||||
set_target_properties(jpeg PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMT /NODEFAULTLIB:LIBCMTD")
|
||||
elseif(MINGW)
|
||||
@@ -90,3 +92,8 @@ install(TARGETS jpeg cjpeg djpeg jpegtran
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
if(NOT CMAKE_VERSION VERSION_LESS "3.1" AND MSVC AND
|
||||
CMAKE_C_LINKER_SUPPORTS_PDB)
|
||||
install(FILES "$<TARGET_PDB_FILE:jpeg>"
|
||||
DESTINATION ${CMAKE_INSTALL_BINDIR} OPTIONAL)
|
||||
endif()
|
||||
|
||||
@@ -91,19 +91,16 @@ message(STATUS "CMAKE_ASM_NASM_FLAGS = ${EFFECTIVE_ASM_NASM_FLAGS}")
|
||||
|
||||
set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -I\"${CMAKE_CURRENT_SOURCE_DIR}/nasm/\" -I\"${CMAKE_CURRENT_SOURCE_DIR}/${CPU_TYPE}/\"")
|
||||
|
||||
if(WIN32)
|
||||
set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -I\"${CMAKE_CURRENT_SOURCE_DIR}/../win/\"")
|
||||
set(JSIMDCFG_INC ${CMAKE_CURRENT_SOURCE_DIR}/../win/jsimdcfg.inc)
|
||||
else()
|
||||
set(GREP grep)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
|
||||
set(GREP ggrep)
|
||||
endif()
|
||||
add_custom_command(OUTPUT jsimdcfg.inc
|
||||
COMMAND ${CMAKE_C_COMPILER} -E -I${CMAKE_BINARY_DIR} -I${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/jsimdcfg.inc.h | ${GREP} -E '^[\;%]|^\ %' | sed 's%_cpp_protection_%%' | sed 's@% define@%define@g' >jsimdcfg.inc)
|
||||
set(JSIMDCFG_INC ${CMAKE_CURRENT_BINARY_DIR}/jsimdcfg.inc)
|
||||
set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -I\"${CMAKE_CURRENT_BINARY_DIR}/\"")
|
||||
set(GREP grep)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
|
||||
set(GREP ggrep)
|
||||
endif()
|
||||
add_custom_target(jsimdcfg COMMAND
|
||||
${CMAKE_C_COMPILER} -E -I${CMAKE_BINARY_DIR} -I${CMAKE_CURRENT_BINARY_DIR}
|
||||
-I${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/nasm/jsimdcfg.inc.h |
|
||||
${GREP} -E '^[\;%]|^\ %' | sed 's%_cpp_protection_%%' |
|
||||
sed 's@% define@%define@g' >${CMAKE_CURRENT_SOURCE_DIR}/nasm/jsimdcfg.inc)
|
||||
|
||||
if(CPU_TYPE STREQUAL "x86_64")
|
||||
set(SIMD_SOURCES x86_64/jsimdcpu.asm x86_64/jfdctflt-sse.asm
|
||||
@@ -138,6 +135,9 @@ endif()
|
||||
if(MSVC_IDE)
|
||||
set(OBJDIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
|
||||
string(REGEX REPLACE " " ";" CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS}")
|
||||
elseif(XCODE)
|
||||
set(OBJDIR "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
string(REGEX REPLACE " " ";" CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS}")
|
||||
endif()
|
||||
|
||||
file(GLOB INC_FILES nasm/*.inc)
|
||||
@@ -164,14 +164,14 @@ foreach(file ${SIMD_SOURCES})
|
||||
set(OBJECT_DEPENDS ${OBJECT_DEPENDS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${DEPFILE})
|
||||
endif()
|
||||
set(OBJECT_DEPENDS ${OBJECT_DEPENDS} ${INC_FILES} ${JSIMDCFG_INC})
|
||||
if(MSVC_IDE)
|
||||
set(OBJECT_DEPENDS ${OBJECT_DEPENDS} ${INC_FILES})
|
||||
if(MSVC_IDE OR XCODE)
|
||||
# The CMake Visual Studio generators do not work properly with the ASM_NASM
|
||||
# language, so we have to go rogue here and use a custom command like we
|
||||
# did in prior versions of libjpeg-turbo. (This is why we can't have nice
|
||||
# things.)
|
||||
string(REGEX REPLACE "${CPU_TYPE}/" "" filename ${file})
|
||||
set(SIMD_OBJ ${OBJDIR}/${filename}.obj)
|
||||
set(SIMD_OBJ ${OBJDIR}/${filename}${CMAKE_C_OUTPUT_EXTENSION})
|
||||
add_custom_command(OUTPUT ${SIMD_OBJ} DEPENDS ${file} ${OBJECT_DEPENDS}
|
||||
COMMAND ${CMAKE_ASM_NASM_COMPILER} -f${CMAKE_ASM_NASM_OBJECT_FORMAT}
|
||||
${CMAKE_ASM_NASM_FLAGS} ${CMAKE_CURRENT_SOURCE_DIR}/${file}
|
||||
@@ -183,7 +183,7 @@ foreach(file ${SIMD_SOURCES})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(MSVC_IDE)
|
||||
if(MSVC_IDE OR XCODE)
|
||||
set(SIMD_OBJS ${SIMD_OBJS} PARENT_SCOPE)
|
||||
add_library(simd OBJECT ${CPU_TYPE}/jsimd.c)
|
||||
add_custom_target(simd-objs DEPENDS ${SIMD_OBJS})
|
||||
@@ -265,7 +265,7 @@ endif()
|
||||
# MIPS (GAS)
|
||||
###############################################################################
|
||||
|
||||
elseif(CPU_TYPE STREQUAL "mips")
|
||||
elseif(CPU_TYPE STREQUAL "mips" OR CPU_TYPE STREQUAL "mipsel")
|
||||
|
||||
enable_language(ASM)
|
||||
|
||||
@@ -273,7 +273,30 @@ string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UC)
|
||||
set(EFFECTIVE_ASM_FLAGS "${CMAKE_ASM_FLAGS} ${CMAKE_ASM_FLAGS_${CMAKE_BUILD_TYPE_UC}}")
|
||||
message(STATUS "CMAKE_ASM_FLAGS = ${EFFECTIVE_ASM_FLAGS}")
|
||||
|
||||
add_library(simd OBJECT ${CPU_TYPE}/jsimd_dspr2.S ${CPU_TYPE}/jsimd.c)
|
||||
set(CMAKE_REQUIRED_FLAGS -mdspr2)
|
||||
|
||||
check_c_source_compiles("
|
||||
#if !(defined(__mips__) && __mips_isa_rev >= 2)
|
||||
#error MIPS DSPr2 is currently only available on MIPS32r2 platforms.
|
||||
#endif
|
||||
int main(void) {
|
||||
int c = 0, a = 0, b = 0;
|
||||
__asm__ __volatile__ (
|
||||
\"precr.qb.ph %[c], %[a], %[b]\"
|
||||
: [c] \"=r\" (c)
|
||||
: [a] \"r\" (a), [b] \"r\" (b)
|
||||
);
|
||||
return c;
|
||||
}" HAVE_DSPR2)
|
||||
|
||||
unset(CMAKE_REQUIRED_FLAGS)
|
||||
|
||||
if(NOT HAVE_DSPR2)
|
||||
simd_fail("SIMD extensions not available for this CPU")
|
||||
return()
|
||||
endif()
|
||||
|
||||
add_library(simd OBJECT mips/jsimd_dspr2.S mips/jsimd.c)
|
||||
|
||||
if(CMAKE_POSITION_INDEPENDENT_CODE OR ENABLE_SHARED)
|
||||
set_target_properties(simd PROPERTIES POSITION_INDEPENDENT_CODE 1)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
* Copyright (C) 2011, Nokia Corporation and/or its subsidiary(-ies).
|
||||
* Copyright (C) 2009-2011, 2013-2014, 2016, 2018, D. R. Commander.
|
||||
* Copyright (C) 2015-2016, 2018, Matthieu Darbois.
|
||||
* Copyright (C) 2019, Google LLC.
|
||||
*
|
||||
* Based on the x86 SIMD extension for IJG JPEG library,
|
||||
* Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
@@ -30,7 +31,7 @@
|
||||
static unsigned int simd_support = ~0;
|
||||
static unsigned int simd_huffman = 1;
|
||||
|
||||
#if defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
|
||||
#if !defined(__ARM_NEON__) && (defined(__linux__) || defined(ANDROID) || defined(__ANDROID__))
|
||||
|
||||
#define SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT (1024 * 1024)
|
||||
|
||||
@@ -105,7 +106,7 @@ init_simd(void)
|
||||
#ifndef NO_GETENV
|
||||
char *env = NULL;
|
||||
#endif
|
||||
#if !defined(__ARM_NEON__) && defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
|
||||
#if !defined(__ARM_NEON__) && (defined(__linux__) || defined(ANDROID) || defined(__ANDROID__))
|
||||
int bufsize = 1024; /* an initial guess for the line buffer size limit */
|
||||
#endif
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ _\fname:
|
||||
trn2 \x1\literal, \xi\literal, \x1\literal
|
||||
.endm
|
||||
|
||||
/* Transpose elements of 2 differnet registers */
|
||||
/* Transpose elements of 2 different registers */
|
||||
.macro transpose x0, x1, xi, xilen, literal
|
||||
mov \xi\xilen, \x0\xilen
|
||||
trn1 \x0\literal, \x0\literal, \x1\literal
|
||||
|
||||
@@ -329,6 +329,8 @@ EXTN(jsimd_encode_mcu_AC_first_prepare_sse2):
|
||||
add LUT, 16*SIZEOF_INT
|
||||
dec K
|
||||
jnz .BLOOP16
|
||||
test LEN, 15
|
||||
je .PADDING
|
||||
.ELOOP16:
|
||||
mov LENEND, LEN
|
||||
and LENEND, 7
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#define IS_ALIGNED_SSE(ptr) (IS_ALIGNED(ptr, 4)) /* 16 byte alignment */
|
||||
#define IS_ALIGNED_AVX(ptr) (IS_ALIGNED(ptr, 5)) /* 32 byte alignment */
|
||||
|
||||
static unsigned int simd_support = ~0;
|
||||
static unsigned int simd_support = (unsigned int)(~0);
|
||||
static unsigned int simd_huffman = 1;
|
||||
|
||||
/*
|
||||
@@ -1210,15 +1210,10 @@ jsimd_can_encode_mcu_AC_first_prepare(void)
|
||||
return 0;
|
||||
if (SIZEOF_SIZE_T != 4)
|
||||
return 0;
|
||||
if (!(simd_support & JSIMD_SSE2))
|
||||
return 0;
|
||||
#if defined(HAVE_BUILTIN_CTZL)
|
||||
return 1;
|
||||
#elif defined(HAVE_BITSCANFORWARD)
|
||||
return 1;
|
||||
#else
|
||||
if (simd_support & JSIMD_SSE2)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
@@ -1241,15 +1236,10 @@ jsimd_can_encode_mcu_AC_refine_prepare(void)
|
||||
return 0;
|
||||
if (SIZEOF_SIZE_T != 4)
|
||||
return 0;
|
||||
if (!(simd_support & JSIMD_SSE2))
|
||||
return 0;
|
||||
#if defined(HAVE_BUILTIN_CTZL)
|
||||
return 1;
|
||||
#elif defined(HAVE_BITSCANFORWARD)
|
||||
return 1;
|
||||
#else
|
||||
if (simd_support & JSIMD_SSE2)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
|
||||
@@ -51,29 +51,14 @@ EXTN(jpeg_simd_cpu_support):
|
||||
xor eax, edx
|
||||
jz near .return ; CPUID is not supported
|
||||
|
||||
; Check for MMX instruction support
|
||||
; Check whether CPUID leaf 07H is supported
|
||||
; (leaf 07H is used to check for AVX2 instruction support)
|
||||
xor eax, eax
|
||||
cpuid
|
||||
test eax, eax
|
||||
jz near .return
|
||||
|
||||
xor eax, eax
|
||||
inc eax
|
||||
cpuid
|
||||
mov eax, edx ; eax = Standard feature flags
|
||||
|
||||
test eax, 1<<23 ; bit23:MMX
|
||||
jz short .no_mmx
|
||||
or edi, byte JSIMD_MMX
|
||||
.no_mmx:
|
||||
test eax, 1<<25 ; bit25:SSE
|
||||
jz short .no_sse
|
||||
or edi, byte JSIMD_SSE
|
||||
.no_sse:
|
||||
test eax, 1<<26 ; bit26:SSE2
|
||||
jz short .no_sse2
|
||||
or edi, byte JSIMD_SSE2
|
||||
.no_sse2:
|
||||
cmp eax, 7
|
||||
jl short .no_avx2 ; Maximum leaf < 07H
|
||||
|
||||
; Check for AVX2 instruction support
|
||||
mov eax, 7
|
||||
@@ -94,13 +79,34 @@ EXTN(jpeg_simd_cpu_support):
|
||||
|
||||
xor ecx, ecx
|
||||
xgetbv
|
||||
test eax, 6 ; O/S does not manage XMM/YMM state
|
||||
and eax, 6
|
||||
cmp eax, 6 ; O/S does not manage XMM/YMM state
|
||||
; using XSAVE
|
||||
jz short .no_avx2
|
||||
jnz short .no_avx2
|
||||
|
||||
or edi, JSIMD_AVX2
|
||||
.no_avx2:
|
||||
|
||||
; Check CPUID leaf 01H for MMX, SSE, and SSE2 support
|
||||
xor eax, eax
|
||||
inc eax
|
||||
cpuid
|
||||
mov eax, edx ; eax = Standard feature flags
|
||||
|
||||
; Check for MMX instruction support
|
||||
test eax, 1<<23 ; bit23:MMX
|
||||
jz short .no_mmx
|
||||
or edi, byte JSIMD_MMX
|
||||
.no_mmx:
|
||||
test eax, 1<<25 ; bit25:SSE
|
||||
jz short .no_sse
|
||||
or edi, byte JSIMD_SSE
|
||||
.no_sse:
|
||||
test eax, 1<<26 ; bit26:SSE2
|
||||
jz short .no_sse2
|
||||
or edi, byte JSIMD_SSE2
|
||||
.no_sse2:
|
||||
|
||||
; Check for 3DNow! instruction support
|
||||
mov eax, 0x80000000
|
||||
cpuid
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
* Loongson MMI optimizations for libjpeg-turbo
|
||||
*
|
||||
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
* Copyright (C) 2014-2015, D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C) 2016-2017, Loongson Technology Corporation Limited, BeiJing.
|
||||
* Copyright (C) 2014-2015, 2019, D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C) 2016-2018, Loongson Technology Corporation Limited, BeiJing.
|
||||
* All Rights Reserved.
|
||||
* Authors: ZhuChen <zhuchen@loongson.cn>
|
||||
* SunZhangzhi <sunzhangzhi-cq@loongson.cn>
|
||||
* CaiWanwei <caiwanwei@loongson.cn>
|
||||
* ZhangLixia <zhanglixia-hf@loongson.cn>
|
||||
*
|
||||
* Based on the x86 SIMD extension for IJG JPEG library
|
||||
* Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
@@ -184,9 +185,15 @@ void jsimd_rgb_ycc_convert_mmi(JDIMENSION image_width, JSAMPARRAY input_buf,
|
||||
"$14", "memory"
|
||||
);
|
||||
} else {
|
||||
mmA = _mm_load_si64((__m64 *)&inptr[0]);
|
||||
mmG = _mm_load_si64((__m64 *)&inptr[8]);
|
||||
mmF = _mm_load_si64((__m64 *)&inptr[16]);
|
||||
if (!(((long)inptr) & 7)) {
|
||||
mmA = _mm_load_si64((__m64 *)&inptr[0]);
|
||||
mmG = _mm_load_si64((__m64 *)&inptr[8]);
|
||||
mmF = _mm_load_si64((__m64 *)&inptr[16]);
|
||||
} else {
|
||||
mmA = _mm_loadu_si64((__m64 *)&inptr[0]);
|
||||
mmG = _mm_loadu_si64((__m64 *)&inptr[8]);
|
||||
mmF = _mm_loadu_si64((__m64 *)&inptr[16]);
|
||||
}
|
||||
inptr += RGB_PIXELSIZE * 8;
|
||||
}
|
||||
mmD = mmA;
|
||||
@@ -268,10 +275,17 @@ void jsimd_rgb_ycc_convert_mmi(JDIMENSION image_width, JSAMPARRAY input_buf,
|
||||
: "$f0", "$f2", "$8", "$9", "$10", "$11", "$13", "memory"
|
||||
);
|
||||
} else {
|
||||
mmA = _mm_load_si64((__m64 *)&inptr[0]);
|
||||
mmF = _mm_load_si64((__m64 *)&inptr[8]);
|
||||
mmD = _mm_load_si64((__m64 *)&inptr[16]);
|
||||
mmC = _mm_load_si64((__m64 *)&inptr[24]);
|
||||
if (!(((long)inptr) & 7)) {
|
||||
mmA = _mm_load_si64((__m64 *)&inptr[0]);
|
||||
mmF = _mm_load_si64((__m64 *)&inptr[8]);
|
||||
mmD = _mm_load_si64((__m64 *)&inptr[16]);
|
||||
mmC = _mm_load_si64((__m64 *)&inptr[24]);
|
||||
} else {
|
||||
mmA = _mm_loadu_si64((__m64 *)&inptr[0]);
|
||||
mmF = _mm_loadu_si64((__m64 *)&inptr[8]);
|
||||
mmD = _mm_loadu_si64((__m64 *)&inptr[16]);
|
||||
mmC = _mm_loadu_si64((__m64 *)&inptr[24]);
|
||||
}
|
||||
inptr += RGB_PIXELSIZE * 8;
|
||||
}
|
||||
mmB = mmA;
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
#include "jsimd_mmi.h"
|
||||
|
||||
|
||||
#define F_0_081 ((short) 5329) /* FIX(0.08131) */
|
||||
#define F_0_114 ((short) 7471) /* FIX(0.11400) */
|
||||
#define F_0_081 ((short)5329) /* FIX(0.08131) */
|
||||
#define F_0_114 ((short)7471) /* FIX(0.11400) */
|
||||
#define F_0_168 ((short)11059) /* FIX(0.16874) */
|
||||
#define F_0_250 ((short)16384) /* FIX(0.25000) */
|
||||
#define F_0_299 ((short)19595) /* FIX(0.29900) */
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
/*
|
||||
* Loongson MMI optimizations for libjpeg-turbo
|
||||
*
|
||||
* Copyright (C) 2016-2017, Loongson Technology Corporation Limited, BeiJing.
|
||||
* Copyright (C) 2016-2018, Loongson Technology Corporation Limited, BeiJing.
|
||||
* All Rights Reserved.
|
||||
* Copyright (C) 2019, D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -41,7 +42,7 @@ typedef float __m32;
|
||||
|
||||
/********** Set Operations **********/
|
||||
|
||||
extern __inline __m64
|
||||
extern __inline __m64 FUNCTION_ATTRIBS
|
||||
_mm_setzero_si64(void)
|
||||
{
|
||||
return 0.0;
|
||||
@@ -1245,6 +1246,22 @@ _mm_load_si64(const __m64 *src)
|
||||
asm("ldc1 %0, %1\n\t"
|
||||
: "=f" (ret)
|
||||
: "m" (*src)
|
||||
: "memory"
|
||||
);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 FUNCTION_ATTRIBS
|
||||
_mm_loadu_si64(const __m64 *src)
|
||||
{
|
||||
__m64 ret;
|
||||
|
||||
asm("gsldlc1 %0, 7(%1)\n\t"
|
||||
"gsldrc1 %0, 0(%1)\n\t"
|
||||
: "=f" (ret)
|
||||
: "r" (src)
|
||||
: "memory"
|
||||
);
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -692,8 +692,10 @@ jsimd_can_convsamp_float(void)
|
||||
if (sizeof(ISLOW_MULT_TYPE) != 2)
|
||||
return 0;
|
||||
|
||||
#ifndef __mips_soft_float
|
||||
if (simd_support & JSIMD_DSPR2)
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -709,7 +711,9 @@ GLOBAL(void)
|
||||
jsimd_convsamp_float(JSAMPARRAY sample_data, JDIMENSION start_col,
|
||||
FAST_FLOAT *workspace)
|
||||
{
|
||||
#ifndef __mips_soft_float
|
||||
jsimd_convsamp_float_dspr2(sample_data, start_col, workspace);
|
||||
#endif
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
@@ -805,8 +809,10 @@ jsimd_can_quantize_float(void)
|
||||
if (sizeof(ISLOW_MULT_TYPE) != 2)
|
||||
return 0;
|
||||
|
||||
#ifndef __mips_soft_float
|
||||
if (simd_support & JSIMD_DSPR2)
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -821,7 +827,9 @@ GLOBAL(void)
|
||||
jsimd_quantize_float(JCOEFPTR coef_block, FAST_FLOAT *divisors,
|
||||
FAST_FLOAT *workspace)
|
||||
{
|
||||
#ifndef __mips_soft_float
|
||||
jsimd_quantize_float_dspr2(coef_block, divisors, workspace);
|
||||
#endif
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
|
||||
@@ -2810,6 +2810,8 @@ LEAF_DSPR2(jsimd_quantize_dspr2)
|
||||
END(jsimd_quantize_dspr2)
|
||||
|
||||
|
||||
#ifndef __mips_soft_float
|
||||
|
||||
/*****************************************************************************/
|
||||
LEAF_DSPR2(jsimd_quantize_float_dspr2)
|
||||
/*
|
||||
@@ -2890,6 +2892,8 @@ LEAF_DSPR2(jsimd_quantize_float_dspr2)
|
||||
|
||||
END(jsimd_quantize_float_dspr2)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
LEAF_DSPR2(jsimd_idct_2x2_dspr2)
|
||||
@@ -4110,6 +4114,8 @@ LEAF_DSPR2(jsimd_convsamp_dspr2)
|
||||
END(jsimd_convsamp_dspr2)
|
||||
|
||||
|
||||
#ifndef __mips_soft_float
|
||||
|
||||
/*****************************************************************************/
|
||||
LEAF_DSPR2(jsimd_convsamp_float_dspr2)
|
||||
/*
|
||||
@@ -4468,4 +4474,6 @@ LEAF_DSPR2(jsimd_convsamp_float_dspr2)
|
||||
|
||||
END(jsimd_convsamp_float_dspr2)
|
||||
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
0
win/jsimdcfg.inc → simd/nasm/jsimdcfg.inc
Executable file → Normal file
0
win/jsimdcfg.inc → simd/nasm/jsimdcfg.inc
Executable file → Normal file
@@ -39,7 +39,7 @@
|
||||
|
||||
static unsigned int simd_support = ~0;
|
||||
|
||||
#if defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
|
||||
#if !defined(__ALTIVEC__) && (defined(__linux__) || defined(ANDROID) || defined(__ANDROID__))
|
||||
|
||||
#define SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT (1024 * 1024)
|
||||
|
||||
|
||||
@@ -322,6 +322,8 @@ EXTN(jsimd_encode_mcu_AC_first_prepare_sse2):
|
||||
add LUT, 16*SIZEOF_INT
|
||||
dec K
|
||||
jnz .BLOOP16
|
||||
test LEN, 15
|
||||
je .PADDING
|
||||
.ELOOP16:
|
||||
test LEN, 8
|
||||
jz .TRY7
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#define IS_ALIGNED_SSE(ptr) (IS_ALIGNED(ptr, 4)) /* 16 byte alignment */
|
||||
#define IS_ALIGNED_AVX(ptr) (IS_ALIGNED(ptr, 5)) /* 32 byte alignment */
|
||||
|
||||
static unsigned int simd_support = ~0;
|
||||
static unsigned int simd_support = (unsigned int)(~0);
|
||||
static unsigned int simd_huffman = 1;
|
||||
|
||||
/*
|
||||
@@ -1033,15 +1033,10 @@ jsimd_can_encode_mcu_AC_first_prepare(void)
|
||||
return 0;
|
||||
if (SIZEOF_SIZE_T != 8)
|
||||
return 0;
|
||||
if (!(simd_support & JSIMD_SSE2))
|
||||
return 0;
|
||||
#if defined(HAVE_BUILTIN_CTZL)
|
||||
return 1;
|
||||
#elif defined(HAVE_BITSCANFORWARD64)
|
||||
return 1;
|
||||
#else
|
||||
if (simd_support & JSIMD_SSE2)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
@@ -1064,15 +1059,10 @@ jsimd_can_encode_mcu_AC_refine_prepare(void)
|
||||
return 0;
|
||||
if (SIZEOF_SIZE_T != 8)
|
||||
return 0;
|
||||
if (!(simd_support & JSIMD_SSE2))
|
||||
return 0;
|
||||
#if defined(HAVE_BUILTIN_CTZL)
|
||||
return 1;
|
||||
#elif defined(HAVE_BITSCANFORWARD64)
|
||||
return 1;
|
||||
#else
|
||||
if (simd_support & JSIMD_SSE2)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
|
||||
@@ -38,14 +38,23 @@ EXTN(jpeg_simd_cpu_support):
|
||||
|
||||
xor rdi, rdi ; simd support flag
|
||||
|
||||
; Assume that all x86-64 processors support SSE & SSE2 instructions
|
||||
or rdi, JSIMD_SSE2
|
||||
or rdi, JSIMD_SSE
|
||||
|
||||
; Check whether CPUID leaf 07H is supported
|
||||
; (leaf 07H is used to check for AVX2 instruction support)
|
||||
mov rax, 0
|
||||
cpuid
|
||||
cmp rax, 7
|
||||
jl short .return ; Maximum leaf < 07H
|
||||
|
||||
; Check for AVX2 instruction support
|
||||
mov rax, 7
|
||||
xor rcx, rcx
|
||||
cpuid
|
||||
mov rax, rbx ; rax = Extended feature flags
|
||||
|
||||
or rdi, JSIMD_SSE2
|
||||
or rdi, JSIMD_SSE
|
||||
test rax, 1<<5 ; bit5:AVX2
|
||||
jz short .return
|
||||
|
||||
@@ -60,9 +69,10 @@ EXTN(jpeg_simd_cpu_support):
|
||||
|
||||
xor rcx, rcx
|
||||
xgetbv
|
||||
test rax, 6 ; O/S does not manage XMM/YMM state
|
||||
and rax, 6
|
||||
cmp rax, 6 ; O/S does not manage XMM/YMM state
|
||||
; using XSAVE
|
||||
jz short .return
|
||||
jnz short .return
|
||||
|
||||
or rdi, JSIMD_AVX2
|
||||
|
||||
|
||||
@@ -89,12 +89,12 @@ nonetheless, they are useful for viewers.
|
||||
The compressor and decompressor are each divided into two main sections:
|
||||
the JPEG compressor or decompressor proper, and the preprocessing or
|
||||
postprocessing functions. The interface between these two sections is the
|
||||
image data that the official JPEG spec regards as its input or output: this
|
||||
data is in the colorspace to be used for compression, and it is downsampled
|
||||
to the sampling factors to be used. The preprocessing and postprocessing
|
||||
steps are responsible for converting a normal image representation to or from
|
||||
this form. (Those few applications that want to deal with YCbCr downsampled
|
||||
data can skip the preprocessing or postprocessing step.)
|
||||
image data that Rec. ITU-T T.81 | ISO/IEC 10918-1 regards as its input or
|
||||
output: this data is in the colorspace to be used for compression, and it is
|
||||
downsampled to the sampling factors to be used. The preprocessing and
|
||||
postprocessing steps are responsible for converting a normal image
|
||||
representation to or from this form. (Those few applications that want to deal
|
||||
with YCbCr downsampled data can skip the preprocessing or postprocessing step.)
|
||||
|
||||
Looking more closely, the compressor library contains the following main
|
||||
elements:
|
||||
@@ -141,22 +141,22 @@ allow such merging where appropriate.
|
||||
|
||||
|
||||
Note: it is convenient to regard edge expansion (padding to block boundaries)
|
||||
as a preprocessing/postprocessing function, even though the JPEG spec includes
|
||||
it in compression/decompression. We do this because downsampling/upsampling
|
||||
can be simplified a little if they work on padded data: it's not necessary to
|
||||
have special cases at the right and bottom edges. Therefore the interface
|
||||
buffer is always an integral number of blocks wide and high, and we expect
|
||||
compression preprocessing to pad the source data properly. Padding will occur
|
||||
only to the next block (8-sample) boundary. In an interleaved-scan situation,
|
||||
additional dummy blocks may be used to fill out MCUs, but the MCU assembly and
|
||||
disassembly logic will create or discard these blocks internally. (This is
|
||||
advantageous for speed reasons, since we avoid DCTing the dummy blocks.
|
||||
It also permits a small reduction in file size, because the compressor can
|
||||
choose dummy block contents so as to minimize their size in compressed form.
|
||||
Finally, it makes the interface buffer specification independent of whether
|
||||
the file is actually interleaved or not.) Applications that wish to deal
|
||||
directly with the downsampled data must provide similar buffering and padding
|
||||
for odd-sized images.
|
||||
as a preprocessing/postprocessing function, even though
|
||||
Rec. ITU-T T.81 | ISO/IEC 10918-1 includes it in compression/decompression. We
|
||||
do this because downsampling/upsampling can be simplified a little if they work
|
||||
on padded data: it's not necessary to have special cases at the right and
|
||||
bottom edges. Therefore the interface buffer is always an integral number of
|
||||
blocks wide and high, and we expect compression preprocessing to pad the source
|
||||
data properly. Padding will occur only to the next block (8-sample) boundary.
|
||||
In an interleaved-scan situation, additional dummy blocks may be used to fill
|
||||
out MCUs, but the MCU assembly and disassembly logic will create or discard
|
||||
these blocks internally. (This is advantageous for speed reasons, since we
|
||||
avoid DCTing the dummy blocks. It also permits a small reduction in file size,
|
||||
because the compressor can choose dummy block contents so as to minimize their
|
||||
size in compressed form. Finally, it makes the interface buffer specification
|
||||
independent of whether the file is actually interleaved or not.) Applications
|
||||
that wish to deal directly with the downsampled data must provide similar
|
||||
buffering and padding for odd-sized images.
|
||||
|
||||
|
||||
*** Poor man's object-oriented programming ***
|
||||
|
||||
5
testimages/test.scan
Normal file
5
testimages/test.scan
Normal file
@@ -0,0 +1,5 @@
|
||||
0 1 2: 0 0 0 0;
|
||||
0: 1 16 0 0;
|
||||
0: 17 63 0 0;
|
||||
1: 1 63 0 0;
|
||||
2: 1 63 0 0;
|
||||
248
tjbench.c
248
tjbench.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C)2009-2017 D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C)2009-2019 D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -32,27 +32,28 @@
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <cdjpeg.h>
|
||||
#include "./tjutil.h"
|
||||
#include "./turbojpeg.h"
|
||||
|
||||
|
||||
#define _throw(op, err) { \
|
||||
#define THROW(op, err) { \
|
||||
printf("ERROR in line %d while %s:\n%s\n", __LINE__, op, err); \
|
||||
retval = -1; goto bailout; \
|
||||
}
|
||||
#define _throwunix(m) _throw(m, strerror(errno))
|
||||
#define THROW_UNIX(m) THROW(m, strerror(errno))
|
||||
|
||||
char tjErrorStr[JMSG_LENGTH_MAX] = "\0", tjErrorMsg[JMSG_LENGTH_MAX] = "\0";
|
||||
int tjErrorLine = -1, tjErrorCode = -1;
|
||||
|
||||
#define _throwtjg(m) { \
|
||||
#define THROW_TJG(m) { \
|
||||
printf("ERROR in line %d while %s:\n%s\n", __LINE__, m, \
|
||||
tjGetErrorStr2(NULL)); \
|
||||
retval = -1; goto bailout; \
|
||||
}
|
||||
|
||||
#define _throwtj(m) { \
|
||||
#define THROW_TJ(m) { \
|
||||
int _tjErrorCode = tjGetErrorCode(handle); \
|
||||
char *_tjErrorStr = tjGetErrorStr2(handle); \
|
||||
\
|
||||
@@ -60,8 +61,8 @@ int tjErrorLine = -1, tjErrorCode = -1;
|
||||
if (strncmp(tjErrorStr, _tjErrorStr, JMSG_LENGTH_MAX) || \
|
||||
strncmp(tjErrorMsg, m, JMSG_LENGTH_MAX) || \
|
||||
tjErrorCode != _tjErrorCode || tjErrorLine != __LINE__) { \
|
||||
strncpy(tjErrorStr, _tjErrorStr, JMSG_LENGTH_MAX); \
|
||||
strncpy(tjErrorMsg, m, JMSG_LENGTH_MAX); \
|
||||
strncpy(tjErrorStr, _tjErrorStr, JMSG_LENGTH_MAX - 1); \
|
||||
strncpy(tjErrorMsg, m, JMSG_LENGTH_MAX - 1); \
|
||||
tjErrorCode = _tjErrorCode; \
|
||||
tjErrorLine = __LINE__; \
|
||||
printf("WARNING in line %d while %s:\n%s\n", __LINE__, m, _tjErrorStr); \
|
||||
@@ -95,11 +96,11 @@ int (*customFilter) (short *, tjregion, tjregion, int, int, tjtransform *);
|
||||
double benchTime = 5.0, warmup = 1.0;
|
||||
|
||||
|
||||
char *formatName(int subsamp, int cs, char *buf)
|
||||
static char *formatName(int subsamp, int cs, char *buf)
|
||||
{
|
||||
if (cs == TJCS_YCbCr)
|
||||
return (char *)subNameLong[subsamp];
|
||||
else if (cs == TJCS_YCCK) {
|
||||
else if (cs == TJCS_YCCK || cs == TJCS_CMYK) {
|
||||
snprintf(buf, 80, "%s %s", csName[cs], subNameLong[subsamp]);
|
||||
return buf;
|
||||
} else
|
||||
@@ -107,7 +108,7 @@ char *formatName(int subsamp, int cs, char *buf)
|
||||
}
|
||||
|
||||
|
||||
char *sigfig(double val, int figs, char *buf, int len)
|
||||
static char *sigfig(double val, int figs, char *buf, int len)
|
||||
{
|
||||
char format[80];
|
||||
int digitsAfterDecimal = figs - (int)ceil(log10(fabs(val)));
|
||||
@@ -122,9 +123,9 @@ char *sigfig(double val, int figs, char *buf, int len)
|
||||
|
||||
|
||||
/* Custom DCT filter which produces a negative of the image */
|
||||
int dummyDCTFilter(short *coeffs, tjregion arrayRegion, tjregion planeRegion,
|
||||
int componentIndex, int transformIndex,
|
||||
tjtransform *transform)
|
||||
static int dummyDCTFilter(short *coeffs, tjregion arrayRegion,
|
||||
tjregion planeRegion, int componentIndex,
|
||||
int transformIndex, tjtransform *transform)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -135,11 +136,12 @@ int dummyDCTFilter(short *coeffs, tjregion arrayRegion, tjregion planeRegion,
|
||||
|
||||
|
||||
/* Decompression test */
|
||||
int decomp(unsigned char *srcBuf, unsigned char **jpegBuf,
|
||||
unsigned long *jpegSize, unsigned char *dstBuf, int w, int h,
|
||||
int subsamp, int jpegQual, char *fileName, int tilew, int tileh)
|
||||
static int decomp(unsigned char *srcBuf, unsigned char **jpegBuf,
|
||||
unsigned long *jpegSize, unsigned char *dstBuf, int w, int h,
|
||||
int subsamp, int jpegQual, char *fileName, int tilew,
|
||||
int tileh)
|
||||
{
|
||||
char tempStr[1024], sizeStr[20] = "\0", qualStr[6] = "\0", *ptr;
|
||||
char tempStr[1024], sizeStr[24] = "\0", qualStr[13] = "\0", *ptr;
|
||||
FILE *file = NULL;
|
||||
tjhandle handle = NULL;
|
||||
int row, col, iter = 0, dstBufAlloc = 0, retval = 0;
|
||||
@@ -152,16 +154,19 @@ int decomp(unsigned char *srcBuf, unsigned char **jpegBuf,
|
||||
unsigned char *dstPtr, *dstPtr2, *yuvBuf = NULL;
|
||||
|
||||
if (jpegQual > 0) {
|
||||
snprintf(qualStr, 6, "_Q%d", jpegQual);
|
||||
qualStr[5] = 0;
|
||||
snprintf(qualStr, 13, "_Q%d", jpegQual);
|
||||
qualStr[12] = 0;
|
||||
}
|
||||
|
||||
if ((handle = tjInitDecompress()) == NULL)
|
||||
_throwtj("executing tjInitDecompress()");
|
||||
THROW_TJ("executing tjInitDecompress()");
|
||||
|
||||
if (dstBuf == NULL) {
|
||||
if ((dstBuf = (unsigned char *)malloc(pitch * scaledh)) == NULL)
|
||||
_throwunix("allocating destination buffer");
|
||||
if ((unsigned long long)pitch * (unsigned long long)scaledh >
|
||||
(unsigned long long)((size_t)-1))
|
||||
THROW("allocating destination buffer", "Image is too large");
|
||||
if ((dstBuf = (unsigned char *)malloc((size_t)pitch * scaledh)) == NULL)
|
||||
THROW_UNIX("allocating destination buffer");
|
||||
dstBufAlloc = 1;
|
||||
}
|
||||
/* Set the destination buffer to gray so we know whether the decompressor
|
||||
@@ -171,10 +176,12 @@ int decomp(unsigned char *srcBuf, unsigned char **jpegBuf,
|
||||
if (doYUV) {
|
||||
int width = doTile ? tilew : scaledw;
|
||||
int height = doTile ? tileh : scaledh;
|
||||
int yuvSize = tjBufSizeYUV2(width, yuvPad, height, subsamp);
|
||||
unsigned long yuvSize = tjBufSizeYUV2(width, yuvPad, height, subsamp);
|
||||
|
||||
if (yuvSize == (unsigned long)-1)
|
||||
THROW_TJ("allocating YUV buffer");
|
||||
if ((yuvBuf = (unsigned char *)malloc(yuvSize)) == NULL)
|
||||
_throwunix("allocating YUV buffer");
|
||||
THROW_UNIX("allocating YUV buffer");
|
||||
memset(yuvBuf, 127, yuvSize);
|
||||
}
|
||||
|
||||
@@ -197,16 +204,16 @@ int decomp(unsigned char *srcBuf, unsigned char **jpegBuf,
|
||||
|
||||
if (tjDecompressToYUV2(handle, jpegBuf[tile], jpegSize[tile], yuvBuf,
|
||||
width, yuvPad, height, flags) == -1)
|
||||
_throwtj("executing tjDecompressToYUV2()");
|
||||
THROW_TJ("executing tjDecompressToYUV2()");
|
||||
startDecode = getTime();
|
||||
if (tjDecodeYUV(handle, yuvBuf, yuvPad, subsamp, dstPtr2, width,
|
||||
pitch, height, pf, flags) == -1)
|
||||
_throwtj("executing tjDecodeYUV()");
|
||||
THROW_TJ("executing tjDecodeYUV()");
|
||||
if (iter >= 0) elapsedDecode += getTime() - startDecode;
|
||||
} else if (tjDecompress2(handle, jpegBuf[tile], jpegSize[tile],
|
||||
dstPtr2, width, pitch, height, pf,
|
||||
flags) == -1)
|
||||
_throwtj("executing tjDecompress2()");
|
||||
THROW_TJ("executing tjDecompress2()");
|
||||
}
|
||||
}
|
||||
elapsed += getTime() - start;
|
||||
@@ -220,7 +227,7 @@ int decomp(unsigned char *srcBuf, unsigned char **jpegBuf,
|
||||
}
|
||||
if (doYUV) elapsed -= elapsedDecode;
|
||||
|
||||
if (tjDestroy(handle) == -1) _throwtj("executing tjDestroy()");
|
||||
if (tjDestroy(handle) == -1) THROW_TJ("executing tjDestroy()");
|
||||
handle = NULL;
|
||||
|
||||
if (quiet) {
|
||||
@@ -249,10 +256,10 @@ int decomp(unsigned char *srcBuf, unsigned char **jpegBuf,
|
||||
if (!doWrite) goto bailout;
|
||||
|
||||
if (sf.num != 1 || sf.denom != 1)
|
||||
snprintf(sizeStr, 20, "%d_%d", sf.num, sf.denom);
|
||||
snprintf(sizeStr, 24, "%d_%d", sf.num, sf.denom);
|
||||
else if (tilew != w || tileh != h)
|
||||
snprintf(sizeStr, 20, "%dx%d", tilew, tileh);
|
||||
else snprintf(sizeStr, 20, "full");
|
||||
snprintf(sizeStr, 24, "%dx%d", tilew, tileh);
|
||||
else snprintf(sizeStr, 24, "full");
|
||||
if (decompOnly)
|
||||
snprintf(tempStr, 1024, "%s_%s.%s", fileName, sizeStr, ext);
|
||||
else
|
||||
@@ -260,19 +267,19 @@ int decomp(unsigned char *srcBuf, unsigned char **jpegBuf,
|
||||
qualStr, sizeStr, ext);
|
||||
|
||||
if (tjSaveImage(tempStr, dstBuf, scaledw, 0, scaledh, pf, flags) == -1)
|
||||
_throwtjg("saving bitmap");
|
||||
THROW_TJG("saving bitmap");
|
||||
ptr = strrchr(tempStr, '.');
|
||||
snprintf(ptr, 1024 - (ptr - tempStr), "-err.%s", ext);
|
||||
if (srcBuf && sf.num == 1 && sf.denom == 1) {
|
||||
if (!quiet) printf("Compression error written to %s.\n", tempStr);
|
||||
if (subsamp == TJ_GRAYSCALE) {
|
||||
int index, index2;
|
||||
unsigned long index, index2;
|
||||
|
||||
for (row = 0, index = 0; row < h; row++, index += pitch) {
|
||||
for (col = 0, index2 = index; col < w; col++, index2 += ps) {
|
||||
int rindex = index2 + tjRedOffset[pf];
|
||||
int gindex = index2 + tjGreenOffset[pf];
|
||||
int bindex = index2 + tjBlueOffset[pf];
|
||||
unsigned long rindex = index2 + tjRedOffset[pf];
|
||||
unsigned long gindex = index2 + tjGreenOffset[pf];
|
||||
unsigned long bindex = index2 + tjBlueOffset[pf];
|
||||
int y = (int)((double)srcBuf[rindex] * 0.299 +
|
||||
(double)srcBuf[gindex] * 0.587 +
|
||||
(double)srcBuf[bindex] * 0.114 + 0.5);
|
||||
@@ -291,7 +298,7 @@ int decomp(unsigned char *srcBuf, unsigned char **jpegBuf,
|
||||
abs(dstBuf[pitch * row + col] - srcBuf[pitch * row + col]);
|
||||
}
|
||||
if (tjSaveImage(tempStr, dstBuf, w, 0, h, pf, flags) == -1)
|
||||
_throwtjg("saving bitmap");
|
||||
THROW_TJG("saving bitmap");
|
||||
}
|
||||
|
||||
bailout:
|
||||
@@ -303,8 +310,8 @@ bailout:
|
||||
}
|
||||
|
||||
|
||||
int fullTest(unsigned char *srcBuf, int w, int h, int subsamp, int jpegQual,
|
||||
char *fileName)
|
||||
static int fullTest(unsigned char *srcBuf, int w, int h, int subsamp,
|
||||
int jpegQual, char *fileName)
|
||||
{
|
||||
char tempStr[1024], tempStr2[80];
|
||||
FILE *file = NULL;
|
||||
@@ -313,14 +320,17 @@ int fullTest(unsigned char *srcBuf, int w, int h, int subsamp, int jpegQual,
|
||||
*srcPtr2;
|
||||
double start, elapsed, elapsedEncode;
|
||||
int totalJpegSize = 0, row, col, i, tilew = w, tileh = h, retval = 0;
|
||||
int iter, yuvSize = 0;
|
||||
unsigned long *jpegSize = NULL;
|
||||
int iter;
|
||||
unsigned long *jpegSize = NULL, yuvSize = 0;
|
||||
int ps = tjPixelSize[pf];
|
||||
int ntilesw = 1, ntilesh = 1, pitch = w * ps;
|
||||
const char *pfStr = pixFormatStr[pf];
|
||||
|
||||
if ((tmpBuf = (unsigned char *)malloc(pitch * h)) == NULL)
|
||||
_throwunix("allocating temporary image buffer");
|
||||
if ((unsigned long long)pitch * (unsigned long long)h >
|
||||
(unsigned long long)((size_t)-1))
|
||||
THROW("allocating temporary image buffer", "Image is too large");
|
||||
if ((tmpBuf = (unsigned char *)malloc((size_t)pitch * h)) == NULL)
|
||||
THROW_UNIX("allocating temporary image buffer");
|
||||
|
||||
if (!quiet)
|
||||
printf(">>>>> %s (%s) <--> JPEG %s Q%d <<<<<\n", pfStr,
|
||||
@@ -336,18 +346,20 @@ int fullTest(unsigned char *srcBuf, int w, int h, int subsamp, int jpegQual,
|
||||
|
||||
if ((jpegBuf = (unsigned char **)malloc(sizeof(unsigned char *) *
|
||||
ntilesw * ntilesh)) == NULL)
|
||||
_throwunix("allocating JPEG tile array");
|
||||
THROW_UNIX("allocating JPEG tile array");
|
||||
memset(jpegBuf, 0, sizeof(unsigned char *) * ntilesw * ntilesh);
|
||||
if ((jpegSize = (unsigned long *)malloc(sizeof(unsigned long) *
|
||||
ntilesw * ntilesh)) == NULL)
|
||||
_throwunix("allocating JPEG size array");
|
||||
THROW_UNIX("allocating JPEG size array");
|
||||
memset(jpegSize, 0, sizeof(unsigned long) * ntilesw * ntilesh);
|
||||
|
||||
if ((flags & TJFLAG_NOREALLOC) != 0)
|
||||
for (i = 0; i < ntilesw * ntilesh; i++) {
|
||||
if (tjBufSize(tilew, tileh, subsamp) > (unsigned long)INT_MAX)
|
||||
THROW("getting buffer size", "Image is too large");
|
||||
if ((jpegBuf[i] = (unsigned char *)
|
||||
tjAlloc(tjBufSize(tilew, tileh, subsamp))) == NULL)
|
||||
_throwunix("allocating JPEG tiles");
|
||||
THROW_UNIX("allocating JPEG tiles");
|
||||
}
|
||||
|
||||
/* Compression test */
|
||||
@@ -358,12 +370,14 @@ int fullTest(unsigned char *srcBuf, int w, int h, int subsamp, int jpegQual,
|
||||
for (i = 0; i < h; i++)
|
||||
memcpy(&tmpBuf[pitch * i], &srcBuf[w * ps * i], w * ps);
|
||||
if ((handle = tjInitCompress()) == NULL)
|
||||
_throwtj("executing tjInitCompress()");
|
||||
THROW_TJ("executing tjInitCompress()");
|
||||
|
||||
if (doYUV) {
|
||||
yuvSize = tjBufSizeYUV2(tilew, yuvPad, tileh, subsamp);
|
||||
if (yuvSize == (unsigned long)-1)
|
||||
THROW_TJ("allocating YUV buffer");
|
||||
if ((yuvBuf = (unsigned char *)malloc(yuvSize)) == NULL)
|
||||
_throwunix("allocating YUV buffer");
|
||||
THROW_UNIX("allocating YUV buffer");
|
||||
memset(yuvBuf, 127, yuvSize);
|
||||
}
|
||||
|
||||
@@ -387,17 +401,17 @@ int fullTest(unsigned char *srcBuf, int w, int h, int subsamp, int jpegQual,
|
||||
|
||||
if (tjEncodeYUV3(handle, srcPtr2, width, pitch, height, pf, yuvBuf,
|
||||
yuvPad, subsamp, flags) == -1)
|
||||
_throwtj("executing tjEncodeYUV3()");
|
||||
THROW_TJ("executing tjEncodeYUV3()");
|
||||
if (iter >= 0) elapsedEncode += getTime() - startEncode;
|
||||
if (tjCompressFromYUV(handle, yuvBuf, width, yuvPad, height,
|
||||
subsamp, &jpegBuf[tile], &jpegSize[tile],
|
||||
jpegQual, flags) == -1)
|
||||
_throwtj("executing tjCompressFromYUV()");
|
||||
THROW_TJ("executing tjCompressFromYUV()");
|
||||
} else {
|
||||
if (tjCompress2(handle, srcPtr2, width, pitch, height, pf,
|
||||
&jpegBuf[tile], &jpegSize[tile], subsamp, jpegQual,
|
||||
flags) == -1)
|
||||
_throwtj("executing tjCompress2()");
|
||||
THROW_TJ("executing tjCompress2()");
|
||||
}
|
||||
totalJpegSize += jpegSize[tile];
|
||||
}
|
||||
@@ -413,7 +427,7 @@ int fullTest(unsigned char *srcBuf, int w, int h, int subsamp, int jpegQual,
|
||||
}
|
||||
if (doYUV) elapsed -= elapsedEncode;
|
||||
|
||||
if (tjDestroy(handle) == -1) _throwtj("executing tjDestroy()");
|
||||
if (tjDestroy(handle) == -1) THROW_TJ("executing tjDestroy()");
|
||||
handle = NULL;
|
||||
|
||||
if (quiet == 1) printf("%-5d %-5d ", tilew, tileh);
|
||||
@@ -436,7 +450,7 @@ int fullTest(unsigned char *srcBuf, int w, int h, int subsamp, int jpegQual,
|
||||
if (doYUV) {
|
||||
printf("Encode YUV --> Frame rate: %f fps\n",
|
||||
(double)iter / elapsedEncode);
|
||||
printf(" Output image size: %d bytes\n", yuvSize);
|
||||
printf(" Output image size: %lu bytes\n", yuvSize);
|
||||
printf(" Compression ratio: %f:1\n",
|
||||
(double)(w * h * ps) / (double)yuvSize);
|
||||
printf(" Throughput: %f Megapixels/sec\n",
|
||||
@@ -460,9 +474,9 @@ int fullTest(unsigned char *srcBuf, int w, int h, int subsamp, int jpegQual,
|
||||
snprintf(tempStr, 1024, "%s_%s_Q%d.jpg", fileName, subName[subsamp],
|
||||
jpegQual);
|
||||
if ((file = fopen(tempStr, "wb")) == NULL)
|
||||
_throwunix("opening reference image");
|
||||
THROW_UNIX("opening reference image");
|
||||
if (fwrite(jpegBuf[0], jpegSize[0], 1, file) != 1)
|
||||
_throwunix("writing reference image");
|
||||
THROW_UNIX("writing reference image");
|
||||
fclose(file); file = NULL;
|
||||
if (!quiet) printf("Reference image written to %s\n", tempStr);
|
||||
}
|
||||
@@ -504,41 +518,45 @@ bailout:
|
||||
}
|
||||
|
||||
|
||||
int decompTest(char *fileName)
|
||||
static int decompTest(char *fileName)
|
||||
{
|
||||
FILE *file = NULL;
|
||||
tjhandle handle = NULL;
|
||||
unsigned char **jpegBuf = NULL, *srcBuf = NULL;
|
||||
unsigned long *jpegSize = NULL, srcSize, totalJpegSize;
|
||||
tjtransform *t = NULL;
|
||||
int w = 0, h = 0, subsamp = -1, cs = -1, _w, _h, _tilew, _tileh, _ntilesw,
|
||||
_ntilesh, _subsamp;
|
||||
char *temp = NULL, tempStr[80], tempStr2[80];
|
||||
int row, col, i, iter, tilew, tileh, ntilesw = 1, ntilesh = 1, retval = 0;
|
||||
double start, elapsed;
|
||||
int ps = tjPixelSize[pf], tile, decompsrc = 0;
|
||||
int ps = tjPixelSize[pf], tile, row, col, i, iter, retval = 0, decompsrc = 0;
|
||||
char *temp = NULL, tempStr[80], tempStr2[80];
|
||||
/* Original image */
|
||||
int w = 0, h = 0, tilew, tileh, ntilesw = 1, ntilesh = 1, subsamp = -1,
|
||||
cs = -1;
|
||||
/* Transformed image */
|
||||
int tw, th, ttilew, ttileh, tntilesw, tntilesh, tsubsamp;
|
||||
|
||||
if ((file = fopen(fileName, "rb")) == NULL)
|
||||
_throwunix("opening file");
|
||||
THROW_UNIX("opening file");
|
||||
if (fseek(file, 0, SEEK_END) < 0 ||
|
||||
(srcSize = ftell(file)) == (unsigned long)-1)
|
||||
_throwunix("determining file size");
|
||||
THROW_UNIX("determining file size");
|
||||
if ((srcBuf = (unsigned char *)malloc(srcSize)) == NULL)
|
||||
_throwunix("allocating memory");
|
||||
THROW_UNIX("allocating memory");
|
||||
if (fseek(file, 0, SEEK_SET) < 0)
|
||||
_throwunix("setting file position");
|
||||
THROW_UNIX("setting file position");
|
||||
if (fread(srcBuf, srcSize, 1, file) < 1)
|
||||
_throwunix("reading JPEG data");
|
||||
THROW_UNIX("reading JPEG data");
|
||||
fclose(file); file = NULL;
|
||||
|
||||
temp = strrchr(fileName, '.');
|
||||
if (temp != NULL) *temp = '\0';
|
||||
|
||||
if ((handle = tjInitTransform()) == NULL)
|
||||
_throwtj("executing tjInitTransform()");
|
||||
THROW_TJ("executing tjInitTransform()");
|
||||
if (tjDecompressHeader3(handle, srcBuf, srcSize, &w, &h, &subsamp,
|
||||
&cs) == -1)
|
||||
_throwtj("executing tjDecompressHeader3()");
|
||||
THROW_TJ("executing tjDecompressHeader3()");
|
||||
if (w < 1 || h < 1)
|
||||
THROW("reading JPEG header", "Invalid image dimensions");
|
||||
if (cs == TJCS_YCCK || cs == TJCS_CMYK) {
|
||||
pf = TJPF_CMYK; ps = tjPixelSize[pf];
|
||||
}
|
||||
@@ -566,25 +584,28 @@ int decompTest(char *fileName)
|
||||
|
||||
if ((jpegBuf = (unsigned char **)malloc(sizeof(unsigned char *) *
|
||||
ntilesw * ntilesh)) == NULL)
|
||||
_throwunix("allocating JPEG tile array");
|
||||
THROW_UNIX("allocating JPEG tile array");
|
||||
memset(jpegBuf, 0, sizeof(unsigned char *) * ntilesw * ntilesh);
|
||||
if ((jpegSize = (unsigned long *)malloc(sizeof(unsigned long) *
|
||||
ntilesw * ntilesh)) == NULL)
|
||||
_throwunix("allocating JPEG size array");
|
||||
THROW_UNIX("allocating JPEG size array");
|
||||
memset(jpegSize, 0, sizeof(unsigned long) * ntilesw * ntilesh);
|
||||
|
||||
if ((flags & TJFLAG_NOREALLOC) != 0 || !doTile)
|
||||
if ((flags & TJFLAG_NOREALLOC) != 0 &&
|
||||
(doTile || xformOp != TJXOP_NONE || xformOpt != 0 || customFilter))
|
||||
for (i = 0; i < ntilesw * ntilesh; i++) {
|
||||
if (tjBufSize(tilew, tileh, subsamp) > (unsigned long)INT_MAX)
|
||||
THROW("getting buffer size", "Image is too large");
|
||||
if ((jpegBuf[i] = (unsigned char *)
|
||||
tjAlloc(tjBufSize(tilew, tileh, subsamp))) == NULL)
|
||||
_throwunix("allocating JPEG tiles");
|
||||
THROW_UNIX("allocating JPEG tiles");
|
||||
}
|
||||
|
||||
_w = w; _h = h; _tilew = tilew; _tileh = tileh;
|
||||
tw = w; th = h; ttilew = tilew; ttileh = tileh;
|
||||
if (!quiet) {
|
||||
printf("\n%s size: %d x %d", doTile ? "Tile" : "Image", _tilew, _tileh);
|
||||
printf("\n%s size: %d x %d", doTile ? "Tile" : "Image", ttilew, ttileh);
|
||||
if (sf.num != 1 || sf.denom != 1)
|
||||
printf(" --> %d x %d", TJSCALED(_w, sf), TJSCALED(_h, sf));
|
||||
printf(" --> %d x %d", TJSCALED(tw, sf), TJSCALED(th, sf));
|
||||
printf("\n");
|
||||
} else if (quiet == 1) {
|
||||
printf("%-4s (%s) %-5s %-5s ", pixFormatStr[pf],
|
||||
@@ -593,41 +614,41 @@ int decompTest(char *fileName)
|
||||
printf("%-5d %-5d ", tilew, tileh);
|
||||
}
|
||||
|
||||
_subsamp = subsamp;
|
||||
tsubsamp = subsamp;
|
||||
if (doTile || xformOp != TJXOP_NONE || xformOpt != 0 || customFilter) {
|
||||
if ((t = (tjtransform *)malloc(sizeof(tjtransform) * ntilesw *
|
||||
ntilesh)) == NULL)
|
||||
_throwunix("allocating image transform array");
|
||||
THROW_UNIX("allocating image transform array");
|
||||
|
||||
if (xformOp == TJXOP_TRANSPOSE || xformOp == TJXOP_TRANSVERSE ||
|
||||
xformOp == TJXOP_ROT90 || xformOp == TJXOP_ROT270) {
|
||||
_w = h; _h = w; _tilew = tileh; _tileh = tilew;
|
||||
tw = h; th = w; ttilew = tileh; ttileh = tilew;
|
||||
}
|
||||
|
||||
if (xformOpt & TJXOPT_GRAY) _subsamp = TJ_GRAYSCALE;
|
||||
if (xformOpt & TJXOPT_GRAY) tsubsamp = TJ_GRAYSCALE;
|
||||
if (xformOp == TJXOP_HFLIP || xformOp == TJXOP_ROT180)
|
||||
_w = _w - (_w % tjMCUWidth[_subsamp]);
|
||||
tw = tw - (tw % tjMCUWidth[tsubsamp]);
|
||||
if (xformOp == TJXOP_VFLIP || xformOp == TJXOP_ROT180)
|
||||
_h = _h - (_h % tjMCUHeight[_subsamp]);
|
||||
th = th - (th % tjMCUHeight[tsubsamp]);
|
||||
if (xformOp == TJXOP_TRANSVERSE || xformOp == TJXOP_ROT90)
|
||||
_w = _w - (_w % tjMCUHeight[_subsamp]);
|
||||
tw = tw - (tw % tjMCUHeight[tsubsamp]);
|
||||
if (xformOp == TJXOP_TRANSVERSE || xformOp == TJXOP_ROT270)
|
||||
_h = _h - (_h % tjMCUWidth[_subsamp]);
|
||||
_ntilesw = (_w + _tilew - 1) / _tilew;
|
||||
_ntilesh = (_h + _tileh - 1) / _tileh;
|
||||
th = th - (th % tjMCUWidth[tsubsamp]);
|
||||
tntilesw = (tw + ttilew - 1) / ttilew;
|
||||
tntilesh = (th + ttileh - 1) / ttileh;
|
||||
|
||||
if (xformOp == TJXOP_TRANSPOSE || xformOp == TJXOP_TRANSVERSE ||
|
||||
xformOp == TJXOP_ROT90 || xformOp == TJXOP_ROT270) {
|
||||
if (_subsamp == TJSAMP_422) _subsamp = TJSAMP_440;
|
||||
else if (_subsamp == TJSAMP_440) _subsamp = TJSAMP_422;
|
||||
if (tsubsamp == TJSAMP_422) tsubsamp = TJSAMP_440;
|
||||
else if (tsubsamp == TJSAMP_440) tsubsamp = TJSAMP_422;
|
||||
}
|
||||
|
||||
for (row = 0, tile = 0; row < _ntilesh; row++) {
|
||||
for (col = 0; col < _ntilesw; col++, tile++) {
|
||||
t[tile].r.w = min(_tilew, _w - col * _tilew);
|
||||
t[tile].r.h = min(_tileh, _h - row * _tileh);
|
||||
t[tile].r.x = col * _tilew;
|
||||
t[tile].r.y = row * _tileh;
|
||||
for (row = 0, tile = 0; row < tntilesh; row++) {
|
||||
for (col = 0; col < tntilesw; col++, tile++) {
|
||||
t[tile].r.w = min(ttilew, tw - col * ttilew);
|
||||
t[tile].r.h = min(ttileh, th - row * ttileh);
|
||||
t[tile].r.x = col * ttilew;
|
||||
t[tile].r.y = row * ttileh;
|
||||
t[tile].op = xformOp;
|
||||
t[tile].options = xformOpt | TJXOPT_TRIM;
|
||||
t[tile].customFilter = customFilter;
|
||||
@@ -641,9 +662,9 @@ int decompTest(char *fileName)
|
||||
elapsed = 0.;
|
||||
while (1) {
|
||||
start = getTime();
|
||||
if (tjTransform(handle, srcBuf, srcSize, _ntilesw * _ntilesh, jpegBuf,
|
||||
if (tjTransform(handle, srcBuf, srcSize, tntilesw * tntilesh, jpegBuf,
|
||||
jpegSize, t, flags) == -1)
|
||||
_throwtj("executing tjTransform()");
|
||||
THROW_TJ("executing tjTransform()");
|
||||
elapsed += getTime() - start;
|
||||
if (iter >= 0) {
|
||||
iter++;
|
||||
@@ -656,7 +677,7 @@ int decompTest(char *fileName)
|
||||
|
||||
free(t); t = NULL;
|
||||
|
||||
for (tile = 0, totalJpegSize = 0; tile < _ntilesw * _ntilesh; tile++)
|
||||
for (tile = 0, totalJpegSize = 0; tile < tntilesw * tntilesh; tile++)
|
||||
totalJpegSize += jpegSize[tile];
|
||||
|
||||
if (quiet) {
|
||||
@@ -680,22 +701,23 @@ int decompTest(char *fileName)
|
||||
}
|
||||
} else {
|
||||
if (quiet == 1) printf("N/A N/A ");
|
||||
tjFree(jpegBuf[0]);
|
||||
if (jpegBuf[0]) tjFree(jpegBuf[0]);
|
||||
jpegBuf[0] = NULL;
|
||||
decompsrc = 1;
|
||||
}
|
||||
|
||||
if (w == tilew) _tilew = _w;
|
||||
if (h == tileh) _tileh = _h;
|
||||
if (w == tilew) ttilew = tw;
|
||||
if (h == tileh) ttileh = th;
|
||||
if (!(xformOpt & TJXOPT_NOOUTPUT)) {
|
||||
if (decomp(NULL, decompsrc ? &srcBuf : jpegBuf,
|
||||
decompsrc ? &srcSize : jpegSize, NULL, _w, _h, _subsamp, 0,
|
||||
fileName, _tilew, _tileh) == -1)
|
||||
decompsrc ? &srcSize : jpegSize, NULL, tw, th, tsubsamp, 0,
|
||||
fileName, ttilew, ttileh) == -1)
|
||||
goto bailout;
|
||||
} else if (quiet == 1) printf("N/A\n");
|
||||
|
||||
for (i = 0; i < ntilesw * ntilesh; i++) {
|
||||
tjFree(jpegBuf[i]); jpegBuf[i] = NULL;
|
||||
if (jpegBuf[i]) tjFree(jpegBuf[i]);
|
||||
jpegBuf[i] = NULL;
|
||||
}
|
||||
free(jpegBuf); jpegBuf = NULL;
|
||||
if (jpegSize) { free(jpegSize); jpegSize = NULL; }
|
||||
@@ -720,7 +742,7 @@ bailout:
|
||||
}
|
||||
|
||||
|
||||
void usage(char *progName)
|
||||
static void usage(char *progName)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -799,7 +821,7 @@ int main(int argc, char *argv[])
|
||||
int minArg = 2, retval = 0, subsamp = -1;
|
||||
|
||||
if ((scalingFactors = tjGetScalingFactors(&nsf)) == NULL || nsf == 0)
|
||||
_throw("executing tjGetScalingFactors()", tjGetErrorStr());
|
||||
THROW("executing tjGetScalingFactors()", tjGetErrorStr());
|
||||
|
||||
if (argc < minArg) usage(argv[0]);
|
||||
|
||||
@@ -898,14 +920,14 @@ int main(int argc, char *argv[])
|
||||
else if (!strcasecmp(argv[i], "-copynone"))
|
||||
xformOpt |= TJXOPT_COPYNONE;
|
||||
else if (!strcasecmp(argv[i], "-benchtime") && i < argc - 1) {
|
||||
double temp = atof(argv[++i]);
|
||||
double tempd = atof(argv[++i]);
|
||||
|
||||
if (temp > 0.0) benchTime = temp;
|
||||
if (tempd > 0.0) benchTime = tempd;
|
||||
else usage(argv[0]);
|
||||
} else if (!strcasecmp(argv[i], "-warmup") && i < argc - 1) {
|
||||
double temp = atof(argv[++i]);
|
||||
double tempd = atof(argv[++i]);
|
||||
|
||||
if (temp >= 0.0) warmup = temp;
|
||||
if (tempd >= 0.0) warmup = tempd;
|
||||
else usage(argv[0]);
|
||||
printf("Warmup time = %.1f seconds\n\n", warmup);
|
||||
} else if (!strcasecmp(argv[i], "-alloc"))
|
||||
@@ -916,16 +938,16 @@ int main(int argc, char *argv[])
|
||||
printf("Testing YUV planar encoding/decoding\n\n");
|
||||
doYUV = 1;
|
||||
} else if (!strcasecmp(argv[i], "-yuvpad") && i < argc - 1) {
|
||||
int temp = atoi(argv[++i]);
|
||||
int tempi = atoi(argv[++i]);
|
||||
|
||||
if (temp >= 1) yuvPad = temp;
|
||||
if (tempi >= 1) yuvPad = tempi;
|
||||
} else if (!strcasecmp(argv[i], "-subsamp") && i < argc - 1) {
|
||||
i++;
|
||||
if (toupper(argv[i][0]) == 'G') subsamp = TJSAMP_GRAY;
|
||||
else {
|
||||
int temp = atoi(argv[i]);
|
||||
int tempi = atoi(argv[i]);
|
||||
|
||||
switch (temp) {
|
||||
switch (tempi) {
|
||||
case 444: subsamp = TJSAMP_444; break;
|
||||
case 422: subsamp = TJSAMP_422; break;
|
||||
case 440: subsamp = TJSAMP_440; break;
|
||||
@@ -957,7 +979,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (!decompOnly) {
|
||||
if ((srcBuf = tjLoadImage(argv[1], &w, 1, &h, &pf, flags)) == NULL)
|
||||
_throwtjg("loading bitmap");
|
||||
THROW_TJG("loading bitmap");
|
||||
temp = strrchr(argv[1], '.');
|
||||
if (temp != NULL) *temp = '\0';
|
||||
}
|
||||
|
||||
61
tjexample.c
61
tjexample.c
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C)2011-2012, 2014-2015, 2017 D. R. Commander.
|
||||
* All Rights Reserved.
|
||||
* Copyright (C)2011-2012, 2014-2015, 2017, 2019 D. R. Commander.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -44,14 +44,14 @@
|
||||
#define strncasecmp strnicmp
|
||||
#endif
|
||||
|
||||
#define _throw(action, message) { \
|
||||
#define THROW(action, message) { \
|
||||
printf("ERROR in line %d while %s:\n%s\n", __LINE__, action, message); \
|
||||
retval = -1; goto bailout; \
|
||||
}
|
||||
|
||||
#define _throwtj(action) _throw(action, tjGetErrorStr2(tjInstance))
|
||||
#define THROW_TJ(action) THROW(action, tjGetErrorStr2(tjInstance))
|
||||
|
||||
#define _throwunix(action) _throw(action, strerror(errno))
|
||||
#define THROW_UNIX(action) THROW(action, strerror(errno))
|
||||
|
||||
#define DEFAULT_SUBSAMP TJSAMP_444
|
||||
#define DEFAULT_QUALITY 95
|
||||
@@ -71,9 +71,9 @@ int numScalingFactors = 0;
|
||||
|
||||
/* DCT filter example. This produces a negative of the image. */
|
||||
|
||||
int customFilter(short *coeffs, tjregion arrayRegion, tjregion planeRegion,
|
||||
int componentIndex, int transformIndex,
|
||||
tjtransform *transform)
|
||||
static int customFilter(short *coeffs, tjregion arrayRegion,
|
||||
tjregion planeRegion, int componentIndex,
|
||||
int transformIndex, tjtransform *transform)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -84,7 +84,7 @@ int customFilter(short *coeffs, tjregion arrayRegion, tjregion planeRegion,
|
||||
}
|
||||
|
||||
|
||||
void usage(char *programName)
|
||||
static void usage(char *programName)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -172,7 +172,7 @@ int main(int argc, char **argv)
|
||||
tjhandle tjInstance = NULL;
|
||||
|
||||
if ((scalingFactors = tjGetScalingFactors(&numScalingFactors)) == NULL)
|
||||
_throwtj("getting scaling factors");
|
||||
THROW_TJ("getting scaling factors");
|
||||
memset(&xform, 0, sizeof(tjtransform));
|
||||
|
||||
if (argc < 3)
|
||||
@@ -266,17 +266,17 @@ int main(int argc, char **argv)
|
||||
|
||||
/* Read the JPEG file into memory. */
|
||||
if ((jpegFile = fopen(argv[1], "rb")) == NULL)
|
||||
_throwunix("opening input file");
|
||||
THROW_UNIX("opening input file");
|
||||
if (fseek(jpegFile, 0, SEEK_END) < 0 || ((size = ftell(jpegFile)) < 0) ||
|
||||
fseek(jpegFile, 0, SEEK_SET) < 0)
|
||||
_throwunix("determining input file size");
|
||||
THROW_UNIX("determining input file size");
|
||||
if (size == 0)
|
||||
_throw("determining input file size", "Input file contains no data");
|
||||
THROW("determining input file size", "Input file contains no data");
|
||||
jpegSize = (unsigned long)size;
|
||||
if ((jpegBuf = (unsigned char *)tjAlloc(jpegSize)) == NULL)
|
||||
_throwunix("allocating JPEG buffer");
|
||||
THROW_UNIX("allocating JPEG buffer");
|
||||
if (fread(jpegBuf, jpegSize, 1, jpegFile) < 1)
|
||||
_throwunix("reading input file");
|
||||
THROW_UNIX("reading input file");
|
||||
fclose(jpegFile); jpegFile = NULL;
|
||||
|
||||
if (doTransform) {
|
||||
@@ -285,22 +285,22 @@ int main(int argc, char **argv)
|
||||
unsigned long dstSize = 0;
|
||||
|
||||
if ((tjInstance = tjInitTransform()) == NULL)
|
||||
_throwtj("initializing transformer");
|
||||
THROW_TJ("initializing transformer");
|
||||
xform.options |= TJXOPT_TRIM;
|
||||
if (tjTransform(tjInstance, jpegBuf, jpegSize, 1, &dstBuf, &dstSize,
|
||||
&xform, flags) < 0)
|
||||
_throwtj("transforming input image");
|
||||
THROW_TJ("transforming input image");
|
||||
tjFree(jpegBuf);
|
||||
jpegBuf = dstBuf;
|
||||
jpegSize = dstSize;
|
||||
} else {
|
||||
if ((tjInstance = tjInitDecompress()) == NULL)
|
||||
_throwtj("initializing decompressor");
|
||||
THROW_TJ("initializing decompressor");
|
||||
}
|
||||
|
||||
if (tjDecompressHeader3(tjInstance, jpegBuf, jpegSize, &width, &height,
|
||||
&inSubsamp, &inColorspace) < 0)
|
||||
_throwtj("reading JPEG header");
|
||||
THROW_TJ("reading JPEG header");
|
||||
|
||||
printf("%s Image: %d x %d pixels, %s subsampling, %s colorspace\n",
|
||||
(doTransform ? "Transformed" : "Input"), width, height,
|
||||
@@ -312,9 +312,9 @@ int main(int argc, char **argv)
|
||||
/* Input image has been transformed, and no re-compression options
|
||||
have been selected. Write the transformed image to disk and exit. */
|
||||
if ((jpegFile = fopen(argv[2], "wb")) == NULL)
|
||||
_throwunix("opening output file");
|
||||
THROW_UNIX("opening output file");
|
||||
if (fwrite(jpegBuf, jpegSize, 1, jpegFile) < 1)
|
||||
_throwunix("writing output file");
|
||||
THROW_UNIX("writing output file");
|
||||
fclose(jpegFile); jpegFile = NULL;
|
||||
goto bailout;
|
||||
}
|
||||
@@ -330,18 +330,18 @@ int main(int argc, char **argv)
|
||||
pixelFormat = TJPF_BGRX;
|
||||
if ((imgBuf = (unsigned char *)tjAlloc(width * height *
|
||||
tjPixelSize[pixelFormat])) == NULL)
|
||||
_throwunix("allocating uncompressed image buffer");
|
||||
THROW_UNIX("allocating uncompressed image buffer");
|
||||
|
||||
if (tjDecompress2(tjInstance, jpegBuf, jpegSize, imgBuf, width, 0, height,
|
||||
pixelFormat, flags) < 0)
|
||||
_throwtj("decompressing JPEG image");
|
||||
THROW_TJ("decompressing JPEG image");
|
||||
tjFree(jpegBuf); jpegBuf = NULL;
|
||||
tjDestroy(tjInstance); tjInstance = NULL;
|
||||
} else {
|
||||
/* Input image is not a JPEG image. Load it into memory. */
|
||||
if ((imgBuf = tjLoadImage(argv[1], &width, 1, &height, &pixelFormat,
|
||||
0)) == NULL)
|
||||
_throwtj("loading input image");
|
||||
THROW_TJ("loading input image");
|
||||
if (outSubsamp < 0) {
|
||||
if (pixelFormat == TJPF_GRAY)
|
||||
outSubsamp = TJSAMP_GRAY;
|
||||
@@ -355,26 +355,27 @@ int main(int argc, char **argv)
|
||||
|
||||
if (!strcasecmp(outFormat, "jpg")) {
|
||||
/* Output image format is JPEG. Compress the uncompressed image. */
|
||||
unsigned char *jpegBuf = NULL; /* Dynamically allocate the JPEG buffer */
|
||||
unsigned long jpegSize = 0;
|
||||
|
||||
jpegBuf = NULL; /* Dynamically allocate the JPEG buffer */
|
||||
|
||||
if (outQual < 0)
|
||||
outQual = DEFAULT_QUALITY;
|
||||
printf(", %s subsampling, quality = %d\n", subsampName[outSubsamp],
|
||||
outQual);
|
||||
|
||||
if ((tjInstance = tjInitCompress()) == NULL)
|
||||
_throwtj("initializing compressor");
|
||||
THROW_TJ("initializing compressor");
|
||||
if (tjCompress2(tjInstance, imgBuf, width, 0, height, pixelFormat,
|
||||
&jpegBuf, &jpegSize, outSubsamp, outQual, flags) < 0)
|
||||
_throwtj("compressing image");
|
||||
THROW_TJ("compressing image");
|
||||
tjDestroy(tjInstance); tjInstance = NULL;
|
||||
|
||||
/* Write the JPEG image to disk. */
|
||||
if ((jpegFile = fopen(argv[2], "wb")) == NULL)
|
||||
_throwunix("opening output file");
|
||||
THROW_UNIX("opening output file");
|
||||
if (fwrite(jpegBuf, jpegSize, 1, jpegFile) < 1)
|
||||
_throwunix("writing output file");
|
||||
THROW_UNIX("writing output file");
|
||||
tjDestroy(tjInstance); tjInstance = NULL;
|
||||
fclose(jpegFile); jpegFile = NULL;
|
||||
tjFree(jpegBuf); jpegBuf = NULL;
|
||||
@@ -383,7 +384,7 @@ int main(int argc, char **argv)
|
||||
directly to disk. */
|
||||
printf("\n");
|
||||
if (tjSaveImage(argv[2], imgBuf, width, 0, height, pixelFormat, 0) < 0)
|
||||
_throwtj("saving output image");
|
||||
THROW_TJ("saving output image");
|
||||
}
|
||||
|
||||
bailout:
|
||||
|
||||
251
tjunittest.c
251
tjunittest.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C)2009-2014, 2017 D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C)2009-2014, 2017-2019 D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -40,13 +40,13 @@
|
||||
#include "cmyk.h"
|
||||
#ifdef _WIN32
|
||||
#include <time.h>
|
||||
#define random() rand()
|
||||
#define random() rand()
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
|
||||
void usage(char *progName)
|
||||
static void usage(char *progName)
|
||||
{
|
||||
printf("\nUSAGE: %s [options]\n\n", progName);
|
||||
printf("Options:\n");
|
||||
@@ -59,16 +59,16 @@ void usage(char *progName)
|
||||
}
|
||||
|
||||
|
||||
#define _throwtj() { \
|
||||
#define THROW_TJ() { \
|
||||
printf("TurboJPEG ERROR:\n%s\n", tjGetErrorStr()); \
|
||||
bailout(); \
|
||||
BAILOUT() \
|
||||
}
|
||||
#define _tj(f) { if ((f) == -1) _throwtj(); }
|
||||
#define _throw(m) { printf("ERROR: %s\n", m); bailout(); }
|
||||
#define _throwmd5(filename, md5sum, ref) { \
|
||||
#define TRY_TJ(f) { if ((f) == -1) THROW_TJ(); }
|
||||
#define THROW(m) { printf("ERROR: %s\n", m); BAILOUT() }
|
||||
#define THROW_MD5(filename, md5sum, ref) { \
|
||||
printf("\n%s has an MD5 sum of %s.\n Should be %s.\n", filename, md5sum, \
|
||||
ref); \
|
||||
bailout(); \
|
||||
BAILOUT() \
|
||||
}
|
||||
|
||||
const char *subNameLong[TJ_NUMSAMP] = {
|
||||
@@ -93,10 +93,10 @@ const int _onlyRGB[] = { TJPF_RGB };
|
||||
int doYUV = 0, alloc = 0, pad = 4;
|
||||
|
||||
int exitStatus = 0;
|
||||
#define bailout() { exitStatus = -1; goto bailout; }
|
||||
#define BAILOUT() { exitStatus = -1; goto bailout; }
|
||||
|
||||
|
||||
void initBuf(unsigned char *buf, int w, int h, int pf, int flags)
|
||||
static void initBuf(unsigned char *buf, int w, int h, int pf, int flags)
|
||||
{
|
||||
int roffset = tjRedOffset[pf];
|
||||
int goffset = tjGreenOffset[pf];
|
||||
@@ -151,7 +151,7 @@ void initBuf(unsigned char *buf, int w, int h, int pf, int flags)
|
||||
}
|
||||
|
||||
|
||||
#define checkval(v, cv) { \
|
||||
#define CHECKVAL(v, cv) { \
|
||||
if (v < cv - 1 || v > cv + 1) { \
|
||||
printf("\nComp. %s at %d,%d should be %d, not %d\n", #v, row, col, cv, \
|
||||
v); \
|
||||
@@ -159,14 +159,14 @@ void initBuf(unsigned char *buf, int w, int h, int pf, int flags)
|
||||
} \
|
||||
}
|
||||
|
||||
#define checkval0(v) { \
|
||||
#define CHECKVAL0(v) { \
|
||||
if (v > 1) { \
|
||||
printf("\nComp. %s at %d,%d should be 0, not %d\n", #v, row, col, v); \
|
||||
retval = 0; exitStatus = -1; goto bailout; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define checkval255(v) { \
|
||||
#define CHECKVAL255(v) { \
|
||||
if (v < 254) { \
|
||||
printf("\nComp. %s at %d,%d should be 255, not %d\n", #v, row, col, v); \
|
||||
retval = 0; exitStatus = -1; goto bailout; \
|
||||
@@ -174,8 +174,8 @@ void initBuf(unsigned char *buf, int w, int h, int pf, int flags)
|
||||
}
|
||||
|
||||
|
||||
int checkBuf(unsigned char *buf, int w, int h, int pf, int subsamp,
|
||||
tjscalingfactor sf, int flags)
|
||||
static int checkBuf(unsigned char *buf, int w, int h, int pf, int subsamp,
|
||||
tjscalingfactor sf, int flags)
|
||||
{
|
||||
int roffset = tjRedOffset[pf];
|
||||
int goffset = tjGreenOffset[pf];
|
||||
@@ -200,13 +200,13 @@ int checkBuf(unsigned char *buf, int w, int h, int pf, int subsamp,
|
||||
y = buf[index * ps + 2];
|
||||
k = buf[index * ps + 3];
|
||||
if (((row / blocksize) + (col / blocksize)) % 2 == 0) {
|
||||
checkval255(c); checkval255(m); checkval255(y);
|
||||
if (row < halfway) checkval255(k)
|
||||
else checkval0(k)
|
||||
CHECKVAL255(c); CHECKVAL255(m); CHECKVAL255(y);
|
||||
if (row < halfway) CHECKVAL255(k)
|
||||
else CHECKVAL0(k)
|
||||
} else {
|
||||
checkval255(c); checkval0(y); checkval255(k);
|
||||
if (row < halfway) checkval0(m)
|
||||
else checkval255(m)
|
||||
CHECKVAL255(c); CHECKVAL0(y); CHECKVAL255(k);
|
||||
if (row < halfway) CHECKVAL0(m)
|
||||
else CHECKVAL255(m)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -225,26 +225,26 @@ int checkBuf(unsigned char *buf, int w, int h, int pf, int subsamp,
|
||||
a = aoffset >= 0 ? buf[index * ps + aoffset] : 0xFF;
|
||||
if (((row / blocksize) + (col / blocksize)) % 2 == 0) {
|
||||
if (row < halfway) {
|
||||
checkval255(r); checkval255(g); checkval255(b);
|
||||
CHECKVAL255(r); CHECKVAL255(g); CHECKVAL255(b);
|
||||
} else {
|
||||
checkval0(r); checkval0(g); checkval0(b);
|
||||
CHECKVAL0(r); CHECKVAL0(g); CHECKVAL0(b);
|
||||
}
|
||||
} else {
|
||||
if (subsamp == TJSAMP_GRAY) {
|
||||
if (row < halfway) {
|
||||
checkval(r, 76); checkval(g, 76); checkval(b, 76);
|
||||
CHECKVAL(r, 76); CHECKVAL(g, 76); CHECKVAL(b, 76);
|
||||
} else {
|
||||
checkval(r, 226); checkval(g, 226); checkval(b, 226);
|
||||
CHECKVAL(r, 226); CHECKVAL(g, 226); CHECKVAL(b, 226);
|
||||
}
|
||||
} else {
|
||||
if (row < halfway) {
|
||||
checkval255(r); checkval0(g); checkval0(b);
|
||||
CHECKVAL255(r); CHECKVAL0(g); CHECKVAL0(b);
|
||||
} else {
|
||||
checkval255(r); checkval255(g); checkval0(b);
|
||||
CHECKVAL255(r); CHECKVAL255(g); CHECKVAL0(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
checkval255(a);
|
||||
CHECKVAL255(a);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,8 +270,8 @@ bailout:
|
||||
|
||||
#define PAD(v, p) ((v + (p) - 1) & (~((p) - 1)))
|
||||
|
||||
int checkBufYUV(unsigned char *buf, int w, int h, int subsamp,
|
||||
tjscalingfactor sf)
|
||||
static int checkBufYUV(unsigned char *buf, int w, int h, int subsamp,
|
||||
tjscalingfactor sf)
|
||||
{
|
||||
int row, col;
|
||||
int hsf = tjMCUWidth[subsamp] / 8, vsf = tjMCUHeight[subsamp] / 8;
|
||||
@@ -287,16 +287,16 @@ int checkBufYUV(unsigned char *buf, int w, int h, int subsamp,
|
||||
unsigned char y = buf[ypitch * row + col];
|
||||
|
||||
if (((row / blocksize) + (col / blocksize)) % 2 == 0) {
|
||||
if (row < halfway) checkval255(y)
|
||||
else checkval0(y);
|
||||
if (row < halfway) CHECKVAL255(y)
|
||||
else CHECKVAL0(y);
|
||||
} else {
|
||||
if (row < halfway) checkval(y, 76)
|
||||
else checkval(y, 226);
|
||||
if (row < halfway) CHECKVAL(y, 76)
|
||||
else CHECKVAL(y, 226);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (subsamp != TJSAMP_GRAY) {
|
||||
int halfway = 16 / vsf * sf.num / sf.denom;
|
||||
halfway = 16 / vsf * sf.num / sf.denom;
|
||||
|
||||
for (row = 0; row < ch; row++) {
|
||||
for (col = 0; col < cw; col++) {
|
||||
@@ -304,12 +304,12 @@ int checkBufYUV(unsigned char *buf, int w, int h, int subsamp,
|
||||
v = buf[ypitch * ph + uvpitch * ch + (uvpitch * row + col)];
|
||||
|
||||
if (((row * vsf / blocksize) + (col * hsf / blocksize)) % 2 == 0) {
|
||||
checkval(u, 128); checkval(v, 128);
|
||||
CHECKVAL(u, 128); CHECKVAL(v, 128);
|
||||
} else {
|
||||
if (row < halfway) {
|
||||
checkval(u, 85); checkval255(v);
|
||||
CHECKVAL(u, 85); CHECKVAL255(v);
|
||||
} else {
|
||||
checkval0(u); checkval(v, 149);
|
||||
CHECKVAL0(u); CHECKVAL(v, 149);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -342,13 +342,14 @@ bailout:
|
||||
}
|
||||
|
||||
|
||||
void writeJPEG(unsigned char *jpegBuf, unsigned long jpegSize, char *filename)
|
||||
static void writeJPEG(unsigned char *jpegBuf, unsigned long jpegSize,
|
||||
char *filename)
|
||||
{
|
||||
FILE *file = fopen(filename, "wb");
|
||||
|
||||
if (!file || fwrite(jpegBuf, jpegSize, 1, file) != 1) {
|
||||
printf("ERROR: Could not write to %s.\n%s\n", filename, strerror(errno));
|
||||
bailout();
|
||||
BAILOUT()
|
||||
}
|
||||
|
||||
bailout:
|
||||
@@ -356,9 +357,9 @@ bailout:
|
||||
}
|
||||
|
||||
|
||||
void compTest(tjhandle handle, unsigned char **dstBuf, unsigned long *dstSize,
|
||||
int w, int h, int pf, char *basename, int subsamp, int jpegQual,
|
||||
int flags)
|
||||
static void compTest(tjhandle handle, unsigned char **dstBuf,
|
||||
unsigned long *dstSize, int w, int h, int pf,
|
||||
char *basename, int subsamp, int jpegQual, int flags)
|
||||
{
|
||||
char tempStr[1024];
|
||||
unsigned char *srcBuf = NULL, *yuvBuf = NULL;
|
||||
@@ -368,7 +369,7 @@ void compTest(tjhandle handle, unsigned char **dstBuf, unsigned long *dstSize,
|
||||
const char *buStr = (flags & TJFLAG_BOTTOMUP) ? "BU" : "TD";
|
||||
|
||||
if ((srcBuf = (unsigned char *)malloc(w * h * tjPixelSize[pf])) == NULL)
|
||||
_throw("Memory allocation failure");
|
||||
THROW("Memory allocation failure");
|
||||
initBuf(srcBuf, w, h, pf, flags);
|
||||
|
||||
if (*dstBuf && *dstSize > 0) memset(*dstBuf, 0, *dstSize);
|
||||
@@ -379,28 +380,28 @@ void compTest(tjhandle handle, unsigned char **dstBuf, unsigned long *dstSize,
|
||||
tjscalingfactor sf = { 1, 1 };
|
||||
tjhandle handle2 = tjInitCompress();
|
||||
|
||||
if (!handle2) _throwtj();
|
||||
if (!handle2) THROW_TJ();
|
||||
|
||||
if ((yuvBuf = (unsigned char *)malloc(yuvSize)) == NULL)
|
||||
_throw("Memory allocation failure");
|
||||
THROW("Memory allocation failure");
|
||||
memset(yuvBuf, 0, yuvSize);
|
||||
|
||||
printf("%s %s -> YUV %s ... ", pfStr, buStrLong, subNameLong[subsamp]);
|
||||
_tj(tjEncodeYUV3(handle2, srcBuf, w, 0, h, pf, yuvBuf, pad, subsamp,
|
||||
flags));
|
||||
TRY_TJ(tjEncodeYUV3(handle2, srcBuf, w, 0, h, pf, yuvBuf, pad, subsamp,
|
||||
flags));
|
||||
tjDestroy(handle2);
|
||||
if (checkBufYUV(yuvBuf, w, h, subsamp, sf)) printf("Passed.\n");
|
||||
else printf("FAILED!\n");
|
||||
|
||||
printf("YUV %s %s -> JPEG Q%d ... ", subNameLong[subsamp], buStrLong,
|
||||
jpegQual);
|
||||
_tj(tjCompressFromYUV(handle, yuvBuf, w, pad, h, subsamp, dstBuf, dstSize,
|
||||
jpegQual, flags));
|
||||
TRY_TJ(tjCompressFromYUV(handle, yuvBuf, w, pad, h, subsamp, dstBuf,
|
||||
dstSize, jpegQual, flags));
|
||||
} else {
|
||||
printf("%s %s -> %s Q%d ... ", pfStr, buStrLong, subNameLong[subsamp],
|
||||
jpegQual);
|
||||
_tj(tjCompress2(handle, srcBuf, w, 0, h, pf, dstBuf, dstSize, subsamp,
|
||||
jpegQual, flags));
|
||||
TRY_TJ(tjCompress2(handle, srcBuf, w, 0, h, pf, dstBuf, dstSize, subsamp,
|
||||
jpegQual, flags));
|
||||
}
|
||||
|
||||
snprintf(tempStr, 1024, "%s_enc_%s_%s_%s_Q%d.jpg", basename, pfStr, buStr,
|
||||
@@ -414,9 +415,10 @@ bailout:
|
||||
}
|
||||
|
||||
|
||||
void _decompTest(tjhandle handle, unsigned char *jpegBuf,
|
||||
unsigned long jpegSize, int w, int h, int pf, char *basename,
|
||||
int subsamp, int flags, tjscalingfactor sf)
|
||||
static void _decompTest(tjhandle handle, unsigned char *jpegBuf,
|
||||
unsigned long jpegSize, int w, int h, int pf,
|
||||
char *basename, int subsamp, int flags,
|
||||
tjscalingfactor sf)
|
||||
{
|
||||
unsigned char *dstBuf = NULL, *yuvBuf = NULL;
|
||||
int _hdrw = 0, _hdrh = 0, _hdrsubsamp = -1;
|
||||
@@ -424,14 +426,14 @@ void _decompTest(tjhandle handle, unsigned char *jpegBuf,
|
||||
int scaledHeight = TJSCALED(h, sf);
|
||||
unsigned long dstSize = 0;
|
||||
|
||||
_tj(tjDecompressHeader2(handle, jpegBuf, jpegSize, &_hdrw, &_hdrh,
|
||||
&_hdrsubsamp));
|
||||
TRY_TJ(tjDecompressHeader2(handle, jpegBuf, jpegSize, &_hdrw, &_hdrh,
|
||||
&_hdrsubsamp));
|
||||
if (_hdrw != w || _hdrh != h || _hdrsubsamp != subsamp)
|
||||
_throw("Incorrect JPEG header");
|
||||
THROW("Incorrect JPEG header");
|
||||
|
||||
dstSize = scaledWidth * scaledHeight * tjPixelSize[pf];
|
||||
if ((dstBuf = (unsigned char *)malloc(dstSize)) == NULL)
|
||||
_throw("Memory allocation failure");
|
||||
THROW("Memory allocation failure");
|
||||
memset(dstBuf, 0, dstSize);
|
||||
|
||||
if (doYUV) {
|
||||
@@ -439,26 +441,26 @@ void _decompTest(tjhandle handle, unsigned char *jpegBuf,
|
||||
subsamp);
|
||||
tjhandle handle2 = tjInitDecompress();
|
||||
|
||||
if (!handle2) _throwtj();
|
||||
if (!handle2) THROW_TJ();
|
||||
|
||||
if ((yuvBuf = (unsigned char *)malloc(yuvSize)) == NULL)
|
||||
_throw("Memory allocation failure");
|
||||
THROW("Memory allocation failure");
|
||||
memset(yuvBuf, 0, yuvSize);
|
||||
|
||||
printf("JPEG -> YUV %s ", subNameLong[subsamp]);
|
||||
if (sf.num != 1 || sf.denom != 1)
|
||||
printf("%d/%d ... ", sf.num, sf.denom);
|
||||
else printf("... ");
|
||||
_tj(tjDecompressToYUV2(handle, jpegBuf, jpegSize, yuvBuf, scaledWidth, pad,
|
||||
scaledHeight, flags));
|
||||
TRY_TJ(tjDecompressToYUV2(handle, jpegBuf, jpegSize, yuvBuf, scaledWidth,
|
||||
pad, scaledHeight, flags));
|
||||
if (checkBufYUV(yuvBuf, scaledWidth, scaledHeight, subsamp, sf))
|
||||
printf("Passed.\n");
|
||||
else printf("FAILED!\n");
|
||||
|
||||
printf("YUV %s -> %s %s ... ", subNameLong[subsamp], pixFormatStr[pf],
|
||||
(flags & TJFLAG_BOTTOMUP) ? "Bottom-Up" : "Top-Down ");
|
||||
_tj(tjDecodeYUV(handle2, yuvBuf, pad, subsamp, dstBuf, scaledWidth, 0,
|
||||
scaledHeight, pf, flags));
|
||||
TRY_TJ(tjDecodeYUV(handle2, yuvBuf, pad, subsamp, dstBuf, scaledWidth, 0,
|
||||
scaledHeight, pf, flags));
|
||||
tjDestroy(handle2);
|
||||
} else {
|
||||
printf("JPEG -> %s %s ", pixFormatStr[pf],
|
||||
@@ -466,8 +468,8 @@ void _decompTest(tjhandle handle, unsigned char *jpegBuf,
|
||||
if (sf.num != 1 || sf.denom != 1)
|
||||
printf("%d/%d ... ", sf.num, sf.denom);
|
||||
else printf("... ");
|
||||
_tj(tjDecompress2(handle, jpegBuf, jpegSize, dstBuf, scaledWidth, 0,
|
||||
scaledHeight, pf, flags));
|
||||
TRY_TJ(tjDecompress2(handle, jpegBuf, jpegSize, dstBuf, scaledWidth, 0,
|
||||
scaledHeight, pf, flags));
|
||||
}
|
||||
|
||||
if (checkBuf(dstBuf, scaledWidth, scaledHeight, pf, subsamp, sf, flags))
|
||||
@@ -481,14 +483,14 @@ bailout:
|
||||
}
|
||||
|
||||
|
||||
void decompTest(tjhandle handle, unsigned char *jpegBuf,
|
||||
unsigned long jpegSize, int w, int h, int pf, char *basename,
|
||||
int subsamp, int flags)
|
||||
static void decompTest(tjhandle handle, unsigned char *jpegBuf,
|
||||
unsigned long jpegSize, int w, int h, int pf,
|
||||
char *basename, int subsamp, int flags)
|
||||
{
|
||||
int i, n = 0;
|
||||
tjscalingfactor *sf = tjGetScalingFactors(&n);
|
||||
|
||||
if (!sf || !n) _throwtj();
|
||||
if (!sf || !n) THROW_TJ();
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (subsamp == TJSAMP_444 || subsamp == TJSAMP_GRAY ||
|
||||
@@ -505,8 +507,8 @@ bailout:
|
||||
}
|
||||
|
||||
|
||||
void doTest(int w, int h, const int *formats, int nformats, int subsamp,
|
||||
char *basename)
|
||||
static void doTest(int w, int h, const int *formats, int nformats, int subsamp,
|
||||
char *basename)
|
||||
{
|
||||
tjhandle chandle = NULL, dhandle = NULL;
|
||||
unsigned char *dstBuf = NULL;
|
||||
@@ -517,11 +519,11 @@ void doTest(int w, int h, const int *formats, int nformats, int subsamp,
|
||||
size = tjBufSize(w, h, subsamp);
|
||||
if (size != 0)
|
||||
if ((dstBuf = (unsigned char *)tjAlloc(size)) == NULL)
|
||||
_throw("Memory allocation failure.");
|
||||
THROW("Memory allocation failure.");
|
||||
|
||||
if ((chandle = tjInitCompress()) == NULL ||
|
||||
(dhandle = tjInitDecompress()) == NULL)
|
||||
_throwtj();
|
||||
THROW_TJ();
|
||||
|
||||
for (pfi = 0; pfi < nformats; pfi++) {
|
||||
for (i = 0; i < 2; i++) {
|
||||
@@ -552,14 +554,50 @@ bailout:
|
||||
}
|
||||
|
||||
|
||||
void bufSizeTest(void)
|
||||
#if SIZEOF_SIZE_T == 8
|
||||
#define CHECKSIZE(function) { \
|
||||
if ((unsigned long long)size < (unsigned long long)0xFFFFFFFF) \
|
||||
THROW(#function " overflow"); \
|
||||
}
|
||||
#else
|
||||
#define CHECKSIZE(function) { \
|
||||
if (size != (unsigned long)(-1) || \
|
||||
!strcmp(tjGetErrorStr2(NULL), "No error")) \
|
||||
THROW(#function " overflow"); \
|
||||
}
|
||||
#endif
|
||||
|
||||
static void overflowTest(void)
|
||||
{
|
||||
/* Ensure that the various buffer size functions don't overflow */
|
||||
unsigned long size;
|
||||
|
||||
size = tjBufSize(26755, 26755, TJSAMP_444);
|
||||
CHECKSIZE(tjBufSize());
|
||||
size = TJBUFSIZE(26755, 26755);
|
||||
CHECKSIZE(TJBUFSIZE());
|
||||
size = tjBufSizeYUV2(37838, 1, 37838, TJSAMP_444);
|
||||
CHECKSIZE(tjBufSizeYUV2());
|
||||
size = TJBUFSIZEYUV(37838, 37838, TJSAMP_444);
|
||||
CHECKSIZE(TJBUFSIZEYUV());
|
||||
size = tjBufSizeYUV(37838, 37838, TJSAMP_444);
|
||||
CHECKSIZE(tjBufSizeYUV());
|
||||
size = tjPlaneSizeYUV(0, 65536, 0, 65536, TJSAMP_444);
|
||||
CHECKSIZE(tjPlaneSizeYUV());
|
||||
|
||||
bailout:
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void bufSizeTest(void)
|
||||
{
|
||||
int w, h, i, subsamp;
|
||||
unsigned char *srcBuf = NULL, *dstBuf = NULL;
|
||||
tjhandle handle = NULL;
|
||||
unsigned long dstSize = 0;
|
||||
|
||||
if ((handle = tjInitCompress()) == NULL) _throwtj();
|
||||
if ((handle = tjInitCompress()) == NULL) THROW_TJ();
|
||||
|
||||
printf("Buffer size regression test\n");
|
||||
for (subsamp = 0; subsamp < TJ_NUMSAMP; subsamp++) {
|
||||
@@ -569,12 +607,12 @@ void bufSizeTest(void)
|
||||
for (h = 1; h < maxh; h++) {
|
||||
if (h % 100 == 0) printf("%.4d x %.4d\b\b\b\b\b\b\b\b\b\b\b", w, h);
|
||||
if ((srcBuf = (unsigned char *)malloc(w * h * 4)) == NULL)
|
||||
_throw("Memory allocation failure");
|
||||
THROW("Memory allocation failure");
|
||||
if (!alloc || doYUV) {
|
||||
if (doYUV) dstSize = tjBufSizeYUV2(w, pad, h, subsamp);
|
||||
else dstSize = tjBufSize(w, h, subsamp);
|
||||
if ((dstBuf = (unsigned char *)tjAlloc(dstSize)) == NULL)
|
||||
_throw("Memory allocation failure");
|
||||
THROW("Memory allocation failure");
|
||||
}
|
||||
|
||||
for (i = 0; i < w * h * 4; i++) {
|
||||
@@ -583,12 +621,12 @@ void bufSizeTest(void)
|
||||
}
|
||||
|
||||
if (doYUV) {
|
||||
_tj(tjEncodeYUV3(handle, srcBuf, w, 0, h, TJPF_BGRX, dstBuf, pad,
|
||||
subsamp, 0));
|
||||
TRY_TJ(tjEncodeYUV3(handle, srcBuf, w, 0, h, TJPF_BGRX, dstBuf, pad,
|
||||
subsamp, 0));
|
||||
} else {
|
||||
_tj(tjCompress2(handle, srcBuf, w, 0, h, TJPF_BGRX, &dstBuf,
|
||||
&dstSize, subsamp, 100,
|
||||
alloc ? 0 : TJFLAG_NOREALLOC));
|
||||
TRY_TJ(tjCompress2(handle, srcBuf, w, 0, h, TJPF_BGRX, &dstBuf,
|
||||
&dstSize, subsamp, 100,
|
||||
alloc ? 0 : TJFLAG_NOREALLOC));
|
||||
}
|
||||
free(srcBuf); srcBuf = NULL;
|
||||
if (!alloc || doYUV) {
|
||||
@@ -596,12 +634,12 @@ void bufSizeTest(void)
|
||||
}
|
||||
|
||||
if ((srcBuf = (unsigned char *)malloc(h * w * 4)) == NULL)
|
||||
_throw("Memory allocation failure");
|
||||
THROW("Memory allocation failure");
|
||||
if (!alloc || doYUV) {
|
||||
if (doYUV) dstSize = tjBufSizeYUV2(h, pad, w, subsamp);
|
||||
else dstSize = tjBufSize(h, w, subsamp);
|
||||
if ((dstBuf = (unsigned char *)tjAlloc(dstSize)) == NULL)
|
||||
_throw("Memory allocation failure");
|
||||
THROW("Memory allocation failure");
|
||||
}
|
||||
|
||||
for (i = 0; i < h * w * 4; i++) {
|
||||
@@ -610,12 +648,12 @@ void bufSizeTest(void)
|
||||
}
|
||||
|
||||
if (doYUV) {
|
||||
_tj(tjEncodeYUV3(handle, srcBuf, h, 0, w, TJPF_BGRX, dstBuf, pad,
|
||||
subsamp, 0));
|
||||
TRY_TJ(tjEncodeYUV3(handle, srcBuf, h, 0, w, TJPF_BGRX, dstBuf, pad,
|
||||
subsamp, 0));
|
||||
} else {
|
||||
_tj(tjCompress2(handle, srcBuf, h, 0, w, TJPF_BGRX, &dstBuf,
|
||||
&dstSize, subsamp, 100,
|
||||
alloc ? 0 : TJFLAG_NOREALLOC));
|
||||
TRY_TJ(tjCompress2(handle, srcBuf, h, 0, w, TJPF_BGRX, &dstBuf,
|
||||
&dstSize, subsamp, 100,
|
||||
alloc ? 0 : TJFLAG_NOREALLOC));
|
||||
}
|
||||
free(srcBuf); srcBuf = NULL;
|
||||
if (!alloc || doYUV) {
|
||||
@@ -633,8 +671,8 @@ bailout:
|
||||
}
|
||||
|
||||
|
||||
void initBitmap(unsigned char *buf, int width, int pitch, int height, int pf,
|
||||
int flags)
|
||||
static void initBitmap(unsigned char *buf, int width, int pitch, int height,
|
||||
int pf, int flags)
|
||||
{
|
||||
int roffset = tjRedOffset[pf];
|
||||
int goffset = tjGreenOffset[pf];
|
||||
@@ -667,8 +705,8 @@ void initBitmap(unsigned char *buf, int width, int pitch, int height, int pf,
|
||||
}
|
||||
|
||||
|
||||
int cmpBitmap(unsigned char *buf, int width, int pitch, int height, int pf,
|
||||
int flags, int gray2rgb)
|
||||
static int cmpBitmap(unsigned char *buf, int width, int pitch, int height,
|
||||
int pf, int flags, int gray2rgb)
|
||||
{
|
||||
int roffset = tjRedOffset[pf];
|
||||
int goffset = tjGreenOffset[pf];
|
||||
@@ -718,8 +756,8 @@ int cmpBitmap(unsigned char *buf, int width, int pitch, int height, int pf,
|
||||
}
|
||||
|
||||
|
||||
int doBmpTest(const char *ext, int width, int align, int height, int pf,
|
||||
int flags)
|
||||
static int doBmpTest(const char *ext, int width, int align, int height, int pf,
|
||||
int flags)
|
||||
{
|
||||
char filename[80], *md5sum, md5buf[65];
|
||||
int ps = tjPixelSize[pf], pitch = PAD(width * ps, align), loadWidth = 0,
|
||||
@@ -736,20 +774,20 @@ int doBmpTest(const char *ext, int width, int align, int height, int pf,
|
||||
}
|
||||
|
||||
if ((buf = (unsigned char *)tjAlloc(pitch * height)) == NULL)
|
||||
_throw("Could not allocate memory");
|
||||
THROW("Could not allocate memory");
|
||||
initBitmap(buf, width, pitch, height, pf, flags);
|
||||
|
||||
snprintf(filename, 80, "test_bmp_%s_%d_%s.%s", pixFormatStr[pf], align,
|
||||
(flags & TJFLAG_BOTTOMUP) ? "bu" : "td", ext);
|
||||
_tj(tjSaveImage(filename, buf, width, pitch, height, pf, flags));
|
||||
TRY_TJ(tjSaveImage(filename, buf, width, pitch, height, pf, flags));
|
||||
md5sum = MD5File(filename, md5buf);
|
||||
if (strcasecmp(md5sum, md5ref))
|
||||
_throwmd5(filename, md5sum, md5ref);
|
||||
THROW_MD5(filename, md5sum, md5ref);
|
||||
|
||||
tjFree(buf); buf = NULL;
|
||||
if ((buf = tjLoadImage(filename, &loadWidth, align, &loadHeight, &pf,
|
||||
flags)) == NULL)
|
||||
_throwtj();
|
||||
THROW_TJ();
|
||||
if (width != loadWidth || height != loadHeight) {
|
||||
printf("\n Image dimensions of %s are bogus\n", filename);
|
||||
retval = -1; goto bailout;
|
||||
@@ -763,7 +801,7 @@ int doBmpTest(const char *ext, int width, int align, int height, int pf,
|
||||
pf = TJPF_XBGR;
|
||||
if ((buf = tjLoadImage(filename, &loadWidth, align, &loadHeight, &pf,
|
||||
flags)) == NULL)
|
||||
_throwtj();
|
||||
THROW_TJ();
|
||||
pitch = PAD(width * tjPixelSize[pf], align);
|
||||
if (!cmpBitmap(buf, width, pitch, height, pf, flags, 1)) {
|
||||
printf("\n Converting %s to RGB failed\n", filename);
|
||||
@@ -774,7 +812,7 @@ int doBmpTest(const char *ext, int width, int align, int height, int pf,
|
||||
pf = TJPF_CMYK;
|
||||
if ((buf = tjLoadImage(filename, &loadWidth, align, &loadHeight, &pf,
|
||||
flags)) == NULL)
|
||||
_throwtj();
|
||||
THROW_TJ();
|
||||
pitch = PAD(width * tjPixelSize[pf], align);
|
||||
if (!cmpBitmap(buf, width, pitch, height, pf, flags, 1)) {
|
||||
printf("\n Converting %s to CMYK failed\n", filename);
|
||||
@@ -788,7 +826,7 @@ int doBmpTest(const char *ext, int width, int align, int height, int pf,
|
||||
pixelFormat = TJPF_UNKNOWN;
|
||||
if ((buf = tjLoadImage(filename, &loadWidth, align, &loadHeight,
|
||||
&pixelFormat, flags)) == NULL)
|
||||
_throwtj();
|
||||
THROW_TJ();
|
||||
if ((pf == TJPF_GRAY && pixelFormat != TJPF_GRAY) ||
|
||||
(pf != TJPF_GRAY && !strcasecmp(ext, "bmp") &&
|
||||
pixelFormat != TJPF_BGR) ||
|
||||
@@ -807,7 +845,7 @@ bailout:
|
||||
}
|
||||
|
||||
|
||||
int bmpTest(void)
|
||||
static int bmpTest(void)
|
||||
{
|
||||
int align, width = 35, height = 39, format;
|
||||
|
||||
@@ -863,6 +901,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
if (alloc) printf("Testing automatic buffer allocation\n");
|
||||
if (doYUV) num4bf = 4;
|
||||
overflowTest();
|
||||
doTest(35, 39, _3byteFormats, 2, TJSAMP_444, "test");
|
||||
doTest(39, 41, _4byteFormats, num4bf, TJSAMP_444, "test");
|
||||
doTest(41, 35, _3byteFormats, 2, TJSAMP_422, "test");
|
||||
|
||||
4
tjutil.c
4
tjutil.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C)2011 D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C)2011, 2019 D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -29,6 +29,7 @@
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
#include "tjutil.h"
|
||||
|
||||
static double getFreq(void)
|
||||
{
|
||||
@@ -56,6 +57,7 @@ double getTime(void)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include "tjutil.h"
|
||||
|
||||
double getTime(void)
|
||||
{
|
||||
|
||||
667
turbojpeg-jni.c
667
turbojpeg-jni.c
File diff suppressed because it is too large
Load Diff
310
turbojpeg.c
310
turbojpeg.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C)2009-2018 D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C)2009-2019 D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -50,7 +50,7 @@ extern void jpeg_mem_src_tj(j_decompress_ptr, const unsigned char *,
|
||||
unsigned long);
|
||||
|
||||
#define PAD(v, p) ((v + (p) - 1) & (~((p) - 1)))
|
||||
#define isPow2(x) (((x) & (x - 1)) == 0)
|
||||
#define IS_POW2(x) (((x) & (x - 1)) == 0)
|
||||
|
||||
|
||||
/* Error handling (based on example in example.txt) */
|
||||
@@ -65,6 +65,12 @@ struct my_error_mgr {
|
||||
};
|
||||
typedef struct my_error_mgr *my_error_ptr;
|
||||
|
||||
#define JMESSAGE(code, string) string,
|
||||
static const char *turbojpeg_message_table[] = {
|
||||
#include "cderror.h"
|
||||
NULL
|
||||
};
|
||||
|
||||
static void my_error_exit(j_common_ptr cinfo)
|
||||
{
|
||||
my_error_ptr myerr = (my_error_ptr)cinfo->err;
|
||||
@@ -158,20 +164,20 @@ static int cs2pf[JPEG_NUMCS] = {
|
||||
TJPF_UNKNOWN
|
||||
};
|
||||
|
||||
#define _throwg(m) { \
|
||||
#define THROWG(m) { \
|
||||
snprintf(errStr, JMSG_LENGTH_MAX, "%s", m); \
|
||||
retval = -1; goto bailout; \
|
||||
}
|
||||
#define _throwunix(m) { \
|
||||
#define THROW_UNIX(m) { \
|
||||
snprintf(errStr, JMSG_LENGTH_MAX, "%s\n%s", m, strerror(errno)); \
|
||||
retval = -1; goto bailout; \
|
||||
}
|
||||
#define _throw(m) { \
|
||||
#define THROW(m) { \
|
||||
snprintf(this->errStr, JMSG_LENGTH_MAX, "%s", m); \
|
||||
this->isInstanceError = TRUE; _throwg(m); \
|
||||
this->isInstanceError = TRUE; THROWG(m) \
|
||||
}
|
||||
|
||||
#define getinstance(handle) \
|
||||
#define GET_INSTANCE(handle) \
|
||||
tjinstance *this = (tjinstance *)handle; \
|
||||
j_compress_ptr cinfo = NULL; \
|
||||
j_decompress_ptr dinfo = NULL; \
|
||||
@@ -184,7 +190,7 @@ static int cs2pf[JPEG_NUMCS] = {
|
||||
this->jerr.warning = FALSE; \
|
||||
this->isInstanceError = FALSE;
|
||||
|
||||
#define getcinstance(handle) \
|
||||
#define GET_CINSTANCE(handle) \
|
||||
tjinstance *this = (tjinstance *)handle; \
|
||||
j_compress_ptr cinfo = NULL; \
|
||||
\
|
||||
@@ -196,7 +202,7 @@ static int cs2pf[JPEG_NUMCS] = {
|
||||
this->jerr.warning = FALSE; \
|
||||
this->isInstanceError = FALSE;
|
||||
|
||||
#define getdinstance(handle) \
|
||||
#define GET_DINSTANCE(handle) \
|
||||
tjinstance *this = (tjinstance *)handle; \
|
||||
j_decompress_ptr dinfo = NULL; \
|
||||
\
|
||||
@@ -231,7 +237,9 @@ static int setCompDefaults(struct jpeg_compress_struct *cinfo, int pixelFormat,
|
||||
int subsamp, int jpegQual, int flags)
|
||||
{
|
||||
int retval = 0;
|
||||
#ifndef NO_GETENV
|
||||
char *env = NULL;
|
||||
#endif
|
||||
|
||||
cinfo->in_color_space = pf2cs[pixelFormat];
|
||||
cinfo->input_components = tjPixelSize[pixelFormat];
|
||||
@@ -319,7 +327,8 @@ static int getSubsamp(j_decompress_ptr dinfo)
|
||||
for (k = 1; k < dinfo->num_components; k++) {
|
||||
int href = 1, vref = 1;
|
||||
|
||||
if (dinfo->jpeg_color_space == JCS_YCCK && k == 3) {
|
||||
if ((dinfo->jpeg_color_space == JCS_YCCK ||
|
||||
dinfo->jpeg_color_space == JCS_CMYK) && k == 3) {
|
||||
href = tjMCUWidth[i] / 8; vref = tjMCUHeight[i] / 8;
|
||||
}
|
||||
if (dinfo->comp_info[k].h_samp_factor == href &&
|
||||
@@ -340,7 +349,8 @@ static int getSubsamp(j_decompress_ptr dinfo)
|
||||
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) {
|
||||
if ((dinfo->jpeg_color_space == JCS_YCCK ||
|
||||
dinfo->jpeg_color_space == JCS_CMYK) && k == 3) {
|
||||
href = vref = 2;
|
||||
}
|
||||
if (dinfo->comp_info[k].h_samp_factor == href &&
|
||||
@@ -351,6 +361,23 @@ static int getSubsamp(j_decompress_ptr dinfo)
|
||||
retval = i; break;
|
||||
}
|
||||
}
|
||||
/* Handle 4:4:4 images whose sampling factors are specified in
|
||||
non-standard ways. */
|
||||
if (dinfo->comp_info[0].h_samp_factor *
|
||||
dinfo->comp_info[0].v_samp_factor <=
|
||||
D_MAX_BLOCKS_IN_MCU / pixelsize[i] && i == TJSAMP_444) {
|
||||
int match = 0;
|
||||
for (k = 1; k < dinfo->num_components; k++) {
|
||||
if (dinfo->comp_info[i].h_samp_factor ==
|
||||
dinfo->comp_info[0].h_samp_factor &&
|
||||
dinfo->comp_info[i].v_samp_factor ==
|
||||
dinfo->comp_info[0].v_samp_factor)
|
||||
match++;
|
||||
if (match == dinfo->num_components - 1) {
|
||||
retval = i; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
@@ -388,7 +415,7 @@ DLLEXPORT int tjGetErrorCode(tjhandle handle)
|
||||
|
||||
DLLEXPORT int tjDestroy(tjhandle handle)
|
||||
{
|
||||
getinstance(handle);
|
||||
GET_INSTANCE(handle);
|
||||
|
||||
if (setjmp(this->jerr.setjmp_buffer)) return -1;
|
||||
if (this->init & COMPRESS) jpeg_destroy_compress(cinfo);
|
||||
@@ -429,6 +456,9 @@ static tjhandle _tjInitCompress(tjinstance *this)
|
||||
this->jerr.pub.output_message = my_output_message;
|
||||
this->jerr.emit_message = this->jerr.pub.emit_message;
|
||||
this->jerr.pub.emit_message = my_emit_message;
|
||||
this->jerr.pub.addon_message_table = turbojpeg_message_table;
|
||||
this->jerr.pub.first_addon_message = JMSG_FIRSTADDONCODE;
|
||||
this->jerr.pub.last_addon_message = JMSG_LASTADDONCODE;
|
||||
|
||||
if (setjmp(this->jerr.setjmp_buffer)) {
|
||||
/* If we get here, the JPEG code has signaled an error. */
|
||||
@@ -461,11 +491,11 @@ DLLEXPORT tjhandle tjInitCompress(void)
|
||||
|
||||
DLLEXPORT unsigned long tjBufSize(int width, int height, int jpegSubsamp)
|
||||
{
|
||||
unsigned long retval = 0;
|
||||
unsigned long long retval = 0;
|
||||
int mcuw, mcuh, chromasf;
|
||||
|
||||
if (width < 1 || height < 1 || jpegSubsamp < 0 || jpegSubsamp >= NUMSUBOPT)
|
||||
_throwg("tjBufSize(): Invalid argument");
|
||||
THROWG("tjBufSize(): Invalid argument");
|
||||
|
||||
/* This allows for rare corner cases in which a JPEG image can actually be
|
||||
larger than the uncompressed input (we wouldn't mention it if it hadn't
|
||||
@@ -473,36 +503,41 @@ DLLEXPORT unsigned long tjBufSize(int width, int height, int jpegSubsamp)
|
||||
mcuw = tjMCUWidth[jpegSubsamp];
|
||||
mcuh = tjMCUHeight[jpegSubsamp];
|
||||
chromasf = jpegSubsamp == TJSAMP_GRAY ? 0 : 4 * 64 / (mcuw * mcuh);
|
||||
retval = PAD(width, mcuw) * PAD(height, mcuh) * (2 + chromasf) + 2048;
|
||||
retval = PAD(width, mcuw) * PAD(height, mcuh) * (2ULL + chromasf) + 2048ULL;
|
||||
if (retval > (unsigned long long)((unsigned long)-1))
|
||||
THROWG("tjBufSize(): Image is too large");
|
||||
|
||||
bailout:
|
||||
return retval;
|
||||
return (unsigned long)retval;
|
||||
}
|
||||
|
||||
DLLEXPORT unsigned long TJBUFSIZE(int width, int height)
|
||||
{
|
||||
unsigned long retval = 0;
|
||||
unsigned long long retval = 0;
|
||||
|
||||
if (width < 1 || height < 1)
|
||||
_throwg("TJBUFSIZE(): Invalid argument");
|
||||
THROWG("TJBUFSIZE(): Invalid argument");
|
||||
|
||||
/* This allows for rare corner cases in which a JPEG image can actually be
|
||||
larger than the uncompressed input (we wouldn't mention it if it hadn't
|
||||
happened before.) */
|
||||
retval = PAD(width, 16) * PAD(height, 16) * 6 + 2048;
|
||||
retval = PAD(width, 16) * PAD(height, 16) * 6ULL + 2048ULL;
|
||||
if (retval > (unsigned long long)((unsigned long)-1))
|
||||
THROWG("TJBUFSIZE(): Image is too large");
|
||||
|
||||
bailout:
|
||||
return retval;
|
||||
return (unsigned long)retval;
|
||||
}
|
||||
|
||||
|
||||
DLLEXPORT unsigned long tjBufSizeYUV2(int width, int pad, int height,
|
||||
int subsamp)
|
||||
{
|
||||
int retval = 0, nc, i;
|
||||
unsigned long long retval = 0;
|
||||
int nc, i;
|
||||
|
||||
if (subsamp < 0 || subsamp >= NUMSUBOPT)
|
||||
_throwg("tjBufSizeYUV2(): Invalid argument");
|
||||
THROWG("tjBufSizeYUV2(): Invalid argument");
|
||||
|
||||
nc = (subsamp == TJSAMP_GRAY ? 1 : 3);
|
||||
for (i = 0; i < nc; i++) {
|
||||
@@ -511,11 +546,13 @@ DLLEXPORT unsigned long tjBufSizeYUV2(int width, int pad, int height,
|
||||
int ph = tjPlaneHeight(i, height, subsamp);
|
||||
|
||||
if (pw < 0 || ph < 0) return -1;
|
||||
else retval += stride * ph;
|
||||
else retval += (unsigned long long)stride * ph;
|
||||
}
|
||||
if (retval > (unsigned long long)((unsigned long)-1))
|
||||
THROWG("tjBufSizeYUV2(): Image is too large");
|
||||
|
||||
bailout:
|
||||
return retval;
|
||||
return (unsigned long)retval;
|
||||
}
|
||||
|
||||
DLLEXPORT unsigned long tjBufSizeYUV(int width, int height, int subsamp)
|
||||
@@ -534,10 +571,10 @@ DLLEXPORT int tjPlaneWidth(int componentID, int width, int subsamp)
|
||||
int pw, nc, retval = 0;
|
||||
|
||||
if (width < 1 || subsamp < 0 || subsamp >= TJ_NUMSAMP)
|
||||
_throwg("tjPlaneWidth(): Invalid argument");
|
||||
THROWG("tjPlaneWidth(): Invalid argument");
|
||||
nc = (subsamp == TJSAMP_GRAY ? 1 : 3);
|
||||
if (componentID < 0 || componentID >= nc)
|
||||
_throwg("tjPlaneWidth(): Invalid argument");
|
||||
THROWG("tjPlaneWidth(): Invalid argument");
|
||||
|
||||
pw = PAD(width, tjMCUWidth[subsamp] / 8);
|
||||
if (componentID == 0)
|
||||
@@ -555,10 +592,10 @@ DLLEXPORT int tjPlaneHeight(int componentID, int height, int subsamp)
|
||||
int ph, nc, retval = 0;
|
||||
|
||||
if (height < 1 || subsamp < 0 || subsamp >= TJ_NUMSAMP)
|
||||
_throwg("tjPlaneHeight(): Invalid argument");
|
||||
THROWG("tjPlaneHeight(): Invalid argument");
|
||||
nc = (subsamp == TJSAMP_GRAY ? 1 : 3);
|
||||
if (componentID < 0 || componentID >= nc)
|
||||
_throwg("tjPlaneHeight(): Invalid argument");
|
||||
THROWG("tjPlaneHeight(): Invalid argument");
|
||||
|
||||
ph = PAD(height, tjMCUHeight[subsamp] / 8);
|
||||
if (componentID == 0)
|
||||
@@ -574,11 +611,11 @@ bailout:
|
||||
DLLEXPORT unsigned long tjPlaneSizeYUV(int componentID, int width, int stride,
|
||||
int height, int subsamp)
|
||||
{
|
||||
unsigned long retval = 0;
|
||||
unsigned long long retval = 0;
|
||||
int pw, ph;
|
||||
|
||||
if (width < 1 || height < 1 || subsamp < 0 || subsamp >= NUMSUBOPT)
|
||||
_throwg("tjPlaneSizeYUV(): Invalid argument");
|
||||
THROWG("tjPlaneSizeYUV(): Invalid argument");
|
||||
|
||||
pw = tjPlaneWidth(componentID, width, subsamp);
|
||||
ph = tjPlaneHeight(componentID, height, subsamp);
|
||||
@@ -587,10 +624,12 @@ DLLEXPORT unsigned long tjPlaneSizeYUV(int componentID, int width, int stride,
|
||||
if (stride == 0) stride = pw;
|
||||
else stride = abs(stride);
|
||||
|
||||
retval = stride * (ph - 1) + pw;
|
||||
retval = (unsigned long long)stride * (ph - 1) + pw;
|
||||
if (retval > (unsigned long long)((unsigned long)-1))
|
||||
THROWG("tjPlaneSizeYUV(): Image is too large");
|
||||
|
||||
bailout:
|
||||
return retval;
|
||||
return (unsigned long)retval;
|
||||
}
|
||||
|
||||
|
||||
@@ -602,21 +641,21 @@ DLLEXPORT int tjCompress2(tjhandle handle, const unsigned char *srcBuf,
|
||||
int i, retval = 0, alloc = 1;
|
||||
JSAMPROW *row_pointer = NULL;
|
||||
|
||||
getcinstance(handle)
|
||||
GET_CINSTANCE(handle)
|
||||
this->jerr.stopOnWarning = (flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE;
|
||||
if ((this->init & COMPRESS) == 0)
|
||||
_throw("tjCompress2(): Instance has not been initialized for compression");
|
||||
THROW("tjCompress2(): Instance has not been initialized for compression");
|
||||
|
||||
if (srcBuf == NULL || width <= 0 || pitch < 0 || height <= 0 ||
|
||||
pixelFormat < 0 || pixelFormat >= TJ_NUMPF || jpegBuf == NULL ||
|
||||
jpegSize == NULL || jpegSubsamp < 0 || jpegSubsamp >= NUMSUBOPT ||
|
||||
jpegQual < 0 || jpegQual > 100)
|
||||
_throw("tjCompress2(): Invalid argument");
|
||||
THROW("tjCompress2(): Invalid argument");
|
||||
|
||||
if (pitch == 0) pitch = width * tjPixelSize[pixelFormat];
|
||||
|
||||
if ((row_pointer = (JSAMPROW *)malloc(sizeof(JSAMPROW) * height)) == NULL)
|
||||
_throw("tjCompress2(): Memory allocation failure");
|
||||
THROW("tjCompress2(): Memory allocation failure");
|
||||
|
||||
if (setjmp(this->jerr.setjmp_buffer)) {
|
||||
/* If we get here, the JPEG code has signaled an error. */
|
||||
@@ -642,9 +681,9 @@ DLLEXPORT int tjCompress2(tjhandle handle, const unsigned char *srcBuf,
|
||||
jpeg_start_compress(cinfo, TRUE);
|
||||
for (i = 0; i < height; i++) {
|
||||
if (flags & TJFLAG_BOTTOMUP)
|
||||
row_pointer[i] = (JSAMPROW)&srcBuf[(height - i - 1) * pitch];
|
||||
row_pointer[i] = (JSAMPROW)&srcBuf[(height - i - 1) * (size_t)pitch];
|
||||
else
|
||||
row_pointer[i] = (JSAMPROW)&srcBuf[i * pitch];
|
||||
row_pointer[i] = (JSAMPROW)&srcBuf[i * (size_t)pitch];
|
||||
}
|
||||
while (cinfo->next_scanline < cinfo->image_height)
|
||||
jpeg_write_scanlines(cinfo, &row_pointer[cinfo->next_scanline],
|
||||
@@ -695,7 +734,7 @@ DLLEXPORT int tjEncodeYUVPlanes(tjhandle handle, const unsigned char *srcBuf,
|
||||
JSAMPLE *ptr;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
getcinstance(handle);
|
||||
GET_CINSTANCE(handle);
|
||||
this->jerr.stopOnWarning = (flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE;
|
||||
|
||||
for (i = 0; i < MAX_COMPONENTS; i++) {
|
||||
@@ -704,17 +743,17 @@ DLLEXPORT int tjEncodeYUVPlanes(tjhandle handle, const unsigned char *srcBuf,
|
||||
}
|
||||
|
||||
if ((this->init & COMPRESS) == 0)
|
||||
_throw("tjEncodeYUVPlanes(): Instance has not been initialized for compression");
|
||||
THROW("tjEncodeYUVPlanes(): Instance has not been initialized for compression");
|
||||
|
||||
if (srcBuf == NULL || width <= 0 || pitch < 0 || height <= 0 ||
|
||||
pixelFormat < 0 || pixelFormat >= TJ_NUMPF || !dstPlanes ||
|
||||
!dstPlanes[0] || subsamp < 0 || subsamp >= NUMSUBOPT)
|
||||
_throw("tjEncodeYUVPlanes(): Invalid argument");
|
||||
THROW("tjEncodeYUVPlanes(): Invalid argument");
|
||||
if (subsamp != TJSAMP_GRAY && (!dstPlanes[1] || !dstPlanes[2]))
|
||||
_throw("tjEncodeYUVPlanes(): Invalid argument");
|
||||
THROW("tjEncodeYUVPlanes(): Invalid argument");
|
||||
|
||||
if (pixelFormat == TJPF_CMYK)
|
||||
_throw("tjEncodeYUVPlanes(): Cannot generate YUV images from CMYK pixels");
|
||||
THROW("tjEncodeYUVPlanes(): Cannot generate YUV images from CMYK pixels");
|
||||
|
||||
if (pitch == 0) pitch = width * tjPixelSize[pixelFormat];
|
||||
|
||||
@@ -739,7 +778,7 @@ DLLEXPORT int tjEncodeYUVPlanes(tjhandle handle, const unsigned char *srcBuf,
|
||||
to write the file headers, which could overflow the output buffer if the
|
||||
YUV image were very small. */
|
||||
if (cinfo->global_state != CSTATE_START)
|
||||
_throw("tjEncodeYUVPlanes(): libjpeg API is in the wrong state");
|
||||
THROW("tjEncodeYUVPlanes(): libjpeg API is in the wrong state");
|
||||
(*cinfo->err->reset_error_mgr) ((j_common_ptr)cinfo);
|
||||
jinit_c_master_control(cinfo, FALSE);
|
||||
jinit_color_converter(cinfo);
|
||||
@@ -750,12 +789,12 @@ DLLEXPORT int tjEncodeYUVPlanes(tjhandle handle, const unsigned char *srcBuf,
|
||||
ph0 = PAD(height, cinfo->max_v_samp_factor);
|
||||
|
||||
if ((row_pointer = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph0)) == NULL)
|
||||
_throw("tjEncodeYUVPlanes(): Memory allocation failure");
|
||||
THROW("tjEncodeYUVPlanes(): Memory allocation failure");
|
||||
for (i = 0; i < height; i++) {
|
||||
if (flags & TJFLAG_BOTTOMUP)
|
||||
row_pointer[i] = (JSAMPROW)&srcBuf[(height - i - 1) * pitch];
|
||||
row_pointer[i] = (JSAMPROW)&srcBuf[(height - i - 1) * (size_t)pitch];
|
||||
else
|
||||
row_pointer[i] = (JSAMPROW)&srcBuf[i * pitch];
|
||||
row_pointer[i] = (JSAMPROW)&srcBuf[i * (size_t)pitch];
|
||||
}
|
||||
if (height < ph0)
|
||||
for (i = height; i < ph0; i++) row_pointer[i] = row_pointer[height - 1];
|
||||
@@ -767,11 +806,11 @@ DLLEXPORT int tjEncodeYUVPlanes(tjhandle handle, const unsigned char *srcBuf,
|
||||
compptr->h_samp_factor, 32) *
|
||||
cinfo->max_v_samp_factor + 32);
|
||||
if (!_tmpbuf[i])
|
||||
_throw("tjEncodeYUVPlanes(): Memory allocation failure");
|
||||
THROW("tjEncodeYUVPlanes(): Memory allocation failure");
|
||||
tmpbuf[i] =
|
||||
(JSAMPROW *)malloc(sizeof(JSAMPROW) * cinfo->max_v_samp_factor);
|
||||
if (!tmpbuf[i])
|
||||
_throw("tjEncodeYUVPlanes(): Memory allocation failure");
|
||||
THROW("tjEncodeYUVPlanes(): Memory allocation failure");
|
||||
for (row = 0; row < cinfo->max_v_samp_factor; row++) {
|
||||
unsigned char *_tmpbuf_aligned =
|
||||
(unsigned char *)PAD((size_t)_tmpbuf[i], 32);
|
||||
@@ -784,10 +823,10 @@ DLLEXPORT int tjEncodeYUVPlanes(tjhandle handle, const unsigned char *srcBuf,
|
||||
(JSAMPLE *)malloc(PAD(compptr->width_in_blocks * DCTSIZE, 32) *
|
||||
compptr->v_samp_factor + 32);
|
||||
if (!_tmpbuf2[i])
|
||||
_throw("tjEncodeYUVPlanes(): Memory allocation failure");
|
||||
THROW("tjEncodeYUVPlanes(): Memory allocation failure");
|
||||
tmpbuf2[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * compptr->v_samp_factor);
|
||||
if (!tmpbuf2[i])
|
||||
_throw("tjEncodeYUVPlanes(): Memory allocation failure");
|
||||
THROW("tjEncodeYUVPlanes(): Memory allocation failure");
|
||||
for (row = 0; row < compptr->v_samp_factor; row++) {
|
||||
unsigned char *_tmpbuf2_aligned =
|
||||
(unsigned char *)PAD((size_t)_tmpbuf2[i], 32);
|
||||
@@ -799,7 +838,7 @@ DLLEXPORT int tjEncodeYUVPlanes(tjhandle handle, const unsigned char *srcBuf,
|
||||
ph[i] = ph0 * compptr->v_samp_factor / cinfo->max_v_samp_factor;
|
||||
outbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph[i]);
|
||||
if (!outbuf[i])
|
||||
_throw("tjEncodeYUVPlanes(): Memory allocation failure");
|
||||
THROW("tjEncodeYUVPlanes(): Memory allocation failure");
|
||||
ptr = dstPlanes[i];
|
||||
for (row = 0; row < ph[i]; row++) {
|
||||
outbuf[i][row] = ptr;
|
||||
@@ -849,12 +888,12 @@ DLLEXPORT int tjEncodeYUV3(tjhandle handle, const unsigned char *srcBuf,
|
||||
int pw0, ph0, strides[3], retval = -1;
|
||||
tjinstance *this = (tjinstance *)handle;
|
||||
|
||||
if (!this) _throwg("tjEncodeYUV3(): Invalid handle");
|
||||
if (!this) THROWG("tjEncodeYUV3(): Invalid handle");
|
||||
this->isInstanceError = FALSE;
|
||||
|
||||
if (width <= 0 || height <= 0 || dstBuf == NULL || pad < 0 || !isPow2(pad) ||
|
||||
subsamp < 0 || subsamp >= NUMSUBOPT)
|
||||
_throw("tjEncodeYUV3(): Invalid argument");
|
||||
if (width <= 0 || height <= 0 || dstBuf == NULL || pad < 0 ||
|
||||
!IS_POW2(pad) || subsamp < 0 || subsamp >= NUMSUBOPT)
|
||||
THROW("tjEncodeYUV3(): Invalid argument");
|
||||
|
||||
pw0 = tjPlaneWidth(0, width, subsamp);
|
||||
ph0 = tjPlaneHeight(0, height, subsamp);
|
||||
@@ -911,7 +950,7 @@ DLLEXPORT int tjCompressFromYUVPlanes(tjhandle handle,
|
||||
JSAMPLE *_tmpbuf = NULL, *ptr;
|
||||
JSAMPROW *inbuf[MAX_COMPONENTS], *tmpbuf[MAX_COMPONENTS];
|
||||
|
||||
getcinstance(handle)
|
||||
GET_CINSTANCE(handle)
|
||||
this->jerr.stopOnWarning = (flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE;
|
||||
|
||||
for (i = 0; i < MAX_COMPONENTS; i++) {
|
||||
@@ -919,14 +958,14 @@ DLLEXPORT int tjCompressFromYUVPlanes(tjhandle handle,
|
||||
}
|
||||
|
||||
if ((this->init & COMPRESS) == 0)
|
||||
_throw("tjCompressFromYUVPlanes(): Instance has not been initialized for compression");
|
||||
THROW("tjCompressFromYUVPlanes(): Instance has not been initialized for compression");
|
||||
|
||||
if (!srcPlanes || !srcPlanes[0] || width <= 0 || height <= 0 ||
|
||||
subsamp < 0 || subsamp >= NUMSUBOPT || jpegBuf == NULL ||
|
||||
jpegSize == NULL || jpegQual < 0 || jpegQual > 100)
|
||||
_throw("tjCompressFromYUVPlanes(): Invalid argument");
|
||||
THROW("tjCompressFromYUVPlanes(): Invalid argument");
|
||||
if (subsamp != TJSAMP_GRAY && (!srcPlanes[1] || !srcPlanes[2]))
|
||||
_throw("tjCompressFromYUVPlanes(): Invalid argument");
|
||||
THROW("tjCompressFromYUVPlanes(): Invalid argument");
|
||||
|
||||
if (setjmp(this->jerr.setjmp_buffer)) {
|
||||
/* If we get here, the JPEG code has signaled an error. */
|
||||
@@ -965,7 +1004,7 @@ DLLEXPORT int tjCompressFromYUVPlanes(tjhandle handle,
|
||||
th[i] = compptr->v_samp_factor * DCTSIZE;
|
||||
tmpbufsize += iw[i] * th[i];
|
||||
if ((inbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph[i])) == NULL)
|
||||
_throw("tjCompressFromYUVPlanes(): Memory allocation failure");
|
||||
THROW("tjCompressFromYUVPlanes(): Memory allocation failure");
|
||||
ptr = (JSAMPLE *)srcPlanes[i];
|
||||
for (row = 0; row < ph[i]; row++) {
|
||||
inbuf[i][row] = ptr;
|
||||
@@ -974,11 +1013,11 @@ DLLEXPORT int tjCompressFromYUVPlanes(tjhandle handle,
|
||||
}
|
||||
if (usetmpbuf) {
|
||||
if ((_tmpbuf = (JSAMPLE *)malloc(sizeof(JSAMPLE) * tmpbufsize)) == NULL)
|
||||
_throw("tjCompressFromYUVPlanes(): Memory allocation failure");
|
||||
THROW("tjCompressFromYUVPlanes(): Memory allocation failure");
|
||||
ptr = _tmpbuf;
|
||||
for (i = 0; i < cinfo->num_components; i++) {
|
||||
if ((tmpbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * th[i])) == NULL)
|
||||
_throw("tjCompressFromYUVPlanes(): Memory allocation failure");
|
||||
THROW("tjCompressFromYUVPlanes(): Memory allocation failure");
|
||||
for (row = 0; row < th[i]; row++) {
|
||||
tmpbuf[i][row] = ptr;
|
||||
ptr += iw[i];
|
||||
@@ -1042,12 +1081,12 @@ DLLEXPORT int tjCompressFromYUV(tjhandle handle, const unsigned char *srcBuf,
|
||||
int pw0, ph0, strides[3], retval = -1;
|
||||
tjinstance *this = (tjinstance *)handle;
|
||||
|
||||
if (!this) _throwg("tjCompressFromYUV(): Invalid handle");
|
||||
if (!this) THROWG("tjCompressFromYUV(): Invalid handle");
|
||||
this->isInstanceError = FALSE;
|
||||
|
||||
if (srcBuf == NULL || width <= 0 || pad < 1 || height <= 0 || subsamp < 0 ||
|
||||
subsamp >= NUMSUBOPT)
|
||||
_throw("tjCompressFromYUV(): Invalid argument");
|
||||
THROW("tjCompressFromYUV(): Invalid argument");
|
||||
|
||||
pw0 = tjPlaneWidth(0, width, subsamp);
|
||||
ph0 = tjPlaneHeight(0, height, subsamp);
|
||||
@@ -1085,6 +1124,9 @@ static tjhandle _tjInitDecompress(tjinstance *this)
|
||||
this->jerr.pub.output_message = my_output_message;
|
||||
this->jerr.emit_message = this->jerr.pub.emit_message;
|
||||
this->jerr.pub.emit_message = my_emit_message;
|
||||
this->jerr.pub.addon_message_table = turbojpeg_message_table;
|
||||
this->jerr.pub.first_addon_message = JMSG_FIRSTADDONCODE;
|
||||
this->jerr.pub.last_addon_message = JMSG_LASTADDONCODE;
|
||||
|
||||
if (setjmp(this->jerr.setjmp_buffer)) {
|
||||
/* If we get here, the JPEG code has signaled an error. */
|
||||
@@ -1123,13 +1165,13 @@ DLLEXPORT int tjDecompressHeader3(tjhandle handle,
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
getdinstance(handle);
|
||||
GET_DINSTANCE(handle);
|
||||
if ((this->init & DECOMPRESS) == 0)
|
||||
_throw("tjDecompressHeader3(): Instance has not been initialized for decompression");
|
||||
THROW("tjDecompressHeader3(): Instance has not been initialized for decompression");
|
||||
|
||||
if (jpegBuf == NULL || jpegSize <= 0 || width == NULL || height == NULL ||
|
||||
jpegSubsamp == NULL || jpegColorspace == NULL)
|
||||
_throw("tjDecompressHeader3(): Invalid argument");
|
||||
THROW("tjDecompressHeader3(): Invalid argument");
|
||||
|
||||
if (setjmp(this->jerr.setjmp_buffer)) {
|
||||
/* If we get here, the JPEG code has signaled an error. */
|
||||
@@ -1154,11 +1196,11 @@ DLLEXPORT int tjDecompressHeader3(tjhandle handle,
|
||||
jpeg_abort_decompress(dinfo);
|
||||
|
||||
if (*jpegSubsamp < 0)
|
||||
_throw("tjDecompressHeader3(): Could not determine subsampling type for JPEG image");
|
||||
THROW("tjDecompressHeader3(): Could not determine subsampling type for JPEG image");
|
||||
if (*jpegColorspace < 0)
|
||||
_throw("tjDecompressHeader3(): Could not determine colorspace of JPEG image");
|
||||
THROW("tjDecompressHeader3(): Could not determine colorspace of JPEG image");
|
||||
if (*width < 1 || *height < 1)
|
||||
_throw("tjDecompressHeader3(): Invalid data returned in header");
|
||||
THROW("tjDecompressHeader3(): Invalid data returned in header");
|
||||
|
||||
bailout:
|
||||
if (this->jerr.warning) retval = -1;
|
||||
@@ -1207,14 +1249,14 @@ DLLEXPORT int tjDecompress2(tjhandle handle, const unsigned char *jpegBuf,
|
||||
JSAMPROW *row_pointer = NULL;
|
||||
int i, retval = 0, jpegwidth, jpegheight, scaledw, scaledh;
|
||||
|
||||
getdinstance(handle);
|
||||
GET_DINSTANCE(handle);
|
||||
this->jerr.stopOnWarning = (flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE;
|
||||
if ((this->init & DECOMPRESS) == 0)
|
||||
_throw("tjDecompress2(): Instance has not been initialized for decompression");
|
||||
THROW("tjDecompress2(): Instance has not been initialized for decompression");
|
||||
|
||||
if (jpegBuf == NULL || jpegSize <= 0 || dstBuf == NULL || width < 0 ||
|
||||
pitch < 0 || height < 0 || pixelFormat < 0 || pixelFormat >= TJ_NUMPF)
|
||||
_throw("tjDecompress2(): Invalid argument");
|
||||
THROW("tjDecompress2(): Invalid argument");
|
||||
|
||||
#ifndef NO_PUTENV
|
||||
if (flags & TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1");
|
||||
@@ -1243,7 +1285,7 @@ DLLEXPORT int tjDecompress2(tjhandle handle, const unsigned char *jpegBuf,
|
||||
break;
|
||||
}
|
||||
if (i >= NUMSF)
|
||||
_throw("tjDecompress2(): Could not scale down to desired image dimensions");
|
||||
THROW("tjDecompress2(): Could not scale down to desired image dimensions");
|
||||
width = scaledw; height = scaledh;
|
||||
dinfo->scale_num = sf[i].num;
|
||||
dinfo->scale_denom = sf[i].denom;
|
||||
@@ -1253,16 +1295,16 @@ DLLEXPORT int tjDecompress2(tjhandle handle, const unsigned char *jpegBuf,
|
||||
|
||||
if ((row_pointer =
|
||||
(JSAMPROW *)malloc(sizeof(JSAMPROW) * 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++) {
|
||||
if (flags & TJFLAG_BOTTOMUP)
|
||||
row_pointer[i] = &dstBuf[(dinfo->output_height - i - 1) * pitch];
|
||||
row_pointer[i] = &dstBuf[(dinfo->output_height - i - 1) * (size_t)pitch];
|
||||
else
|
||||
row_pointer[i] = &dstBuf[i * pitch];
|
||||
row_pointer[i] = &dstBuf[i * (size_t)pitch];
|
||||
}
|
||||
while (dinfo->output_scanline < dinfo->output_height)
|
||||
jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline],
|
||||
@@ -1331,12 +1373,12 @@ static int setDecodeDefaults(struct jpeg_decompress_struct *dinfo,
|
||||
}
|
||||
|
||||
|
||||
int my_read_markers(j_decompress_ptr dinfo)
|
||||
static int my_read_markers(j_decompress_ptr dinfo)
|
||||
{
|
||||
return JPEG_REACHED_SOS;
|
||||
}
|
||||
|
||||
void my_reset_marker_reader(j_decompress_ptr dinfo)
|
||||
static void my_reset_marker_reader(j_decompress_ptr dinfo)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1355,7 +1397,7 @@ DLLEXPORT int tjDecodeYUVPlanes(tjhandle handle,
|
||||
int (*old_read_markers) (j_decompress_ptr);
|
||||
void (*old_reset_marker_reader) (j_decompress_ptr);
|
||||
|
||||
getdinstance(handle);
|
||||
GET_DINSTANCE(handle);
|
||||
this->jerr.stopOnWarning = (flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE;
|
||||
|
||||
for (i = 0; i < MAX_COMPONENTS; i++) {
|
||||
@@ -1363,14 +1405,14 @@ DLLEXPORT int tjDecodeYUVPlanes(tjhandle handle,
|
||||
}
|
||||
|
||||
if ((this->init & DECOMPRESS) == 0)
|
||||
_throw("tjDecodeYUVPlanes(): Instance has not been initialized for decompression");
|
||||
THROW("tjDecodeYUVPlanes(): Instance has not been initialized for decompression");
|
||||
|
||||
if (!srcPlanes || !srcPlanes[0] || subsamp < 0 || subsamp >= NUMSUBOPT ||
|
||||
dstBuf == NULL || width <= 0 || pitch < 0 || height <= 0 ||
|
||||
pixelFormat < 0 || pixelFormat >= TJ_NUMPF)
|
||||
_throw("tjDecodeYUVPlanes(): Invalid argument");
|
||||
THROW("tjDecodeYUVPlanes(): Invalid argument");
|
||||
if (subsamp != TJSAMP_GRAY && (!srcPlanes[1] || !srcPlanes[2]))
|
||||
_throw("tjDecodeYUVPlanes(): Invalid argument");
|
||||
THROW("tjDecodeYUVPlanes(): Invalid argument");
|
||||
|
||||
if (setjmp(this->jerr.setjmp_buffer)) {
|
||||
/* If we get here, the JPEG code has signaled an error. */
|
||||
@@ -1378,7 +1420,7 @@ DLLEXPORT int tjDecodeYUVPlanes(tjhandle handle,
|
||||
}
|
||||
|
||||
if (pixelFormat == TJPF_CMYK)
|
||||
_throw("tjDecodeYUVPlanes(): Cannot decode YUV images into CMYK pixels.");
|
||||
THROW("tjDecodeYUVPlanes(): Cannot decode YUV images into CMYK pixels.");
|
||||
|
||||
if (pitch == 0) pitch = width * tjPixelSize[pixelFormat];
|
||||
dinfo->image_width = width;
|
||||
@@ -1390,6 +1432,9 @@ DLLEXPORT int tjDecodeYUVPlanes(tjhandle handle,
|
||||
else if (flags & TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1");
|
||||
#endif
|
||||
|
||||
dinfo->progressive_mode = dinfo->inputctl->has_multiple_scans = FALSE;
|
||||
dinfo->Ss = dinfo->Ah = dinfo->Al = 0;
|
||||
dinfo->Se = DCTSIZE2 - 1;
|
||||
if (setDecodeDefaults(dinfo, pixelFormat, subsamp, flags) == -1) {
|
||||
retval = -1; goto bailout;
|
||||
}
|
||||
@@ -1414,12 +1459,12 @@ DLLEXPORT int tjDecodeYUVPlanes(tjhandle handle,
|
||||
if (pitch == 0) pitch = dinfo->output_width * tjPixelSize[pixelFormat];
|
||||
|
||||
if ((row_pointer = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph0)) == NULL)
|
||||
_throw("tjDecodeYUVPlanes(): Memory allocation failure");
|
||||
THROW("tjDecodeYUVPlanes(): Memory allocation failure");
|
||||
for (i = 0; i < height; i++) {
|
||||
if (flags & TJFLAG_BOTTOMUP)
|
||||
row_pointer[i] = &dstBuf[(height - i - 1) * pitch];
|
||||
row_pointer[i] = &dstBuf[(height - i - 1) * (size_t)pitch];
|
||||
else
|
||||
row_pointer[i] = &dstBuf[i * pitch];
|
||||
row_pointer[i] = &dstBuf[i * (size_t)pitch];
|
||||
}
|
||||
if (height < ph0)
|
||||
for (i = height; i < ph0; i++) row_pointer[i] = row_pointer[height - 1];
|
||||
@@ -1430,10 +1475,10 @@ DLLEXPORT int tjDecodeYUVPlanes(tjhandle handle,
|
||||
(JSAMPLE *)malloc(PAD(compptr->width_in_blocks * DCTSIZE, 32) *
|
||||
compptr->v_samp_factor + 32);
|
||||
if (!_tmpbuf[i])
|
||||
_throw("tjDecodeYUVPlanes(): Memory allocation failure");
|
||||
THROW("tjDecodeYUVPlanes(): Memory allocation failure");
|
||||
tmpbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * compptr->v_samp_factor);
|
||||
if (!tmpbuf[i])
|
||||
_throw("tjDecodeYUVPlanes(): Memory allocation failure");
|
||||
THROW("tjDecodeYUVPlanes(): Memory allocation failure");
|
||||
for (row = 0; row < compptr->v_samp_factor; row++) {
|
||||
unsigned char *_tmpbuf_aligned =
|
||||
(unsigned char *)PAD((size_t)_tmpbuf[i], 32);
|
||||
@@ -1445,7 +1490,7 @@ DLLEXPORT int tjDecodeYUVPlanes(tjhandle handle,
|
||||
ph[i] = ph0 * compptr->v_samp_factor / dinfo->max_v_samp_factor;
|
||||
inbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph[i]);
|
||||
if (!inbuf[i])
|
||||
_throw("tjDecodeYUVPlanes(): Memory allocation failure");
|
||||
THROW("tjDecodeYUVPlanes(): Memory allocation failure");
|
||||
ptr = (JSAMPLE *)srcPlanes[i];
|
||||
for (row = 0; row < ph[i]; row++) {
|
||||
inbuf[i][row] = ptr;
|
||||
@@ -1494,12 +1539,12 @@ DLLEXPORT int tjDecodeYUV(tjhandle handle, const unsigned char *srcBuf,
|
||||
int pw0, ph0, strides[3], retval = -1;
|
||||
tjinstance *this = (tjinstance *)handle;
|
||||
|
||||
if (!this) _throwg("tjDecodeYUV(): Invalid handle");
|
||||
if (!this) THROWG("tjDecodeYUV(): Invalid handle");
|
||||
this->isInstanceError = FALSE;
|
||||
|
||||
if (srcBuf == NULL || pad < 0 || !isPow2(pad) || subsamp < 0 ||
|
||||
if (srcBuf == NULL || pad < 0 || !IS_POW2(pad) || subsamp < 0 ||
|
||||
subsamp >= NUMSUBOPT || width <= 0 || height <= 0)
|
||||
_throw("tjDecodeYUV(): Invalid argument");
|
||||
THROW("tjDecodeYUV(): Invalid argument");
|
||||
|
||||
pw0 = tjPlaneWidth(0, width, subsamp);
|
||||
ph0 = tjPlaneHeight(0, height, subsamp);
|
||||
@@ -1538,7 +1583,7 @@ DLLEXPORT int tjDecompressToYUVPlanes(tjhandle handle,
|
||||
JSAMPROW *outbuf[MAX_COMPONENTS], *tmpbuf[MAX_COMPONENTS];
|
||||
int dctsize;
|
||||
|
||||
getdinstance(handle);
|
||||
GET_DINSTANCE(handle);
|
||||
this->jerr.stopOnWarning = (flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE;
|
||||
|
||||
for (i = 0; i < MAX_COMPONENTS; i++) {
|
||||
@@ -1546,11 +1591,11 @@ DLLEXPORT int tjDecompressToYUVPlanes(tjhandle handle,
|
||||
}
|
||||
|
||||
if ((this->init & DECOMPRESS) == 0)
|
||||
_throw("tjDecompressToYUVPlanes(): Instance has not been initialized for decompression");
|
||||
THROW("tjDecompressToYUVPlanes(): Instance has not been initialized for decompression");
|
||||
|
||||
if (jpegBuf == NULL || jpegSize <= 0 || !dstPlanes || !dstPlanes[0] ||
|
||||
width < 0 || height < 0)
|
||||
_throw("tjDecompressToYUVPlanes(): Invalid argument");
|
||||
THROW("tjDecompressToYUVPlanes(): Invalid argument");
|
||||
|
||||
#ifndef NO_PUTENV
|
||||
if (flags & TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1");
|
||||
@@ -1570,10 +1615,10 @@ DLLEXPORT int tjDecompressToYUVPlanes(tjhandle handle,
|
||||
this->headerRead = 0;
|
||||
jpegSubsamp = getSubsamp(dinfo);
|
||||
if (jpegSubsamp < 0)
|
||||
_throw("tjDecompressToYUVPlanes(): Could not determine subsampling type for JPEG image");
|
||||
THROW("tjDecompressToYUVPlanes(): Could not determine subsampling type for JPEG image");
|
||||
|
||||
if (jpegSubsamp != TJSAMP_GRAY && (!dstPlanes[1] || !dstPlanes[2]))
|
||||
_throw("tjDecompressToYUVPlanes(): Invalid argument");
|
||||
THROW("tjDecompressToYUVPlanes(): Invalid argument");
|
||||
|
||||
jpegwidth = dinfo->image_width; jpegheight = dinfo->image_height;
|
||||
if (width == 0) width = jpegwidth;
|
||||
@@ -1585,9 +1630,9 @@ DLLEXPORT int tjDecompressToYUVPlanes(tjhandle handle,
|
||||
break;
|
||||
}
|
||||
if (i >= NUMSF)
|
||||
_throw("tjDecompressToYUVPlanes(): Could not scale down to desired image dimensions");
|
||||
THROW("tjDecompressToYUVPlanes(): Could not scale down to desired image dimensions");
|
||||
if (dinfo->num_components > 3)
|
||||
_throw("tjDecompressToYUVPlanes(): JPEG image must have 3 or fewer components");
|
||||
THROW("tjDecompressToYUVPlanes(): JPEG image must have 3 or fewer components");
|
||||
|
||||
width = scaledw; height = scaledh;
|
||||
dinfo->scale_num = sf[i].num;
|
||||
@@ -1611,7 +1656,7 @@ DLLEXPORT int tjDecompressToYUVPlanes(tjhandle handle,
|
||||
th[i] = compptr->v_samp_factor * dctsize;
|
||||
tmpbufsize += iw[i] * th[i];
|
||||
if ((outbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph[i])) == NULL)
|
||||
_throw("tjDecompressToYUVPlanes(): Memory allocation failure");
|
||||
THROW("tjDecompressToYUVPlanes(): Memory allocation failure");
|
||||
ptr = dstPlanes[i];
|
||||
for (row = 0; row < ph[i]; row++) {
|
||||
outbuf[i][row] = ptr;
|
||||
@@ -1620,11 +1665,11 @@ DLLEXPORT int tjDecompressToYUVPlanes(tjhandle handle,
|
||||
}
|
||||
if (usetmpbuf) {
|
||||
if ((_tmpbuf = (JSAMPLE *)malloc(sizeof(JSAMPLE) * tmpbufsize)) == NULL)
|
||||
_throw("tjDecompressToYUVPlanes(): Memory allocation failure");
|
||||
THROW("tjDecompressToYUVPlanes(): Memory allocation failure");
|
||||
ptr = _tmpbuf;
|
||||
for (i = 0; i < dinfo->num_components; i++) {
|
||||
if ((tmpbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * th[i])) == NULL)
|
||||
_throw("tjDecompressToYUVPlanes(): Memory allocation failure");
|
||||
THROW("tjDecompressToYUVPlanes(): Memory allocation failure");
|
||||
for (row = 0; row < th[i]; row++) {
|
||||
tmpbuf[i][row] = ptr;
|
||||
ptr += iw[i];
|
||||
@@ -1705,12 +1750,12 @@ DLLEXPORT int tjDecompressToYUV2(tjhandle handle, const unsigned char *jpegBuf,
|
||||
int pw0, ph0, strides[3], retval = -1, jpegSubsamp = -1;
|
||||
int i, jpegwidth, jpegheight, scaledw, scaledh;
|
||||
|
||||
getdinstance(handle);
|
||||
GET_DINSTANCE(handle);
|
||||
this->jerr.stopOnWarning = (flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE;
|
||||
|
||||
if (jpegBuf == NULL || jpegSize <= 0 || dstBuf == NULL || width < 0 ||
|
||||
pad < 1 || !isPow2(pad) || height < 0)
|
||||
_throw("tjDecompressToYUV2(): Invalid argument");
|
||||
pad < 1 || !IS_POW2(pad) || height < 0)
|
||||
THROW("tjDecompressToYUV2(): Invalid argument");
|
||||
|
||||
if (setjmp(this->jerr.setjmp_buffer)) {
|
||||
/* If we get here, the JPEG code has signaled an error. */
|
||||
@@ -1721,7 +1766,7 @@ DLLEXPORT int tjDecompressToYUV2(tjhandle handle, const unsigned char *jpegBuf,
|
||||
jpeg_read_header(dinfo, TRUE);
|
||||
jpegSubsamp = getSubsamp(dinfo);
|
||||
if (jpegSubsamp < 0)
|
||||
_throw("tjDecompressToYUV2(): Could not determine subsampling type for JPEG image");
|
||||
THROW("tjDecompressToYUV2(): Could not determine subsampling type for JPEG image");
|
||||
|
||||
jpegwidth = dinfo->image_width; jpegheight = dinfo->image_height;
|
||||
if (width == 0) width = jpegwidth;
|
||||
@@ -1734,7 +1779,7 @@ DLLEXPORT int tjDecompressToYUV2(tjhandle handle, const unsigned char *jpegBuf,
|
||||
break;
|
||||
}
|
||||
if (i >= NUMSF)
|
||||
_throw("tjDecompressToYUV2(): Could not scale down to desired image dimensions");
|
||||
THROW("tjDecompressToYUV2(): Could not scale down to desired image dimensions");
|
||||
|
||||
pw0 = tjPlaneWidth(0, width, jpegSubsamp);
|
||||
ph0 = tjPlaneHeight(0, height, jpegSubsamp);
|
||||
@@ -1799,14 +1844,14 @@ DLLEXPORT int tjTransform(tjhandle handle, const unsigned char *jpegBuf,
|
||||
jvirt_barray_ptr *srccoefs, *dstcoefs;
|
||||
int retval = 0, i, jpegSubsamp, saveMarkers = 0;
|
||||
|
||||
getinstance(handle);
|
||||
GET_INSTANCE(handle);
|
||||
this->jerr.stopOnWarning = (flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE;
|
||||
if ((this->init & COMPRESS) == 0 || (this->init & DECOMPRESS) == 0)
|
||||
_throw("tjTransform(): Instance has not been initialized for transformation");
|
||||
THROW("tjTransform(): Instance has not been initialized for transformation");
|
||||
|
||||
if (jpegBuf == NULL || jpegSize <= 0 || n < 1 || dstBufs == NULL ||
|
||||
dstSizes == NULL || t == NULL || flags < 0)
|
||||
_throw("tjTransform(): Invalid argument");
|
||||
THROW("tjTransform(): Invalid argument");
|
||||
|
||||
#ifndef NO_PUTENV
|
||||
if (flags & TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1");
|
||||
@@ -1816,7 +1861,7 @@ DLLEXPORT int tjTransform(tjhandle handle, const unsigned char *jpegBuf,
|
||||
|
||||
if ((xinfo =
|
||||
(jpeg_transform_info *)malloc(sizeof(jpeg_transform_info) * n)) == NULL)
|
||||
_throw("tjTransform(): Memory allocation failure");
|
||||
THROW("tjTransform(): Memory allocation failure");
|
||||
MEMZERO(xinfo, sizeof(jpeg_transform_info) * n);
|
||||
|
||||
if (setjmp(this->jerr.setjmp_buffer)) {
|
||||
@@ -1854,11 +1899,11 @@ DLLEXPORT int tjTransform(tjhandle handle, const unsigned char *jpegBuf,
|
||||
jpeg_read_header(dinfo, TRUE);
|
||||
jpegSubsamp = getSubsamp(dinfo);
|
||||
if (jpegSubsamp < 0)
|
||||
_throw("tjTransform(): Could not determine subsampling type for JPEG image");
|
||||
THROW("tjTransform(): Could not determine subsampling type for JPEG image");
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (!jtransform_request_workspace(dinfo, &xinfo[i]))
|
||||
_throw("tjTransform(): Transform is not perfect");
|
||||
THROW("tjTransform(): Transform is not perfect");
|
||||
|
||||
if (xinfo[i].crop) {
|
||||
if ((t[i].r.x % xinfo[i].iMCU_sample_width) != 0 ||
|
||||
@@ -1921,7 +1966,7 @@ DLLEXPORT int tjTransform(tjhandle handle, const unsigned char *jpegBuf,
|
||||
for (y = 0; y < compptr->v_samp_factor; y++) {
|
||||
if (t[i].customFilter(barray[y][0], arrayRegion, planeRegion, ci,
|
||||
i, &t[i]) == -1)
|
||||
_throw("tjTransform(): Error in custom filter");
|
||||
THROW("tjTransform(): Error in custom filter");
|
||||
arrayRegion.y += DCTSIZE;
|
||||
}
|
||||
}
|
||||
@@ -1946,7 +1991,8 @@ DLLEXPORT unsigned char *tjLoadImage(const char *filename, int *width,
|
||||
int align, int *height, int *pixelFormat,
|
||||
int flags)
|
||||
{
|
||||
int retval = 0, tempc, pitch;
|
||||
int retval = 0, tempc;
|
||||
size_t pitch;
|
||||
tjhandle handle = NULL;
|
||||
tjinstance *this;
|
||||
j_compress_ptr cinfo = NULL;
|
||||
@@ -1957,21 +2003,21 @@ DLLEXPORT unsigned char *tjLoadImage(const char *filename, int *width,
|
||||
|
||||
if (!filename || !width || align < 1 || !height || !pixelFormat ||
|
||||
*pixelFormat < TJPF_UNKNOWN || *pixelFormat >= TJ_NUMPF)
|
||||
_throwg("tjLoadImage(): Invalid argument");
|
||||
THROWG("tjLoadImage(): Invalid argument");
|
||||
if ((align & (align - 1)) != 0)
|
||||
_throwg("tjLoadImage(): Alignment must be a power of 2");
|
||||
THROWG("tjLoadImage(): Alignment must be a power of 2");
|
||||
|
||||
if ((handle = tjInitCompress()) == NULL) return NULL;
|
||||
this = (tjinstance *)handle;
|
||||
cinfo = &this->cinfo;
|
||||
|
||||
if ((file = fopen(filename, "rb")) == NULL)
|
||||
_throwunix("tjLoadImage(): Cannot open input file");
|
||||
THROW_UNIX("tjLoadImage(): Cannot open input file");
|
||||
|
||||
if ((tempc = getc(file)) < 0 || ungetc(tempc, file) == EOF)
|
||||
_throwunix("tjLoadImage(): Could not read input file")
|
||||
THROW_UNIX("tjLoadImage(): Could not read input file")
|
||||
else if (tempc == EOF)
|
||||
_throwg("tjLoadImage(): Input file contains no data");
|
||||
THROWG("tjLoadImage(): Input file contains no data");
|
||||
|
||||
if (setjmp(this->jerr.setjmp_buffer)) {
|
||||
/* If we get here, the JPEG code has signaled an error. */
|
||||
@@ -1982,14 +2028,14 @@ DLLEXPORT unsigned char *tjLoadImage(const char *filename, int *width,
|
||||
else cinfo->in_color_space = pf2cs[*pixelFormat];
|
||||
if (tempc == 'B') {
|
||||
if ((src = jinit_read_bmp(cinfo, FALSE)) == NULL)
|
||||
_throwg("tjLoadImage(): Could not initialize bitmap loader");
|
||||
THROWG("tjLoadImage(): Could not initialize bitmap loader");
|
||||
invert = (flags & TJFLAG_BOTTOMUP) == 0;
|
||||
} else if (tempc == 'P') {
|
||||
if ((src = jinit_read_ppm(cinfo)) == NULL)
|
||||
_throwg("tjLoadImage(): Could not initialize bitmap loader");
|
||||
THROWG("tjLoadImage(): Could not initialize bitmap loader");
|
||||
invert = (flags & TJFLAG_BOTTOMUP) != 0;
|
||||
} else
|
||||
_throwg("tjLoadImage(): Unsupported file type");
|
||||
THROWG("tjLoadImage(): Unsupported file type");
|
||||
|
||||
src->input_file = file;
|
||||
(*src->start_input) (cinfo, src);
|
||||
@@ -1999,8 +2045,10 @@ DLLEXPORT unsigned char *tjLoadImage(const char *filename, int *width,
|
||||
*pixelFormat = cs2pf[cinfo->in_color_space];
|
||||
|
||||
pitch = PAD((*width) * tjPixelSize[*pixelFormat], align);
|
||||
if ((dstBuf = (unsigned char *)malloc(pitch * (*height))) == NULL)
|
||||
_throwg("tjLoadImage(): Memory allocation failure");
|
||||
if ((unsigned long long)pitch * (unsigned long long)(*height) >
|
||||
(unsigned long long)((size_t)-1) ||
|
||||
(dstBuf = (unsigned char *)malloc(pitch * (*height))) == NULL)
|
||||
THROWG("tjLoadImage(): Memory allocation failure");
|
||||
|
||||
if (setjmp(this->jerr.setjmp_buffer)) {
|
||||
/* If we get here, the JPEG code has signaled an error. */
|
||||
@@ -2047,7 +2095,7 @@ DLLEXPORT int tjSaveImage(const char *filename, unsigned char *buffer,
|
||||
|
||||
if (!filename || !buffer || width < 1 || pitch < 0 || height < 1 ||
|
||||
pixelFormat < 0 || pixelFormat >= TJ_NUMPF)
|
||||
_throwg("tjSaveImage(): Invalid argument");
|
||||
THROWG("tjSaveImage(): Invalid argument");
|
||||
|
||||
if ((handle = tjInitDecompress()) == NULL)
|
||||
return -1;
|
||||
@@ -2055,7 +2103,7 @@ DLLEXPORT int tjSaveImage(const char *filename, unsigned char *buffer,
|
||||
dinfo = &this->dinfo;
|
||||
|
||||
if ((file = fopen(filename, "wb")) == NULL)
|
||||
_throwunix("tjSaveImage(): Cannot open output file");
|
||||
THROW_UNIX("tjSaveImage(): Cannot open output file");
|
||||
|
||||
if (setjmp(this->jerr.setjmp_buffer)) {
|
||||
/* If we get here, the JPEG code has signaled an error. */
|
||||
@@ -2070,11 +2118,11 @@ DLLEXPORT int tjSaveImage(const char *filename, unsigned char *buffer,
|
||||
ptr = strrchr(filename, '.');
|
||||
if (ptr && !strcasecmp(ptr, ".bmp")) {
|
||||
if ((dst = jinit_write_bmp(dinfo, FALSE, FALSE)) == NULL)
|
||||
_throwg("tjSaveImage(): Could not initialize bitmap writer");
|
||||
THROWG("tjSaveImage(): Could not initialize bitmap writer");
|
||||
invert = (flags & TJFLAG_BOTTOMUP) == 0;
|
||||
} else {
|
||||
if ((dst = jinit_write_ppm(dinfo)) == NULL)
|
||||
_throwg("tjSaveImage(): Could not initialize PPM writer");
|
||||
THROWG("tjSaveImage(): Could not initialize PPM writer");
|
||||
invert = (flags & TJFLAG_BOTTOMUP) != 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,8 @@ appear between numbers. Also, comments can be included: a comment starts
|
||||
with '#' and extends to the end of the line. Here is an example file that
|
||||
duplicates the default quantization tables:
|
||||
|
||||
# Quantization tables given in JPEG spec, section K.1
|
||||
# Quantization tables given in Annex K (Clause K.1) of
|
||||
# Recommendation ITU-T T.81 (1992) | ISO/IEC 10918-1:1994.
|
||||
|
||||
# This is table 0 (the luminance table):
|
||||
16 11 10 16 24 40 51 61
|
||||
|
||||
15
wrbmp.c
15
wrbmp.c
@@ -5,7 +5,7 @@
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2013, Linaro Limited.
|
||||
* Copyright (C) 2014-2015, 2017, D. R. Commander.
|
||||
* Copyright (C) 2014-2015, 2017, 2019, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -303,9 +303,7 @@ write_os2_header(j_decompress_ptr cinfo, bmp_dest_ptr dest)
|
||||
int bits_per_pixel, cmap_entries;
|
||||
|
||||
/* Compute colormap size and total file size */
|
||||
if (cinfo->out_color_space == JCS_RGB ||
|
||||
(cinfo->out_color_space >= JCS_EXT_RGB &&
|
||||
cinfo->out_color_space <= JCS_EXT_ARGB)) {
|
||||
if (IsExtRGB(cinfo->out_color_space)) {
|
||||
if (cinfo->quantize_colors) {
|
||||
/* Colormapped RGB */
|
||||
bits_per_pixel = 8;
|
||||
@@ -499,15 +497,14 @@ jinit_write_bmp(j_decompress_ptr cinfo, boolean is_os2,
|
||||
|
||||
if (cinfo->out_color_space == JCS_GRAYSCALE) {
|
||||
dest->pub.put_pixel_rows = put_gray_rows;
|
||||
} else if (cinfo->out_color_space == JCS_RGB ||
|
||||
(cinfo->out_color_space >= JCS_EXT_RGB &&
|
||||
cinfo->out_color_space <= JCS_EXT_ARGB)) {
|
||||
} else if (IsExtRGB(cinfo->out_color_space)) {
|
||||
if (cinfo->quantize_colors)
|
||||
dest->pub.put_pixel_rows = put_gray_rows;
|
||||
else
|
||||
dest->pub.put_pixel_rows = put_pixel_rows;
|
||||
} else if (cinfo->out_color_space == JCS_RGB565 ||
|
||||
cinfo->out_color_space == JCS_CMYK) {
|
||||
} else if (!cinfo->quantize_colors &&
|
||||
(cinfo->out_color_space == JCS_RGB565 ||
|
||||
cinfo->out_color_space == JCS_CMYK)) {
|
||||
dest->pub.put_pixel_rows = put_pixel_rows;
|
||||
} else {
|
||||
ERREXIT(cinfo, JERR_BMP_COLORSPACE);
|
||||
|
||||
@@ -580,7 +580,7 @@ main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
/* Duplicate the remainder of the source file.
|
||||
* Note that any COM markers occuring after SOF will not be touched.
|
||||
* Note that any COM markers occurring after SOF will not be touched.
|
||||
*/
|
||||
write_marker(marker);
|
||||
copy_rest_of_file();
|
||||
|
||||
19
wrppm.c
19
wrppm.c
@@ -5,7 +5,7 @@
|
||||
* Copyright (C) 1991-1996, Thomas G. Lane.
|
||||
* Modified 2009 by Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2017, D. R. Commander.
|
||||
* Copyright (C) 2017, 2019, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
@@ -256,6 +256,8 @@ start_output_ppm(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
|
||||
case JCS_EXT_ABGR:
|
||||
case JCS_EXT_ARGB:
|
||||
case JCS_CMYK:
|
||||
if (!IsExtRGB(cinfo->out_color_space) && cinfo->quantize_colors)
|
||||
ERREXIT(cinfo, JERR_PPM_COLORSPACE);
|
||||
/* emit header for raw PPM format */
|
||||
fprintf(dest->pub.output_file, "P6\n%ld %ld\n%d\n",
|
||||
(long)cinfo->output_width, (long)cinfo->output_height, PPM_MAXVAL);
|
||||
@@ -337,13 +339,14 @@ jinit_write_ppm(j_decompress_ptr cinfo)
|
||||
((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
cinfo->output_width * cinfo->output_components, (JDIMENSION)1);
|
||||
dest->pub.buffer_height = 1;
|
||||
if (IsExtRGB(cinfo->out_color_space))
|
||||
dest->pub.put_pixel_rows = put_rgb;
|
||||
else if (cinfo->out_color_space == JCS_CMYK)
|
||||
dest->pub.put_pixel_rows = put_cmyk;
|
||||
else if (!cinfo->quantize_colors)
|
||||
dest->pub.put_pixel_rows = copy_pixel_rows;
|
||||
else if (cinfo->out_color_space == JCS_GRAYSCALE)
|
||||
if (!cinfo->quantize_colors) {
|
||||
if (IsExtRGB(cinfo->out_color_space))
|
||||
dest->pub.put_pixel_rows = put_rgb;
|
||||
else if (cinfo->out_color_space == JCS_CMYK)
|
||||
dest->pub.put_pixel_rows = put_cmyk;
|
||||
else
|
||||
dest->pub.put_pixel_rows = copy_pixel_rows;
|
||||
} else if (cinfo->out_color_space == JCS_GRAYSCALE)
|
||||
dest->pub.put_pixel_rows = put_demapped_gray;
|
||||
else
|
||||
dest->pub.put_pixel_rows = put_demapped_rgb;
|
||||
|
||||
Reference in New Issue
Block a user