Compare commits

..

1 Commits

Author SHA1 Message Date
Even Rouault 4549632162 .travis.yml: use coverity_scan .travis.yml version 2017-09-21 11:48:58 +02:00
255 changed files with 64193 additions and 13767 deletions

View File

@ -1,30 +0,0 @@
<!--
IMPORTANT: Do NOT use GitHub to post any questions or support requests!
They will be closed immediately and ignored.
Questions should go to the OpenJPEG mailing list at
https://groups.google.com/g/openjpeg or other support forums.
GitHub issues are for bug reports and suggestions for new features.
The OpenJPEG project is made of contributions from various individuals and
organizations, each with their own focus. The issue you are facing is
not necessarily in the priority list of those contributors and consequently
there is no guarantee that it will be addressed in a timely manner.
-->
## Expected behavior and actual behavior.
...to fill...
## Steps to reproduce the problem.
...to fill...
## Operating system
...to fill...
## openjpeg version
...to fill...

View File

@ -1,24 +0,0 @@
name: ABI check
on: [push, pull_request, workflow_dispatch]
jobs:
abi_check:
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]')"
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install Requirements
run: |
sudo apt update
sudo apt install -y gcc g++ libelf-dev elfutils texinfo exuberant-ctags libtiff-dev libwebp-dev libzstd-dev
- name: Build
run: |
./tools/travis-ci/install.sh
./tools/travis-ci/run.sh
./tools/travis-ci/abi-check.sh
env:
OPJ_CI_ABI_CHECK: 1

View File

@ -1,189 +0,0 @@
name: Build
on: [push, pull_request, workflow_dispatch]
jobs:
regular:
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]')"
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install Requirements
run: |
sudo apt update
sudo apt install -y gcc g++ libtiff-dev libwebp-dev libzstd-dev
- name: Build and run tests
run: |
./tools/travis-ci/install.sh
./tools/travis-ci/run.sh
env:
OPJ_CI_ARCH: x86_64
OPJ_CI_BUILD_CONFIGURATION: Release
OPJ_CI_PERF_TESTS: 1
OPJ_CI_BUILD_FUZZERS: 1
OPJ_CI_INCLUDE_IF_DEPLOY: 1
OPJ_NONCOMMERCIAL: 1
- name: Release
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
with:
files: build/openjpeg-*.tar.gz
asan:
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]')"
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install Requirements
run: |
sudo apt update
sudo apt install -y gcc g++
- name: Build and run tests
run: |
./tools/travis-ci/install.sh
./tools/travis-ci/run.sh
env:
OPJ_CI_ARCH: x86_64
OPJ_CI_BUILD_CONFIGURATION: Debug
OPJ_CI_ASAN: 1
OPJ_NONCOMMERCIAL: 1
clang_32bit:
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]')"
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install Requirements
run: |
sudo apt update
sudo apt install -y clang gcc-multilib
- name: Build and run tests
run: |
./tools/travis-ci/install.sh
./tools/travis-ci/run.sh
env:
OPJ_CI_CC: clang
OPJ_CI_CXX: clang++
OPJ_CI_INSTRUCTION_SETS: "-mavx2"
OPJ_CI_BUILD_CONFIGURATION: Release
OPJ_CI_ARCH: i386
OPJ_NUM_THREADS: 2
OPJ_NONCOMMERCIAL: 1
mingw_64:
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]')"
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install Requirements
run: |
sudo apt update
sudo apt install -y gcc-mingw-w64-base binutils-mingw-w64-x86-64 gcc-mingw-w64-x86-64 gcc-mingw-w64 g++-mingw-w64-x86-64
- name: Build and run tests
run: |
./tools/travis-ci/install.sh
./tools/travis-ci/run.sh
env:
OPJ_CI_CC: x86_64-w64-mingw32-gcc
OPJ_CI_CXX: x86_64-w64-mingw32-g++
OPJ_CI_ARCH: x86_64
OPJ_CI_BUILD_CONFIGURATION: Release
OPJ_NONCOMMERCIAL: 1
macos:
runs-on: macos-latest
if: "!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]')"
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Build and run tests
run: |
./tools/travis-ci/install.sh
./tools/travis-ci/run.sh
env:
OPJ_CI_ARCH: x86_64
OPJ_CI_BUILD_CONFIGURATION: Release
OPJ_CI_INCLUDE_IF_DEPLOY: 1
#OPJ_NONCOMMERCIAL: 1
- name: Release
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
with:
files: build/openjpeg-*.zip
windows_build:
runs-on: windows-2019
if: "!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]')"
strategy:
matrix:
include:
- VS_VER: 2019
OPJ_CI_ARCH: x64
OPJ_CI_INCLUDE_IF_DEPLOY: 1
- VS_VER: 2019
OPJ_CI_ARCH: x86
OPJ_CI_INCLUDE_IF_DEPLOY: 1
- VS_VER: 2019
OPJ_CI_ARCH: x64
# We do have specific failures noted in tools/travis-ci/knownfailures-windows-vs2015-x64-avx2-Release-3rdP.txt
# not sure why that happens
OPJ_CI_INSTRUCTION_SETS: "/arch:AVX2"
env:
VS_VER: ${{ matrix.VS_VER }}
OPJ_CI_ARCH: ${{ matrix.OPJ_CI_ARCH }}
OPJ_CI_INCLUDE_IF_DEPLOY: ${{ matrix.OPJ_CI_INCLUDE_IF_DEPLOY }}
OPJ_CI_INSTRUCTION_SETS: ${{ matrix.OPJ_CI_INSTRUCTION_SETS }}
#OPJ_NONCOMMERCIAL: 1
steps:
- name: Setup git
run: |
git config --global core.autocrlf false
git config --system core.longpaths true
- name: Checkout
uses: actions/checkout@v2
- name: Set compiler environment
shell: cmd
run: |
if "%VS_VER%" == "2019" CALL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=%OPJ_CI_ARCH%
echo PATH=%PATH%>> %GITHUB_ENV%
echo INCLUDE=%INCLUDE%>> %GITHUB_ENV%
echo LIB=%LIB%>> %GITHUB_ENV%
echo LIBPATH=%LIBPATH%>> %GITHUB_ENV%
- name: Install wget
shell: cmd
run: |
choco install wget --no-progress
- name: Build and run tests
run: |
./tools/travis-ci/install.sh
./tools/travis-ci/run.sh
shell: bash
- name: Release
uses: softprops/action-gh-release@v1
if: ${{startsWith(github.ref, 'refs/tags/') && env.OPJ_CI_INCLUDE_IF_DEPLOY == 1}}
with:
files: build/openjpeg-*.zip

View File

@ -1,26 +0,0 @@
name: CIFuzz
on: [pull_request]
jobs:
Fuzzing:
runs-on: ubuntu-latest
steps:
- name: Build Fuzzers
id: build
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
with:
oss-fuzz-project-name: 'openjpeg'
dry-run: false
language: c
- name: Run Fuzzers
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
with:
oss-fuzz-project-name: 'openjpeg'
fuzz-seconds: 600
dry-run: false
language: c
- name: Upload Crash
uses: actions/upload-artifact@v1
if: failure() && steps.build.outcome == 'success'
with:
name: artifacts
path: ./out/artifacts

View File

@ -1,26 +0,0 @@
name: Code Style
on: [push, pull_request, workflow_dispatch]
jobs:
code_style:
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]')"
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Install Requirements
run: |
sudo apt update
sudo apt install -y gcc g++ flip
- name: Run check
run: |
./tools/travis-ci/install.sh
./tools/travis-ci/run.sh
env:
OPJ_CI_CHECK_STYLE: 1
OPJ_CI_SKIP_TESTS: 1

3
.gitignore vendored
View File

@ -16,6 +16,3 @@ scripts/opjstyle*
# Ignore directories made by `make`.
/bin/
build
SDK
*.lha

View File

@ -1,163 +1,21 @@
language: cpp
language: c
env:
global:
- secure: "Tx8C7AkTwGDiPEzEaS6t3emevQMYzlcDGilbGWXT7vnSKbftH6lr/9djoKhD2Y2xA62XEfHr9fho9FzUGYuuTADz05qYIdc5m1lILRWok8SFwDt27DS0CpaSpvDYzzCPe70zBdEq1VZ05U+kXA2a4bS+R0xDA8q8vRx4jOl9LjpHvt8R2K7qHkx9LH5YmBz42PjbXdmxJPdFTY8SgWUy7dOMsnPMq0UzTLS54DMlOxSRaCrVw6qv15uIBrgTQiy+XtNft2qe5J+61w6WEhaWhbofuaxuc86jiryA8XUv04WuafoYxaErgf5+nw2/CfMAP2k5TFsNDN/F07xlCj/0aL/kVJGmVsKHUlDBbzEDhkQjw8C6hANOfagBSfRgWvko0E5o0bo0sRrIsbg1feVby7zkfX2a73fTDNC30Z3SSkzTWz37VNJLUMF14LmRDaq4/0DtIAjJDy4qaUwh4RCLcCPlbAf9nmBZn8asIFswPLd4gnktk9n42AyPHNDLExKCwe3+LsVO8ruAlejlnZyEU91vpVMF14j6WeQm2mnYb9CBdOVsBmrskyuTZ4oENDAx14CoxgL6lvxhf+gnZMhvIft1ybM+wQTdfBIl6cqlOMmU9uC8IecQx1Rz/ek17cR3PQXOWQu/jNiU2nJt1WGpBfzYSBjg/e1cVzRvIi+eI5k="
matrix:
include:
# OSX
# OPJ_NONCOMMERCIAL=0 because Kakadu install hangs (cf https://travis-ci.org/github/uclouvain/openjpeg/builds/769447606)
# - os: osx
# compiler: clang
# env: OPJ_NONCOMMERCIAL=0 OPJ_CI_ARCH=x86_64 OPJ_CI_BUILD_CONFIGURATION=Release OPJ_CI_INCLUDE_IF_DEPLOY=1
# Test code style
- os: linux
compiler: clang-3.8
env: OPJ_CI_CC=clang-3.8 OPJ_CI_CXX=clang-3.8 OPJ_CI_CHECK_STYLE=1 OPJ_CI_SKIP_TESTS=1
addons:
apt:
sources:
- llvm-toolchain-precise-3.8
- ubuntu-toolchain-r-test
packages:
- clang-3.8
- flip
# Performance test with GCC
# Disabled because tests fail
# - os: linux
# compiler: g++
# dist: precise
# env: OPJ_CI_ARCH=x86_64 OPJ_CI_BUILD_CONFIGURATION=Release OPJ_CI_INCLUDE_IF_DEPLOY=1 OPJ_CI_PERF_TESTS=1
# Test compilation with AVX2
- os: linux
# "sudo: yes" and "dist: trusty" give us a worker with the AVX2 instruction set
sudo: yes
dist: trusty
compiler: clang-3.8
env: OPJ_CI_CC=clang-3.8 OPJ_CI_CXX=clang-3.8 OPJ_CI_INSTRUCTION_SETS="-mavx2" OPJ_CI_BUILD_CONFIGURATION=Release
addons:
apt:
sources:
- llvm-toolchain-precise-3.8
- ubuntu-toolchain-r-test
packages:
- clang-3.8
# Test multi-threading
# Disabled because tests fail (cf https://travis-ci.org/github/uclouvain/openjpeg/builds/769447606)
# - os: linux
# compiler: g++
# dist: precise
# env: OPJ_CI_ARCH=x86_64 OPJ_CI_BUILD_CONFIGURATION=Release OPJ_NUM_THREADS=2
# Test 32-bit compilation
# Disabled because tests fail (cf https://travis-ci.org/github/uclouvain/openjpeg/builds/769447606)
# - os: linux
# compiler: g++
# env: OPJ_CI_ARCH=i386 OPJ_CI_BUILD_CONFIGURATION=Release
# dist: trusty
# addons:
# apt:
# packages:
# - gcc-multilib
# - g++-multilib
# Profile code (gcc -pg)
# Disabled because tests fail (cf https://travis-ci.org/github/uclouvain/openjpeg/builds/769447606)
# - os: linux
# compiler: g++
# env: OPJ_CI_ARCH=x86_64 OPJ_CI_BUILD_CONFIGURATION=Debug OPJ_CI_PROFILE=1
# dist: trusty
# addons:
# apt:
# packages:
# - valgrind
# Test under ASAN
# Temporarily disabled since broken. See https://github.com/uclouvain/openjpeg/issues/1091
# - os: linux
# compiler: clang
# env: OPJ_CI_ARCH=x86_64 OPJ_CI_BUILD_CONFIGURATION=Debug OPJ_CI_ASAN=1
# Test with CLang 3.8
- os: linux
compiler: clang-3.8
env: OPJ_CI_CC=clang-3.8 OPJ_CI_CXX=clang-3.8 OPJ_CI_ARCH=x86_64 OPJ_CI_BUILD_CONFIGURATION=Release OPJ_CI_PERF_TESTS=1 OPJ_CI_BUILD_FUZZERS=1
dist: trusty
addons:
apt:
sources:
- llvm-toolchain-precise-3.8
- ubuntu-toolchain-r-test
packages:
- clang-3.8
# Test with mingw 32 bit
- os: linux
compiler: x86_64-w64-mingw32-g++
env: OPJ_CI_CC=x86_64-w64-mingw32-gcc OPJ_CI_CXX=x86_64-w64-mingw32-g++ OPJ_CI_ARCH=i386 OPJ_CI_BUILD_CONFIGURATION=Release
dist: trusty
addons:
apt:
packages:
- gcc-mingw-w64-base
- binutils-mingw-w64-i686
- gcc-mingw-w64-i686
- gcc-mingw-w64
- g++-mingw-w64-i686
- gcc-multilib
- g++-multilib
# Test with mingw 64 bit
- os: linux
compiler: x86_64-w64-mingw32-g++
env: OPJ_CI_CC=x86_64-w64-mingw32-gcc OPJ_CI_CXX=x86_64-w64-mingw32-g++ OPJ_CI_ARCH=x86_64 OPJ_CI_BUILD_CONFIGURATION=Release
dist: trusty
addons:
apt:
packages:
- gcc-mingw-w64-base
- binutils-mingw-w64-x86-64
- gcc-mingw-w64-x86-64
- gcc-mingw-w64
- g++-mingw-w64-x86-64
# Test with gcc 4.8
- os: linux
compiler: g++-4.8
env: OPJ_CI_CC=gcc-4.8 OPJ_CI_CXX=g++-4.8 OPJ_CI_ABI_CHECK=1
dist: xenial
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-4.8
- g++-4.8
- libelf-dev
- elfutils
- texinfo
- exuberant-ctags
addons:
coverity_scan:
project:
name: "uclouvain/openjpeg"
description: "Build submitted via Travis CI"
notification_email: info@openjpeg.org
build_command_prepend: "mkdir build && cd build && cmake -G 'Unix Makefiles' -DBUILD_CODEC=ON -DBUILD_THIRDPARTY=ON .."
build_command: "make -j 4"
branch_pattern: coverity_scan
install:
- "./tools/travis-ci/install.sh"
- echo "Coverity scan build"
script:
- "./tools/travis-ci/run.sh"
- "./tools/travis-ci/abi-check.sh"
before_deploy:
- export OPJ_RELEASE_PKG_FILE=$(ls build/openjpeg-${TRAVIS_TAG}*)
- echo "deploying $OPJ_RELEASE_PKG_FILE to GitHub releases"
deploy:
provider: releases
api_key:
secure: dJXdzoFwk9wYWIKztnXKlVIr1QDmeXtk3oK+2MEzy22fBTKPuphU/cYMvhi5B7sWDwm77f43vbAYO6z7IFmuThwhkuVMD/o+lUyCqGffGeiU1pKpxEvB+LbO/C5asdSnor3RfYdOyo3x4cNlhNtfhXIn7FcAg371yEY6VSIP87adoQcuE+taig0cYWcrNWYGHirHlzEz1utnKwCT/nlhV4nSIWxjwYUp3nt8PAw3RbqQkPPNBniW92g6JA25vLRc3HMD18ISCfNLC2fI6a/dTR+vd+bCySA7JvqeDZnv8SxbVIabu5T+A5CHzHbdp2l2kynPwqHOO47pGa+VfisXEwSsOpa+4EZsPLdwOhaFFnvDwKwR3EjI1TkRVd26IcK61Y5zVZQgalnXBowBEZoI4fT/oEPF7VZMjN3sy/do1U6d5kO0UGqCHCJIVwPeELhwq5z7Ld04K7dSFFVenZhhQKCwxI1o8vgkGNJUWD2Ii6ZLrZKYZ0lC65hr2d39e/KoK3Yh5KHF0cVn6ppBTcUjYr/tdHHO43rwoaf3r1CdAQAYpFvfi3900hl9I/GPwky0YJ6W2QDS2vincwaqWDQ0+WNGf4AKSdx5kCgQU45PSfDb/lxAyXkqmBuI3h/C2ellleaWVL9sGtNRWa/w6WseGMGwfCXgN82XRVM2bgP6pYg=
file_glob: true
file: "${OPJ_RELEASE_PKG_FILE}"
skip_cleanup: true
on:
repo: uclouvain/openjpeg
tags: true
condition: "$OPJ_CI_INCLUDE_IF_DEPLOY = 1"
- echo "Coverity scan build"

View File

@ -1,354 +1,6 @@
# Changelog
## [v2.5.0](https://github.com/uclouvain/openjpeg/releases/v2.5.0) (2022-05-13)
[Full Changelog](https://github.com/uclouvain/openjpeg/compare/v2.4.0...v2.5.0)
**Merged pull requests:**
- tools/travis-ci/install.sh: git clone with https:// to fix 'The unaut… [\#1419](https://github.com/uclouvain/openjpeg/pull/1419) ([rouault](https://github.com/rouault))
- Java Support 1.8 now... [\#1418](https://github.com/uclouvain/openjpeg/pull/1418) ([jiapei100](https://github.com/jiapei100))
- Separate fuzz targets to increase coverage [\#1416](https://github.com/uclouvain/openjpeg/pull/1416) ([Navidem](https://github.com/Navidem))
- CMakeLists.txt: do not set INSTALL\_NAME\_DIR for MacOS builds for CMake \>= 3.0 \(fixes \#1404\) [\#1410](https://github.com/uclouvain/openjpeg/pull/1410) ([rouault](https://github.com/rouault))
- Avoid integer overflows in DWT. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=44544 [\#1408](https://github.com/uclouvain/openjpeg/pull/1408) ([rouault](https://github.com/rouault))
- Updated "added support for partial bitstream decoding" [\#1407](https://github.com/uclouvain/openjpeg/pull/1407) ([Neopallium](https://github.com/Neopallium))
- opj\_encoder\_set\_extra\_options\(\): add a GUARD\_BITS=value option [\#1403](https://github.com/uclouvain/openjpeg/pull/1403) ([rouault](https://github.com/rouault))
- More overflow related bug fixes [\#1402](https://github.com/uclouvain/openjpeg/pull/1402) ([Eharve14](https://github.com/Eharve14))
- opj\_j2k\_setup\_encoder\(\): validate number of tiles to avoid illegal values and potential overflow \(fixes \#1399\) [\#1401](https://github.com/uclouvain/openjpeg/pull/1401) ([rouault](https://github.com/rouault))
- Missed conversion from unsigned int to OPJ\_INT32 [\#1398](https://github.com/uclouvain/openjpeg/pull/1398) ([Eharve14](https://github.com/Eharve14))
- Added check for integer overflow in get\_num\_images [\#1397](https://github.com/uclouvain/openjpeg/pull/1397) ([Eharve14](https://github.com/Eharve14))
- Added overflow check for CVE-2021-29338 [\#1396](https://github.com/uclouvain/openjpeg/pull/1396) ([Eharve14](https://github.com/Eharve14))
- Fix integer overflow in num\_images [\#1395](https://github.com/uclouvain/openjpeg/pull/1395) ([baparham](https://github.com/baparham))
- Remove duplicate assignments in function tiftoimage [\#1392](https://github.com/uclouvain/openjpeg/pull/1392) ([stweil](https://github.com/stweil))
- Fix some typos \(found by codespell\) [\#1390](https://github.com/uclouvain/openjpeg/pull/1390) ([stweil](https://github.com/stweil))
- CI: Add CIFuzz action [\#1386](https://github.com/uclouvain/openjpeg/pull/1386) ([DavidKorczynski](https://github.com/DavidKorczynski))
- Feature/decimation [\#1384](https://github.com/uclouvain/openjpeg/pull/1384) ([msheby](https://github.com/msheby))
- API: deprecate 'bpp' member in favor of 'prec' [\#1383](https://github.com/uclouvain/openjpeg/pull/1383) ([rouault](https://github.com/rouault))
- Added support for high throughput \(HTJ2K\) decoding. [\#1381](https://github.com/uclouvain/openjpeg/pull/1381) ([rouault](https://github.com/rouault))
- verify-indentation.sh: fix for pull request from bar/master to foo/master [\#1380](https://github.com/uclouvain/openjpeg/pull/1380) ([rouault](https://github.com/rouault))
- Change integer for version libtiff 4.3.0 [\#1377](https://github.com/uclouvain/openjpeg/pull/1377) ([Jamaika1](https://github.com/Jamaika1))
- Port continuous integration to github actions [\#1376](https://github.com/uclouvain/openjpeg/pull/1376) ([rouault](https://github.com/rouault))
- Avoid integer overflows in DWT. [\#1375](https://github.com/uclouvain/openjpeg/pull/1375) ([rouault](https://github.com/rouault))
- LGTM warning: Comparison result is always the same [\#1373](https://github.com/uclouvain/openjpeg/pull/1373) ([DimitriPapadopoulos](https://github.com/DimitriPapadopoulos))
- A couple typos found by codespell [\#1371](https://github.com/uclouvain/openjpeg/pull/1371) ([DimitriPapadopoulos](https://github.com/DimitriPapadopoulos))
- cmake: add install interface include directory [\#1370](https://github.com/uclouvain/openjpeg/pull/1370) ([madebr](https://github.com/madebr))
- fix issues 1368: exist a issues of freeing uninitialized pointer in src/bin/jp2/opj\_decompress.cthat will cause a segfault [\#1369](https://github.com/uclouvain/openjpeg/pull/1369) ([xiaoxiaoafeifei](https://github.com/xiaoxiaoafeifei))
- opj\_j2k\_is\_imf\_compliant: Fix out of bounds access [\#1366](https://github.com/uclouvain/openjpeg/pull/1366) ([sebras](https://github.com/sebras))
- opj\_j2k\_is\_imf\_compliant: Fix argument formatting for warnings. [\#1365](https://github.com/uclouvain/openjpeg/pull/1365) ([sebras](https://github.com/sebras))
- CMakeLists.txt/appveyor.yml: update version number to 2.5.0… [\#1361](https://github.com/uclouvain/openjpeg/pull/1361) ([rouault](https://github.com/rouault))
- .travis.yml: try to fix gcc 4.8 config by updating to xenial [\#1360](https://github.com/uclouvain/openjpeg/pull/1360) ([rouault](https://github.com/rouault))
- Add support for enabling generation of TLM markers in encoder [\#1359](https://github.com/uclouvain/openjpeg/pull/1359) ([rouault](https://github.com/rouault))
- Fix various compiler warnings [\#1358](https://github.com/uclouvain/openjpeg/pull/1358) ([rouault](https://github.com/rouault))
- fix \#1345: don't remove big endian test for other platforms [\#1354](https://github.com/uclouvain/openjpeg/pull/1354) ([msabwat](https://github.com/msabwat))
- Remove obsolete components JPWL, JP3D and MJ2 [\#1350](https://github.com/uclouvain/openjpeg/pull/1350) ([rouault](https://github.com/rouault))
- tools/travis-ci/install.sh: fix links to Kakadu and jpylyzer binaries [\#1348](https://github.com/uclouvain/openjpeg/pull/1348) ([rouault](https://github.com/rouault))
- emscripten: disable big endian test [\#1345](https://github.com/uclouvain/openjpeg/pull/1345) ([msabwat](https://github.com/msabwat))
- Fix cmake file with DESTDIR [\#1321](https://github.com/uclouvain/openjpeg/pull/1321) ([ffontaine](https://github.com/ffontaine))
- CMakeLists.txt: Don't require a C++ compiler [\#1317](https://github.com/uclouvain/openjpeg/pull/1317) ([ffontaine](https://github.com/ffontaine))
- Import files tiff and yuv\(raw\) [\#1316](https://github.com/uclouvain/openjpeg/pull/1316) ([Jamaika1](https://github.com/Jamaika1))
- Fix year in NEWS [\#1312](https://github.com/uclouvain/openjpeg/pull/1312) ([stweil](https://github.com/stweil))
- Fix lcms2 static linking using pgk config [\#867](https://github.com/uclouvain/openjpeg/pull/867) ([pseiderer](https://github.com/pseiderer))
- fix static build only against tiff and its indirect dependencies [\#866](https://github.com/uclouvain/openjpeg/pull/866) ([tSed](https://github.com/tSed))
**Closed issues:**
- integer constant is too large for 'long' type [\#61](https://github.com/uclouvain/openjpeg/issues/61)
- Openjpeg3D lossy compression not working [\#501](https://github.com/uclouvain/openjpeg/issues/501)
- mj2: Array overflow [\#485](https://github.com/uclouvain/openjpeg/issues/485)
- OPJ fails to decode image that KDU manages correctly [\#419](https://github.com/uclouvain/openjpeg/issues/419)
- yuvtoimage\(\) bug in v1 and v2 for 16-Bit: please apply ASAP [\#384](https://github.com/uclouvain/openjpeg/issues/384)
- JP3D: Fix CVE-2013-4289 CVE-2013-4290 [\#298](https://github.com/uclouvain/openjpeg/issues/298)
- MJ2 libraries are installed in lib [\#204](https://github.com/uclouvain/openjpeg/issues/204)
- MJ2: realloc is misused and may leak memory [\#168](https://github.com/uclouvain/openjpeg/issues/168)
- MJ2 wrapper not functional [\#143](https://github.com/uclouvain/openjpeg/issues/143)
- JPWL is broken in trunk [\#137](https://github.com/uclouvain/openjpeg/issues/137)
- MJ2 files not using OPENJPEG API correctly [\#53](https://github.com/uclouvain/openjpeg/issues/53)
- Maximum bit depth supported by the OpenJPEG implementation of JP3D [\#9](https://github.com/uclouvain/openjpeg/issues/9)
- does openjpeg support either visually lossless or numerically lossless jpeg2000 compression? [\#1406](https://github.com/uclouvain/openjpeg/issues/1406)
- extract jpeg2000 tile without decompression [\#1405](https://github.com/uclouvain/openjpeg/issues/1405)
- openjpeg doesn't install a relocatable shared lib on macOS [\#1404](https://github.com/uclouvain/openjpeg/issues/1404)
- pull request - the cinema industry awaits! [\#1400](https://github.com/uclouvain/openjpeg/issues/1400)
- Integer overflows in j2K [\#1399](https://github.com/uclouvain/openjpeg/issues/1399)
- why lossly compression performance worse than jpeg when compress png [\#1393](https://github.com/uclouvain/openjpeg/issues/1393)
- cect [\#1389](https://github.com/uclouvain/openjpeg/issues/1389)
- the docs don't describe bpp and prec in opj\_image\_comp very well [\#1379](https://github.com/uclouvain/openjpeg/issues/1379)
- converting .png to .jp2 by opj\_compress is different from the original image [\#1378](https://github.com/uclouvain/openjpeg/issues/1378)
- Comparison result is always the same [\#1372](https://github.com/uclouvain/openjpeg/issues/1372)
- Exist a issues of freeing uninitialized pointer in src/bin/jp2/opj\_decompress.cthat will cause a segfault [\#1368](https://github.com/uclouvain/openjpeg/issues/1368)
- \[TEST NOT RUNNING\]: bigendian test [\#1355](https://github.com/uclouvain/openjpeg/issues/1355)
- opj\_decompress 2.4.0 built with library 2.3.0. [\#1352](https://github.com/uclouvain/openjpeg/issues/1352)
- New library htjpeg2000 [\#1351](https://github.com/uclouvain/openjpeg/issues/1351)
- Integer Overflow in num\_images [\#1338](https://github.com/uclouvain/openjpeg/issues/1338)
- All IMF Profile Selections Result in PART1 [\#1337](https://github.com/uclouvain/openjpeg/issues/1337)
- grayscale image [\#1334](https://github.com/uclouvain/openjpeg/issues/1334)
- error C2169: 'lrintf': intrinsic function, cannot be defined [\#1333](https://github.com/uclouvain/openjpeg/issues/1333)
- Generate lower-case extension [\#1332](https://github.com/uclouvain/openjpeg/issues/1332)
- color of reconstructed png file much darker [\#1330](https://github.com/uclouvain/openjpeg/issues/1330)
- CVE-2019-6988, CVE-2018-20846 and CVE-2018-16376 [\#1328](https://github.com/uclouvain/openjpeg/issues/1328)
- opj 2.4.0: opj\_free missing in opj3d [\#1327](https://github.com/uclouvain/openjpeg/issues/1327)
- Not able to compress volumetric data [\#1326](https://github.com/uclouvain/openjpeg/issues/1326)
- HTML documents are not installed in specified place [\#1322](https://github.com/uclouvain/openjpeg/issues/1322)
- Can't find openjpeg.h when cross-compile. [\#1320](https://github.com/uclouvain/openjpeg/issues/1320)
- OpenJPEG is available with EasyConfig [\#1319](https://github.com/uclouvain/openjpeg/issues/1319)
- Building Test Programs [\#1318](https://github.com/uclouvain/openjpeg/issues/1318)
- Builds are not reproducible [\#1275](https://github.com/uclouvain/openjpeg/issues/1275)
- strange behaviour of opj\_jp3d\_compress/decompress utility [\#1274](https://github.com/uclouvain/openjpeg/issues/1274)
- Potential heap-based buffer overflow in function t2\_encode\_packet in src/lib/openmj2/t2.c and src/lib/openjp3d/t2.c [\#1272](https://github.com/uclouvain/openjpeg/issues/1272)
- Function tgatoimage in src/bin/jpwl/convert.c need to check that the file is big enough to avoid excessive memory allocations [\#1271](https://github.com/uclouvain/openjpeg/issues/1271)
- memory & cpu are exhausted when converting jp2 file into png [\#1250](https://github.com/uclouvain/openjpeg/issues/1250)
- Cannot compress PGX into JP3D despite following the directions? [\#1134](https://github.com/uclouvain/openjpeg/issues/1134)
- sscanf buffer overflow in opj\_jp3d\_compress.c [\#1130](https://github.com/uclouvain/openjpeg/issues/1130)
- integer underflow may lead to writing garbage [\#1089](https://github.com/uclouvain/openjpeg/issues/1089)
- sscanf buffer overflow [\#1087](https://github.com/uclouvain/openjpeg/issues/1087)
- strcpy overflows [\#1086](https://github.com/uclouvain/openjpeg/issues/1086)
- sprintf buffer overflows [\#1084](https://github.com/uclouvain/openjpeg/issues/1084)
- strcpy buffer overflow [\#1083](https://github.com/uclouvain/openjpeg/issues/1083)
- integer overflow in malloc\(\) [\#1082](https://github.com/uclouvain/openjpeg/issues/1082)
- out of bounds writes [\#1078](https://github.com/uclouvain/openjpeg/issues/1078)
- out of bounds writes [\#1077](https://github.com/uclouvain/openjpeg/issues/1077)
- divide by zero, perhaps multiplication overflow [\#1076](https://github.com/uclouvain/openjpeg/issues/1076)
- missing format string parameter [\#1075](https://github.com/uclouvain/openjpeg/issues/1075)
- leaks from cppcheck in lib folder [\#1038](https://github.com/uclouvain/openjpeg/issues/1038)
- How to initialize DEBUG\_PROFILE in color.c? [\#958](https://github.com/uclouvain/openjpeg/issues/958)
- JP3D sample files [\#865](https://github.com/uclouvain/openjpeg/issues/865)
- BIG\_ENDIAN bug in jpwl.c [\#839](https://github.com/uclouvain/openjpeg/issues/839)
- OpenJPEG fails to decode partial j2c where kdu succeeds [\#715](https://github.com/uclouvain/openjpeg/issues/715)
- building mj2 binaries fails [\#652](https://github.com/uclouvain/openjpeg/issues/652)
- openmj2\mj2.c: Out of bounds [\#646](https://github.com/uclouvain/openjpeg/issues/646)
- bin\mj2\opj\_mj2\_decompress.c 101 wrong check / leak [\#608](https://github.com/uclouvain/openjpeg/issues/608)
## [v2.4.0](https://github.com/uclouvain/openjpeg/releases/v2.4.0) (2020-12-28)
[Full Changelog](https://github.com/uclouvain/openjpeg/compare/v2.3.1...v2.4.0)
**Closed issues:**
- OPENJPEG\_INSTALL\_DOC\_DIR does not control a destination directory where HTML docs would be installed. [\#1309](https://github.com/uclouvain/openjpeg/issues/1309)
- Heap-buffer-overflow in lib/openjp2/pi.c:312 [\#1302](https://github.com/uclouvain/openjpeg/issues/1302)
- Heap-buffer-overflow in lib/openjp2/t2.c:973 [\#1299](https://github.com/uclouvain/openjpeg/issues/1299)
- Heap-buffer-overflow in lib/openjp2/pi.c:623 [\#1293](https://github.com/uclouvain/openjpeg/issues/1293)
- Global-buffer-overflow in lib/openjp2/dwt.c:1980 [\#1286](https://github.com/uclouvain/openjpeg/issues/1286)
- Heap-buffer-overflow in lib/openjp2/tcd.c:2417 [\#1284](https://github.com/uclouvain/openjpeg/issues/1284)
- Heap-buffer-overflow in lib/openjp2/mqc.c:499 [\#1283](https://github.com/uclouvain/openjpeg/issues/1283)
- Openjpeg could not encode 32bit RGB float image [\#1281](https://github.com/uclouvain/openjpeg/issues/1281)
- Openjpeg could not encode 32bit RGB float image [\#1280](https://github.com/uclouvain/openjpeg/issues/1280)
- ISO/IEC 15444-1:2019 \(E\) compared with 'cio.h' [\#1277](https://github.com/uclouvain/openjpeg/issues/1277)
- Test-suite failure due to hash mismatch [\#1264](https://github.com/uclouvain/openjpeg/issues/1264)
- Heap use-after-free [\#1261](https://github.com/uclouvain/openjpeg/issues/1261)
- Memory leak when failing to allocate object... [\#1259](https://github.com/uclouvain/openjpeg/issues/1259)
- Memory leak of Tier 1 handle when OpenJPEG fails to set it as TLS... [\#1257](https://github.com/uclouvain/openjpeg/issues/1257)
- Any plan to build release for CVE-2020-8112/CVE-2020-6851 [\#1247](https://github.com/uclouvain/openjpeg/issues/1247)
- failing to convert 16-bit file: opj\_t2\_encode\_packet\(\): only 5251 bytes remaining in output buffer. 5621 needed. [\#1243](https://github.com/uclouvain/openjpeg/issues/1243)
- CMake+VS2017 Compile OK, thirdparty Compile OK, but thirdparty not install [\#1239](https://github.com/uclouvain/openjpeg/issues/1239)
- New release to solve CVE-2019-6988 ? [\#1238](https://github.com/uclouvain/openjpeg/issues/1238)
- Many tests fail to pass after the update of libtiff to version 4.1.0 [\#1233](https://github.com/uclouvain/openjpeg/issues/1233)
- Another heap buffer overflow in libopenjp2 [\#1231](https://github.com/uclouvain/openjpeg/issues/1231)
- Heap buffer overflow in libopenjp2 [\#1228](https://github.com/uclouvain/openjpeg/issues/1228)
- Endianness of binary volume \(JP3D\) [\#1224](https://github.com/uclouvain/openjpeg/issues/1224)
- New release to resolve CVE-2019-12973 [\#1222](https://github.com/uclouvain/openjpeg/issues/1222)
- how to set the block size,like 128,256 ? [\#1216](https://github.com/uclouvain/openjpeg/issues/1216)
- compress YUV files to motion jpeg2000 standard [\#1213](https://github.com/uclouvain/openjpeg/issues/1213)
- Repair/update Java wrapper, and include in release [\#1208](https://github.com/uclouvain/openjpeg/issues/1208)
- abc [\#1206](https://github.com/uclouvain/openjpeg/issues/1206)
- Slow decoding [\#1202](https://github.com/uclouvain/openjpeg/issues/1202)
- Installation question [\#1201](https://github.com/uclouvain/openjpeg/issues/1201)
- Typo in test\_decode\_area - \*ptilew is assigned instead of \*ptileh [\#1195](https://github.com/uclouvain/openjpeg/issues/1195)
- Creating a J2K file with one POC is broken [\#1191](https://github.com/uclouvain/openjpeg/issues/1191)
- Make fails on Arch Linux [\#1174](https://github.com/uclouvain/openjpeg/issues/1174)
- Heap buffer overflow in opj\_t1\_clbl\_decode\_processor\(\) triggered with Ghostscript [\#1158](https://github.com/uclouvain/openjpeg/issues/1158)
- opj\_stream\_get\_number\_byte\_left: Assertion `p\_stream-\>m\_byte\_offset \>= 0' failed. [\#1151](https://github.com/uclouvain/openjpeg/issues/1151)
- The fuzzer ignores too many inputs [\#1079](https://github.com/uclouvain/openjpeg/issues/1079)
- out of bounds read [\#1068](https://github.com/uclouvain/openjpeg/issues/1068)
**Merged pull requests:**
- Change defined WIN32 [\#1310](https://github.com/uclouvain/openjpeg/pull/1310) ([Jamaika1](https://github.com/Jamaika1))
- docs: fix simple typo, producted -\> produced [\#1308](https://github.com/uclouvain/openjpeg/pull/1308) ([timgates42](https://github.com/timgates42))
- Set ${OPENJPEG\_INSTALL\_DOC\_DIR} to DESTINATION of HTMLs [\#1307](https://github.com/uclouvain/openjpeg/pull/1307) ([lemniscati](https://github.com/lemniscati))
- Use INC\_DIR for OPENJPEG\_INCLUDE\_DIRS \(fixes uclouvain\#1174\) [\#1306](https://github.com/uclouvain/openjpeg/pull/1306) ([matthew-sharp](https://github.com/matthew-sharp))
- pi.c: avoid out of bounds access with POC \(fixes \#1302\) [\#1304](https://github.com/uclouvain/openjpeg/pull/1304) ([rouault](https://github.com/rouault))
- Encoder: grow again buffer size [\#1303](https://github.com/uclouvain/openjpeg/pull/1303) ([zodf0055980](https://github.com/zodf0055980))
- opj\_j2k\_write\_sod\(\): avoid potential heap buffer overflow \(fixes \#1299\) \(probably master only\) [\#1301](https://github.com/uclouvain/openjpeg/pull/1301) ([rouault](https://github.com/rouault))
- pi.c: avoid out of bounds access with POC \(refs https://github.com/uclouvain/openjpeg/issues/1293\#issuecomment-737122836\) [\#1300](https://github.com/uclouvain/openjpeg/pull/1300) ([rouault](https://github.com/rouault))
- opj\_t2\_encode\_packet\(\): avoid out of bound access of \#1297, but likely not the proper fix [\#1298](https://github.com/uclouvain/openjpeg/pull/1298) ([rouault](https://github.com/rouault))
- opj\_t2\_encode\_packet\(\): avoid out of bound access of \#1294, but likely not the proper fix [\#1296](https://github.com/uclouvain/openjpeg/pull/1296) ([rouault](https://github.com/rouault))
- opj\_j2k\_setup\_encoder\(\): validate POC compno0 and compno1 \(fixes \#1293\) [\#1295](https://github.com/uclouvain/openjpeg/pull/1295) ([rouault](https://github.com/rouault))
- Encoder: avoid global buffer overflow on irreversible conversion when… [\#1292](https://github.com/uclouvain/openjpeg/pull/1292) ([rouault](https://github.com/rouault))
- Decoding: deal with some SPOT6 images that have tiles with a single tile-part with TPsot == 0 and TNsot == 0, and with missing EOC [\#1291](https://github.com/uclouvain/openjpeg/pull/1291) ([rouault](https://github.com/rouault))
- Free p\_tcd\_marker\_info to avoid memory leak [\#1288](https://github.com/uclouvain/openjpeg/pull/1288) ([zodf0055980](https://github.com/zodf0055980))
- Encoder: grow again buffer size [\#1287](https://github.com/uclouvain/openjpeg/pull/1287) ([zodf0055980](https://github.com/zodf0055980))
- Encoder: avoid uint32 overflow when allocating memory for codestream buffer \(fixes \#1243\) [\#1276](https://github.com/uclouvain/openjpeg/pull/1276) ([rouault](https://github.com/rouault))
- Java compatibility from 1.5 to 1.6 [\#1263](https://github.com/uclouvain/openjpeg/pull/1263) ([jiapei100](https://github.com/jiapei100))
- opj\_decompress: fix double-free on input directory with mix of valid and invalid images [\#1262](https://github.com/uclouvain/openjpeg/pull/1262) ([rouault](https://github.com/rouault))
- openjp2: Plug image leak when failing to allocate codestream index. [\#1260](https://github.com/uclouvain/openjpeg/pull/1260) ([sebras](https://github.com/sebras))
- openjp2: Plug memory leak when setting data as TLS fails. [\#1258](https://github.com/uclouvain/openjpeg/pull/1258) ([sebras](https://github.com/sebras))
- openjp2: Error out if failing to create Tier 1 handle. [\#1256](https://github.com/uclouvain/openjpeg/pull/1256) ([sebras](https://github.com/sebras))
- Testing for invalid values of width, height, numcomps [\#1254](https://github.com/uclouvain/openjpeg/pull/1254) ([szukw000](https://github.com/szukw000))
- Single-threaded performance improvements in forward DWT for 5-3 and 9-7 \(and other improvements\) [\#1253](https://github.com/uclouvain/openjpeg/pull/1253) ([rouault](https://github.com/rouault))
- Add support for multithreading in encoder [\#1248](https://github.com/uclouvain/openjpeg/pull/1248) ([rouault](https://github.com/rouault))
- Add support for generation of PLT markers in encoder [\#1246](https://github.com/uclouvain/openjpeg/pull/1246) ([rouault](https://github.com/rouault))
- Fix warnings about signed/unsigned casts in pi.c [\#1244](https://github.com/uclouvain/openjpeg/pull/1244) ([rouault](https://github.com/rouault))
- opj\_decompress: add sanity checks to avoid segfault in case of decoding error [\#1240](https://github.com/uclouvain/openjpeg/pull/1240) ([rouault](https://github.com/rouault))
- ignore wrong icc [\#1236](https://github.com/uclouvain/openjpeg/pull/1236) ([szukw000](https://github.com/szukw000))
- Implement writing of IMF profiles [\#1235](https://github.com/uclouvain/openjpeg/pull/1235) ([rouault](https://github.com/rouault))
- tests: add alternate checksums for libtiff 4.1 [\#1234](https://github.com/uclouvain/openjpeg/pull/1234) ([rouault](https://github.com/rouault))
- opj\_tcd\_init\_tile\(\): avoid integer overflow [\#1232](https://github.com/uclouvain/openjpeg/pull/1232) ([rouault](https://github.com/rouault))
- tests/fuzzers: link fuzz binaries using $LIB\_FUZZING\_ENGINE. [\#1230](https://github.com/uclouvain/openjpeg/pull/1230) ([Dor1s](https://github.com/Dor1s))
- opj\_j2k\_update\_image\_dimensions\(\): reject images whose coordinates are beyond INT\_MAX \(fixes \#1228\) [\#1229](https://github.com/uclouvain/openjpeg/pull/1229) ([rouault](https://github.com/rouault))
- Fix resource leaks [\#1226](https://github.com/uclouvain/openjpeg/pull/1226) ([dodys](https://github.com/dodys))
- abi-check.sh: fix false positive ABI error, and display output error log [\#1218](https://github.com/uclouvain/openjpeg/pull/1218) ([rouault](https://github.com/rouault))
- pi.c: avoid integer overflow, resulting in later invalid access to memory in opj\_t2\_decode\_packets\(\) [\#1217](https://github.com/uclouvain/openjpeg/pull/1217) ([rouault](https://github.com/rouault))
- Add check to validate SGcod/SPcoc/SPcod parameter values. [\#1211](https://github.com/uclouvain/openjpeg/pull/1211) ([sebras](https://github.com/sebras))
- Fix buffer overflow reading an image file less than four characters [\#1196](https://github.com/uclouvain/openjpeg/pull/1196) ([robert-ancell](https://github.com/robert-ancell))
- compression: emit POC marker when only one single POC is requested \(f… [\#1192](https://github.com/uclouvain/openjpeg/pull/1192) ([rouault](https://github.com/rouault))
- Fix several potential vulnerabilities [\#1185](https://github.com/uclouvain/openjpeg/pull/1185) ([Young-X](https://github.com/Young-X))
- openjp2/j2k: Report error if all wanted components are not decoded. [\#1164](https://github.com/uclouvain/openjpeg/pull/1164) ([sebras](https://github.com/sebras))
## [v2.3.1](https://github.com/uclouvain/openjpeg/releases/v2.3.1) (2019-04-02)
[Full Changelog](https://github.com/uclouvain/openjpeg/compare/v2.3.0...v2.3.1)
**Closed issues:**
- v2.2.0 regression for decoding images where TNsot == 0 [\#1120](https://github.com/uclouvain/openjpeg/issues/1120)
- Int overflow in jp3d [\#1162](https://github.com/uclouvain/openjpeg/issues/1162)
- Heap buffer overflow in opj\_j2k\_update\_image\_data\(\) triggered with Ghostscript [\#1157](https://github.com/uclouvain/openjpeg/issues/1157)
- LINUX install doesn't work when building shared libraries is disabled [\#1155](https://github.com/uclouvain/openjpeg/issues/1155)
- OPENJPEG null ptr dereference in openjpeg-2.3.0/src/bin/jp2/convert.c:2243 [\#1152](https://github.com/uclouvain/openjpeg/issues/1152)
- How to drop certain subbands/layers in DWT [\#1147](https://github.com/uclouvain/openjpeg/issues/1147)
- where is the MQ-Coder ouput stream in t2.c? [\#1146](https://github.com/uclouvain/openjpeg/issues/1146)
- OpenJPEG 2.3 \(and 2.2?\) multi component image fails to decode with KDU v7.10 [\#1132](https://github.com/uclouvain/openjpeg/issues/1132)
- Missing checks for header\_info.height and header\_info.width in function pnmtoimage in src/bin/jpwl/convert.c, which can lead to heap buffer overflow [\#1126](https://github.com/uclouvain/openjpeg/issues/1126)
- Assertion Failure in jp2.c [\#1125](https://github.com/uclouvain/openjpeg/issues/1125)
- Division-by-zero vulnerabilities in the function pi\_next\_pcrl, pi\_next\_cprl and pi\_next\_rpcl in src/lib/openjp3d/pi.c [\#1123](https://github.com/uclouvain/openjpeg/issues/1123)
- Precinct switch \(-c\) doesn't right-shift last record to remaining resolution levels [\#1117](https://github.com/uclouvain/openjpeg/issues/1117)
- Sample: encode J2K a data using streams??? [\#1114](https://github.com/uclouvain/openjpeg/issues/1114)
- HIGH THROUGHPUT JPEG 2000 \(HTJ2K\) [\#1112](https://github.com/uclouvain/openjpeg/issues/1112)
- How to build openjpeg for arm linux? [\#1108](https://github.com/uclouvain/openjpeg/issues/1108)
- crash [\#1106](https://github.com/uclouvain/openjpeg/issues/1106)
- JP2000 returning OPJ\_CLRSPC\_UNKNOWN color space [\#1103](https://github.com/uclouvain/openjpeg/issues/1103)
- Compilation successful but install unsuccessful: Calling executables throws libraries missing error [\#1102](https://github.com/uclouvain/openjpeg/issues/1102)
- fprintf format string requires 1 parameter but only 0 are given [\#1093](https://github.com/uclouvain/openjpeg/issues/1093)
- fprintf format string requires 1 parameter but only 0 are given [\#1092](https://github.com/uclouvain/openjpeg/issues/1092)
- sprintf buffer overflow [\#1088](https://github.com/uclouvain/openjpeg/issues/1088)
- sprintf buffer overflow [\#1085](https://github.com/uclouvain/openjpeg/issues/1085)
- Infinite loop when reading jp2 [\#1081](https://github.com/uclouvain/openjpeg/issues/1081)
- missing format string parameter [\#1074](https://github.com/uclouvain/openjpeg/issues/1074)
- Excessive Iteration in opj\_t1\_encode\_cblks \(src/lib/openjp2/t1.c\) [\#1059](https://github.com/uclouvain/openjpeg/issues/1059)
- Out-of-bound left shift in opj\_j2k\_setup\_encoder \(src/lib/openjp2/j2k.c\) [\#1057](https://github.com/uclouvain/openjpeg/issues/1057)
- Encode image on Unsplash [\#1054](https://github.com/uclouvain/openjpeg/issues/1054)
- Integer overflow in opj\_t1\_encode\_cblks \(src/lib/openjp2/t1.c\) [\#1053](https://github.com/uclouvain/openjpeg/issues/1053)
- Signed Integer Overflow - 68065512 [\#1048](https://github.com/uclouvain/openjpeg/issues/1048)
- Similar vulnerable functions related to CVE-2017-14041 [\#1044](https://github.com/uclouvain/openjpeg/issues/1044)
- \[ERROR\] COD marker already read. No more than one COD marker per tile. [\#1043](https://github.com/uclouvain/openjpeg/issues/1043)
- failing to install latest version of openjpeg from source [\#1041](https://github.com/uclouvain/openjpeg/issues/1041)
- Trouble compressing large raw image [\#1032](https://github.com/uclouvain/openjpeg/issues/1032)
- Download and installed code from 2.3 archive. Installing 2.2? [\#1030](https://github.com/uclouvain/openjpeg/issues/1030)
- missing fclose [\#1029](https://github.com/uclouvain/openjpeg/issues/1029)
- NULL Pointer Access in function imagetopnm of convert.c\(jp2\):1289 [\#860](https://github.com/uclouvain/openjpeg/issues/860)
- NULL Pointer Access in function imagetopnm of convert.c:2226\(jp2\) [\#859](https://github.com/uclouvain/openjpeg/issues/859)
- Heap Buffer Overflow in function imagetotga of convert.c\(jp2\):942 [\#858](https://github.com/uclouvain/openjpeg/issues/858)
**Merged pull requests:**
- abi-check.sh: fix broken download URL [\#1188](https://github.com/uclouvain/openjpeg/pull/1188) ([rouault](https://github.com/rouault))
- opj\_t1\_encode\_cblks: fix UBSAN signed integer overflow [\#1187](https://github.com/uclouvain/openjpeg/pull/1187) ([rouault](https://github.com/rouault))
- convertbmp: detect invalid file dimensions early \(CVE-2018-6616\) [\#1172](https://github.com/uclouvain/openjpeg/pull/1172) ([hlef](https://github.com/hlef))
- color\_apply\_icc\_profile: avoid potential heap buffer overflow [\#1170](https://github.com/uclouvain/openjpeg/pull/1170) ([rouault](https://github.com/rouault))
- Fix multiple potential vulnerabilities and bugs [\#1168](https://github.com/uclouvain/openjpeg/pull/1168) ([Young-X](https://github.com/Young-X))
- Fix several memory and resource leaks [\#1163](https://github.com/uclouvain/openjpeg/pull/1163) ([nforro](https://github.com/nforro))
- Fix some potential overflow issues [\#1161](https://github.com/uclouvain/openjpeg/pull/1161) ([stweil](https://github.com/stweil))
- jp3d/jpwl convert: fix write stack buffer overflow [\#1160](https://github.com/uclouvain/openjpeg/pull/1160) ([hlef](https://github.com/hlef))
- Int overflow fixed [\#1159](https://github.com/uclouvain/openjpeg/pull/1159) ([ichlubna](https://github.com/ichlubna))
- Update knownfailures- files given current configurations [\#1149](https://github.com/uclouvain/openjpeg/pull/1149) ([rouault](https://github.com/rouault))
- CVE-2018-5785: fix issues with zero bitmasks [\#1148](https://github.com/uclouvain/openjpeg/pull/1148) ([hlef](https://github.com/hlef))
- openjp2/jp2: Fix two format strings [\#1143](https://github.com/uclouvain/openjpeg/pull/1143) ([stweil](https://github.com/stweil))
- Changes in pnmtoimage if image data are missing [\#1141](https://github.com/uclouvain/openjpeg/pull/1141) ([szukw000](https://github.com/szukw000))
- Relative path to header files is hardcoded in OpenJPEGConfig.cmake.in file [\#1140](https://github.com/uclouvain/openjpeg/pull/1140) ([bukatlib](https://github.com/bukatlib))
- Cast on uint ceildiv [\#1136](https://github.com/uclouvain/openjpeg/pull/1136) ([reverson](https://github.com/reverson))
- Add -DBUILD\_PKGCONFIG\_FILES to install instructions [\#1133](https://github.com/uclouvain/openjpeg/pull/1133) ([robe2](https://github.com/robe2))
- Fix some typos in code comments and documentation [\#1128](https://github.com/uclouvain/openjpeg/pull/1128) ([stweil](https://github.com/stweil))
- Fix regression in reading files with TNsot == 0 \(refs \#1120\) [\#1121](https://github.com/uclouvain/openjpeg/pull/1121) ([rouault](https://github.com/rouault))
- Use local type declaration for POSIX standard type only for MS compiler [\#1119](https://github.com/uclouvain/openjpeg/pull/1119) ([stweil](https://github.com/stweil))
- Fix Mac builds [\#1104](https://github.com/uclouvain/openjpeg/pull/1104) ([rouault](https://github.com/rouault))
- jp3d: Replace sprintf\(\) by snprintf\(\) in volumetobin\(\) [\#1101](https://github.com/uclouvain/openjpeg/pull/1101) ([kbabioch](https://github.com/kbabioch))
- opj\_mj2\_extract: Rename output\_location to output\_prefix [\#1096](https://github.com/uclouvain/openjpeg/pull/1096) ([kbabioch](https://github.com/kbabioch))
- mj2: Add missing variable to format string in fprintf\(\) invocation in meta\_out.c [\#1094](https://github.com/uclouvain/openjpeg/pull/1094) ([kbabioch](https://github.com/kbabioch))
- Convert files to UTF-8 encoding [\#1090](https://github.com/uclouvain/openjpeg/pull/1090) ([stweil](https://github.com/stweil))
- fix unchecked integer multiplication overflow [\#1080](https://github.com/uclouvain/openjpeg/pull/1080) ([setharnold](https://github.com/setharnold))
- Fixed typos [\#1062](https://github.com/uclouvain/openjpeg/pull/1062) ([radarhere](https://github.com/radarhere))
- Note that seek uses SEEK\_SET behavior. [\#1055](https://github.com/uclouvain/openjpeg/pull/1055) ([ideasman42](https://github.com/ideasman42))
- Some Doxygen tags are removed [\#1050](https://github.com/uclouvain/openjpeg/pull/1050) ([szukw000](https://github.com/szukw000))
- Fix resource leak \(CID 179466\) [\#1047](https://github.com/uclouvain/openjpeg/pull/1047) ([stweil](https://github.com/stweil))
- Changed cmake version test to allow for cmake 2.8.11.x [\#1042](https://github.com/uclouvain/openjpeg/pull/1042) ([radarhere](https://github.com/radarhere))
- Add missing fclose\(\) statement in error condition. [\#1037](https://github.com/uclouvain/openjpeg/pull/1037) ([gfiumara](https://github.com/gfiumara))
## [v2.3.0](https://github.com/uclouvain/openjpeg/releases/v2.3.0) (2017-10-04)
[Full Changelog](https://github.com/uclouvain/openjpeg/compare/v2.2.0...v2.3.0)
**Implemented enhancements:**
- Sub-tile decoding: only decode precincts and codeblocks that intersect the window specified in opj_set_decode_area() [\#990](https://github.com/uclouvain/openjpeg/pull/990) ([rouault](https://github.com/rouault))
- Sub-tile decoding: only apply IDWT on areas that participate to the window of interest [\#1001](https://github.com/uclouvain/openjpeg/pull/1001) ([rouault](https://github.com/rouault))
- Sub-tile decoding: memory use reduction and perf improvements [\#1010](https://github.com/uclouvain/openjpeg/pull/1010) ([rouault](https://github.com/rouault))
- Add capability to decode only a subset of all components of an image. [\#1022](https://github.com/uclouvain/openjpeg/pull/1022) ([rouault](https://github.com/rouault))
**Fixed bugs:**
- Setting x offset of decode region to -1 causes opj\_decompress to go into infinite loop [\#736](https://github.com/uclouvain/openjpeg/issues/736)
- Problem decoding multiple tiles with get\_decoded\_tile when cmap/pclr/cdef boxes are present in jp2 file [\#484](https://github.com/uclouvain/openjpeg/issues/484)
- set reduce\_factor\_may\_fail [\#474](https://github.com/uclouvain/openjpeg/issues/474)
- opj\_compress.exe, command line parser, infinite loop [\#469](https://github.com/uclouvain/openjpeg/issues/469)
- Various memory access issues found via fuzzing [\#448](https://github.com/uclouvain/openjpeg/issues/448)
- Multiple warnings when building OpenJPEG \(trunk\) [\#442](https://github.com/uclouvain/openjpeg/issues/442)
- Bulk fuzz-testing report [\#427](https://github.com/uclouvain/openjpeg/issues/427)
- remove all printf from openjpeg / use proper function pointer for logging [\#371](https://github.com/uclouvain/openjpeg/issues/371)
- minor changes, clean-up [\#349](https://github.com/uclouvain/openjpeg/issues/349)
- image-\>numcomps \> 4 [\#333](https://github.com/uclouvain/openjpeg/issues/333)
- Improve support for region of interest [\#39](https://github.com/uclouvain/openjpeg/issues/39)
- Public function to tell kernel type used \(5x3 vs 9x7\) [\#3](https://github.com/uclouvain/openjpeg/issues/3)
- elf binary in source package ? [\#1026](https://github.com/uclouvain/openjpeg/issues/1026)
- opj\_cio\_open [\#1025](https://github.com/uclouvain/openjpeg/issues/1025)
- Building with Visual Studio 2015 [\#1023](https://github.com/uclouvain/openjpeg/issues/1023)
- tcd.cpp\>:1617:33: error: assigning to 'OPJ\_INT32 \*' \(aka 'int \*'\) from incompatible type 'void \*' [\#1021](https://github.com/uclouvain/openjpeg/issues/1021)
- j2k.cpp \> comparison of address of 'p\_j2k-\>m\_cp.tcps\[0\].m\_data' not equal to a null pointer is always true [\#1020](https://github.com/uclouvain/openjpeg/issues/1020)
- Openjpeg 2.2.0 always build shared library even though -DBUILD\_SHARED\_LIBS:bool=off [\#1019](https://github.com/uclouvain/openjpeg/issues/1019)
- missing fclose [\#1018](https://github.com/uclouvain/openjpeg/issues/1018)
- Use opj\_image\_data\_free instead of opj\_free for image-\>comps\[\].data [\#1014](https://github.com/uclouvain/openjpeg/issues/1014)
- malloc poison on some compilers - cross compiling [\#1013](https://github.com/uclouvain/openjpeg/issues/1013)
- Add OPJ\_VERSION\_MAJOR, OPJ\_VERSION\_MINOR, OPJ\_VERSION\_MICRO macros in openjpeg.h [\#1011](https://github.com/uclouvain/openjpeg/issues/1011)
- Encode: do not perform rate control for single-tile lossless [\#1009](https://github.com/uclouvain/openjpeg/issues/1009)
- opj\_set\_decoded\_resolution\_factor\(\): bad interaction with opj\_set\_decode\_area\(\) and/or opj\_decode\(\) [\#1006](https://github.com/uclouvain/openjpeg/issues/1006)
- memory allocation failure with .pgx file [\#999](https://github.com/uclouvain/openjpeg/issues/999)
- Unable to fuzz with raw image as input [\#998](https://github.com/uclouvain/openjpeg/issues/998)
- stack-based buffer overflow write in pgxtoimage \(/convert.c\) [\#997](https://github.com/uclouvain/openjpeg/issues/997)
- freeze with a crafted bmp [\#996](https://github.com/uclouvain/openjpeg/issues/996)
- invalid memory write in tgatoimage \(convert.c\) [\#995](https://github.com/uclouvain/openjpeg/issues/995)
- static build on Windows fails [\#994](https://github.com/uclouvain/openjpeg/issues/994)
- another heap-based buffer overflow in opj\_t2\_encode\_packet \(t2.c\) [\#993](https://github.com/uclouvain/openjpeg/issues/993)
- heap-based buffer overflow in opj\_t2\_encode\_packet \(t2.c\) [\#992](https://github.com/uclouvain/openjpeg/issues/992)
- heap-based buffer overflow in opj\_write\_bytes\_LE \(cio.c\) \(unfixed \#985\) [\#991](https://github.com/uclouvain/openjpeg/issues/991)
- heap overflow in opj\_compress [\#988](https://github.com/uclouvain/openjpeg/issues/988)
- heap overflow in opj\_decompress [\#987](https://github.com/uclouvain/openjpeg/issues/987)
- heap-based buffer overflow in opj\_bio\_byteout \(bio.c\) [\#986](https://github.com/uclouvain/openjpeg/issues/986)
- heap-based buffer overflow in opj\_write\_bytes\_LE \(cio.c\) [\#985](https://github.com/uclouvain/openjpeg/issues/985)
- memory allocation failure in opj\_aligned\_alloc\_n \(opj\_malloc.c\) [\#983](https://github.com/uclouvain/openjpeg/issues/983)
- heap-base buffer overflow in opj\_mqc\_flush \(mqc.c\) [\#982](https://github.com/uclouvain/openjpeg/issues/982)
- Decode fails for JP2s with ICC profile [\#981](https://github.com/uclouvain/openjpeg/issues/981)
- Unit tests failing on Ubuntu 17.04 [\#916](https://github.com/uclouvain/openjpeg/issues/916)
- Encoder crashes on small images [\#901](https://github.com/uclouvain/openjpeg/issues/901)
- openjpeg-1.5.3 fails to compile [\#830](https://github.com/uclouvain/openjpeg/issues/830)
- opj\_compress crops image \(win\) or creates a jp2 which cannot be decompressed \(lin\) [\#716](https://github.com/uclouvain/openjpeg/issues/716)
- -d flag is silently ignored when decoding a single tile [\#693](https://github.com/uclouvain/openjpeg/issues/693)
- transition away from dev-utils [\#628](https://github.com/uclouvain/openjpeg/issues/628)
- update instructions to build with Visual Studio and 64-Bit Visual C++ Toolset. [\#1028](https://github.com/uclouvain/openjpeg/pull/1028) ([quangnh89](https://github.com/quangnh89))
- Add missing newline at end of file [\#1024](https://github.com/uclouvain/openjpeg/pull/1024) ([stweil](https://github.com/stweil))
- merge master into coverity\_scan to update coverity results [\#1008](https://github.com/uclouvain/openjpeg/pull/1008) ([detonin](https://github.com/detonin))
- Use more const qualifiers [\#984](https://github.com/uclouvain/openjpeg/pull/984) ([stweil](https://github.com/stweil))
- Changes in converttif.c for PPC64 [\#980](https://github.com/uclouvain/openjpeg/pull/980) ([szukw000](https://github.com/szukw000))
## [v2.2.0](https://github.com/uclouvain/openjpeg/releases/v2.2.0) (2017-08-10)
## [v2.2.0]("https://github.com/uclouvain/openjpeg/releases/v2.2.0" ) (2017-08-10)
[Full Changelog](https://github.com/uclouvain/openjpeg/compare/v2.1.2...v2.2.0)
**Implemented enhancements:**
@ -672,7 +324,7 @@
- Migration guide v2 [\#160](https://github.com/uclouvain/openjpeg/issues/160)
- Cannot decompress JPEG2000Aware3.18.7.3Win32\_kdutranscode6.3.1.j2k [\#158](https://github.com/uclouvain/openjpeg/issues/158)
- Cannot decompress JPEG2000Aware3.18.7.3Win32.j2k [\#157](https://github.com/uclouvain/openjpeg/issues/157)
- openjpeg@googlegroups.com has disappeared [\#153](https://github.com/uclouvain/openjpeg/issues/153)
- openjpeg@googlegroups.com has disappeard [\#153](https://github.com/uclouvain/openjpeg/issues/153)
- OpenJPEG 1.5.0 crashes on a ridiculously big file... [\#151](https://github.com/uclouvain/openjpeg/issues/151)
- opj\_image vs free [\#146](https://github.com/uclouvain/openjpeg/issues/146)
- Windows .dll file invalid [\#140](https://github.com/uclouvain/openjpeg/issues/140)
@ -735,7 +387,7 @@
- Support unscaled 10 bit data for 2K cinema @ 48 FPS, as per DCI standard [\#671](https://github.com/uclouvain/openjpeg/issues/671)
- Use parallel jobs in ctest [\#664](https://github.com/uclouvain/openjpeg/issues/664)
- \[Security\]Multiple Memory error [\#663](https://github.com/uclouvain/openjpeg/issues/663)
- lossy encoding a 16 bit TIF file : severe artifacts in decompressed image [\#660](https://github.com/uclouvain/openjpeg/issues/660)
- lossy encoding a 16 bit TIF file : severe artifiacts in decompressed image [\#660](https://github.com/uclouvain/openjpeg/issues/660)
- opj\_compress and opj\_decompress : get\_next\_file method uses hard-coded unix path separator [\#630](https://github.com/uclouvain/openjpeg/issues/630)
- Uninitialized variable [\#629](https://github.com/uclouvain/openjpeg/issues/629)
- Use of enum variable for bit flags prevents compilation as C++ source [\#619](https://github.com/uclouvain/openjpeg/issues/619)
@ -772,7 +424,7 @@
- Correct abi-check.sh for PR [\#791](https://github.com/uclouvain/openjpeg/pull/791) ([mayeut](https://github.com/mayeut))
- Update tcd.c [\#790](https://github.com/uclouvain/openjpeg/pull/790) ([maddin200](https://github.com/maddin200))
- Update lcms2 [\#773](https://github.com/uclouvain/openjpeg/pull/773) ([mayeut](https://github.com/mayeut))
- Use lowercase for cmake commands consistently [\#769](https://github.com/uclouvain/openjpeg/pull/769) ([julienmalik](https://github.com/julienmalik))
- Use lowercase for cmake commands consistenly [\#769](https://github.com/uclouvain/openjpeg/pull/769) ([julienmalik](https://github.com/julienmalik))
- Ignore clang's summary warning [\#768](https://github.com/uclouvain/openjpeg/pull/768) ([julienmalik](https://github.com/julienmalik))
- Fix UBSan gcc warning for first arg to memset non null [\#767](https://github.com/uclouvain/openjpeg/pull/767) ([julienmalik](https://github.com/julienmalik))
- Update to libtiff-4.0.6 [\#764](https://github.com/uclouvain/openjpeg/pull/764) ([mayeut](https://github.com/mayeut))

View File

@ -7,7 +7,7 @@
# For this purpose you can define a CMake var: OPENJPEG_NAMESPACE to whatever you like
# e.g.:
# set(OPENJPEG_NAMESPACE "GDCMOPENJPEG")
cmake_minimum_required(VERSION 2.8.5)
cmake_minimum_required(VERSION 2.8.2)
if(COMMAND CMAKE_POLICY)
cmake_policy(SET CMP0003 NEW)
@ -24,7 +24,7 @@ endif()
#string(TOLOWER ${OPENJPEG_NAMESPACE} OPENJPEG_LIBRARY_NAME)
set(OPENJPEG_LIBRARY_NAME openjp2)
project(${OPENJPEG_NAMESPACE} C)
project(${OPENJPEG_NAMESPACE})
# Do full dependency headers.
include_regular_expression("^.*$")
@ -32,7 +32,7 @@ include_regular_expression("^.*$")
#-----------------------------------------------------------------------------
# OPENJPEG version number, useful for packaging and doxygen doc:
set(OPENJPEG_VERSION_MAJOR 2)
set(OPENJPEG_VERSION_MINOR 5)
set(OPENJPEG_VERSION_MINOR 2)
set(OPENJPEG_VERSION_BUILD 0)
set(OPENJPEG_VERSION
"${OPENJPEG_VERSION_MAJOR}.${OPENJPEG_VERSION_MINOR}.${OPENJPEG_VERSION_BUILD}")
@ -55,10 +55,6 @@ set(PACKAGE_VERSION
# 2.1.1 | 7
# 2.1.2 | 7
# 2.2.0 | 7
# 2.3.0 | 7
# 2.3.1 | 7
# 2.4.0 | 7
# 2.5.0 | 7
# above is the recommendation by the OPJ team. If you really need to override this default,
# you can specify your own OPENJPEG_SOVERSION at cmake configuration time:
# cmake -DOPENJPEG_SOVERSION:STRING=42 /path/to/openjpeg
@ -105,42 +101,66 @@ endif()
# --------------------------------------------------------------------------
# Install directories
string(TOLOWER ${PROJECT_NAME} PROJECT_NAME)
include(GNUInstallDirs)
# Build DOCUMENTATION (not in ALL target and only if Doxygen is found)
option(BUILD_DOC "Build the HTML documentation (with doxygen if available)." OFF)
set(OPENJPEG_INSTALL_SUBDIR "${PROJECT_NAME}-${OPENJPEG_VERSION_MAJOR}.${OPENJPEG_VERSION_MINOR}")
string(TOLOWER ${PROJECT_NAME} projectname)
set(OPENJPEG_INSTALL_SUBDIR "${projectname}-${OPENJPEG_VERSION_MAJOR}.${OPENJPEG_VERSION_MINOR}")
if(NOT OPENJPEG_INSTALL_BIN_DIR)
set(OPENJPEG_INSTALL_BIN_DIR "bin")
endif()
if(NOT OPENJPEG_INSTALL_LIB_DIR)
set(OPENJPEG_INSTALL_LIB_DIR "lib")
endif()
if(NOT OPENJPEG_INSTALL_SHARE_DIR)
set(OPENJPEG_INSTALL_SHARE_DIR "share")
endif()
if(NOT OPENJPEG_INSTALL_DATA_DIR)
set(OPENJPEG_INSTALL_DATA_DIR "${OPENJPEG_INSTALL_SHARE_DIR}/${OPENJPEG_INSTALL_SUBDIR}")
endif()
if(NOT OPENJPEG_INSTALL_INCLUDE_DIR)
set(OPENJPEG_INSTALL_INCLUDE_DIR "include/${OPENJPEG_INSTALL_SUBDIR}")
endif()
if(BUILD_DOC)
if(NOT OPENJPEG_INSTALL_MAN_DIR)
set(OPENJPEG_INSTALL_MAN_DIR "share/man/")
endif()
if(NOT OPENJPEG_INSTALL_DOC_DIR)
set(OPENJPEG_INSTALL_DOC_DIR "share/doc/${OPENJPEG_INSTALL_SUBDIR}")
endif()
endif()
if(NOT OPENJPEG_INSTALL_JNI_DIR)
if(WIN32)
set(OPENJPEG_INSTALL_JNI_DIR ${CMAKE_INSTALL_BINDIR})
set(OPENJPEG_INSTALL_JNI_DIR ${OPENJPEG_INSTALL_BIN_DIR})
else()
set(OPENJPEG_INSTALL_JNI_DIR ${CMAKE_INSTALL_LIBDIR})
set(OPENJPEG_INSTALL_JNI_DIR ${OPENJPEG_INSTALL_LIB_DIR})
endif()
endif()
if(NOT OPENJPEG_INSTALL_PACKAGE_DIR)
set(OPENJPEG_INSTALL_PACKAGE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${OPENJPEG_INSTALL_SUBDIR}")
# We could install *.cmake files in share/ however those files contains
# hardcoded path to libraries on a multi-arch system (fedora/debian) those
# path will be different (lib/i386-linux-gnu vs lib/x86_64-linux-gnu)
set(OPENJPEG_INSTALL_PACKAGE_DIR "${OPENJPEG_INSTALL_LIB_DIR}/${OPENJPEG_INSTALL_SUBDIR}")
endif()
if (APPLE)
if (${CMAKE_VERSION} VERSION_LESS 3.0)
# For cmake >= 3.0, we turn on CMP0042 and
# https://cmake.org/cmake/help/v3.0/policy/CMP0042.html mentions
# "Projects wanting @rpath in a targets install name may remove any setting of the INSTALL_NAME_DIR and CMAKE_INSTALL_NAME_DIR variables"
list(APPEND OPENJPEG_LIBRARY_PROPERTIES INSTALL_NAME_DIR "${CMAKE_INSTALL_FULL_LIBDIR}")
endif()
list(APPEND OPENJPEG_LIBRARY_PROPERTIES INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${OPENJPEG_INSTALL_LIB_DIR}")
option(OPJ_USE_DSYMUTIL "Call dsymutil on binaries after build." OFF)
endif()
#-----------------------------------------------------------------------------
# Big endian test:
if (NOT EMSCRIPTEN)
include (${CMAKE_ROOT}/Modules/TestBigEndian.cmake)
TEST_BIG_ENDIAN(OPJ_BIG_ENDIAN)
endif()
#-----------------------------------------------------------------------------
# Setup file for setting custom ctest vars
@ -234,23 +254,25 @@ if(BUILD_JPIP_SERVER)
endif()
add_subdirectory(src/lib)
option(BUILD_LUTS_GENERATOR "Build utility to generate t1_luts.h" OFF)
if(UNIX)
option(BUILD_UNIT_TESTS "Build unit tests (bench_dwt, test_sparse_array, etc..)" OFF)
endif()
#-----------------------------------------------------------------------------
# Build Applications
option(BUILD_CODEC "Build the CODEC executables" ON)
option(BUILD_MJ2 "Build the MJ2 executables." OFF)
option(BUILD_JPWL "Build the JPWL library and executables" OFF)
option(BUILD_JPIP "Build the JPIP library and executables." OFF)
if(BUILD_JPIP)
option(BUILD_JPIP_SERVER "Build the JPIP server." OFF)
endif()
option(BUILD_VIEWER "Build the OPJViewer executable (C++)" OFF)
option(BUILD_JAVA "Build the openjpeg jar (Java)" OFF)
option(BUILD_JP3D "Build the JP3D comp" OFF)
mark_as_advanced(BUILD_VIEWER)
mark_as_advanced(BUILD_JAVA)
mark_as_advanced(BUILD_JP3D)
if(BUILD_CODEC)
if(BUILD_CODEC OR BUILD_MJ2)
# OFF: It will only build 3rd party libs if they are not found on the system
# ON: 3rd party libs will ALWAYS be build, and used
option(BUILD_THIRDPARTY "Build the thirdparty executables if it is needed" OFF)
@ -280,7 +302,7 @@ if(BUILD_DOC)
endif()
#-----------------------------------------------------------------------------
# Build Testing
# Buld Testing
option(BUILD_TESTING "Build the tests." OFF)
if(BUILD_TESTING)
if(BUILD_CODEC)
@ -304,64 +326,65 @@ if(BUILD_TESTING)
endif()
#-----------------------------------------------------------------------------
# install all targets referenced as OPENJPEGTargets (relocatable with CMake 3.0+)
# install all targets referenced as OPENJPEGTargets
install(EXPORT OpenJPEGTargets DESTINATION ${OPENJPEG_INSTALL_PACKAGE_DIR})
if (${CMAKE_VERSION} VERSION_LESS 3.0)
set(PACKAGE_INIT)
set(PACKAGE_CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_FULL_INCLUDEDIR})
configure_file( ${${OPENJPEG_NAMESPACE}_SOURCE_DIR}/cmake/OpenJPEGConfig.cmake.in
${${OPENJPEG_NAMESPACE}_BINARY_DIR}/OpenJPEGConfig.cmake
@ONLY
)
else()
include(CMakePackageConfigHelpers)
configure_package_config_file(${CMAKE_CURRENT_LIST_DIR}/cmake/OpenJPEGConfig.cmake.in
${OPENJPEG_BINARY_DIR}/OpenJPEGConfig.cmake
INSTALL_DESTINATION ${OPENJPEG_INSTALL_PACKAGE_DIR}
PATH_VARS CMAKE_INSTALL_INCLUDEDIR)
endif()
configure_file( ${${OPENJPEG_NAMESPACE}_SOURCE_DIR}/cmake/OpenJPEGConfig.cmake.in
${${OPENJPEG_NAMESPACE}_BINARY_DIR}/OpenJPEGConfig.cmake
@ONLY
)
install( FILES ${OPENJPEG_BINARY_DIR}/OpenJPEGConfig.cmake
DESTINATION ${OPENJPEG_INSTALL_PACKAGE_DIR}
)
#-----------------------------------------------------------------------------
# install CHANGES and LICENSE
if(BUILD_DOC)
if(EXISTS ${OPENJPEG_SOURCE_DIR}/CHANGES)
install(FILES CHANGES DESTINATION ${OPENJPEG_INSTALL_DOC_DIR})
endif()
install(FILES LICENSE DESTINATION ${OPENJPEG_INSTALL_DOC_DIR})
endif()
include (cmake/OpenJPEGCPack.cmake)
#-----------------------------------------------------------------------------
# pkgconfig support
# enabled by default on Unix or if using GCC, disabled by default on other platforms
if(UNIX OR CMAKE_COMPILER_IS_GNUCC)
# enabled by default on Unix, disabled by default on other platforms
if(UNIX)
option(BUILD_PKGCONFIG_FILES "Build and install pkg-config files" ON)
else()
option(BUILD_PKGCONFIG_FILES "Build and install pkg-config files" OFF)
endif()
if(BUILD_PKGCONFIG_FILES)
macro(set_variable_from_rel_or_absolute_path var root rel_or_abs_path)
if(IS_ABSOLUTE "${rel_or_abs_path}")
set(${var} "${rel_or_abs_path}")
else()
set(${var} "${root}/${rel_or_abs_path}")
endif()
endmacro()
set_variable_from_rel_or_absolute_path("bindir" "\\\${prefix}" "${CMAKE_INSTALL_BINDIR}")
set_variable_from_rel_or_absolute_path("mandir" "\\\${prefix}" "${CMAKE_INSTALL_MANDIR}")
set_variable_from_rel_or_absolute_path("docdir" "\\\${prefix}" "${CMAKE_INSTALL_DOCDIR}")
set_variable_from_rel_or_absolute_path("libdir" "\\\${prefix}" "${CMAKE_INSTALL_LIBDIR}")
set_variable_from_rel_or_absolute_path("includedir" "\\\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}/${OPENJPEG_INSTALL_SUBDIR}")
# install in lib and not share (CMAKE_INSTALL_LIBDIR takes care of it for multi-arch)
# install in lib and not share (see multi-arch note above)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/lib/openjp2/libopenjp2.pc.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/libopenjp2.pc @ONLY)
install( FILES ${CMAKE_CURRENT_BINARY_DIR}/libopenjp2.pc DESTINATION
${CMAKE_INSTALL_LIBDIR}/pkgconfig )
${OPENJPEG_INSTALL_LIB_DIR}/pkgconfig )
#
if(BUILD_JPWL)
# install in lib and not share (see multi-arch note above)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/lib/openjpwl/libopenjpwl.pc.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/libopenjpwl.pc @ONLY)
install( FILES ${CMAKE_CURRENT_BINARY_DIR}/libopenjpwl.pc DESTINATION
${OPENJPEG_INSTALL_LIB_DIR}/pkgconfig )
endif()
#
if(BUILD_JPIP)
# install in lib and not share (see multi-arch note above)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/lib/openjpip/libopenjpip.pc.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/libopenjpip.pc @ONLY)
install( FILES ${CMAKE_CURRENT_BINARY_DIR}/libopenjpip.pc DESTINATION
${CMAKE_INSTALL_LIBDIR}/pkgconfig )
${OPENJPEG_INSTALL_LIB_DIR}/pkgconfig )
endif()
#
if(BUILD_JP3D)
# install in lib and not share (see multi-arch note above)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/lib/openjp3d/libopenjp3d.pc.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/libopenjp3d.pc @ONLY)
install( FILES ${CMAKE_CURRENT_BINARY_DIR}/libopenjp3d.pc DESTINATION
${OPENJPEG_INSTALL_LIB_DIR}/pkgconfig )
endif()
endif()

View File

@ -1,32 +0,0 @@
Check-list OpenJPEG Release
* update MAJOR, MINOR, BUILD, SOVERSION in CMakeLists.txt
* update MAJOR, MINOR, BUILD in appveyor.yml
* update CHANGELOG with
`github_changelog_generator --token TOKEN_HERE --exclude-labels gcode_fixed,OpjVersion-1.x --release-url "https://github.com/uclouvain/openjpeg/releases/%s" --since-tag v2.3.1 --future-release v2.4.0 --output append2changelog.md --user uclouvain --project openjpeg --exclude-tags version.1.0` . TOKEN_HERE is created at https://github.com/settings/tokens
* update NEWS.md
* git tag -a v2.4.0 -m "OpenJPEG v2.4.0 release"
* git push origin --tags
* add post to OpenJPEG website in gh-pages branch in _posts/ subdirectory. See commit https://github.com/uclouvain/openjpeg/commit/6563d704f5fb896209dd862ccfc6b97eb9183c5c
* change binversion of openjpeg website in _config.yml in gh-pages branch
* update release description if needed
* update openjpeg.json with latest release
* update OPJ_LATEST_VERSION in abi-check.sh, uncomment and update OPJ_PREVIOUS_VERSION in abi-check.sh, and push
* locally run: OPJ_CI_ABI_CHECK=1 ./tools/travis-ci/abi-check.sh
* cd ~/abi-check/work/abi-check/
* put the sources of the new version in src/openjpeg/2.X.0/version.-2.X.0.tar.gz
* PATH=$PWD/../../tools/abi-tracker/bin:$PWD/../../tools/wdiff/bin:$PWD/../../tools:$PATH abi-monitor -v 2.X.0 -build ./openjpeg.json
* PATH=$PWD/../../tools/abi-tracker/bin:$PWD/../../tools/wdiff/bin:$PWD/../../tools:$PATH abi-tracker -build ./openjpeg.json
* rm -rf src/openjpeg/current
* rm -rf build_logs
* git add --all .
* git commit -m "Update ABI/API compatibility reports after 2.X.0 release"
* git push
* cd ~/openjpeg/openjpeg
* comment back OPJ_PREVIOUS_VERSION and push
* build doc and update Doxygen on website
* manual build on Windows:
- cmake .. -G "Visual Studio 15 2017" -A x64 -DCMAKE_CONFIGURATION_TYPES=Release -DBUILD_THIRDPARTY=ON -D CPACK_GENERATOR:STRING=ZIP -D CPACK_PACKAGE_FILE_NAME:STRING=openjpeg-v2.4.0-windows-x64
- cmake --build . --target package --config Release
* send email to ML opj, comp.compression, iiif
* tweet

View File

@ -30,7 +30,6 @@ Main available cmake flags:
* To specify the install path: '-DCMAKE\_INSTALL\_PREFIX=/path'
* To build the shared libraries and links the executables against it: '-DBUILD\_SHARED\_LIBS:bool=on' (default: 'ON')
> Note: when using this option, static libraries are not built and executables are dynamically linked.
* PKG_CONFIG files are by default built for Unix compile, you can force to build on other platforms by adding: '-DBUILD_PKGCONFIG_FILES=on'
* To build the CODEC executables: '-DBUILD\_CODEC:bool=on' (default: 'ON')
* To build opjstyle (internal version of astyle) for OpenJPEG development: '-DWITH_ASTYLE=ON'
* [OBSOLETE] To build the MJ2 executables: '-DBUILD\_MJ2:bool=on' (default: 'OFF')
@ -62,35 +61,7 @@ Note 4 : On MacOS, if it does not work, try adding the following flag to the cma
## MacOS (XCode) - WINDOWS (VisualStudio, etc)
You can use cmake to generate the project files for the IDE you are using (VC2010, XCode, etc).
Type `cmake --help` for available generators on your platform.
Examples for Windows with Visual Studio C++ compiler:
If using directly the cl compiler:
```
cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE:string="Release" -DBUILD_SHARED_LIBS:bool=on -DCMAKE_INSTALL_PREFIX:path="%USERPROFILE%" -DCMAKE_LIBRARY_PATH:path="%USERPROFILE%" -DCMAKE_INCLUDE_PATH:path="%USERPROFILE%\include" ..
```
To compile a 64-bit application, open 64-Bit Visual C\+\+ toolset on the command line and run cmake. For further information, please refer to: [How to: Enable a 64-Bit Visual C\+\+ Toolset on the Command Line](https://msdn.microsoft.com/en-us/library/x4d2c09s.aspx).
If you do not want directly use the cl compiler, you could use:
```
cmake -DCMAKE_BUILD_TYPE:string="Release" -DBUILD_SHARED_LIBS:bool=on -DCMAKE_INSTALL_PREFIX:path="%USERPROFILE%" -DCMAKE_LIBRARY_PATH:path="%USERPROFILE%" -DCMAKE_INCLUDE_PATH:path="%USERPROFILE%\include" ..
```
To create Visual Studio solution (.sln) and project files (.vcproj / .vcxproj):
```
cmake -G "Visual Studio 14 2015" -DCMAKE_BUILD_TYPE:string="Release" -DBUILD_SHARED_LIBS:bool=on -DCMAKE_INSTALL_PREFIX:path="%USERPROFILE%" -DCMAKE_LIBRARY_PATH:path="%USERPROFILE%" -DCMAKE_INCLUDE_PATH:path="%USERPROFILE%\include" ..
```
64-bit application:
```
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_BUILD_TYPE:string="Release" -DBUILD_SHARED_LIBS:bool=on -DCMAKE_INSTALL_PREFIX:path="%USERPROFILE%" -DCMAKE_LIBRARY_PATH:path="%USERPROFILE%" -DCMAKE_INCLUDE_PATH:path="%USERPROFILE%\include" ..
```
Type 'cmake --help' for available generators on your platform.
# Enabling CPU specific optimizations
@ -103,27 +74,21 @@ CPUs)
With gcc/clang, it is possible to enable those instruction sets with the following :
```
cmake -DCMAKE_C_FLAGS="-O3 -msse4.1 -DNDEBUG" ..
```
```
cmake -DCMAKE_C_FLAGS="-O3 -mavx2 -DNDEBUG" ..
```
(AVX2 implies SSE4.1)
Or if the binary is dedicated to run on the machine where it has
been compiled :
```
cmake -DCMAKE_C_FLAGS="-O3 -march=native -DNDEBUG" ..
```
# Modifying OpenJPEG
Before committing changes, run:
```scripts/prepare-commit.sh```
scripts/prepare-commit.sh
# Using OpenJPEG

View File

@ -1,55 +0,0 @@
USE_CLIB2=YES
ifeq ($(USE_CLIB2), YES)
LIBC=clib2
CODEC=OFF
else
LIBC=newlib
CODEC=ON
endif
all: build
build:
mkdir build && \
cd build && \
cmake .. -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CROSSCOMPILING=ON \
-DCMAKE_TOOLCHAIN_FILE=$(realpath amigaos4.cmake) \
-DCMAKE_C_FLAGS="-mcrt=${LIBC} -O2 -fPIC" \
-DCMAKE_MODULE_LINKER_FLAGS="-mcrt=${LIBC} -lpthread -athread=native" \
-DBUILD_TESTING=OFF \
-DBUILD_CODEC=${CODEC} \
-DBUILD_SHARED_LIBS=OFF && \
make
clean:
@echo "Clean the build"
@rm -rf build
cleanall: clean
@echo "Clean the build and the release files"
@rm -rf SDK
@rm libopenjpeg.lha
release:
@echo "Create release folders..."
@mkdir -p SDK/local/common/include
@mkdir -p SDK/local/clib2/lib
@mkdir -p SDK/local/newlib/lib SDK/local/newlib/bin
@echo "Building clib2 based libraries..."
@make -f Makefile.os4 USE_CLIB2=YES
@cp ./build/bin/libopenjp2.a SDK/local/clib2/lib/
@cp ./src/lib/openjp2/openjpeg.h SDK/local/common/include/
@echo "Clean build and libraries files..."
@make -f Makefile.os4 clean
@echo "Building newlib based libraries..."
@make -f Makefile.os4 USE_CLIB2=NO
@cp ./build/bin/libopenjp2.a SDK/local/newlib/lib/
@cp ./build/bin/opj_* SDK/local/newlib/bin/
@echo "Creating the lha release file..."
@lha -aeq libopenjpeg.lha SDK/

46
NEWS.md
View File

@ -1,44 +1,8 @@
# OpenJPEG NEWS
More details in the [CHANGELOG](https://github.com/uclouvain/openjpeg/blob/master/CHANGELOG.md)
More details in the [Changelog](https://github.com/uclouvain/openjpeg/blob/master/CHANGELOG.md)
## OpenJPEG 2.5.0 (May 2022)
No API/ABI break compared to v2.4.0, but additional symbols for subset of components decoding (hence the MINOR version bump).
* Encoder: add support for generation of TLM markers [\#1359](https://github.com/uclouvain/openjpeg/pull/1359)
* Decoder: add support for high throughput \(HTJ2K\) decoding. [\#1381](https://github.com/uclouvain/openjpeg/pull/1381)
* Decoder: add support for partial bitstream decoding [\#1407](https://github.com/uclouvain/openjpeg/pull/1407)
* Bug fixes (including security fixes)
## OpenJPEG 2.4.0 (December 2020)
No API/ABI break compared to v2.3.1, but additional symbols for subset of components decoding (hence the MINOR version bump).
* Encoder: add support for multithreading [\#1248](https://github.com/uclouvain/openjpeg/pull/1248)
* Encoder: add support for generation of PLT markers [\#1246](https://github.com/uclouvain/openjpeg/pull/1246)
* Encoder: single-threaded performance improvements in forward DWT for 5-3 and 9-7 (and other improvements) [\#1253](https://github.com/uclouvain/openjpeg/pull/1253)
* Encoder: support IMF profiles [\#1235](https://github.com/uclouvain/openjpeg/pull/1235)
* Many bug fixes (including security fixes)
## OpenJPEG 2.3.1 (April 2019)
No API/ABI break compared to v2.3.0
* Many bug fixes (including security fixes)
## OpenJPEG 2.3.0 (October 2017)
No API/ABI break compared to v2.2.0 but additional symbols for subset of components decoding (hence the MINOR version bump).
* Sub-tile decoding: when setting a window of interest through the API function opj_set_decode_area(), only codeblocks that intersect this window are now decoded (i.e. MCT, IDWT, and entropy decoding are only done on the window of interest). Moreover, memory allocation now depends on the size of the window of interest (instead of the full tile size).
[\#990](https://github.com/uclouvain/openjpeg/pull/990) [\#1001](https://github.com/uclouvain/openjpeg/pull/1001) [\#1010](https://github.com/uclouvain/openjpeg/pull/1010)
* Ability to decode only a subset of components. This adds the following function `opj_set_decoded_components(opj_codec_t p_codec, OPJ_UINT32 numcomps, const OPJ_UINT32 comps_indices, OPJ_BOOL apply_color_transforms)` and equivalent `opj_decompress -c compno[,compno]*`
option.
[\#1022](https://github.com/uclouvain/openjpeg/pull/1022)
* Many bug fixes (including security fixes)
## OpenJPEG 2.2.0 (August 2017)
## OpenJPEG 2.2.0
No API/ABI break compared to v2.1.2 but additional symbols for multithreading support (hence the MINOR version bump).
@ -60,18 +24,18 @@ No API/ABI break compared to v2.1.2 but additional symbols for multithreading su
* Codebase reformatting (with astyle) and scripts to automatically check that new commits comply with formatting guidelines [\#919](https://github.com/uclouvain/openjpeg/pull/919)
* Register OpenJPEG at Google OSS Fuzz initiative, so as to automatically have OpenJPEG tested against Google fuzzer [\#965](https://github.com/uclouvain/openjpeg/issues/965)
## OpenJPEG 2.1.2 (September 2016)
## OpenJPEG 2.1.2
* Bug fixes (including security fixes)
* No API/ABI break compared to v2.1.1
## OpenJPEG 2.1.1 (July 2016)
## OpenJPEG 2.1.1
* Huge amount of critical bugfixes
* Speed improvements
* No API/ABI break compared to v2.1
## OpenJPEG 2.1.0 (April 2014)
## OpenJPEG 2.1.0
### New Features

View File

@ -29,12 +29,18 @@ The library is developed and maintained by the Image and Signal Processing Group
* src
* lib
* openjp2: contains the sources of the openjp2 library (Part 1 & 2)
* openjpwl: contains the additional sources if you want to build a JPWL-flavoured library.
* openjpip: complete client-server architecture for remote browsing of jpeg 2000 images.
* openjp3d: JP3D implementation
* openmj2: MJ2 implementation
* bin: contains all applications that use the openjpeg library
* common: common files to all applications
* jp2: a basic codec
* mj2: motion jpeg 2000 executables
* jpip: OpenJPIP applications (server and dec server)
* java: a Java client viewer for JPIP
* jp3d: JP3D applications
* tcltk: a test tool for JP3D
* wx
* OPJViewer: gui for displaying j2k files (based on wxWidget)
* wrapping
@ -51,12 +57,6 @@ See [INSTALL](https://github.com/uclouvain/openjpeg/blob/master/INSTALL.md) for
See [NEWS](https://github.com/uclouvain/openjpeg/blob/master/NEWS.md) for user visible changes in successive releases.
## Deprecated components
The openjpwl, openjp3d and openmj2 components have been removed after the
2.4.0 release. Their building and working state is unknown. People interested
in them should start from the 2.4.0 tag.
## API/ABI
An API/ABI timeline is automatically updated [here][link-api-timeline].
@ -74,8 +74,8 @@ API available is the one supported by OpenJPEG.
[comment-license]: https://img.shields.io/github/license/uclouvain/openjpeg.svg "https://img.shields.io/badge/license-BSD--2--Clause-blue.svg"
[badge-license]: https://img.shields.io/badge/license-BSD--2--Clause-blue.svg "BSD 2-clause \"Simplified\" License"
[link-license]: https://github.com/uclouvain/openjpeg/blob/master/LICENSE "BSD 2-clause \"Simplified\" License"
[badge-build]: https://github.com/uclouvain/openjpeg/actions/workflows/build.yml/badge.svg "Build Status"
[link-build]: https://github.com/uclouvain/openjpeg/actions/workflows/build.yml "Build Status"
[badge-build]: https://travis-ci.org/uclouvain/openjpeg.svg?branch=master "Build Status"
[link-build]: https://travis-ci.org/uclouvain/openjpeg "Build Status"
[badge-msvc-build]: https://ci.appveyor.com/api/projects/status/github/uclouvain/openjpeg?branch=master&svg=true "Windows Build Status"
[link-msvc-build]: https://ci.appveyor.com/project/detonin/openjpeg/branch/master "Windows Build Status"
[badge-coverity]: https://scan.coverity.com/projects/6383/badge.svg "Coverity Scan Build Status"

View File

@ -1,9 +0,0 @@
SET(CMAKE_SYSTEM_NAME Generic)
SET(CMAKE_SYSTEM_PROCESSOR ppc)
SET(CMAKE_C_COMPILER /opt/ppc-amigaos/bin/ppc-amigaos-gcc)
SET(CMAKE_CXX_COMPILER /opt/ppc-amigaos/bin/ppc-amigaos-g++)
SET(CMAKE_FIND_LIBRARY_SUFFIXES "*.a")
SET(CMAKE_FIND_ROOT_PATH /opt/sdk)
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

View File

@ -1,4 +1,4 @@
version: 2.5.0.{build}
version: 2.2.0.{build}
branches:
except:
- coverity_scan
@ -27,15 +27,15 @@ build_script:
test: off
#before_deploy:
#- cmd: c:\cygwin\bin\bash ./tools/travis-ci/before_deploy.sh
#deploy:
# #release: openjpeg-$(appveyor_repo_tag_name)
# description: 'OpenJPEG $(appveyor_repo_tag_name) has been released. More info [here](https://github.com/uclouvain/openjpeg/blob/$(appveyor_repo_tag_name)/NEWS) and a detailed view [here](https://github.com/uclouvain/openjpeg/blob/$(appveyor_repo_tag_name)/CHANGES).'
# provider: GitHub
# auth_token:
# secure: XUL+IoRRw8U/4tupa/fMpinxurft7WRQHZiWHMLO5iuFbwZ+C3vCjVVVM+5Ebky7 # your encrypted token from GitHub
# artifact: /.*\.zip/ # upload all zip packages to release assets
# draft: true
# prerelease: false
# on:
# appveyor_repo_tag: true # deploy on tag push only
# OPJ_CI_INCLUDE_IF_DEPLOY: 1
deploy:
#release: openjpeg-$(appveyor_repo_tag_name)
description: 'OpenJPEG $(appveyor_repo_tag_name) has been released. More info [here](https://github.com/uclouvain/openjpeg/blob/$(appveyor_repo_tag_name)/NEWS) and a detailed view [here](https://github.com/uclouvain/openjpeg/blob/$(appveyor_repo_tag_name)/CHANGES).'
provider: GitHub
auth_token:
secure: Huk03f1heCD/HMyA+4ZeVmICdmKn9rPxK5p8/KxzgL+FtJDHlqcllcCrtN9bDxRH # your encrypted token from GitHub
artifact: /.*\.zip/ # upload all zip packages to release assets
draft: false
prerelease: false
on:
appveyor_repo_tag: true # deploy on tag push only
OPJ_CI_INCLUDE_IF_DEPLOY: 1

View File

@ -5,7 +5,6 @@
# This file is configured by OPENJPEG and used by the UseOPENJPEG.cmake
# module to load OPENJPEG's settings for an external project.
@OPENJPEG_CONFIG_INSTALL_ONLY@
@PACKAGE_INIT@
# The OPENJPEG version number.
set(OPENJPEG_MAJOR_VERSION "@OPENJPEG_VERSION_MAJOR@")
set(OPENJPEG_MINOR_VERSION "@OPENJPEG_VERSION_MINOR@")
@ -27,9 +26,8 @@ get_filename_component(SELF_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
if(EXISTS ${SELF_DIR}/OpenJPEGTargets.cmake)
# This is an install tree
include(${SELF_DIR}/OpenJPEGTargets.cmake)
set(INC_DIR "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@/@OPENJPEG_INSTALL_SUBDIR@")
get_filename_component(OPENJPEG_INCLUDE_DIRS "${INC_DIR}" ABSOLUTE)
get_filename_component(OPENJPEG_INCLUDE_ROOT "${SELF_DIR}/../../@OPENJPEG_INSTALL_INCLUDE_DIR@" ABSOLUTE)
set(OPENJPEG_INCLUDE_DIRS ${OPENJPEG_INCLUDE_ROOT})
else()
if(EXISTS ${SELF_DIR}/OpenJPEGExports.cmake)

View File

@ -44,7 +44,7 @@ if(DOXYGEN_FOUND)
# install HTML documentation (install png files too):
install(DIRECTORY ${CMAKE_BINARY_DIR}/doc/html
DESTINATION ${CMAKE_INSTALL_DOCDIR}
DESTINATION share/doc
PATTERN ".svn" EXCLUDE
)
else()

View File

@ -47,6 +47,7 @@ IDL_PROPERTY_SUPPORT = YES
DISTRIBUTE_GROUP_DOC = NO
SUBGROUPING = YES
TYPEDEF_HIDES_STRUCT = NO
SYMBOL_CACHE_SIZE = 0
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
@ -78,6 +79,7 @@ GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_DIRECTORIES = NO
SHOW_FILES = YES
SHOW_NAMESPACES = YES
FILE_VERSION_FILTER =
@ -144,6 +146,7 @@ HTML_COLORSTYLE_HUE = 220
HTML_COLORSTYLE_SAT = 100
HTML_COLORSTYLE_GAMMA = 80
HTML_TIMESTAMP = NO
HTML_ALIGN_MEMBERS = YES
HTML_DYNAMIC_SECTIONS = NO
GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"
@ -170,6 +173,7 @@ ECLIPSE_DOC_ID = org.doxygen.Project
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 4
GENERATE_TREEVIEW = NO
USE_INLINE_TREES = NO
TREEVIEW_WIDTH = 250
EXT_LINKS_IN_WINDOW = NO
FORMULA_FONTSIZE = 10
@ -213,6 +217,8 @@ MAN_LINKS = NO
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output

View File

@ -3,7 +3,7 @@ cd $(git rev-parse --show-toplevel)
export PATH=$PATH:$PWD/scripts
if [ -z "$TRAVIS_COMMIT_RANGE" -a -z "$GITHUB_SHA" ]; then
if [ -z "$TRAVIS_COMMIT_RANGE" ]; then
echo "No commit range given"
exit 0
fi
@ -18,22 +18,14 @@ set -e
ASTYLEDIFF=/tmp/astyle.diff
>$ASTYLEDIFF
if [ ! -z $GITHUB_BASE_REF ] && [ ! -z $GITHUB_HEAD_REF ]; then
# on a PR
echo "GitHub PR COMMIT RANGE: ${GITHUB_BASE_REF}..${GITHUB_HEAD_REF}"
git branch tmp_${GITHUB_BASE_REF} origin/${GITHUB_BASE_REF}
BASE_SHA1=$(git rev-parse tmp_${GITHUB_BASE_REF})
FILES=$(git diff --diff-filter=AMR --name-only ${BASE_SHA1}..${GITHUB_SHA} | tr '\n' ' ' )
elif [ ! -z $GITHUB_SHA ]; then
echo "GitHub push COMMIT $GITHUB_SHA"
FILES=$(git diff --diff-filter=AMR --name-only ${GITHUB_SHA}~1..${GITHUB_SHA} | tr '\n' ' ' )
elif [ ! -z $TRAVIS_PULL_REQUEST_BRANCH ]; then
if [[ ! -z $TRAVIS_PULL_REQUEST_BRANCH ]]; then
# if on a PR, just analyse the changed files
echo "TRAVIS PR BRANCH: $TRAVIS_PULL_REQUEST_BRANCH"
FILES=$(git diff --diff-filter=AMR --name-only $(git merge-base HEAD master) | tr '\n' ' ' )
elif [ ! -z $TRAVIS_COMMIT_RANGE ]; then
FILES=$(git diff --diff-filter=AM --name-only $(git merge-base HEAD master) | tr '\n' ' ' )
elif [[ ! -z $TRAVIS_COMMIT_RANGE ]]; then
echo "TRAVIS COMMIT RANGE: $TRAVIS_COMMIT_RANGE"
FILES=$(git diff --diff-filter=AMR --name-only ${TRAVIS_COMMIT_RANGE/.../..} | tr '\n' ' ' )
FILES=$(git diff --diff-filter=AM --name-only ${TRAVIS_COMMIT_RANGE/.../..} | tr '\n' ' ' )
fi
for f in $FILES; do

View File

@ -4,9 +4,18 @@ add_subdirectory(common)
add_subdirectory(jp2)
# optionals components:
if(BUILD_JPWL)
add_subdirectory(jpwl)
endif()
if(BUILD_MJ2)
add_subdirectory(mj2)
endif()
if(BUILD_JPIP)
add_subdirectory(jpip)
endif()
if(BUILD_JP3D)
add_subdirectory(jp3d)
endif()
# wx apps:
add_subdirectory(wx)

View File

@ -488,10 +488,6 @@ void color_apply_icc_profile(opj_image_t *image)
if (out_space == cmsSigRgbData) { /* enumCS 16 */
unsigned int i, nr_comp = image->numcomps;
if (nr_comp < 3) { /* GRAY or GRAYA, not RGB or RGBA */
cmsCloseProfile(in_prof);
return;
}
if (nr_comp > 4) {
nr_comp = 4;
}
@ -533,10 +529,6 @@ void color_apply_icc_profile(opj_image_t *image)
out_prof = cmsCreate_sRGBProfile();
new_space = OPJ_CLRSPC_SRGB;
} else if (out_space == cmsSigYCbCrData) { /* enumCS 18 */
if (image->numcomps < 3) {
cmsCloseProfile(in_prof);
return;
}
in_type = TYPE_YCbCr_16;
out_type = TYPE_RGB_16;
out_prof = cmsCreate_sRGBProfile();
@ -605,92 +597,82 @@ void color_apply_icc_profile(opj_image_t *image)
}
if (image->numcomps > 2) { /* RGB, RGBA */
if ((image->comps[0].w == image->comps[1].w &&
image->comps[0].w == image->comps[2].w) &&
(image->comps[0].h == image->comps[1].h &&
image->comps[0].h == image->comps[2].h)) {
if (prec <= 8) {
unsigned char *inbuf, *outbuf, *in, *out;
if (prec <= 8) {
unsigned char *inbuf, *outbuf, *in, *out;
max = max_w * max_h;
nr_samples = (size_t)(max * 3U * sizeof(unsigned char));
in = inbuf = (unsigned char*)opj_image_data_alloc(nr_samples);
out = outbuf = (unsigned char*)opj_image_data_alloc(nr_samples);
max = max_w * max_h;
nr_samples = (size_t)(max * 3U * sizeof(unsigned char));
in = inbuf = (unsigned char*)opj_image_data_alloc(nr_samples);
out = outbuf = (unsigned char*)opj_image_data_alloc(nr_samples);
if (inbuf == NULL || outbuf == NULL) {
goto fails0;
}
if (inbuf == NULL || outbuf == NULL) {
goto fails0;
}
r = image->comps[0].data;
g = image->comps[1].data;
b = image->comps[2].data;
r = image->comps[0].data;
g = image->comps[1].data;
b = image->comps[2].data;
for (i = 0U; i < max; ++i) {
*in++ = (unsigned char) * r++;
*in++ = (unsigned char) * g++;
*in++ = (unsigned char) * b++;
}
for (i = 0U; i < max; ++i) {
*in++ = (unsigned char) * r++;
*in++ = (unsigned char) * g++;
*in++ = (unsigned char) * b++;
}
cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);
cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);
r = image->comps[0].data;
g = image->comps[1].data;
b = image->comps[2].data;
r = image->comps[0].data;
g = image->comps[1].data;
b = image->comps[2].data;
for (i = 0U; i < max; ++i) {
*r++ = (int) * out++;
*g++ = (int) * out++;
*b++ = (int) * out++;
}
ok = 1;
for (i = 0U; i < max; ++i) {
*r++ = (int) * out++;
*g++ = (int) * out++;
*b++ = (int) * out++;
}
ok = 1;
fails0:
opj_image_data_free(inbuf);
opj_image_data_free(outbuf);
} else { /* prec > 8 */
unsigned short *inbuf, *outbuf, *in, *out;
opj_image_data_free(inbuf);
opj_image_data_free(outbuf);
} else { /* prec > 8 */
unsigned short *inbuf, *outbuf, *in, *out;
max = max_w * max_h;
nr_samples = (size_t)(max * 3U * sizeof(unsigned short));
in = inbuf = (unsigned short*)opj_image_data_alloc(nr_samples);
out = outbuf = (unsigned short*)opj_image_data_alloc(nr_samples);
max = max_w * max_h;
nr_samples = (size_t)(max * 3U * sizeof(unsigned short));
in = inbuf = (unsigned short*)opj_image_data_alloc(nr_samples);
out = outbuf = (unsigned short*)opj_image_data_alloc(nr_samples);
if (inbuf == NULL || outbuf == NULL) {
goto fails1;
}
if (inbuf == NULL || outbuf == NULL) {
goto fails1;
}
r = image->comps[0].data;
g = image->comps[1].data;
b = image->comps[2].data;
r = image->comps[0].data;
g = image->comps[1].data;
b = image->comps[2].data;
for (i = 0U ; i < max; ++i) {
*in++ = (unsigned short) * r++;
*in++ = (unsigned short) * g++;
*in++ = (unsigned short) * b++;
}
for (i = 0U ; i < max; ++i) {
*in++ = (unsigned short) * r++;
*in++ = (unsigned short) * g++;
*in++ = (unsigned short) * b++;
}
cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);
cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);
r = image->comps[0].data;
g = image->comps[1].data;
b = image->comps[2].data;
r = image->comps[0].data;
g = image->comps[1].data;
b = image->comps[2].data;
for (i = 0; i < max; ++i) {
*r++ = (int) * out++;
*g++ = (int) * out++;
*b++ = (int) * out++;
}
ok = 1;
for (i = 0; i < max; ++i) {
*r++ = (int) * out++;
*g++ = (int) * out++;
*b++ = (int) * out++;
}
ok = 1;
fails1:
opj_image_data_free(inbuf);
opj_image_data_free(outbuf);
}
} else {
fprintf(stderr,
"[ERROR] Image components should have the same width and height\n");
cmsDeleteTransform(transform);
return;
opj_image_data_free(inbuf);
opj_image_data_free(outbuf);
}
} else { /* image->numcomps <= 2 : GRAY, GRAYA */
if (prec <= 8) {

View File

@ -44,7 +44,7 @@ endif()
# Loop over all executables:
foreach(exe opj_decompress opj_compress opj_dump)
add_executable(${exe} ${exe}.c ${common_SRCS})
if(NOT ${CMAKE_VERSION} VERSION_LESS "2.8.12")
if(${CMAKE_VERSION} VERSION_GREATER "2.8.11")
target_compile_options(${exe} PRIVATE ${OPENJP2_COMPILE_OPTIONS})
endif()
target_link_libraries(${exe} ${OPENJPEG_LIBRARY_NAME}
@ -67,7 +67,7 @@ foreach(exe opj_decompress opj_compress opj_dump)
# Install exe
install(TARGETS ${exe}
EXPORT OpenJPEGTargets
DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Applications
DESTINATION ${OPENJPEG_INSTALL_BIN_DIR} COMPONENT Applications
)
if(OPJ_USE_DSYMUTIL)
add_custom_command(TARGET ${exe} POST_BUILD
@ -83,6 +83,6 @@ install(
FILES ${OPENJPEG_SOURCE_DIR}/doc/man/man1/opj_compress.1
${OPENJPEG_SOURCE_DIR}/doc/man/man1/opj_decompress.1
${OPENJPEG_SOURCE_DIR}/doc/man/man1/opj_dump.1
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
DESTINATION ${OPENJPEG_INSTALL_MAN_DIR}/man1)
#
endif()

View File

@ -117,6 +117,7 @@ static void scale_component_up(opj_image_comp_t* component,
}
}
component->prec = precision;
component->bpp = precision;
}
void scale_component(opj_image_comp_t* component, OPJ_UINT32 precision)
{
@ -143,6 +144,7 @@ void scale_component(opj_image_comp_t* component, OPJ_UINT32 precision)
l_data[i] >>= shift;
}
}
component->bpp = precision;
component->prec = precision;
}
@ -836,6 +838,7 @@ opj_image_t* tgatoimage(const char *filename, opj_cparameters_t *parameters)
for (i = 0; i < numcomps; i++) {
cmptparm[i].prec = 8;
cmptparm[i].bpp = 8;
cmptparm[i].sgnd = 0;
cmptparm[i].dx = (OPJ_UINT32)subsampling_dx;
cmptparm[i].dy = (OPJ_UINT32)subsampling_dy;
@ -1266,6 +1269,7 @@ opj_image_t* pgxtoimage(const char *filename, opj_cparameters_t *parameters)
}
cmptparm.prec = (OPJ_UINT32)prec;
cmptparm.bpp = (OPJ_UINT32)prec;
cmptparm.dx = (OPJ_UINT32)parameters->subsampling_dx;
cmptparm.dy = (OPJ_UINT32)parameters->subsampling_dy;
@ -1323,7 +1327,7 @@ opj_image_t* pgxtoimage(const char *filename, opj_cparameters_t *parameters)
comp->data[i] = v;
}
fclose(f);
comp->prec = (OPJ_UINT32)int_floorlog2(max) + 1;
comp->bpp = (OPJ_UINT32)int_floorlog2(max) + 1;
return image;
}
@ -1380,7 +1384,7 @@ int imagetopgx(opj_image_t * image, const char *outfile)
goto fin;
}
}
memcpy(name, outfile, dotpos);
strncpy(name, outfile, dotpos);
sprintf(name + dotpos, "_%u.pgx", compno);
fdest = fopen(name, "wb");
/* don't need name anymore */
@ -1412,9 +1416,6 @@ int imagetopgx(opj_image_t * image, const char *outfile)
unsigned char* line_buffer = malloc((size_t)w);
if (line_buffer == NULL) {
fprintf(stderr, "Out of memory");
if (total > 256) {
free(name);
}
goto fin;
}
for (j = 0; j < h; j++) {
@ -1808,13 +1809,6 @@ opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters)
return NULL;
}
if (header_info.width == 0
|| header_info.height == 0
|| (header_info.format == 7 && header_info.depth == 0)) {
fclose(fp);
return NULL;
}
/* This limitation could be removed by making sure to use size_t below */
if (header_info.height != 0 &&
header_info.width > INT_MAX / header_info.height) {
@ -1871,6 +1865,7 @@ opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters)
for (i = 0; i < numcomps; i++) {
cmptparm[i].prec = (OPJ_UINT32)prec;
cmptparm[i].bpp = (OPJ_UINT32)prec;
cmptparm[i].sgnd = 0;
cmptparm[i].dx = (OPJ_UINT32)subsampling_dx;
cmptparm[i].dy = (OPJ_UINT32)subsampling_dy;
@ -1899,10 +1894,8 @@ opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters)
for (compno = 0; compno < numcomps; compno++) {
index = 0;
if (fscanf(fp, "%u", &index) != 1) {
fprintf(stderr, "Missing data. Quitting.\n");
opj_image_destroy(image);
fclose(fp);
return NULL;
fprintf(stderr,
"\nWARNING: fscanf return a number of element different from the expected.\n");
}
image->comps[compno].data[i] = (OPJ_INT32)(index * 255) / header_info.maxval;
@ -1920,7 +1913,8 @@ opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters)
for (i = 0; i < w * h; i++) {
for (compno = 0; compno < numcomps; compno++) {
if (!fread(&c0, 1, 1, fp)) {
fprintf(stderr, "Missing data. Quitting.\n");
fprintf(stderr,
"\nError: fread return a number of element different from the expected.\n");
opj_image_destroy(image);
fclose(fp);
return NULL;
@ -1929,10 +1923,8 @@ opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters)
image->comps[compno].data[i] = c0;
} else {
if (!fread(&c1, 1, 1, fp)) {
fprintf(stderr, "Missing data. Quitting.\n");
opj_image_destroy(image);
fclose(fp);
return NULL;
fprintf(stderr,
"\nError: fread return a number of element different from the expected.\n");
}
/* netpbm: */
image->comps[compno].data[i] = ((c0 << 8) | c1);
@ -1944,17 +1936,15 @@ opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters)
unsigned int index;
if (fscanf(fp, "%u", &index) != 1) {
fprintf(stderr, "Missing data. Quitting.\n");
opj_image_destroy(image);
fclose(fp);
return NULL;
fprintf(stderr,
"\nWARNING: fscanf return a number of element different from the expected.\n");
}
image->comps[0].data[i] = (index ? 0 : 255);
}
} else if (format == 4) {
int x, y, bit;
int uc;
unsigned char uc;
i = 0;
for (y = 0; y < h; ++y) {
@ -1964,15 +1954,9 @@ opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters)
for (x = 0; x < w; ++x) {
if (bit == -1) {
bit = 7;
uc = getc(fp);
if (uc == EOF) {
fprintf(stderr, "Missing data. Quitting.\n");
opj_image_destroy(image);
fclose(fp);
return NULL;
}
uc = (unsigned char)getc(fp);
}
image->comps[0].data[i] = ((((unsigned char)uc >> bit) & 1) ? 0 : 255);
image->comps[0].data[i] = (((uc >> bit) & 1) ? 0 : 255);
--bit;
++i;
}
@ -1982,10 +1966,8 @@ opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters)
for (i = 0; i < w * h; ++i) {
if (!fread(&uc, 1, 1, fp)) {
fprintf(stderr, "Missing data. Quitting.\n");
opj_image_destroy(image);
fclose(fp);
return NULL;
fprintf(stderr,
"\nError: fread return a number of element different from the expected.\n");
}
image->comps[0].data[i] = (uc & 1) ? 0 : 255;
}
@ -2062,26 +2044,10 @@ int imagetopnm(opj_image_t * image, const char *outfile, int force_split)
has_alpha = (ncomp == 4 || ncomp == 2);
red = image->comps[0].data;
if (red == NULL) {
fprintf(stderr,
"imagetopnm: planes[%d] == NULL.\n", 0);
fprintf(stderr, "\tAborting\n");
fclose(fdest);
return fails;
}
if (triple) {
green = image->comps[1].data;
blue = image->comps[2].data;
for (i = 1; i <= 2; i++) {
if (image->comps[i].data == NULL) {
fprintf(stderr,
"imagetopnm: planes[%d] == NULL.\n", i);
fprintf(stderr, "\tAborting\n");
fclose(fdest);
return fails;
}
}
} else {
green = blue = NULL;
}
@ -2223,7 +2189,7 @@ int imagetopnm(opj_image_t * image, const char *outfile, int force_split)
const size_t olen = strlen(outfile);
const size_t dotpos = olen - 4;
memcpy(destname, outfile, dotpos);
strncpy(destname, outfile, dotpos);
sprintf(destname + dotpos, "_%u.pgm", compno);
} else {
sprintf(destname, "%s", outfile);
@ -2244,11 +2210,6 @@ int imagetopnm(opj_image_t * image, const char *outfile, int force_split)
opj_version(), wr, hr, max);
red = image->comps[compno].data;
if (!red) {
fclose(fdest);
continue;
}
adjustR =
(image->comps[compno].sgnd ? 1 << (image->comps[compno].prec - 1) : 0);
@ -2361,6 +2322,7 @@ static opj_image_t* rawtoimage_common(const char *filename,
/* initialize image components */
for (i = 0; i < numcomps; i++) {
cmptparm[i].prec = (OPJ_UINT32)raw_cp->rawBitDepth;
cmptparm[i].bpp = (OPJ_UINT32)raw_cp->rawBitDepth;
cmptparm[i].sgnd = (OPJ_UINT32)raw_cp->rawSigned;
cmptparm[i].dx = (OPJ_UINT32)(subsampling_dx * raw_cp->rawComps[i].dx);
cmptparm[i].dy = (OPJ_UINT32)(subsampling_dy * raw_cp->rawComps[i].dy);

View File

@ -95,8 +95,7 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters);
int imagetobmp(opj_image_t *image, const char *outfile);
/* TIFF conversion*/
opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters,
const unsigned int target_bitdepth);
opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters);
int imagetotif(opj_image_t *image, const char *outfile);
/**
Load a single image component encoded in PGX file format

View File

@ -198,10 +198,14 @@ static void bmpmask32toimage(const OPJ_UINT8* pData, OPJ_UINT32 stride,
bmp_mask_get_shift_and_prec(blueMask, &blueShift, &bluePrec);
bmp_mask_get_shift_and_prec(alphaMask, &alphaShift, &alphaPrec);
image->comps[0].bpp = redPrec;
image->comps[0].prec = redPrec;
image->comps[1].bpp = greenPrec;
image->comps[1].prec = greenPrec;
image->comps[2].bpp = bluePrec;
image->comps[2].prec = bluePrec;
if (hasAlpha) {
image->comps[3].bpp = alphaPrec;
image->comps[3].prec = alphaPrec;
}
@ -256,10 +260,14 @@ static void bmpmask16toimage(const OPJ_UINT8* pData, OPJ_UINT32 stride,
bmp_mask_get_shift_and_prec(blueMask, &blueShift, &bluePrec);
bmp_mask_get_shift_and_prec(alphaMask, &alphaShift, &alphaPrec);
image->comps[0].bpp = redPrec;
image->comps[0].prec = redPrec;
image->comps[1].bpp = greenPrec;
image->comps[1].prec = greenPrec;
image->comps[2].bpp = bluePrec;
image->comps[2].prec = bluePrec;
if (hasAlpha) {
image->comps[3].bpp = alphaPrec;
image->comps[3].prec = alphaPrec;
}
@ -427,31 +435,16 @@ static OPJ_BOOL bmp_read_info_header(FILE* IN, OPJ_BITMAPINFOHEADER* header)
header->biRedMask |= (OPJ_UINT32)getc(IN) << 16;
header->biRedMask |= (OPJ_UINT32)getc(IN) << 24;
if (!header->biRedMask) {
fprintf(stderr, "Error, invalid red mask value %d\n", header->biRedMask);
return OPJ_FALSE;
}
header->biGreenMask = (OPJ_UINT32)getc(IN);
header->biGreenMask |= (OPJ_UINT32)getc(IN) << 8;
header->biGreenMask |= (OPJ_UINT32)getc(IN) << 16;
header->biGreenMask |= (OPJ_UINT32)getc(IN) << 24;
if (!header->biGreenMask) {
fprintf(stderr, "Error, invalid green mask value %d\n", header->biGreenMask);
return OPJ_FALSE;
}
header->biBlueMask = (OPJ_UINT32)getc(IN);
header->biBlueMask |= (OPJ_UINT32)getc(IN) << 8;
header->biBlueMask |= (OPJ_UINT32)getc(IN) << 16;
header->biBlueMask |= (OPJ_UINT32)getc(IN) << 24;
if (!header->biBlueMask) {
fprintf(stderr, "Error, invalid blue mask value %d\n", header->biBlueMask);
return OPJ_FALSE;
}
header->biAlphaMask = (OPJ_UINT32)getc(IN);
header->biAlphaMask |= (OPJ_UINT32)getc(IN) << 8;
header->biAlphaMask |= (OPJ_UINT32)getc(IN) << 16;
@ -526,14 +519,14 @@ static OPJ_BOOL bmp_read_raw_data(FILE* IN, OPJ_UINT8* pData, OPJ_UINT32 stride,
static OPJ_BOOL bmp_read_rle8_data(FILE* IN, OPJ_UINT8* pData,
OPJ_UINT32 stride, OPJ_UINT32 width, OPJ_UINT32 height)
{
OPJ_UINT32 x, y, written;
OPJ_UINT32 x, y;
OPJ_UINT8 *pix;
const OPJ_UINT8 *beyond;
beyond = pData + stride * height;
pix = pData;
x = y = written = 0U;
x = y = 0U;
while (y < height) {
int c = getc(IN);
if (c == EOF) {
@ -553,7 +546,6 @@ static OPJ_BOOL bmp_read_rle8_data(FILE* IN, OPJ_UINT8* pData,
for (j = 0; (j < c) && (x < width) &&
((OPJ_SIZE_T)pix < (OPJ_SIZE_T)beyond); j++, x++, pix++) {
*pix = c1;
written++;
}
} else {
c = getc(IN);
@ -591,7 +583,6 @@ static OPJ_BOOL bmp_read_rle8_data(FILE* IN, OPJ_UINT8* pData,
}
c1 = (OPJ_UINT8)c1_int;
*pix = c1;
written++;
}
if ((OPJ_UINT32)c & 1U) { /* skip padding byte */
c = getc(IN);
@ -602,50 +593,37 @@ static OPJ_BOOL bmp_read_rle8_data(FILE* IN, OPJ_UINT8* pData,
}
}
}/* while() */
if (written != width * height) {
fprintf(stderr, "warning, image's actual size does not match advertized one\n");
return OPJ_FALSE;
}
return OPJ_TRUE;
}
static OPJ_BOOL bmp_read_rle4_data(FILE* IN, OPJ_UINT8* pData,
OPJ_UINT32 stride, OPJ_UINT32 width, OPJ_UINT32 height)
{
OPJ_UINT32 x, y, written;
OPJ_UINT32 x, y;
OPJ_UINT8 *pix;
const OPJ_UINT8 *beyond;
beyond = pData + stride * height;
pix = pData;
x = y = written = 0U;
x = y = 0U;
while (y < height) {
int c = getc(IN);
if (c == EOF) {
return OPJ_FALSE;
break;
}
if (c) { /* encoded mode */
int j, c1_int;
OPJ_UINT8 c1;
c1_int = getc(IN);
if (c1_int == EOF) {
return OPJ_FALSE;
}
c1 = (OPJ_UINT8)c1_int;
int j;
OPJ_UINT8 c1 = (OPJ_UINT8)getc(IN);
for (j = 0; (j < c) && (x < width) &&
((OPJ_SIZE_T)pix < (OPJ_SIZE_T)beyond); j++, x++, pix++) {
*pix = (OPJ_UINT8)((j & 1) ? (c1 & 0x0fU) : ((c1 >> 4) & 0x0fU));
written++;
}
} else { /* absolute mode */
c = getc(IN);
if (c == EOF) {
return OPJ_FALSE;
break;
}
if (c == 0x00) { /* EOL */
@ -656,14 +634,8 @@ static OPJ_BOOL bmp_read_rle4_data(FILE* IN, OPJ_UINT8* pData,
break;
} else if (c == 0x02) { /* MOVE by dxdy */
c = getc(IN);
if (c == EOF) {
return OPJ_FALSE;
}
x += (OPJ_UINT32)c;
c = getc(IN);
if (c == EOF) {
return OPJ_FALSE;
}
y += (OPJ_UINT32)c;
pix = pData + y * stride + x;
} else { /* 03 .. 255 : absolute mode */
@ -673,29 +645,16 @@ static OPJ_BOOL bmp_read_rle4_data(FILE* IN, OPJ_UINT8* pData,
for (j = 0; (j < c) && (x < width) &&
((OPJ_SIZE_T)pix < (OPJ_SIZE_T)beyond); j++, x++, pix++) {
if ((j & 1) == 0) {
int c1_int;
c1_int = getc(IN);
if (c1_int == EOF) {
return OPJ_FALSE;
}
c1 = (OPJ_UINT8)c1_int;
c1 = (OPJ_UINT8)getc(IN);
}
*pix = (OPJ_UINT8)((j & 1) ? (c1 & 0x0fU) : ((c1 >> 4) & 0x0fU));
written++;
}
if (((c & 3) == 1) || ((c & 3) == 2)) { /* skip padding byte */
c = getc(IN);
if (c == EOF) {
return OPJ_FALSE;
}
getc(IN);
}
}
}
} /* while(y < height) */
if (written != width * height) {
fprintf(stderr, "warning, image's actual size does not match advertized one\n");
return OPJ_FALSE;
}
return OPJ_TRUE;
}
@ -789,7 +748,7 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters)
fclose(IN);
return NULL;
}
pData = (OPJ_UINT8 *) calloc(1, sizeof(OPJ_UINT8) * stride * Info_h.biHeight);
pData = (OPJ_UINT8 *) calloc(1, stride * Info_h.biHeight * sizeof(OPJ_UINT8));
if (pData == NULL) {
fclose(IN);
return NULL;
@ -830,6 +789,7 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters)
memset(&cmptparm[0], 0, sizeof(cmptparm));
for (i = 0; i < 4U; i++) {
cmptparm[i].prec = 8;
cmptparm[i].bpp = 8;
cmptparm[i].sgnd = 0;
cmptparm[i].dx = (OPJ_UINT32)parameters->subsampling_dx;
cmptparm[i].dy = (OPJ_UINT32)parameters->subsampling_dy;
@ -871,12 +831,6 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters)
bmpmask32toimage(pData, stride, image, 0x00FF0000U, 0x0000FF00U, 0x000000FFU,
0x00000000U);
} else if (Info_h.biBitCount == 32 && Info_h.biCompression == 3) { /* bitmask */
if ((Info_h.biRedMask == 0U) && (Info_h.biGreenMask == 0U) &&
(Info_h.biBlueMask == 0U)) {
Info_h.biRedMask = 0x00FF0000U;
Info_h.biGreenMask = 0x0000FF00U;
Info_h.biBlueMask = 0x000000FFU;
}
bmpmask32toimage(pData, stride, image, Info_h.biRedMask, Info_h.biGreenMask,
Info_h.biBlueMask, Info_h.biAlphaMask);
} else if (Info_h.biBitCount == 16 && Info_h.biCompression == 0) { /* RGBX */

View File

@ -65,192 +65,26 @@ static void convert_16u32s_C1R(const OPJ_BYTE* pSrc, OPJ_INT32* pDst,
}
}
static opj_image_t * pngtoimage_internal(opj_cparameters_t * params,
FILE *reader,
png_structp png,
png_infop info,
png_uint_32* pheight,
OPJ_BYTE*** prows,
OPJ_INT32** prow32s)
{
*pheight = 0;
*prows = NULL;
*prow32s = NULL;
if (setjmp(png_jmpbuf(png))) {
return NULL;
}
{
opj_image_t *image = NULL;
opj_image_cmptparm_t cmptparm[4];
OPJ_UINT32 nr_comp;
convert_XXx32s_C1R cvtXXTo32s = NULL;
convert_32s_CXPX cvtCxToPx = NULL;
OPJ_INT32* planes[4];
double gamma;
int bit_depth, interlace_type, compression_type, filter_type;
OPJ_UINT32 i;
png_uint_32 width, height = 0U;
int color_type;
OPJ_BYTE** rows = NULL;
OPJ_INT32* row32s = NULL;
png_init_io(png, reader);
png_set_sig_bytes(png, MAGIC_SIZE);
png_read_info(png, info);
if (png_get_IHDR(png, info, &width, &height,
&bit_depth, &color_type, &interlace_type,
&compression_type, &filter_type) == 0) {
return image;
}
*pheight = height;
/* png_set_expand():
* expand paletted images to RGB, expand grayscale images of
* less than 8-bit depth to 8-bit depth, and expand tRNS chunks
* to alpha channels.
*/
if (color_type == PNG_COLOR_TYPE_PALETTE) {
png_set_expand(png);
}
if (png_get_valid(png, info, PNG_INFO_tRNS)) {
png_set_expand(png);
}
/* We might want to expand background */
/*
if(png_get_valid(png, info, PNG_INFO_bKGD)) {
png_color_16p bgnd;
png_get_bKGD(png, info, &bgnd);
png_set_background(png, bgnd, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
}
*/
if (!png_get_gAMA(png, info, &gamma)) {
gamma = 1.0;
}
/* we're not displaying but converting, screen gamma == 1.0 */
png_set_gamma(png, 1.0, gamma);
png_read_update_info(png, info);
color_type = png_get_color_type(png, info);
switch (color_type) {
case PNG_COLOR_TYPE_GRAY:
nr_comp = 1;
break;
case PNG_COLOR_TYPE_GRAY_ALPHA:
nr_comp = 2;
break;
case PNG_COLOR_TYPE_RGB:
nr_comp = 3;
break;
case PNG_COLOR_TYPE_RGB_ALPHA:
nr_comp = 4;
break;
default:
fprintf(stderr, "pngtoimage: colortype %d is not supported\n", color_type);
return image;
}
cvtCxToPx = convert_32s_CXPX_LUT[nr_comp];
bit_depth = png_get_bit_depth(png, info);
switch (bit_depth) {
case 1:
case 2:
case 4:
case 8:
cvtXXTo32s = convert_XXu32s_C1R_LUT[bit_depth];
break;
case 16: /* 16 bpp is specific to PNG */
cvtXXTo32s = convert_16u32s_C1R;
break;
default:
fprintf(stderr, "pngtoimage: bit depth %d is not supported\n", bit_depth);
return image;
}
rows = (OPJ_BYTE**)calloc(height + 1, sizeof(OPJ_BYTE*));
if (rows == NULL) {
fprintf(stderr, "pngtoimage: memory out\n");
return image;
}
*prows = rows;
for (i = 0; i < height; ++i) {
rows[i] = (OPJ_BYTE*)malloc(png_get_rowbytes(png, info));
if (rows[i] == NULL) {
fprintf(stderr, "pngtoimage: memory out\n");
return image;
}
}
png_read_image(png, rows);
/* Create image */
memset(cmptparm, 0, sizeof(cmptparm));
for (i = 0; i < nr_comp; ++i) {
/* bits_per_pixel: 8 or 16 */
cmptparm[i].prec = (OPJ_UINT32)bit_depth;
cmptparm[i].sgnd = 0;
cmptparm[i].dx = (OPJ_UINT32)params->subsampling_dx;
cmptparm[i].dy = (OPJ_UINT32)params->subsampling_dy;
cmptparm[i].w = (OPJ_UINT32)width;
cmptparm[i].h = (OPJ_UINT32)height;
}
image = opj_image_create(nr_comp, &cmptparm[0],
(nr_comp > 2U) ? OPJ_CLRSPC_SRGB : OPJ_CLRSPC_GRAY);
if (image == NULL) {
return image;
}
image->x0 = (OPJ_UINT32)params->image_offset_x0;
image->y0 = (OPJ_UINT32)params->image_offset_y0;
image->x1 = (OPJ_UINT32)(image->x0 + (width - 1) * (OPJ_UINT32)
params->subsampling_dx + 1);
image->y1 = (OPJ_UINT32)(image->y0 + (height - 1) * (OPJ_UINT32)
params->subsampling_dy + 1);
row32s = (OPJ_INT32 *)malloc((size_t)width * nr_comp * sizeof(OPJ_INT32));
if (row32s == NULL) {
return image;
}
*prow32s = row32s;
/* Set alpha channel */
image->comps[nr_comp - 1U].alpha = 1U - (nr_comp & 1U);
for (i = 0; i < nr_comp; i++) {
planes[i] = image->comps[i].data;
}
for (i = 0; i < height; ++i) {
cvtXXTo32s(rows[i], row32s, (OPJ_SIZE_T)width * nr_comp);
cvtCxToPx(row32s, planes, width);
planes[0] += width;
planes[1] += width;
planes[2] += width;
planes[3] += width;
}
return image;
}
}
opj_image_t *pngtoimage(const char *read_idf, opj_cparameters_t * params)
{
png_structp png = NULL;
png_infop info = NULL;
double gamma;
int bit_depth, interlace_type, compression_type, filter_type;
OPJ_UINT32 i;
png_uint_32 height = 0U;
png_uint_32 width, height = 0U;
int color_type;
FILE *reader = NULL;
OPJ_BYTE** rows = NULL;
OPJ_INT32* row32s = NULL;
OPJ_BYTE sigbuf[8];
/* j2k: */
opj_image_t *image = NULL;
opj_image_cmptparm_t cmptparm[4];
OPJ_UINT32 nr_comp;
OPJ_BYTE sigbuf[8];
convert_XXx32s_C1R cvtXXTo32s = NULL;
convert_32s_CXPX cvtCxToPx = NULL;
OPJ_INT32* planes[4];
if ((reader = fopen(read_idf, "rb")) == NULL) {
fprintf(stderr, "pngtoimage: can not open %s\n", read_idf);
@ -271,7 +105,148 @@ opj_image_t *pngtoimage(const char *read_idf, opj_cparameters_t * params)
goto fin;
}
image = pngtoimage_internal(params, reader, png, info, &height, &rows, &row32s);
if (setjmp(png_jmpbuf(png))) {
goto fin;
}
png_init_io(png, reader);
png_set_sig_bytes(png, MAGIC_SIZE);
png_read_info(png, info);
if (png_get_IHDR(png, info, &width, &height,
&bit_depth, &color_type, &interlace_type,
&compression_type, &filter_type) == 0) {
goto fin;
}
/* png_set_expand():
* expand paletted images to RGB, expand grayscale images of
* less than 8-bit depth to 8-bit depth, and expand tRNS chunks
* to alpha channels.
*/
if (color_type == PNG_COLOR_TYPE_PALETTE) {
png_set_expand(png);
}
if (png_get_valid(png, info, PNG_INFO_tRNS)) {
png_set_expand(png);
}
/* We might wan't to expand background */
/*
if(png_get_valid(png, info, PNG_INFO_bKGD)) {
png_color_16p bgnd;
png_get_bKGD(png, info, &bgnd);
png_set_background(png, bgnd, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
}
*/
if (!png_get_gAMA(png, info, &gamma)) {
gamma = 1.0;
}
/* we're not displaying but converting, screen gamma == 1.0 */
png_set_gamma(png, 1.0, gamma);
png_read_update_info(png, info);
color_type = png_get_color_type(png, info);
switch (color_type) {
case PNG_COLOR_TYPE_GRAY:
nr_comp = 1;
break;
case PNG_COLOR_TYPE_GRAY_ALPHA:
nr_comp = 2;
break;
case PNG_COLOR_TYPE_RGB:
nr_comp = 3;
break;
case PNG_COLOR_TYPE_RGB_ALPHA:
nr_comp = 4;
break;
default:
fprintf(stderr, "pngtoimage: colortype %d is not supported\n", color_type);
goto fin;
}
cvtCxToPx = convert_32s_CXPX_LUT[nr_comp];
bit_depth = png_get_bit_depth(png, info);
switch (bit_depth) {
case 1:
case 2:
case 4:
case 8:
cvtXXTo32s = convert_XXu32s_C1R_LUT[bit_depth];
break;
case 16: /* 16 bpp is specific to PNG */
cvtXXTo32s = convert_16u32s_C1R;
break;
default:
fprintf(stderr, "pngtoimage: bit depth %d is not supported\n", bit_depth);
goto fin;
}
rows = (OPJ_BYTE**)calloc(height + 1, sizeof(OPJ_BYTE*));
if (rows == NULL) {
fprintf(stderr, "pngtoimage: memory out\n");
goto fin;
}
for (i = 0; i < height; ++i) {
rows[i] = (OPJ_BYTE*)malloc(png_get_rowbytes(png, info));
if (rows[i] == NULL) {
fprintf(stderr, "pngtoimage: memory out\n");
goto fin;
}
}
png_read_image(png, rows);
/* Create image */
memset(cmptparm, 0, sizeof(cmptparm));
for (i = 0; i < nr_comp; ++i) {
cmptparm[i].prec = (OPJ_UINT32)bit_depth;
/* bits_per_pixel: 8 or 16 */
cmptparm[i].bpp = (OPJ_UINT32)bit_depth;
cmptparm[i].sgnd = 0;
cmptparm[i].dx = (OPJ_UINT32)params->subsampling_dx;
cmptparm[i].dy = (OPJ_UINT32)params->subsampling_dy;
cmptparm[i].w = (OPJ_UINT32)width;
cmptparm[i].h = (OPJ_UINT32)height;
}
image = opj_image_create(nr_comp, &cmptparm[0],
(nr_comp > 2U) ? OPJ_CLRSPC_SRGB : OPJ_CLRSPC_GRAY);
if (image == NULL) {
goto fin;
}
image->x0 = (OPJ_UINT32)params->image_offset_x0;
image->y0 = (OPJ_UINT32)params->image_offset_y0;
image->x1 = (OPJ_UINT32)(image->x0 + (width - 1) * (OPJ_UINT32)
params->subsampling_dx + 1 + image->x0);
image->y1 = (OPJ_UINT32)(image->y0 + (height - 1) * (OPJ_UINT32)
params->subsampling_dy + 1 + image->y0);
row32s = (OPJ_INT32 *)malloc((size_t)width * nr_comp * sizeof(OPJ_INT32));
if (row32s == NULL) {
goto fin;
}
/* Set alpha channel */
image->comps[nr_comp - 1U].alpha = 1U - (nr_comp & 1U);
for (i = 0; i < nr_comp; i++) {
planes[i] = image->comps[i].data;
}
for (i = 0; i < height; ++i) {
cvtXXTo32s(rows[i], row32s, (OPJ_SIZE_T)width * nr_comp);
cvtCxToPx(row32s, planes, width);
planes[0] += width;
planes[1] += width;
planes[2] += width;
planes[3] += width;
}
fin:
if (rows) {
for (i = 0; i < height; ++i)
@ -322,12 +297,6 @@ int imagetopng(opj_image_t * image, const char *write_idf)
memset(&sig_bit, 0, sizeof(sig_bit));
prec = (int)image->comps[0].prec;
planes[0] = image->comps[0].data;
if (planes[0] == NULL) {
fprintf(stderr,
"imagetopng: planes[%d] == NULL.\n", 0);
fprintf(stderr, "\tAborting\n");
return 1;
}
nr_comp = (int)image->numcomps;
if (nr_comp > 4) {
@ -347,12 +316,6 @@ int imagetopng(opj_image_t * image, const char *write_idf)
break;
}
planes[i] = image->comps[i].data;
if (planes[i] == NULL) {
fprintf(stderr,
"imagetopng: planes[%d] == NULL.\n", i);
fprintf(stderr, "\tAborting\n");
return 1;
}
}
if (i != nr_comp) {
fprintf(stderr,

View File

@ -568,8 +568,8 @@ int imagetotif(opj_image_t * image, const char *outfile)
{
TIFF *tif;
tdata_t buf;
uint32_t width, height;
uint16_t bps, tiPhoto;
uint32 width, height;
uint16 bps, tiPhoto;
int adjust, sgnd;
int64_t strip_size, rowStride, TIFF_MAX;
OPJ_UINT32 i, numcomps;
@ -578,7 +578,7 @@ int imagetotif(opj_image_t * image, const char *outfile)
convert_32s_PXCX cvtPxToCx = NULL;
convert_32sXXx_C1R cvt32sToTif = NULL;
bps = (uint16_t)image->comps[0].prec;
bps = (uint16)image->comps[0].prec;
planes[0] = image->comps[0].data;
numcomps = image->numcomps;
@ -616,12 +616,6 @@ int imagetotif(opj_image_t * image, const char *outfile)
break;
}
planes[i] = image->comps[i].data;
if (planes[i] == NULL) {
fprintf(stderr,
"imagetotif: planes[%d] == NULL.\n", i);
fprintf(stderr, "\tAborting\n");
return 1;
}
}
if (i != numcomps) {
fprintf(stderr,
@ -694,12 +688,12 @@ int imagetotif(opj_image_t * image, const char *outfile)
}
sgnd = (int)image->comps[0].sgnd;
adjust = sgnd ? (int)(1 << (image->comps[0].prec - 1)) : 0;
width = (uint32_t)image->comps[0].w;
height = (uint32_t)image->comps[0].h;
width = (uint32)image->comps[0].w;
height = (uint32)image->comps[0].h;
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, (uint16_t)numcomps);
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, (uint16)numcomps);
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
@ -731,7 +725,8 @@ int imagetotif(opj_image_t * image, const char *outfile)
TIFFClose(tif);
return 1;
}
buffer32s = (OPJ_INT32 *)malloc(sizeof(OPJ_INT32) * width * numcomps);
buffer32s = (OPJ_INT32 *)malloc((OPJ_SIZE_T)(width * numcomps * sizeof(
OPJ_INT32)));
if (buffer32s == NULL) {
_TIFFfree(buf);
TIFFClose(tif);
@ -1247,8 +1242,7 @@ static void tif_16uto32s(const OPJ_UINT16* pSrc, OPJ_INT32* pDst,
* libtiff/tif_getimage.c : 1,2,4,8,16 bitspersample accepted
* CINEMA : 12 bit precision
*/
opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters,
const unsigned int target_bitdepth)
opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters)
{
int subsampling_dx = parameters->subsampling_dx;
int subsampling_dy = parameters->subsampling_dy;
@ -1260,8 +1254,8 @@ opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters,
OPJ_COLOR_SPACE color_space = OPJ_CLRSPC_UNKNOWN;
opj_image_cmptparm_t cmptparm[4]; /* RGBA */
opj_image_t *image = NULL;
uint16_t tiBps, tiPhoto, tiSf, tiSpp, tiPC;
uint32_t tiWidth, tiHeight;
uint16 tiBps, tiPhoto, tiSf, tiSpp, tiPC;
uint32 tiWidth, tiHeight;
OPJ_BOOL is_cinema = OPJ_IS_CINEMA(parameters->rsiz);
convert_XXx32s_C1R cvtTifTo32s = NULL;
convert_32s_CXPX cvtCxToPx = NULL;
@ -1284,6 +1278,8 @@ opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters,
TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &tiSpp);
TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &tiPhoto);
TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &tiPC);
w = (int)tiWidth;
h = (int)tiHeight;
if (tiSpp == 0 || tiSpp > 4) { /* should be 1 ... 4 */
fprintf(stderr, "tiftoimage: Bad value for samples per pixel == %d.\n"
@ -1388,6 +1384,7 @@ opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters,
for (j = 0; j < numcomps; j++) {
cmptparm[j].prec = tiBps;
cmptparm[j].bpp = tiBps;
cmptparm[j].dx = (OPJ_UINT32)subsampling_dx;
cmptparm[j].dy = (OPJ_UINT32)subsampling_dy;
cmptparm[j].w = (OPJ_UINT32)w;
@ -1450,7 +1447,8 @@ opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters,
}
rowStride = (int64_t)((tiWidth * tiSpp * tiBps + 7U) / 8U);
buffer32s = (OPJ_INT32 *)malloc(sizeof(OPJ_INT32) * tiWidth * tiSpp);
buffer32s = (OPJ_INT32 *)malloc((OPJ_SIZE_T)(tiWidth * tiSpp * sizeof(
OPJ_INT32)));
if (buffer32s == NULL) {
_TIFFfree(buf);
TIFFClose(tif);
@ -1505,10 +1503,6 @@ opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters,
scale_component(&(image->comps[j]), 12);
}
} else if ((target_bitdepth > 0) && (target_bitdepth != tiBps)) {
for (j = 0; j < numcomps; ++j) {
scale_component(&(image->comps[j]), target_bitdepth);
}
}
return image;

View File

@ -44,7 +44,6 @@
#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include <limits.h>
#ifdef _WIN32
#include "windirent.h"
@ -142,7 +141,7 @@ static void encode_help_display(void)
fprintf(stdout, "-i <file>\n");
fprintf(stdout, " Input file\n");
fprintf(stdout,
" Known extensions are <PBM|PGM|PPM|PNM|PAM|PGX|PNG|BMP|TIF|TIFF|RAW|YUV|RAWL|TGA>\n");
" Known extensions are <PBM|PGM|PPM|PNM|PAM|PGX|PNG|BMP|TIF|RAW|RAWL|TGA>\n");
fprintf(stdout, " If used, '-o <file>' must be provided\n");
fprintf(stdout, "-o <compressed file>\n");
fprintf(stdout, " Output file (accepted extensions are j2k or jp2).\n");
@ -154,12 +153,12 @@ static void encode_help_display(void)
fprintf(stdout, " Required only if -ImgDir is used\n");
fprintf(stdout,
"-F <width>,<height>,<ncomp>,<bitdepth>,{s,u}@<dx1>x<dy1>:...:<dxn>x<dyn>\n");
fprintf(stdout, " Characteristics of the raw or yuv input image\n");
fprintf(stdout, " Characteristics of the raw input image\n");
fprintf(stdout,
" If subsampling is omitted, 1x1 is assumed for all components\n");
fprintf(stdout, " Example: -F 512,512,3,8,u@1x1:2x2:2x2\n");
fprintf(stdout, " Example: -F 512,512,3,8,u@1x1:2x2:2x2\n");
fprintf(stdout,
" for raw or yuv 512x512 size with 4:2:0 subsampling\n");
" for raw 512x512 image with 4:2:0 subsampling\n");
fprintf(stdout, " Required only if RAW or RAWL input file is provided.\n");
fprintf(stdout, "\n");
fprintf(stdout, "Optional Parameters:\n");
@ -187,11 +186,6 @@ static void encode_help_display(void)
fprintf(stdout,
" It corresponds to the number of DWT decompositions +1. \n");
fprintf(stdout, " Default: 6.\n");
fprintf(stdout, "-TargetBitDepth <target bit depth>\n");
fprintf(stdout, " Target bit depth.\n");
fprintf(stdout, " Number of bits per component to use from input image\n");
fprintf(stdout, " if all bits are unwanted.\n");
fprintf(stdout, " (Currently only implemented for TIF.)\n");
fprintf(stdout, "-b <cblk width>,<cblk height>\n");
fprintf(stdout,
" Code-block size. The dimension must respect the constraint \n");
@ -209,9 +203,9 @@ static void encode_help_display(void)
fprintf(stdout,
" to the highest resolution level and subsequent records to lower \n");
fprintf(stdout,
" resolution levels. The last specified record is halved successively for each \n");
" resolution levels. The last specified record is right-shifted for each \n");
fprintf(stdout, " remaining lower resolution levels.\n");
fprintf(stdout, " Default: 2^15x2^15 at each resolution.\n");
fprintf(stdout, " Default: 215x215 at each resolution.\n");
fprintf(stdout, "-t <tile width>,<tile height>\n");
fprintf(stdout, " Tile size.\n");
fprintf(stdout,
@ -235,10 +229,6 @@ static void encode_help_display(void)
fprintf(stdout, " Write SOP marker before each packet.\n");
fprintf(stdout, "-EPH\n");
fprintf(stdout, " Write EPH marker after each header packet.\n");
fprintf(stdout, "-PLT\n");
fprintf(stdout, " Write PLT marker in tile-part header.\n");
fprintf(stdout, "-TLM\n");
fprintf(stdout, " Write TLM marker in main header.\n");
fprintf(stdout, "-M <key value>\n");
fprintf(stdout, " Mode switch.\n");
fprintf(stdout, " [1=BYPASS(LAZY) 2=RESET 4=RESTART(TERMALL)\n");
@ -297,25 +287,11 @@ static void encode_help_display(void)
fprintf(stdout, "-cinema4K\n");
fprintf(stdout, " Digital Cinema 4K profile compliant codestream.\n");
fprintf(stdout, " Frames per second not required. Default value is 24fps.\n");
fprintf(stdout, "-IMF <PROFILE>[,mainlevel=X][,sublevel=Y][,framerate=FPS]\n");
fprintf(stdout, " Interoperable Master Format compliant codestream.\n");
fprintf(stdout, " <PROFILE>=2K, 4K, 8K, 2K_R, 4K_R or 8K_R.\n");
fprintf(stdout, " X >= 0 and X <= 11.\n");
fprintf(stdout, " Y >= 0 and Y <= 9.\n");
fprintf(stdout,
" framerate > 0 may be specified to enhance checks and set maximum bit rate when Y > 0.\n");
fprintf(stdout, "-GuardBits value\n");
fprintf(stdout,
" Number of guard bits in [0,7] range. Usually 1 or 2 (default value).\n");
fprintf(stdout, "-jpip\n");
fprintf(stdout, " Write jpip codestream index box in JP2 output file.\n");
fprintf(stdout, " Currently supports only RPCL order.\n");
fprintf(stdout, "-C <comment>\n");
fprintf(stdout, " Add <comment> in the comment marker segment.\n");
if (opj_has_thread_support()) {
fprintf(stdout, "-threads <num_threads|ALL_CPUS>\n"
" Number of threads to use for encoding or ALL_CPUS for all available cores.\n");
}
/* UniPG>> */
#ifdef USE_JPWL
fprintf(stdout, "-W <params>\n");
@ -337,7 +313,7 @@ static void encode_help_display(void)
JPWL_MAX_NO_TILESPECS);
fprintf(stdout,
" p selects the packet error protection (EEP/UEP with EPBs)\n");
fprintf(stdout, " to be applied to raw or yuv data: 'type' can be\n");
fprintf(stdout, " to be applied to raw data: 'type' can be\n");
fprintf(stdout,
" [0=none 1,absent=predefined 16=CRC-16 32=CRC-32 37-128=RS]\n");
fprintf(stdout,
@ -489,11 +465,6 @@ static unsigned int get_num_images(char *imgdirpath)
if (strcmp(".", content->d_name) == 0 || strcmp("..", content->d_name) == 0) {
continue;
}
if (num_images == UINT_MAX) {
fprintf(stderr, "Too many files in folder %s\n", imgdirpath);
num_images = 0;
break;
}
num_images++;
}
closedir(dir);
@ -532,10 +503,10 @@ static int get_file_format(char *filename)
{
unsigned int i;
static const char *extension[] = {
"pgx", "pnm", "pgm", "ppm", "pbm", "pam", "bmp", "tif", "tiff", "raw", "yuv", "rawl", "tga", "png", "j2k", "jp2", "j2c", "jpc"
"pgx", "pnm", "pgm", "ppm", "pbm", "pam", "bmp", "tif", "raw", "rawl", "tga", "png", "j2k", "jp2", "j2c", "jpc"
};
static const int format[] = {
PGX_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, BMP_DFMT, TIF_DFMT, TIF_DFMT, RAW_DFMT, RAW_DFMT, RAWL_DFMT, TGA_DFMT, PNG_DFMT, J2K_CFMT, JP2_CFMT, J2K_CFMT, J2K_CFMT
PGX_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, BMP_DFMT, TIF_DFMT, RAW_DFMT, RAWL_DFMT, TGA_DFMT, PNG_DFMT, J2K_CFMT, JP2_CFMT, J2K_CFMT, J2K_CFMT
};
char * ext = strrchr(filename, '.');
if (ext == NULL) {
@ -556,8 +527,7 @@ static char * get_file_name(char *name)
return fname;
}
static char get_next_file(unsigned int imageno, dircnt_t *dirptr,
img_fol_t *img_fol,
static char get_next_file(int imageno, dircnt_t *dirptr, img_fol_t *img_fol,
opj_cparameters_t *parameters)
{
char image_filename[OPJ_PATH_LEN], infilename[OPJ_PATH_LEN],
@ -565,18 +535,12 @@ static char get_next_file(unsigned int imageno, dircnt_t *dirptr,
char *temp_p, temp1[OPJ_PATH_LEN] = "";
strcpy(image_filename, dirptr->filename[imageno]);
fprintf(stderr, "File Number %u \"%s\"\n", imageno, image_filename);
fprintf(stderr, "File Number %d \"%s\"\n", imageno, image_filename);
parameters->decod_format = get_file_format(image_filename);
if (parameters->decod_format == -1) {
return 1;
}
if (strlen(img_fol->imgdirpath) + 1 + strlen(image_filename) + 1 > sizeof(
infilename)) {
return 1;
}
strcpy(infilename, img_fol->imgdirpath);
strcat(infilename, "/");
strcat(infilename, image_filename);
sprintf(infilename, "%s/%s", img_fol->imgdirpath, image_filename);
if (opj_strcpy_s(parameters->infile, sizeof(parameters->infile),
infilename) != 0) {
return 1;
@ -589,15 +553,8 @@ static char get_next_file(unsigned int imageno, dircnt_t *dirptr,
sprintf(temp1, ".%s", temp_p);
}
if (img_fol->set_out_format == 1) {
if (strlen(img_fol->imgdirpath) + 1 + strlen(temp_ofname) + 1 + strlen(
img_fol->out_format) + 1 > sizeof(outfilename)) {
return 1;
}
strcpy(outfilename, img_fol->imgdirpath);
strcat(outfilename, "/");
strcat(outfilename, temp_ofname);
strcat(outfilename, ".");
strcat(outfilename, img_fol->out_format);
sprintf(outfilename, "%s/%s.%s", img_fol->imgdirpath, temp_ofname,
img_fol->out_format);
if (opj_strcpy_s(parameters->outfile, sizeof(parameters->outfile),
outfilename) != 0) {
return 1;
@ -611,13 +568,7 @@ static char get_next_file(unsigned int imageno, dircnt_t *dirptr,
static int parse_cmdline_encoder(int argc, char **argv,
opj_cparameters_t *parameters,
img_fol_t *img_fol, raw_cparameters_t *raw_cp, char *indexfilename,
size_t indexfilename_size,
int* pOutFramerate,
OPJ_BOOL* pOutPLT,
OPJ_BOOL* pOutTLM,
int* pOutGuardBits,
int* pOutNumThreads,
unsigned int* pTarget_bitdepth)
size_t indexfilename_size)
{
OPJ_UINT32 i, j;
int totlen, c;
@ -632,17 +583,11 @@ static int parse_cmdline_encoder(int argc, char **argv,
{"POC", REQ_ARG, NULL, 'P'},
{"ROI", REQ_ARG, NULL, 'R'},
{"jpip", NO_ARG, NULL, 'J'},
{"mct", REQ_ARG, NULL, 'Y'},
{"IMF", REQ_ARG, NULL, 'Z'},
{"PLT", NO_ARG, NULL, 'A'},
{"threads", REQ_ARG, NULL, 'B'},
{"TLM", NO_ARG, NULL, 'D'},
{"TargetBitDepth", REQ_ARG, NULL, 'X'},
{"GuardBits", REQ_ARG, NULL, 'G'}
{"mct", REQ_ARG, NULL, 'Y'}
};
/* parse the command line */
const char optlist[] = "i:o:r:q:n:b:c:t:p:s:SEM:x:R:d:T:If:P:C:F:u:JY:X:G:"
const char optlist[] = "i:o:r:q:n:b:c:t:p:s:SEM:x:R:d:T:If:P:C:F:u:JY:"
#ifdef USE_JPWL
"W:"
#endif /* USE_JPWL */
@ -674,7 +619,7 @@ static int parse_cmdline_encoder(int argc, char **argv,
default:
fprintf(stderr,
"[ERROR] Unknown input file format: %s \n"
" Known file formats are *.pnm, *.pgm, *.ppm, *.pgx, *png, *.bmp, *.tif(f), *.raw, *.yuv or *.tga\n",
" Known file formats are *.pnm, *.pgm, *.ppm, *.pgx, *png, *.bmp, *.tif, *.raw or *.tga\n",
infile);
return 1;
}
@ -828,7 +773,7 @@ static int parse_cmdline_encoder(int argc, char **argv,
}
free(substr1);
if (wrong) {
fprintf(stderr, "\nError: invalid raw or yuv image parameters\n");
fprintf(stderr, "\nError: invalid raw image parameters\n");
fprintf(stderr, "Please use the Format option -F:\n");
fprintf(stderr,
"-F <width>,<height>,<ncomp>,<bitdepth>,{s,u}@<dx1>x<dy1>:...:<dxn>x<dyn>\n");
@ -836,8 +781,7 @@ static int parse_cmdline_encoder(int argc, char **argv,
"If subsampling is omitted, 1x1 is assumed for all components\n");
fprintf(stderr,
"Example: -i image.raw -o image.j2k -F 512,512,3,8,u@1x1:2x2:2x2\n");
fprintf(stderr,
" for raw or yuv 512x512 size with 4:2:0 subsampling\n");
fprintf(stderr, " for raw 512x512 image with 4:2:0 subsampling\n");
fprintf(stderr, "Aborting.\n");
return 1;
}
@ -846,7 +790,7 @@ static int parse_cmdline_encoder(int argc, char **argv,
/* ----------------------------------------------------- */
case 'q': { /* layer allocation by distortion ratio (PSNR) */
case 'q': { /* add fixed_quality */
char *s = opj_optarg;
while (sscanf(s, "%f", &parameters->tcp_distoratio[parameters->tcp_numlayers])
== 1) {
@ -866,7 +810,7 @@ static int parse_cmdline_encoder(int argc, char **argv,
/* dda */
/* ----------------------------------------------------- */
case 'f': { /* layer allocation by fixed layer */
case 'f': { /* mod fixed_quality (before : -q) */
int *row = NULL, *col = NULL;
OPJ_UINT32 numlayers = 0, numresolution = 0, matrix_width = 0;
@ -880,7 +824,7 @@ static int parse_cmdline_encoder(int argc, char **argv,
parameters->tcp_numlayers = (int)numlayers;
numresolution = (OPJ_UINT32)parameters->numresolution;
matrix_width = numresolution * 3;
parameters->cp_matrice = (int *) malloc(sizeof(int) * numlayers * matrix_width);
parameters->cp_matrice = (int *) malloc(numlayers * matrix_width * sizeof(int));
if (parameters->cp_matrice == NULL) {
return 1;
}
@ -927,24 +871,6 @@ static int parse_cmdline_encoder(int argc, char **argv,
}
break;
/* ----------------------------------------------------- */
case 'X': { /* target bitdepth */
char *s = opj_optarg;
sscanf(s, "%u", pTarget_bitdepth);
if (*pTarget_bitdepth == 0) {
fprintf(stderr, "Target bitdepth must be at least 1 bit.\n");
return 1;
}
}
break;
/* ----------------------------------------------------- */
case 'G': { /* guard bits */
char *s = opj_optarg;
sscanf(s, "%d", pOutGuardBits);
}
break;
/* ----------------------------------------------------- */
case 'n': { /* resolution */
@ -1012,10 +938,9 @@ static int parse_cmdline_encoder(int argc, char **argv,
/* ----------------------------------------------------- */
case 'p': { /* progression order */
char progression[5];
char progression[4];
strncpy(progression, opj_optarg, 4);
progression[4] = 0;
parameters->prog_order = give_progression(progression);
if (parameters->prog_order == -1) {
fprintf(stderr, "Unrecognized progression order "
@ -1204,98 +1129,6 @@ static int parse_cmdline_encoder(int argc, char **argv,
/* ------------------------------------------------------ */
case 'Z': { /* IMF profile*/
int mainlevel = 0;
int sublevel = 0;
int profile = 0;
int framerate = 0;
const char* msg =
"Wrong value for -IMF. Should be "
"<PROFILE>[,mainlevel=X][,sublevel=Y][,framerate=FPS] where <PROFILE> is one "
"of 2K/4K/8K/2K_R/4K_R/8K_R.\n";
char* comma;
comma = strstr(opj_optarg, ",mainlevel=");
if (comma && sscanf(comma + 1, "mainlevel=%d", &mainlevel) != 1) {
fprintf(stderr, "%s", msg);
return 1;
}
comma = strstr(opj_optarg, ",sublevel=");
if (comma && sscanf(comma + 1, "sublevel=%d", &sublevel) != 1) {
fprintf(stderr, "%s", msg);
return 1;
}
comma = strstr(opj_optarg, ",framerate=");
if (comma && sscanf(comma + 1, "framerate=%d", &framerate) != 1) {
fprintf(stderr, "%s", msg);
return 1;
}
comma = strchr(opj_optarg, ',');
if (comma != NULL) {
*comma = 0;
}
if (strcmp(opj_optarg, "2K") == 0) {
profile = OPJ_PROFILE_IMF_2K;
} else if (strcmp(opj_optarg, "4K") == 0) {
profile = OPJ_PROFILE_IMF_4K;
} else if (strcmp(opj_optarg, "8K") == 0) {
profile = OPJ_PROFILE_IMF_8K;
} else if (strcmp(opj_optarg, "2K_R") == 0) {
profile = OPJ_PROFILE_IMF_2K_R;
} else if (strcmp(opj_optarg, "4K_R") == 0) {
profile = OPJ_PROFILE_IMF_4K_R;
} else if (strcmp(opj_optarg, "8K_R") == 0) {
profile = OPJ_PROFILE_IMF_8K_R;
} else {
fprintf(stderr, "%s", msg);
return 1;
}
if (!(mainlevel >= 0 && mainlevel <= 15)) {
/* Voluntarily rough validation. More fine grained done in library */
fprintf(stderr, "Invalid mainlevel value.\n");
return 1;
}
if (!(sublevel >= 0 && sublevel <= 15)) {
/* Voluntarily rough validation. More fine grained done in library */
fprintf(stderr, "Invalid sublevel value.\n");
return 1;
}
parameters->rsiz = (OPJ_UINT16)(profile | (sublevel << 4) | mainlevel);
fprintf(stdout, "IMF profile activated\n"
"Other options specified could be overridden\n");
if (pOutFramerate) {
*pOutFramerate = framerate;
}
if (framerate > 0 && sublevel > 0 && sublevel <= 9) {
const int limitMBitsSec[] = {
0,
OPJ_IMF_SUBLEVEL_1_MBITSSEC,
OPJ_IMF_SUBLEVEL_2_MBITSSEC,
OPJ_IMF_SUBLEVEL_3_MBITSSEC,
OPJ_IMF_SUBLEVEL_4_MBITSSEC,
OPJ_IMF_SUBLEVEL_5_MBITSSEC,
OPJ_IMF_SUBLEVEL_6_MBITSSEC,
OPJ_IMF_SUBLEVEL_7_MBITSSEC,
OPJ_IMF_SUBLEVEL_8_MBITSSEC,
OPJ_IMF_SUBLEVEL_9_MBITSSEC
};
parameters->max_cs_size = limitMBitsSec[sublevel] * (1000 * 1000 / 8) /
framerate;
fprintf(stdout, "Setting max codestream size to %d bytes.\n",
parameters->max_cs_size);
}
}
break;
/* ------------------------------------------------------ */
case 'Y': { /* Shall we do an MCT ? 0:no_mct;1:rgb->ycc;2:custom mct (-m option required)*/
int mct_mode = 0;
sscanf(opj_optarg, "%d", &mct_mode);
@ -1736,32 +1569,6 @@ static int parse_cmdline_encoder(int argc, char **argv,
break;
/* ------------------------------------------------------ */
case 'A': { /* PLT markers */
*pOutPLT = OPJ_TRUE;
}
break;
/* ----------------------------------------------------- */
case 'B': { /* Number of threads */
if (strcmp(opj_optarg, "ALL_CPUS") == 0) {
*pOutNumThreads = opj_get_num_cpus();
if (*pOutNumThreads == 1) {
*pOutNumThreads = 0;
}
} else {
sscanf(opj_optarg, "%d", pOutNumThreads);
}
}
break;
/* ------------------------------------------------------ */
case 'D': { /* TLM markers */
*pOutTLM = OPJ_TRUE;
}
break;
/* ------------------------------------------------------ */
default:
fprintf(stderr, "[WARNING] An invalid option has been ignored\n");
@ -1794,10 +1601,9 @@ static int parse_cmdline_encoder(int argc, char **argv,
}
}
if ((parameters->decod_format == RAW_DFMT ||
parameters->decod_format == RAWL_DFMT)
&& (raw_cp->rawWidth == 0)) {
fprintf(stderr, "[ERROR] invalid raw or yuv image parameters\n");
if ((parameters->decod_format == RAW_DFMT && raw_cp->rawWidth == 0)
|| (parameters->decod_format == RAWL_DFMT && raw_cp->rawWidth == 0)) {
fprintf(stderr, "[ERROR] invalid raw image parameters\n");
fprintf(stderr, "Please use the Format option -F:\n");
fprintf(stderr,
"-F rawWidth,rawHeight,rawComp,rawBitDepth,s/u (Signed/Unsigned)\n");
@ -1812,7 +1618,7 @@ static int parse_cmdline_encoder(int argc, char **argv,
parameters->cp_fixed_quality))) {
fprintf(stderr, "[ERROR] options -r -q and -f cannot be used together !!\n");
return 1;
}
} /* mod fixed_quality */
/* if no rate entered, lossless by default */
@ -1933,22 +1739,11 @@ int main(int argc, char **argv)
img_fol_t img_fol;
dircnt_t *dirptr = NULL;
int ret = 0;
OPJ_BOOL bSuccess;
OPJ_BOOL bUseTiles = OPJ_FALSE; /* OPJ_TRUE */
OPJ_UINT32 l_nb_tiles = 4;
int framerate = 0;
OPJ_FLOAT64 t = opj_clock();
OPJ_BOOL PLT = OPJ_FALSE;
OPJ_BOOL TLM = OPJ_FALSE;
int num_threads = 0;
int guard_bits = -1;
/** desired bitdepth from input file */
unsigned int target_bitdepth = 0;
/* set encoding parameters to default values */
opj_set_default_encoder_parameters(&parameters);
@ -1968,38 +1763,32 @@ int main(int argc, char **argv)
parameters.tcp_mct = (char)
255; /* This will be set later according to the input image or the provided option */
if (parse_cmdline_encoder(argc, argv, &parameters, &img_fol, &raw_cp,
indexfilename, sizeof(indexfilename), &framerate, &PLT, &TLM,
&guard_bits, &num_threads, &target_bitdepth) == 1) {
ret = 1;
goto fin;
indexfilename, sizeof(indexfilename)) == 1) {
goto fails;
}
/* Read directory if necessary */
if (img_fol.set_imgdir == 1) {
num_images = get_num_images(img_fol.imgdirpath);
if (num_images == 0) {
fprintf(stdout, "Folder is empty\n");
ret = 0;
goto fin;
}
dirptr = (dircnt_t*)malloc(sizeof(dircnt_t));
if (dirptr) {
dirptr->filename_buf = (char*)calloc(num_images, OPJ_PATH_LEN * sizeof(
dirptr->filename_buf = (char*)malloc(num_images * OPJ_PATH_LEN * sizeof(
char)); /* Stores at max 10 image file names*/
dirptr->filename = (char**) calloc(num_images, sizeof(char*));
dirptr->filename = (char**) malloc(num_images * sizeof(char*));
if (!dirptr->filename_buf) {
ret = 0;
goto fin;
return 0;
}
for (i = 0; i < num_images; i++) {
dirptr->filename[i] = dirptr->filename_buf + (size_t)i * OPJ_PATH_LEN;
dirptr->filename[i] = dirptr->filename_buf + i * OPJ_PATH_LEN;
}
}
if (load_images(dirptr, img_fol.imgdirpath) == 1) {
ret = 0;
goto fin;
return 0;
}
if (num_images == 0) {
fprintf(stdout, "Folder is empty\n");
return 0;
}
} else {
num_images = 1;
}
@ -2009,7 +1798,7 @@ int main(int argc, char **argv)
fprintf(stderr, "\n");
if (img_fol.set_imgdir == 1) {
if (get_next_file(imageno, dirptr, &img_fol, &parameters)) {
if (get_next_file((int)imageno, dirptr, &img_fol, &parameters)) {
fprintf(stderr, "skipping file...\n");
continue;
}
@ -2017,12 +1806,18 @@ int main(int argc, char **argv)
switch (parameters.decod_format) {
case PGX_DFMT:
break;
case PXM_DFMT:
break;
case BMP_DFMT:
break;
case TIF_DFMT:
break;
case RAW_DFMT:
case RAWL_DFMT:
break;
case TGA_DFMT:
break;
case PNG_DFMT:
break;
default:
@ -2038,8 +1833,7 @@ int main(int argc, char **argv)
image = pgxtoimage(parameters.infile, &parameters);
if (!image) {
fprintf(stderr, "Unable to load pgx file\n");
ret = 1;
goto fin;
return 1;
}
break;
@ -2047,8 +1841,7 @@ int main(int argc, char **argv)
image = pnmtoimage(parameters.infile, &parameters);
if (!image) {
fprintf(stderr, "Unable to load pnm file\n");
ret = 1;
goto fin;
return 1;
}
break;
@ -2056,18 +1849,16 @@ int main(int argc, char **argv)
image = bmptoimage(parameters.infile, &parameters);
if (!image) {
fprintf(stderr, "Unable to load bmp file\n");
ret = 1;
goto fin;
return 1;
}
break;
#ifdef OPJ_HAVE_LIBTIFF
case TIF_DFMT:
image = tiftoimage(parameters.infile, &parameters, target_bitdepth);
image = tiftoimage(parameters.infile, &parameters);
if (!image) {
fprintf(stderr, "Unable to load tif(f) file\n");
ret = 1;
goto fin;
fprintf(stderr, "Unable to load tiff file\n");
return 1;
}
break;
#endif /* OPJ_HAVE_LIBTIFF */
@ -2075,9 +1866,8 @@ int main(int argc, char **argv)
case RAW_DFMT:
image = rawtoimage(parameters.infile, &parameters, &raw_cp);
if (!image) {
fprintf(stderr, "Unable to load raw or yuv file\n");
ret = 1;
goto fin;
fprintf(stderr, "Unable to load raw file\n");
return 1;
}
break;
@ -2085,8 +1875,7 @@ int main(int argc, char **argv)
image = rawltoimage(parameters.infile, &parameters, &raw_cp);
if (!image) {
fprintf(stderr, "Unable to load raw file\n");
ret = 1;
goto fin;
return 1;
}
break;
@ -2094,8 +1883,7 @@ int main(int argc, char **argv)
image = tgatoimage(parameters.infile, &parameters);
if (!image) {
fprintf(stderr, "Unable to load tga file\n");
ret = 1;
goto fin;
return 1;
}
break;
@ -2104,20 +1892,18 @@ int main(int argc, char **argv)
image = pngtoimage(parameters.infile, &parameters);
if (!image) {
fprintf(stderr, "Unable to load png file\n");
ret = 1;
goto fin;
return 1;
}
break;
#endif /* OPJ_HAVE_LIBPNG */
}
/* Can happen if input file is TIF(F) or PNG
/* Can happen if input file is TIFF or PNG
* and OPJ_HAVE_LIBTIF or OPJ_HAVE_LIBPNG is undefined
*/
if (!image) {
fprintf(stderr, "Unable to load file: got no image\n");
ret = 1;
goto fin;
return 1;
}
/* Decide if MCT should be used */
@ -2128,49 +1914,12 @@ int main(int argc, char **argv)
if ((parameters.tcp_mct == 1) && (image->numcomps < 3)) {
fprintf(stderr, "RGB->YCC conversion cannot be used:\n");
fprintf(stderr, "Input image has less than 3 components\n");
ret = 1;
goto fin;
return 1;
}
if ((parameters.tcp_mct == 2) && (!parameters.mct_data)) {
fprintf(stderr, "Custom MCT has been set but no array-based MCT\n");
fprintf(stderr, "has been provided. Aborting.\n");
ret = 1;
goto fin;
}
}
if (OPJ_IS_IMF(parameters.rsiz) && framerate > 0) {
const int mainlevel = OPJ_GET_IMF_MAINLEVEL(parameters.rsiz);
if (mainlevel > 0 && mainlevel <= OPJ_IMF_MAINLEVEL_MAX) {
const int limitMSamplesSec[] = {
0,
OPJ_IMF_MAINLEVEL_1_MSAMPLESEC,
OPJ_IMF_MAINLEVEL_2_MSAMPLESEC,
OPJ_IMF_MAINLEVEL_3_MSAMPLESEC,
OPJ_IMF_MAINLEVEL_4_MSAMPLESEC,
OPJ_IMF_MAINLEVEL_5_MSAMPLESEC,
OPJ_IMF_MAINLEVEL_6_MSAMPLESEC,
OPJ_IMF_MAINLEVEL_7_MSAMPLESEC,
OPJ_IMF_MAINLEVEL_8_MSAMPLESEC,
OPJ_IMF_MAINLEVEL_9_MSAMPLESEC,
OPJ_IMF_MAINLEVEL_10_MSAMPLESEC,
OPJ_IMF_MAINLEVEL_11_MSAMPLESEC
};
OPJ_UINT32 avgcomponents = image->numcomps;
double msamplespersec;
if (image->numcomps == 3 &&
image->comps[1].dx == 2 &&
image->comps[1].dy == 2) {
avgcomponents = 2;
}
msamplespersec = (double)image->x1 * image->y1 * avgcomponents * framerate /
1e6;
if (msamplespersec > limitMSamplesSec[mainlevel]) {
fprintf(stderr,
"Warning: MSamples/sec is %f, whereas limit is %d.\n",
msamplespersec,
limitMSamplesSec[mainlevel]);
}
return 1;
}
}
@ -2210,47 +1959,13 @@ int main(int argc, char **argv)
fprintf(stderr, "failed to encode image: opj_setup_encoder\n");
opj_destroy_codec(l_codec);
opj_image_destroy(image);
ret = 1;
goto fin;
}
{
const char* options[4] = { NULL, NULL, NULL, NULL };
int iOpt = 0;
char szGuardBits[32];
if (PLT) {
options[iOpt++] = "PLT=YES";
}
if (TLM) {
options[iOpt++] = "TLM=YES";
}
if (guard_bits >= 0) {
sprintf(szGuardBits, "GUARD_BITS=%d", guard_bits);
options[iOpt++] = szGuardBits;
}
if (iOpt > 0 && !opj_encoder_set_extra_options(l_codec, options)) {
fprintf(stderr, "failed to encode image: opj_encoder_set_extra_options\n");
opj_destroy_codec(l_codec);
opj_image_destroy(image);
ret = 1;
goto fin;
}
}
if (num_threads >= 1 &&
!opj_codec_set_threads(l_codec, num_threads)) {
fprintf(stderr, "failed to set number of threads\n");
opj_destroy_codec(l_codec);
opj_image_destroy(image);
ret = 1;
goto fin;
return 1;
}
/* open a byte stream for writing and allocate memory for all tiles */
l_stream = opj_stream_create_default_file_stream(parameters.outfile, OPJ_FALSE);
if (! l_stream) {
ret = 1;
goto fin;
return 1;
}
/* encode the image */
@ -2263,18 +1978,16 @@ int main(int argc, char **argv)
OPJ_UINT32 l_data_size = 512 * 512 * 3;
l_data = (OPJ_BYTE*) calloc(1, l_data_size);
if (l_data == NULL) {
ret = 1;
goto fin;
goto fails;
}
for (i = 0; i < l_nb_tiles; ++i) {
if (! opj_write_tile(l_codec, i, l_data, l_data_size, l_stream)) {
fprintf(stderr, "ERROR -> test_tile_encoder: failed to write the tile %u!\n",
fprintf(stderr, "ERROR -> test_tile_encoder: failed to write the tile %d!\n",
i);
opj_stream_destroy(l_stream);
opj_destroy_codec(l_codec);
opj_image_destroy(image);
ret = 1;
goto fin;
return 1;
}
}
free(l_data);
@ -2295,8 +2008,7 @@ int main(int argc, char **argv)
opj_image_destroy(image);
fprintf(stderr, "failed to encode image\n");
remove(parameters.outfile);
ret = 1;
goto fin;
return 1;
}
num_compressed_files++;
@ -2312,15 +2024,26 @@ int main(int argc, char **argv)
}
/* free user parameters structure */
if (parameters.cp_comment) {
free(parameters.cp_comment);
}
if (parameters.cp_matrice) {
free(parameters.cp_matrice);
}
if (raw_cp.rawComps) {
free(raw_cp.rawComps);
}
t = opj_clock() - t;
if (num_compressed_files) {
fprintf(stdout, "encode time: %d ms \n",
(int)((t * 1000.0) / (OPJ_FLOAT64)num_compressed_files));
}
ret = 0;
return 0;
fin:
fails:
if (parameters.cp_comment) {
free(parameters.cp_comment);
}
@ -2342,5 +2065,5 @@ fin:
}
free(dirptr);
}
return ret;
return 1;
}

View File

@ -44,7 +44,6 @@
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <limits.h>
#ifdef _WIN32
#include "windirent.h"
@ -135,7 +134,7 @@ typedef struct opj_decompress_params {
/** Verbose mode */
OPJ_BOOL m_verbose;
/** tile number of the decoded tile */
/** tile number ot the decoded tile*/
OPJ_UINT32 tile_index;
/** Nb of tile to decode */
OPJ_UINT32 nb_tile_to_decode;
@ -153,20 +152,14 @@ typedef struct opj_decompress_params {
int num_threads;
/* Quiet */
int quiet;
/* Allow partial decode */
int allow_partial;
/** number of components to decode */
OPJ_UINT32 numcomps;
/** indices of components to decode */
OPJ_UINT32* comps_indices;
} opj_decompress_parameters;
/* -------------------------------------------------------------------------- */
/* Declarations */
unsigned int get_num_images(char *imgdirpath);
int get_num_images(char *imgdirpath);
int load_images(dircnt_t *dirptr, char *imgdirpath);
int get_file_format(const char *filename);
char get_next_file(unsigned int imageno, dircnt_t *dirptr, img_fol_t *img_fol,
char get_next_file(int imageno, dircnt_t *dirptr, img_fol_t *img_fol,
opj_decompress_parameters *parameters);
static int infile_format(const char *fname);
@ -190,7 +183,7 @@ static void decode_help_display(void)
"\n"
" -ImgDir <directory> \n"
" Image file Directory path \n"
" -OutFor <PBM|PGM|PPM|PNM|PAM|PGX|PNG|BMP|TIF|TIFF|RAW|YUV|RAWL|TGA>\n"
" -OutFor <PBM|PGM|PPM|PNM|PAM|PGX|PNG|BMP|TIF|RAW|RAWL|TGA>\n"
" REQUIRED only if -ImgDir is used\n"
" Output format for decompressed images.\n");
fprintf(stdout, " -i <compressed file>\n"
@ -229,15 +222,11 @@ static void decode_help_display(void)
" OPTIONAL\n"
" Force the precision (bit depth) of components.\n");
fprintf(stdout,
" There shall be at least 1 value. There is no limit on the number of values (comma separated, last values ignored if too much values).\n"
" There shall be at least 1 value. Theres no limit on the number of values (comma separated, last values ignored if too much values).\n"
" If there are less values than components, the last value is used for remaining components.\n"
" If 'C' is specified (default), values are clipped.\n"
" If 'S' is specified, values are scaled.\n"
" A 0 value can be specified (meaning original bit depth).\n");
fprintf(stdout, " -c first_comp_index[,second_comp_index][,...]\n"
" OPTIONAL\n"
" To limit the number of components to decoded.\n"
" Component indices are numbered starting at 0.\n");
fprintf(stdout, " -force-rgb\n"
" Force output image colorspace to RGB\n"
" -upsample\n"
@ -245,11 +234,9 @@ static void decode_help_display(void)
" -split-pnm\n"
" Split output components to different files when writing to PNM\n");
if (opj_has_thread_support()) {
fprintf(stdout, " -threads <num_threads|ALL_CPUS>\n"
" Number of threads to use for decoding or ALL_CPUS for all available cores.\n");
fprintf(stdout, " -threads <num_threads>\n"
" Number of threads to use for decoding.\n");
}
fprintf(stdout, " -allow-partial\n"
" Disable strict mode to allow decoding partial codestreams.\n");
fprintf(stdout, " -quiet\n"
" Disable output from the library and other output.\n");
/* UniPG>> */
@ -375,11 +362,11 @@ static OPJ_BOOL parse_precision(const char* option,
/* -------------------------------------------------------------------------- */
unsigned int get_num_images(char *imgdirpath)
int get_num_images(char *imgdirpath)
{
DIR *dir;
struct dirent* content;
unsigned int num_images = 0;
int num_images = 0;
/*Reading the input images from given input directory*/
@ -393,13 +380,7 @@ unsigned int get_num_images(char *imgdirpath)
if (strcmp(".", content->d_name) == 0 || strcmp("..", content->d_name) == 0) {
continue;
}
if (num_images == UINT_MAX) {
fprintf(stderr, "Too many files in folder %s\n", imgdirpath);
num_images = 0;
break;
}
num_images++;
}
closedir(dir);
return num_images;
@ -438,24 +419,8 @@ int load_images(dircnt_t *dirptr, char *imgdirpath)
int get_file_format(const char *filename)
{
unsigned int i;
static const char * const extension[] = {
"pgx", "pnm", "pgm", "ppm", "bmp",
"tif", "tiff",
"raw", "yuv", "rawl",
"tga", "png",
"j2k", "jp2", "jpt", "j2c", "jpc",
"jph", /* HTJ2K with JP2 boxes */
"jhc" /* HTJ2K codestream */
};
static const int format[] = {
PGX_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, BMP_DFMT,
TIF_DFMT, TIF_DFMT,
RAW_DFMT, RAW_DFMT, RAWL_DFMT,
TGA_DFMT, PNG_DFMT,
J2K_CFMT, JP2_CFMT, JPT_CFMT, J2K_CFMT, J2K_CFMT,
JP2_CFMT, /* HTJ2K with JP2 boxes */
J2K_CFMT /* HTJ2K codestream */
};
static const char *extension[] = {"pgx", "pnm", "pgm", "ppm", "bmp", "tif", "raw", "rawl", "tga", "png", "j2k", "jp2", "jpt", "j2c", "jpc" };
static const int format[] = { PGX_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, BMP_DFMT, TIF_DFMT, RAW_DFMT, RAWL_DFMT, TGA_DFMT, PNG_DFMT, J2K_CFMT, JP2_CFMT, JPT_CFMT, J2K_CFMT, J2K_CFMT };
const char * ext = strrchr(filename, '.');
if (ext == NULL) {
return -1;
@ -479,7 +444,7 @@ const char* path_separator = "/";
#endif
/* -------------------------------------------------------------------------- */
char get_next_file(unsigned int imageno, dircnt_t *dirptr, img_fol_t *img_fol,
char get_next_file(int imageno, dircnt_t *dirptr, img_fol_t *img_fol,
opj_decompress_parameters *parameters)
{
char image_filename[OPJ_PATH_LEN], infilename[OPJ_PATH_LEN],
@ -487,14 +452,9 @@ char get_next_file(unsigned int imageno, dircnt_t *dirptr, img_fol_t *img_fol,
char *temp_p, temp1[OPJ_PATH_LEN] = "";
strcpy(image_filename, dirptr->filename[imageno]);
fprintf(stderr, "File Number %u \"%s\"\n", imageno, image_filename);
if (strlen(img_fol->imgdirpath) + strlen(path_separator) + strlen(
image_filename) + 1 > sizeof(infilename)) {
return 1;
}
strcpy(infilename, img_fol->imgdirpath);
strcat(infilename, path_separator);
strcat(infilename, image_filename);
fprintf(stderr, "File Number %d \"%s\"\n", imageno, image_filename);
sprintf(infilename, "%s%s%s", img_fol->imgdirpath, path_separator,
image_filename);
parameters->decod_format = infile_format(infilename);
if (parameters->decod_format == -1) {
return 1;
@ -511,15 +471,8 @@ char get_next_file(unsigned int imageno, dircnt_t *dirptr, img_fol_t *img_fol,
sprintf(temp1, ".%s", temp_p);
}
if (img_fol->set_out_format == 1) {
if (strlen(img_fol->imgdirpath) + 1 + strlen(temp_ofname) + 1 + strlen(
img_fol->out_format) + 1 > sizeof(outfilename)) {
return 1;
}
strcpy(outfilename, img_fol->imgdirpath);
strcat(outfilename, "/");
strcat(outfilename, temp_ofname);
strcat(outfilename, ".");
strcat(outfilename, img_fol->out_format);
sprintf(outfilename, "%s/%s.%s", img_fol->imgdirpath, temp_ofname,
img_fol->out_format);
if (opj_strcpy_s(parameters->outfile, sizeof(parameters->outfile),
outfilename) != 0) {
return 1;
@ -565,10 +518,10 @@ static int infile_format(const char *fname)
if (memcmp(buf, JP2_RFC3745_MAGIC, 12) == 0 || memcmp(buf, JP2_MAGIC, 4) == 0) {
magic_format = JP2_CFMT;
magic_s = ".jp2 or .jph";
magic_s = ".jp2";
} else if (memcmp(buf, J2K_CODESTREAM_MAGIC, 4) == 0) {
magic_format = J2K_CFMT;
magic_s = ".j2k or .jpc or .j2c or .jhc";
magic_s = ".j2k or .jpc or .j2c";
} else {
return -1;
}
@ -605,10 +558,9 @@ int parse_cmdline_decoder(int argc, char **argv,
{"split-pnm", NO_ARG, NULL, 1},
{"threads", REQ_ARG, NULL, 'T'},
{"quiet", NO_ARG, NULL, 1},
{"allow-partial", NO_ARG, NULL, 1},
};
const char optlist[] = "i:o:r:l:x:d:t:p:c:"
const char optlist[] = "i:o:r:l:x:d:t:p:"
/* UniPG>> */
#ifdef USE_JPWL
@ -621,7 +573,6 @@ int parse_cmdline_decoder(int argc, char **argv,
long_option[3].flag = &(parameters->upsample);
long_option[4].flag = &(parameters->split_pnm);
long_option[6].flag = &(parameters->quiet);
long_option[7].flag = &(parameters->allow_partial);
totlen = sizeof(long_option);
opj_reset_options_reading();
img_fol->set_out_format = 0;
@ -669,17 +620,24 @@ int parse_cmdline_decoder(int argc, char **argv,
parameters->cod_format = get_file_format(outfile);
switch (parameters->cod_format) {
case PGX_DFMT:
break;
case PXM_DFMT:
break;
case BMP_DFMT:
break;
case TIF_DFMT:
break;
case RAW_DFMT:
break;
case RAWL_DFMT:
break;
case TGA_DFMT:
break;
case PNG_DFMT:
break;
default:
fprintf(stderr,
"Unknown output format image %s [only *.png, *.pnm, *.pgm, *.ppm, *.pgx, *.bmp, *.tif(f), *.raw, *.yuv or *.tga]!!\n",
"Unknown output format image %s [only *.png, *.pnm, *.pgm, *.ppm, *.pgx, *.bmp, *.tif, *.raw or *.tga]!!\n",
outfile);
return 1;
}
@ -726,7 +684,7 @@ int parse_cmdline_decoder(int argc, char **argv,
break;
default:
fprintf(stderr,
"Unknown output format image %s [only *.png, *.pnm, *.pgm, *.ppm, *.pgx, *.bmp, *.tif(f), *.raw, *.yuv or *.tga]!!\n",
"Unknown output format image %s [only *.png, *.pnm, *.pgm, *.ppm, *.pgx, *.bmp, *.tif, *.raw or *.tga]!!\n",
outformat);
return 1;
break;
@ -812,25 +770,6 @@ int parse_cmdline_decoder(int argc, char **argv,
return 1;
}
}
break;
/* ----------------------------------------------------- */
case 'c': { /* Components */
const char* iter = opj_optarg;
while (1) {
parameters->numcomps ++;
parameters->comps_indices = (OPJ_UINT32*) realloc(
parameters->comps_indices,
parameters->numcomps * sizeof(OPJ_UINT32));
parameters->comps_indices[parameters->numcomps - 1] =
(OPJ_UINT32) atoi(iter);
iter = strchr(iter, ',');
if (iter == NULL) {
break;
}
iter ++;
}
}
break;
/* ----------------------------------------------------- */
@ -937,7 +876,7 @@ int parse_cmdline_decoder(int argc, char **argv,
fprintf(stderr,
"[ERROR] When -ImgDir is used, -OutFor <FORMAT> must be used.\n");
fprintf(stderr, "Only one format allowed.\n"
"Valid format are PGM, PPM, PNM, PGX, BMP, TIF, TIFF, RAW, YUV, and TGA.\n");
"Valid format are PGM, PPM, PNM, PGX, BMP, TIF, RAW and TGA.\n");
return 1;
}
if (!((parameters->outfile[0] == 0))) {
@ -1076,9 +1015,6 @@ static void destroy_parameters(opj_decompress_parameters* parameters)
free(parameters->precision);
parameters->precision = NULL;
}
free(parameters->comps_indices);
parameters->comps_indices = NULL;
}
}
@ -1099,6 +1035,8 @@ static opj_image_t* convert_gray_to_rgb(opj_image_t* original)
return NULL;
}
l_new_components[0].bpp = l_new_components[1].bpp = l_new_components[2].bpp =
original->comps[0].bpp;
l_new_components[0].dx = l_new_components[1].dx = l_new_components[2].dx =
original->comps[0].dx;
l_new_components[0].dy = l_new_components[1].dy = l_new_components[2].dy =
@ -1117,6 +1055,7 @@ static opj_image_t* convert_gray_to_rgb(opj_image_t* original)
original->comps[0].y0;
for (compno = 1U; compno < original->numcomps; ++compno) {
l_new_components[compno + 2U].bpp = original->comps[compno].bpp;
l_new_components[compno + 2U].dx = original->comps[compno].dx;
l_new_components[compno + 2U].dy = original->comps[compno].dy;
l_new_components[compno + 2U].h = original->comps[compno].h;
@ -1150,11 +1089,11 @@ static opj_image_t* convert_gray_to_rgb(opj_image_t* original)
l_new_image->comps[2].resno_decoded = original->comps[0].resno_decoded;
memcpy(l_new_image->comps[0].data, original->comps[0].data,
sizeof(OPJ_INT32) * original->comps[0].w * original->comps[0].h);
original->comps[0].w * original->comps[0].h * sizeof(OPJ_INT32));
memcpy(l_new_image->comps[1].data, original->comps[0].data,
sizeof(OPJ_INT32) * original->comps[0].w * original->comps[0].h);
original->comps[0].w * original->comps[0].h * sizeof(OPJ_INT32));
memcpy(l_new_image->comps[2].data, original->comps[0].data,
sizeof(OPJ_INT32) * original->comps[0].w * original->comps[0].h);
original->comps[0].w * original->comps[0].h * sizeof(OPJ_INT32));
for (compno = 1U; compno < original->numcomps; ++compno) {
l_new_image->comps[compno + 2U].factor = original->comps[compno].factor;
@ -1162,7 +1101,7 @@ static opj_image_t* convert_gray_to_rgb(opj_image_t* original)
l_new_image->comps[compno + 2U].resno_decoded =
original->comps[compno].resno_decoded;
memcpy(l_new_image->comps[compno + 2U].data, original->comps[compno].data,
sizeof(OPJ_INT32) * original->comps[compno].w * original->comps[compno].h);
original->comps[compno].w * original->comps[compno].h * sizeof(OPJ_INT32));
}
opj_image_destroy(original);
return l_new_image;
@ -1206,6 +1145,7 @@ static opj_image_t* upsample_image_components(opj_image_t* original)
opj_image_cmptparm_t* l_new_cmp = &(l_new_components[compno]);
opj_image_comp_t* l_org_cmp = &(original->comps[compno]);
l_new_cmp->bpp = l_org_cmp->bpp;
l_new_cmp->prec = l_org_cmp->prec;
l_new_cmp->sgnd = l_org_cmp->sgnd;
l_new_cmp->x0 = original->x0;
@ -1331,7 +1271,7 @@ static opj_image_t* upsample_image_components(opj_image_t* original)
}
} else {
memcpy(l_new_cmp->data, l_org_cmp->data,
sizeof(OPJ_INT32) * l_org_cmp->w * l_org_cmp->h);
l_org_cmp->w * l_org_cmp->h * sizeof(OPJ_INT32));
}
}
opj_image_destroy(original);
@ -1346,8 +1286,12 @@ static opj_image_t* upsample_image_components(opj_image_t* original)
int main(int argc, char **argv)
{
opj_decompress_parameters parameters; /* decompression parameters */
opj_image_t* image = NULL;
opj_stream_t *l_stream = NULL; /* Stream */
opj_codec_t* l_codec = NULL; /* Handle to a decompressor */
opj_codestream_index_t* cstr_index = NULL;
unsigned int num_images, imageno;
OPJ_INT32 num_images, imageno;
img_fol_t img_fol;
dircnt_t *dirptr = NULL;
int failed = 0;
@ -1378,51 +1322,46 @@ int main(int argc, char **argv)
/* Initialize reading of directory */
if (img_fol.set_imgdir == 1) {
unsigned int it_image;
int it_image;
num_images = get_num_images(img_fol.imgdirpath);
if (num_images == 0) {
fprintf(stderr, "Folder is empty\n");
failed = 1;
goto fin;
}
dirptr = (dircnt_t*)calloc(1, sizeof(dircnt_t));
dirptr = (dircnt_t*)malloc(sizeof(dircnt_t));
if (!dirptr) {
destroy_parameters(&parameters);
return EXIT_FAILURE;
}
/* Stores at max 10 image file names */
dirptr->filename_buf = calloc((size_t) num_images, sizeof(char) * OPJ_PATH_LEN);
dirptr->filename_buf = (char*)malloc((size_t)num_images * OPJ_PATH_LEN * sizeof(
char)); /* Stores at max 10 image file names*/
if (!dirptr->filename_buf) {
failed = 1;
goto fin;
}
dirptr->filename = (char**) calloc((size_t) num_images, sizeof(char*));
dirptr->filename = (char**) malloc((size_t)num_images * sizeof(char*));
if (!dirptr->filename) {
failed = 1;
goto fin;
}
for (it_image = 0; it_image < num_images; it_image++) {
dirptr->filename[it_image] = dirptr->filename_buf + (size_t)it_image *
OPJ_PATH_LEN;
dirptr->filename[it_image] = dirptr->filename_buf + it_image * OPJ_PATH_LEN;
}
if (load_images(dirptr, img_fol.imgdirpath) == 1) {
failed = 1;
goto fin;
}
if (num_images == 0) {
fprintf(stderr, "Folder is empty\n");
failed = 1;
goto fin;
}
} else {
num_images = 1;
}
/*Decoding image one by one*/
for (imageno = 0; imageno < num_images ; imageno++) {
opj_image_t* image = NULL;
opj_stream_t *l_stream = NULL; /* Stream */
opj_codec_t* l_codec = NULL; /* Handle to a decompressor */
opj_codestream_index_t* cstr_index = NULL;
if (!parameters.quiet) {
fprintf(stderr, "\n");
@ -1497,16 +1436,6 @@ int main(int argc, char **argv)
goto fin;
}
/* Disable strict mode if we want to decode partial codestreams. */
if (parameters.allow_partial &&
!opj_decoder_set_strict_mode(l_codec, OPJ_FALSE)) {
fprintf(stderr, "ERROR -> opj_decompress: failed to disable strict mode\n");
opj_stream_destroy(l_stream);
opj_destroy_codec(l_codec);
failed = 1;
goto fin;
}
if (parameters.num_threads >= 1 &&
!opj_codec_set_threads(l_codec, parameters.num_threads)) {
fprintf(stderr, "ERROR -> opj_decompress: failed to set number of threads\n");
@ -1526,21 +1455,6 @@ int main(int argc, char **argv)
goto fin;
}
if (parameters.numcomps) {
if (! opj_set_decoded_components(l_codec,
parameters.numcomps,
parameters.comps_indices,
OPJ_FALSE)) {
fprintf(stderr,
"ERROR -> opj_decompress: failed to set the component indices!\n");
opj_destroy_codec(l_codec);
opj_stream_destroy(l_stream);
opj_image_destroy(image);
failed = 1;
goto fin;
}
}
if (getenv("USE_OPJ_SET_DECODED_RESOLUTION_FACTOR") != NULL) {
/* For debugging/testing purposes, and also an illustration on how to */
/* use the alternative API opj_set_decoded_resolution_factor() instead */
@ -1611,6 +1525,17 @@ int main(int argc, char **argv)
}
}
/* FIXME? Shouldn't that situation be considered as an error of */
/* opj_decode() / opj_get_decoded_tile() ? */
if (image->comps[0].data == NULL) {
fprintf(stderr, "ERROR -> opj_decompress: no image data!\n");
opj_destroy_codec(l_codec);
opj_stream_destroy(l_stream);
opj_image_destroy(image);
failed = 1;
goto fin;
}
tCumulative += opj_clock() - t;
numDecompressedImages++;
@ -1745,7 +1670,7 @@ int main(int argc, char **argv)
}
break;
#ifdef OPJ_HAVE_LIBTIFF
case TIF_DFMT: /* TIF(F) */
case TIF_DFMT: /* TIFF */
if (imagetotif(image, parameters.outfile)) {
fprintf(stderr, "[ERROR] Outfile %s not generated\n", parameters.outfile);
failed = 1;
@ -1756,8 +1681,7 @@ int main(int argc, char **argv)
#endif /* OPJ_HAVE_LIBTIFF */
case RAW_DFMT: /* RAW */
if (imagetoraw(image, parameters.outfile)) {
fprintf(stderr,
"[ERROR] Error generating raw or yuv file. Outfile %s not generated\n",
fprintf(stderr, "[ERROR] Error generating raw file. Outfile %s not generated\n",
parameters.outfile);
failed = 1;
} else if (!(parameters.quiet)) {
@ -1796,7 +1720,7 @@ int main(int argc, char **argv)
}
break;
#endif /* OPJ_HAVE_LIBPNG */
/* Can happen if output file is TIF(F) or PNG
/* Can happen if output file is TIFF or PNG
* and OPJ_HAVE_LIBTIF or OPJ_HAVE_LIBPNG is undefined
*/
default:

View File

@ -36,7 +36,6 @@
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <limits.h>
#ifdef _WIN32
#include "windirent.h"
@ -83,11 +82,10 @@ typedef struct img_folder {
/* -------------------------------------------------------------------------- */
/* Declarations */
static unsigned int get_num_images(char *imgdirpath);
static int get_num_images(char *imgdirpath);
static int load_images(dircnt_t *dirptr, char *imgdirpath);
static int get_file_format(const char *filename);
static char get_next_file(unsigned int imageno, dircnt_t *dirptr,
img_fol_t *img_fol,
static char get_next_file(int imageno, dircnt_t *dirptr, img_fol_t *img_fol,
opj_dparameters_t *parameters);
static int infile_format(const char *fname);
@ -124,11 +122,11 @@ static void decode_help_display(void)
}
/* -------------------------------------------------------------------------- */
static unsigned int get_num_images(char *imgdirpath)
static int get_num_images(char *imgdirpath)
{
DIR *dir;
struct dirent* content;
unsigned int num_images = 0;
int num_images = 0;
/*Reading the input images from given input directory*/
@ -142,11 +140,6 @@ static unsigned int get_num_images(char *imgdirpath)
if (strcmp(".", content->d_name) == 0 || strcmp("..", content->d_name) == 0) {
continue;
}
if (num_images == UINT_MAX) {
fprintf(stderr, "Too many files in folder %s\n", imgdirpath);
num_images = 0;
break;
}
num_images++;
}
closedir(dir);
@ -186,24 +179,8 @@ static int load_images(dircnt_t *dirptr, char *imgdirpath)
static int get_file_format(const char *filename)
{
unsigned int i;
static const char * const extension[] = {
"pgx", "pnm", "pgm", "ppm", "bmp",
"tif", "tiff",
"raw", "yuv", "rawl",
"tga", "png",
"j2k", "jp2", "jpt", "j2c", "jpc",
"jph", /* HTJ2K with JP2 boxes */
"jhc" /* HTJ2K codestream */
};
static const int format[] = {
PGX_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, BMP_DFMT,
TIF_DFMT, TIF_DFMT,
RAW_DFMT, RAW_DFMT, RAWL_DFMT,
TGA_DFMT, PNG_DFMT,
J2K_CFMT, JP2_CFMT, JPT_CFMT, J2K_CFMT, J2K_CFMT,
JP2_CFMT, /* HTJ2K with JP2 boxes */
J2K_CFMT /* HTJ2K codestream */
};
static const char *extension[] = {"pgx", "pnm", "pgm", "ppm", "bmp", "tif", "raw", "tga", "png", "j2k", "jp2", "jpt", "j2c", "jpc" };
static const int format[] = { PGX_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, BMP_DFMT, TIF_DFMT, RAW_DFMT, TGA_DFMT, PNG_DFMT, J2K_CFMT, JP2_CFMT, JPT_CFMT, J2K_CFMT, J2K_CFMT };
const char *ext = strrchr(filename, '.');
if (ext == NULL) {
return -1;
@ -221,8 +198,7 @@ static int get_file_format(const char *filename)
}
/* -------------------------------------------------------------------------- */
static char get_next_file(unsigned int imageno, dircnt_t *dirptr,
img_fol_t *img_fol,
static char get_next_file(int imageno, dircnt_t *dirptr, img_fol_t *img_fol,
opj_dparameters_t *parameters)
{
char image_filename[OPJ_PATH_LEN], infilename[OPJ_PATH_LEN],
@ -230,18 +206,12 @@ static char get_next_file(unsigned int imageno, dircnt_t *dirptr,
char *temp_p, temp1[OPJ_PATH_LEN] = "";
strcpy(image_filename, dirptr->filename[imageno]);
fprintf(stderr, "File Number %u \"%s\"\n", imageno, image_filename);
fprintf(stderr, "File Number %d \"%s\"\n", imageno, image_filename);
parameters->decod_format = get_file_format(image_filename);
if (parameters->decod_format == -1) {
return 1;
}
if (strlen(img_fol->imgdirpath) + 1 + strlen(
image_filename) + 1 > sizeof(infilename)) {
return 1;
}
strcpy(infilename, img_fol->imgdirpath);
strcat(infilename, "/");
strcat(infilename, image_filename);
sprintf(infilename, "%s/%s", img_fol->imgdirpath, image_filename);
if (opj_strcpy_s(parameters->infile, sizeof(parameters->infile),
infilename) != 0) {
return 1;
@ -254,15 +224,8 @@ static char get_next_file(unsigned int imageno, dircnt_t *dirptr,
sprintf(temp1, ".%s", temp_p);
}
if (img_fol->set_out_format == 1) {
if (strlen(img_fol->imgdirpath) + 1 + strlen(temp_ofname) + 1 + strlen(
img_fol->out_format) + 1 > sizeof(outfilename)) {
return 1;
}
strcpy(outfilename, img_fol->imgdirpath);
strcat(outfilename, "/");
strcat(outfilename, temp_ofname);
strcat(outfilename, ".");
strcat(outfilename, img_fol->out_format);
sprintf(outfilename, "%s/%s.%s", img_fol->imgdirpath, temp_ofname,
img_fol->out_format);
if (opj_strcpy_s(parameters->outfile, sizeof(parameters->outfile),
outfilename) != 0) {
return 1;
@ -308,10 +271,10 @@ static int infile_format(const char *fname)
if (memcmp(buf, JP2_RFC3745_MAGIC, 12) == 0 || memcmp(buf, JP2_MAGIC, 4) == 0) {
magic_format = JP2_CFMT;
magic_s = ".jp2 or .jph";
magic_s = ".jp2";
} else if (memcmp(buf, J2K_CODESTREAM_MAGIC, 4) == 0) {
magic_format = J2K_CFMT;
magic_s = ".j2k or .jpc or .j2c or .jhc";
magic_s = ".j2k or .jpc or .j2c";
} else {
return -1;
}
@ -432,7 +395,7 @@ static int parse_cmdline_decoder(int argc, char **argv,
fprintf(stderr,
"[ERROR] When -ImgDir is used, -OutFor <FORMAT> must be used.\n");
fprintf(stderr, "Only one format allowed.\n"
"Valid format are PGM, PPM, PNM, PGX, BMP, TIF, TIFF, RAW, YUV and TGA.\n");
"Valid format are PGM, PPM, PNM, PGX, BMP, TIF, RAW and TGA.\n");
return 1;
}
if (!(parameters->outfile[0] == 0)) {
@ -494,7 +457,7 @@ int main(int argc, char *argv[])
opj_codestream_info_v2_t* cstr_info = NULL;
opj_codestream_index_t* cstr_index = NULL;
unsigned int num_images, imageno;
OPJ_INT32 num_images, imageno;
img_fol_t img_fol;
dircnt_t *dirptr = NULL;
@ -516,38 +479,37 @@ int main(int argc, char *argv[])
/* Initialize reading of directory */
if (img_fol.set_imgdir == 1) {
unsigned int it_image;
int it_image;
num_images = get_num_images(img_fol.imgdirpath);
if (num_images == 0) {
fprintf(stdout, "Folder is empty\n");
goto fails;
}
dirptr = (dircnt_t*)malloc(sizeof(dircnt_t));
if (!dirptr) {
return EXIT_FAILURE;
}
/* Stores at max 10 image file names*/
dirptr->filename_buf = (char*) calloc((size_t) num_images,
OPJ_PATH_LEN * sizeof(char));
dirptr->filename_buf = (char*)malloc((size_t)num_images * OPJ_PATH_LEN * sizeof(
char)); /* Stores at max 10 image file names*/
if (!dirptr->filename_buf) {
free(dirptr);
return EXIT_FAILURE;
}
dirptr->filename = (char**) calloc((size_t) num_images, sizeof(char*));
dirptr->filename = (char**) malloc((size_t)num_images * sizeof(char*));
if (!dirptr->filename) {
goto fails;
}
for (it_image = 0; it_image < num_images; it_image++) {
dirptr->filename[it_image] = dirptr->filename_buf + (size_t)it_image *
OPJ_PATH_LEN;
dirptr->filename[it_image] = dirptr->filename_buf + it_image * OPJ_PATH_LEN;
}
if (load_images(dirptr, img_fol.imgdirpath) == 1) {
goto fails;
}
if (num_images == 0) {
fprintf(stdout, "Folder is empty\n");
goto fails;
}
} else {
num_images = 1;
}

View File

@ -69,7 +69,7 @@
* handle inclusion of sys/dir.h in a part that is compiled only in Apollo
* operating system. To fix the problem you need to insert DIR.H into
* SYSINCL.DAT located in MSVC\BIN directory and restart visual C++.
* Consult manuals for more information about the problem.
* Consult manuals for more informaton about the problem.
*
* Since many UNIX systems have dirent.h we assume to have one also.
* However, if your UNIX system does not have dirent.h you can download one
@ -102,7 +102,7 @@
/*
* See what kind of dirent interface we have unless autoconf has already
* determined that.
* determinated that.
*/
#if !defined(HAVE_DIRENT_H) && !defined(HAVE_DIRECT_H) && !defined(HAVE_SYS_DIR_H) && !defined(HAVE_NDIR_H) && !defined(HAVE_SYS_NDIR_H) && !defined(HAVE_DIR_H)
# if defined(_MSC_VER) /* Microsoft C/C++ */
@ -172,7 +172,7 @@
#elif defined(MSDOS) || defined(WIN32)
/* figure out type of underlying directory interface to be used */
/* figure out type of underlaying directory interface to be used */
# if defined(WIN32)
# define DIRENT_WIN32_INTERFACE
# elif defined(MSDOS)
@ -254,7 +254,7 @@ typedef struct dirent {
/*** Operating system specific part ***/
# if defined(DIRENT_WIN32_INTERFACE) /*WIN32*/
WIN32_FIND_DATA data;
# elif defined(DIRENT_MSDOS_INTERFACE) /*MS-DOS*/
# elif defined(DIRENT_MSDOS_INTERFACE) /*MSDOS*/
# if defined(DIRENT_USE_FFBLK)
struct ffblk data;
# else
@ -592,7 +592,7 @@ rewinddir(DIR *dirp)
/* re-open previous stream */
if (_initdir(dirp) == 0) {
/* initialization failed but we cannot deal with error. User will notice
* error later when she tries to retrieve first directory entry. */
* error later when she tries to retrieve first directory enty. */
/*EMPTY*/;
}
}

View File

@ -0,0 +1,41 @@
# Build the demo app, small examples
# First thing define the common source:
set(common_SRCS
convert.c
${OPENJPEG_SOURCE_DIR}/src/bin/common/opj_getopt.c
)
# Headers file are located here:
include_directories(
${OPENJPEG_BINARY_DIR}/src/lib/openjp2 # opj_config.h
${OPENJPEG_SOURCE_DIR}/src/lib/openjp3d
${LCMS_INCLUDE_DIRNAME}
${OPENJPEG_SOURCE_DIR}/src/bin/common
${Z_INCLUDE_DIRNAME}
${PNG_INCLUDE_DIRNAME}
${TIFF_INCLUDE_DIRNAME}
)
if(WIN32)
if(BUILD_SHARED_LIBS)
add_definitions(-DOPJ_EXPORTS)
else()
add_definitions(-DOPJ_STATIC)
endif()
endif()
# Loop over all executables:
foreach(exe opj_jp3d_compress opj_jp3d_decompress)
add_executable(${exe} ${exe}.c ${common_SRCS})
target_link_libraries(${exe} openjp3d)
# On unix you need to link to the math library:
if(UNIX)
target_link_libraries(${exe} m)
endif(UNIX)
# Install exe
install(TARGETS ${exe}
EXPORT OpenJP3DTargets
DESTINATION ${OPENJPEG_INSTALL_BIN_DIR} COMPONENT Applications
)
endforeach()

1050
src/bin/jp3d/convert.c Normal file

File diff suppressed because it is too large Load Diff

52
src/bin/jp3d/convert.h Normal file
View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2001-2003, David Janssens
* Copyright (c) 2002-2003, Yannick Verschueren
* Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
* Copyright (c) 2006, Mónica Díez García, Image Processing Laboratory, University of Valladolid, Spain
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 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 OWNER 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.
*/
#ifndef __JP3D_CONVERT_H
#define __JP3D_CONVERT_H
/**
Load a single volume component encoded in PGX file format
@param filename Name of the PGX file to load
@param parameters *List ?*
@return Returns a greyscale volume if successful, returns NULL otherwise
*/
opj_volume_t* pgxtovolume(char *filename, opj_cparameters_t *parameters);
int volumetopgx(opj_volume_t *volume, char *outfile);
opj_volume_t* bintovolume(char *filename, char *fileimg,
opj_cparameters_t *parameters);
int volumetobin(opj_volume_t *volume, char *outfile);
opj_volume_t* imgtovolume(char *fileimg, opj_cparameters_t *parameters);
#endif /* __J2K_CONVERT_H */

119
src/bin/jp3d/getopt.c Normal file
View File

@ -0,0 +1,119 @@
/*
* Copyright (c) 1987, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
*/
/* last review : october 29th, 2002 */
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int opterr = 1, /* if error message should be printed */
optind = 1, /* index into parent argv vector */
optopt, /* character checked for validity */
optreset; /* reset getopt */
char *optarg; /* argument associated with option */
#define BADCH (int)'?'
#define BADARG (int)':'
#define EMSG ""
/*
* getopt --
* Parse argc/argv argument vector.
*/
int getopt(int nargc, char *const *nargv, const char *ostr)
{
# define __progname nargv[0] /* program name */
static char *place = EMSG; /* option letter processing */
char *oli; /* option letter list index */
if (optreset || !*place) { /* update scanning pointer */
optreset = 0;
if (optind >= nargc || *(place = nargv[optind]) != '-') {
place = EMSG;
return (-1);
}
if (place[1] && *++place == '-') { /* found "--" */
++optind;
place = EMSG;
return (-1);
}
} /* option letter okay? */
if ((optopt = (int) * place++) == (int) ':' || !(oli = strchr(ostr, optopt))) {
/* if the user didn't specify '-' as an option, assume it means -1. */
if (optopt == (int) '-') {
return (-1);
}
if (!*place) {
++optind;
}
if (opterr && *ostr != ':') {
(void) fprintf(stdout, "[ERROR] %s: illegal option -- %c\n", __progname,
optopt);
}
return (BADCH);
}
if (*++oli != ':') { /* don't need argument */
optarg = NULL;
if (!*place) {
++optind;
}
} else { /* need an argument */
if (*place) { /* no white space */
optarg = place;
} else if (nargc <= ++optind) { /* no arg */
place = EMSG;
if (*ostr == ':') {
return (BADARG);
}
if (opterr) {
(void) fprintf(stdout, "[ERROR] %s: option requires an argument -- %c\n",
__progname, optopt);
}
return (BADCH);
} else { /* white space */
optarg = nargv[optind];
}
place = EMSG;
++optind;
}
return (optopt); /* dump back option letter */
}

14
src/bin/jp3d/getopt.h Normal file
View File

@ -0,0 +1,14 @@
/* last review : october 29th, 2002 */
#ifndef _GETOPT_H_
#define _GETOPT_H_
extern int opterr;
extern int optind;
extern int optopt;
extern int optreset;
extern char *optarg;
extern int getopt(int nargc, char *const *nargv, const char *ostr);
#endif /* _GETOPT_H_ */

View File

@ -0,0 +1,989 @@
/*
* Copyright (c) 2001-2003, David Janssens
* Copyright (c) 2002-2003, Yannick Verschueren
* Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
* Copyright (c) 2006, Mónica Díez García, Image Processing Laboratory, University of Valladolid, Spain
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 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 OWNER 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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "opj_config.h"
#include "openjp3d.h"
#include "opj_getopt.h"
#include "convert.h"
#ifdef _WIN32
#include <windows.h>
#else
#define stricmp strcasecmp
#define strnicmp strncasecmp
#endif /* _WIN32 */
/* ----------------------------------------------------------------------- */
void encode_help_display()
{
fprintf(stdout, "List of parameters for the JPEG2000 Part 10 encoder:\n");
fprintf(stdout, "------------\n");
fprintf(stdout, "\n");
fprintf(stdout, "Required Parameters (except with -h):\n");
fprintf(stdout, "\n");
fprintf(stdout,
"-i : source file (-i source.bin or source*.pgx) \n");
fprintf(stdout, "\n");
fprintf(stdout,
"-m : source characteristics file (-m imgfile.img) \n");
fprintf(stdout, "\n");
fprintf(stdout, "-o : destination file (-o dest.jp3d) \n");
fprintf(stdout, "\n");
fprintf(stdout, "Optional Parameters:\n");
fprintf(stdout, "\n");
fprintf(stdout, "-h : display the help information \n ");
fprintf(stdout, "\n");
fprintf(stdout, "-n : number of resolutions (-n 3,3,3) \n");
fprintf(stdout, "\n");
fprintf(stdout,
"-I : use the irreversible transforms: ICT + DWT 9-7 (-I) \n");
fprintf(stdout, "\n");
fprintf(stdout, "-C : coding algorithm (-C 2EB) [2EB, 3EB] \n");
fprintf(stdout, "\n");
fprintf(stdout,
"-r : different compression ratios for successive layers (-r 20,10,5)\n ");
fprintf(stdout,
" - The rate specified for each quality level is the desired compression factor.\n");
fprintf(stdout, " - Rate 1 means lossless compression\n");
fprintf(stdout,
" (options -r and -q cannot be used together)\n ");
fprintf(stdout, "\n");
fprintf(stdout,
"-q : different psnr for successive layers (-q 30,40,50) \n ");
fprintf(stdout,
" (options -r and -q cannot be used together)\n ");
fprintf(stdout, "\n");
fprintf(stdout, "-b : size of code block (-b 32,32,32) \n");
fprintf(stdout, "\n");
fprintf(stdout, "-c : size of precinct (-c 128,128,128) \n");
fprintf(stdout, "\n");
fprintf(stdout, "-t : size of tile (-t 512,512,512) \n");
fprintf(stdout, "\n");
fprintf(stdout,
"-p : progression order (-p LRCP) [LRCP, RLCP, RPCL, PCRL, CPRL] \n");
fprintf(stdout, "\n");
fprintf(stdout, "-s : subsampling factor (-s 2,2,2) [-s X,Y,Z] \n");
fprintf(stdout, " - Remark: subsampling bigger than 2 can produce error\n");
fprintf(stdout, "\n");
fprintf(stdout, "-SOP : write SOP marker before each packet \n");
fprintf(stdout, "\n");
fprintf(stdout, "-EPH : write EPH marker after each header packet \n");
fprintf(stdout, "\n");
fprintf(stdout,
"-M : code-block style (-M 0) [1=BYPASS(LAZY) 2=RESET 4=RESTART(TERMALL)\n");
fprintf(stdout, " 8=VSC 16=PTERM 32=SEGSYM 64=3DCTXT] \n");
fprintf(stdout,
" Indicate multiple modes by adding their values. \n");
fprintf(stdout,
" ex: RESTART(4) + RESET(2) + SEGMARK(32) = -M 38\n");
fprintf(stdout, "\n");
fprintf(stdout, "-D : define DC offset (-D 12) \n");
fprintf(stdout, "\n");
fprintf(stdout,
"-x : create an index file *.Idx (-x index_name.Idx) \n");
fprintf(stdout, "\n");
fprintf(stdout,
"-ROI : c=%%d,U=%%d : quantization indices upshifted \n");
fprintf(stdout, " for component c=%%d [%%d = 0,1,2]\n");
fprintf(stdout,
" with a value of U=%%d [0 <= %%d <= 37] (i.e. -ROI:c=0,U=25) \n");
fprintf(stdout, "\n");
fprintf(stdout,
"-d : offset of the origin of the volume (-d 150,300,100) \n");
fprintf(stdout, "\n");
fprintf(stdout,
"-l : offset of the origin of the tiles (-l 100,75,25) \n");
fprintf(stdout, "\n");
fprintf(stdout, "\n");
fprintf(stdout, "DEFAULT CODING:\n");
fprintf(stdout, "------------\n");
fprintf(stdout, "\n");
fprintf(stdout, " * Lossless\n");
fprintf(stdout, " * 1 tile\n");
fprintf(stdout,
" * Size of precinct : 2^15 x 2^15 x 2^15 (means 1 precinct)\n");
fprintf(stdout, " * Size of code-block : 64 x 64 x 64\n");
fprintf(stdout, " * Number of resolutions in x, y and z axis: 3\n");
fprintf(stdout, " * No SOP marker in the codestream\n");
fprintf(stdout, " * No EPH marker in the codestream\n");
fprintf(stdout, " * No sub-sampling in x, y or z direction\n");
fprintf(stdout, " * No mode switch activated\n");
fprintf(stdout, " * Progression order: LRCP\n");
fprintf(stdout, " * No index file\n");
fprintf(stdout, " * No ROI upshifted\n");
fprintf(stdout, " * No offset of the origin of the volume\n");
fprintf(stdout, " * No offset of the origin of the tiles\n");
fprintf(stdout, " * Reversible DWT 5-3 on each 2D slice\n");
fprintf(stdout, " * Coding algorithm: 2D-EBCOT \n");
fprintf(stdout, "\n");
fprintf(stdout, "REMARKS:\n");
fprintf(stdout, "---------\n");
fprintf(stdout, "\n");
fprintf(stdout,
"- The markers written to the main_header are : SOC SIZ COD QCD COM.\n");
fprintf(stdout,
"- COD and QCD markers will never appear in the tile_header.\n");
fprintf(stdout, "\n");
fprintf(stdout,
"- You need enough disk space memory (twice the original) to encode \n");
fprintf(stdout,
"the volume,i.e. for a 1.5 GB volume you need a minimum of 3GB of disk memory)\n");
fprintf(stdout, "\n");
fprintf(stdout,
"- When loading *.pgx files, a relative path to directory is needed for input argument \n");
fprintf(stdout,
" followed by the common prefix of the slices and a '*' character representing sequential numeration.\n");
fprintf(stdout, "( -i relativepath/slices*.pgx )\n");
fprintf(stdout, "\n");
fprintf(stdout, " - The index file has the structure below:\n");
fprintf(stdout, "\n");
fprintf(stdout, "\t Image_height Image_width Image_depth\n");
fprintf(stdout, "\t Progression order: 0 (LRCP)\n");
fprintf(stdout, "\t Tiles_size_X Tiles_size_Y Tiles_size_Z\n");
fprintf(stdout, "\t Components_nb\n");
fprintf(stdout, "\t Layers_nb\n");
fprintf(stdout, "\t Decomposition_levels\n");
fprintf(stdout,
"\t [Precincts_size_X_res_Nr Precincts_size_Y_res_Nr Precincts_size_Z_res_Nr]\n\t ...\n");
fprintf(stdout,
"\t [Precincts_size_X_res_0 Precincts_size_Y_res_0 Precincts_size_Z_res_0]\n");
fprintf(stdout, "\t Main_header_end_position\n");
fprintf(stdout, "\t Codestream_size\n");
fprintf(stdout,
"\t Tile_0 [start_pos end_header end_pos TotalDisto NumPix MaxMSE]\n");
fprintf(stdout, "\t ...\n");
fprintf(stdout,
"\t Tile_Nt [ '' '' '' '' '' '' ]\n");
fprintf(stdout,
"\t Tpacket_0 [Tile layer res. comp. prec. start_pos end_pos disto]\n");
fprintf(stdout, "\t ...\n");
fprintf(stdout,
"\t Tpacket_Np ['' '' '' '' '' '' '' '' ]\n");
fprintf(stdout, "\t MaxDisto\n");
fprintf(stdout, "\t TotalDisto\n\n");
fprintf(stdout, "\n");
}
OPJ_PROG_ORDER give_progression(char progression[4])
{
if (strncmp(progression, "LRCP", 4) == 0) {
return LRCP;
}
if (strncmp(progression, "RLCP", 4) == 0) {
return RLCP;
}
if (strncmp(progression, "RPCL", 4) == 0) {
return RPCL;
}
if (strncmp(progression, "PCRL", 4) == 0) {
return PCRL;
}
if (strncmp(progression, "CPRL", 4) == 0) {
return CPRL;
}
return PROG_UNKNOWN;
}
OPJ_TRANSFORM give_transform(char transform[4])
{
if (strncmp(transform, "2DWT", 4) == 0) {
return TRF_2D_DWT;
}
if (strncmp(transform, "3DWT", 4) == 0) {
return TRF_3D_DWT;
}
return TRF_UNKNOWN;
}
OPJ_ENTROPY_CODING give_coding(char coding[3])
{
if (strncmp(coding, "2EB", 3) == 0) {
return ENCOD_2EB;
}
if (strncmp(coding, "3EB", 3) == 0) {
return ENCOD_3EB;
}
/*if(strncmp(coding, "2GR", 3) == 0) {
return ENCOD_2GR;
}
if(strncmp(coding, "3GR", 3) == 0) {
return ENCOD_3GR;
}*/
return ENCOD_UNKNOWN;
}
int get_file_format(char *filename)
{
int i;
static const char *extension[] = {"pgx", "bin", "img", "j3d", "jp3d", "j2k"};
static const int format[] = { PGX_DFMT, BIN_DFMT, IMG_DFMT, J3D_CFMT, J3D_CFMT, J2K_CFMT};
char * ext = strrchr(filename, '.');
if (ext) {
ext++;
for (i = 0; i < sizeof(format) / sizeof(*format); i++) {
if (strnicmp(ext, extension[i], 3) == 0) {
return format[i];
}
}
}
return -1;
}
/* ------------------------------------------------------------------------------------ */
int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters)
{
int i, value;
/* parse the command line */
while (1) {
int c = opj_getopt(argc, argv,
"i:m:o:r:q:f:t:n:c:b:x:p:s:d:hP:S:E:M:D:R:l:T:C:A:I");
if (c == -1) {
break;
}
switch (c) {
case 'i': { /* input file */
char *infile = opj_optarg;
parameters->decod_format = get_file_format(infile);
switch (parameters->decod_format) {
case PGX_DFMT:
case BIN_DFMT:
case IMG_DFMT:
break;
default:
fprintf(stdout,
"[ERROR] Unrecognized format for infile : %s [accept only *.pgx or *.bin] !!\n\n",
infile);
return 1;
break;
}
strncpy(parameters->infile, infile, MAX_PATH);
fprintf(stdout, "[INFO] Infile: %s \n", parameters->infile);
}
break;
/* ----------------------------------------------------- */
case 'm': { /* input IMG file */
char *imgfile = opj_optarg;
int imgformat = get_file_format(imgfile);
switch (imgformat) {
case IMG_DFMT:
break;
default:
fprintf(stdout,
"[ERROR] Unrecognized format for imgfile : %s [accept only *.img] !!\n\n",
imgfile);
return 1;
break;
}
strncpy(parameters->imgfile, imgfile, MAX_PATH);
fprintf(stdout, "[INFO] Imgfile: %s Format: %d\n", parameters->imgfile,
imgformat);
}
break;
/* ----------------------------------------------------- */
case 'o': { /* output file */
char *outfile = opj_optarg;
parameters->cod_format = get_file_format(outfile);
switch (parameters->cod_format) {
case J3D_CFMT:
case J2K_CFMT:
case LSE_CFMT:
break;
default:
fprintf(stdout,
"[ERROR] Unknown output format volume %s [only *.j2k, *.lse3d or *.jp3d]!! \n",
outfile);
return 1;
break;
}
strncpy(parameters->outfile, outfile, MAX_PATH);
fprintf(stdout, "[INFO] Outfile: %s \n", parameters->outfile);
}
break;
/* ----------------------------------------------------- */
case 'r': { /* define compression rates for each layer */
char *s = opj_optarg;
while (sscanf(s, "%f", &parameters->tcp_rates[parameters->tcp_numlayers]) ==
1) {
parameters->tcp_numlayers++;
while (*s && *s != ',') {
s++;
}
if (!*s) {
break;
}
s++;
}
parameters->cp_disto_alloc = 1;
}
break;
/* ----------------------------------------------------- */
case 'q': { /* define distorsion (PSNR) for each layer */
char *s = opj_optarg;
while (sscanf(s, "%f", &parameters->tcp_distoratio[parameters->tcp_numlayers])
== 1) {
parameters->tcp_numlayers++;
while (*s && *s != ',') {
s++;
}
if (!*s) {
break;
}
s++;
}
parameters->cp_fixed_quality = 1;
}
break;
/* ----------------------------------------------------- */
case 'f': {
fprintf(stdout, "/---------------------------------------------------\\\n");
fprintf(stdout, "| Fixed layer allocation option not implemented !! |\n");
fprintf(stdout, "\\---------------------------------------------------/\n");
/*int *row = NULL, *col = NULL;
int numlayers = 0, matrix_width = 0;
char *s = opj_optarg;
sscanf(s, "%d", &numlayers);
s++;
if (numlayers > 9)
s++;
parameters->tcp_numlayers = numlayers;
matrix_width = parameters->numresolution[0] + parameters->numresolution[1] + parameters->numresolution[2];
parameters->cp_matrice = (int *) malloc(numlayers * matrix_width * sizeof(int));
s = s + 2;
for (i = 0; i < numlayers; i++) {
row = &parameters->cp_matrice[i * matrix_width];
col = row;
parameters->tcp_rates[i] = 1;
sscanf(s, "%d,", &col[0]);
s += 2;
if (col[0] > 9)
s++;
col[1] = 0;
col[2] = 0;
for (j = 1; j < matrix_width; j++) {
col += 3; j+=2;
sscanf(s, "%d,%d,%d", &col[0], &col[1], &col[2]);
s += 6;
if (col[0] > 9)
s++;
if (col[1] > 9)
s++;
if (col[2] > 9)
s++;
}
if (i < numlayers - 1)
s++;
}
parameters->cp_fixed_alloc = 1; */
}
break;
/* ----------------------------------------------------- */
case 't': { /* tiles */
if (sscanf(opj_optarg, "%d,%d,%d", &parameters->cp_tdx, &parameters->cp_tdy,
&parameters->cp_tdz) != 3) {
fprintf(stdout,
"[ERROR] '-t' 'dimensions of tiles' argument error ! [-t tdx,tdy,tdz]\n");
return 1;
}
parameters->tile_size_on = true;
}
break;
/* ----------------------------------------------------- */
case 'n': { /* resolution */
int aux;
aux = sscanf(opj_optarg, "%d,%d,%d", &parameters->numresolution[0],
&parameters->numresolution[1], &parameters->numresolution[2]);
if (aux == 2) {
parameters->numresolution[2] = 1;
} else if (aux == 1) {
parameters->numresolution[1] = parameters->numresolution[0];
parameters->numresolution[2] = 1;
} else if (aux == 0) {
parameters->numresolution[0] = 1;
parameters->numresolution[1] = 1;
parameters->numresolution[2] = 1;
}
}
break;
/* ----------------------------------------------------- */
case 'c': { /* precinct dimension */
char sep;
int res_spec = 0;
int aux;
char *s = opj_optarg;
do {
sep = 0;
aux = sscanf(s, "[%d,%d,%d]%c", &parameters->prct_init[0][res_spec],
&parameters->prct_init[1][res_spec], &parameters->prct_init[2][res_spec], &sep);
if (sep == ',' && aux != 4) {
fprintf(stdout,
"[ERROR] '-c' 'dimensions of precincts' argument error ! [-c [prcx_res0,prcy_res0,prcz_res0],...,[prcx_resN,prcy_resN,prcz_resN]]\n");
return 1;
}
parameters->csty |= 0x01;
res_spec++;
s = strpbrk(s, "]") + 2;
} while (sep == ',');
parameters->res_spec = res_spec; /* number of precinct size specifications */
}
break;
/* ----------------------------------------------------- */
case 'b': { /* code-block dimension */
int cblockw_init = 0, cblockh_init = 0, cblockl_init = 0;
if (sscanf(opj_optarg, "%d,%d,%d", &cblockw_init, &cblockh_init,
&cblockl_init) != 3) {
fprintf(stdout,
"[ERROR] '-b' 'dimensions of codeblocks' argument error ! [-b cblkx,cblky,cblkz]\n");
return 1;
}
if (cblockw_init * cblockh_init * cblockl_init > (1 << 18) ||
cblockw_init > 1024 || cblockw_init < 4 || cblockh_init > 1024 ||
cblockh_init < 4 || cblockl_init > 1024 || cblockl_init < 4) {
fprintf(stdout,
"[ERROR] Size of code_block error (option -b) !!\n\nRestriction :\n * width*height*length<=4096\n * 4<=width,height,length<= 1024\n\n");
return 1;
}
parameters->cblock_init[0] = cblockw_init;
parameters->cblock_init[1] = cblockh_init;
parameters->cblock_init[2] = cblockl_init;
}
break;
/* ----------------------------------------------------- */
case 'x': { /* creation of index file */
char *index = opj_optarg;
strncpy(parameters->index, index, MAX_PATH);
parameters->index_on = 1;
}
break;
/* ----------------------------------------------------- */
case 'p': { /* progression order */
char progression[4];
strncpy(progression, opj_optarg, 4);
parameters->prog_order = give_progression(progression);
if (parameters->prog_order == -1) {
fprintf(stdout,
"[ERROR] Unrecognized progression order [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n");
return 1;
}
}
break;
/* ----------------------------------------------------- */
case 's': { /* subsampling factor */
if (sscanf(opj_optarg, "%d,%d,%d", &parameters->subsampling_dx,
&parameters->subsampling_dy, &parameters->subsampling_dz) != 3) {
fprintf(stdout, "[ERROR] '-s' sub-sampling argument error ! [-s dx,dy,dz]\n");
return 1;
}
}
break;
/* ----------------------------------------------------- */
case 'd': { /* coordonnate of the reference grid */
if (sscanf(opj_optarg, "%d,%d,%d", &parameters->volume_offset_x0,
&parameters->volume_offset_y0, &parameters->volume_offset_z0) != 3) {
fprintf(stdout,
"[ERROR] -d 'coordonnate of the reference grid' argument error !! [-d x0,y0,z0]\n");
return 1;
}
}
break;
/* ----------------------------------------------------- */
case 'h': { /* display an help description */
encode_help_display();
return 1;
}
break;
/* ----------------------------------------------------- */
case 'P': { /* POC */
int numpocs = 0; /* number of progression order change (POC) default 0 */
opj_poc_t *POC = NULL; /* POC : used in case of Progression order change */
char *s = opj_optarg;
POC = parameters->POC;
fprintf(stdout, "/----------------------------------\\\n");
fprintf(stdout, "| POC option not fully tested !! |\n");
fprintf(stdout, "\\----------------------------------/\n");
while (sscanf(s, "T%d=%d,%d,%d,%d,%d,%s", &POC[numpocs].tile,
&POC[numpocs].resno0, &POC[numpocs].compno0,
&POC[numpocs].layno1, &POC[numpocs].resno1,
&POC[numpocs].compno1, POC[numpocs].progorder) == 7) {
POC[numpocs].prg = give_progression(POC[numpocs].progorder);
/* POC[numpocs].tile; */
numpocs++;
while (*s && *s != '/') {
s++;
}
if (!*s) {
break;
}
s++;
}
parameters->numpocs = numpocs;
}
break;
/* ------------------------------------------------------ */
case 'S': { /* SOP marker */
parameters->csty |= 0x02;
}
break;
/* ------------------------------------------------------ */
case 'E': { /* EPH marker */
parameters->csty |= 0x04;
}
break;
/* ------------------------------------------------------ */
case 'M': { /* Codification mode switch */
fprintf(stdout, "[INFO] Mode switch option not fully tested !!\n");
value = 0;
if (sscanf(opj_optarg, "%d", &value) == 1) {
for (i = 0; i <= 6; i++) {
int cache = value & (1 << i);
if (cache) {
parameters->mode |= (1 << i);
}
}
}
}
break;
/* ------------------------------------------------------ */
case 'D': { /* DCO */
if (sscanf(opj_optarg, "%d", &parameters->dcoffset) != 1) {
fprintf(stdout, "[ERROR] DC offset error !! [-D %d]\n", parameters->dcoffset);
return 1;
}
}
break;
/* ------------------------------------------------------ */
case 'R': { /* ROI */
if (sscanf(opj_optarg, "OI:c=%d,U=%d", &parameters->roi_compno,
&parameters->roi_shift) != 2) {
fprintf(stdout, "[ERROR] ROI error !! [-ROI:c='compno',U='shift']\n");
return 1;
}
}
break;
/* ------------------------------------------------------ */
case 'l': { /* Tile offset */
if (sscanf(opj_optarg, "%d,%d,%d", &parameters->cp_tx0, &parameters->cp_ty0,
&parameters->cp_tz0) != 3) {
fprintf(stdout, "[ERROR] -l 'tile offset' argument error !! [-l X0,Y0,Z0]");
return 1;
}
}
break;
/* ------------------------------------------------------
case 'T': // Transformation of original data (2D-DWT/3D-DWT/3D-RLS/2D-DWT+1D-RLS)
{
char transform[4];
strncpy(transform, opj_optarg, 4);
parameters->transform_format = give_transform(transform);
if (parameters->transform_format == -1) {
fprintf(stdout, "[ERROR] -T 'Transform domain' argument error !! [-T 2DWT, 3DWT, 3RLS or 3LSE only]");
return 1;
}
}
break;
------------------------------------------------------ */
case 'C': { /* Coding of transformed data */
char coding[3];
strncpy(coding, opj_optarg, 3);
parameters->encoding_format = give_coding(coding);
if (parameters->encoding_format == -1) {
fprintf(stdout,
"[ERROR] -C 'Coding algorithm' argument error !! [-C 2EB, 3EB, 2GR, 3GR or GRI only]");
return 1;
}
}
break;
/* ------------------------------------------------------ */
case 'I': { /* reversible or not */
parameters->irreversible = 1;
}
break;
default:
fprintf(stdout, "[ERROR] This option is not valid \"-%c %s\"\n", c, opj_optarg);
return 1;
}
}
/* check for possible errors */
if ((parameters->infile[0] == 0) || (parameters->outfile[0] == 0)) {
fprintf(stdout, "usage: jp3d_vm_enc -i volume-file -o jp3d-file (+ options)\n");
return 1;
}
if ((parameters->decod_format == BIN_DFMT) && (parameters->imgfile[0] == 0)) {
fprintf(stdout,
"usage: jp3d_vm_enc -i bin-volume-file -m img-file -o jp3d-file (+ options)\n");
return 1;
}
if ((parameters->decod_format != BIN_DFMT) &&
(parameters->decod_format != PGX_DFMT) &&
(parameters->decod_format != IMG_DFMT)) {
fprintf(stdout,
"usage: jp3d_vm_enc -i input-volume-file [*.bin,*.pgx,*.img] -o jp3d-file [*.jp3d,*.j2k] (+ options)\n");
return 1;
}
if ((parameters->cod_format != J3D_CFMT) &&
(parameters->cod_format != J2K_CFMT)) {
fprintf(stdout,
"usage: jp3d_vm_enc -i input-volume-file [*.bin,*.pgx,*.img] -o jp3d-file [*.jp3d,*.j2k] (+ options)\n");
return 1;
}
if ((parameters->encoding_format == ENCOD_2GR ||
parameters->encoding_format == ENCOD_3GR) &&
parameters->transform_format != TRF_3D_LSE &&
parameters->transform_format != TRF_3D_RLS) {
fprintf(stdout,
"[ERROR] Entropy coding options -C [2GR,3GR] are only compatible with predictive-based transform algorithms: -T [3RLS,3LSE].\n");
return 1;
}
if (parameters->encoding_format == ENCOD_3EB) {
parameters->mode |= (1 << 6);
}
if ((parameters->mode >> 6) & 1) {
parameters->encoding_format = ENCOD_3EB;
}
if ((parameters->numresolution[2] == 0 || (parameters->numresolution[1] == 0) ||
(parameters->numresolution[0] == 0))) {
fprintf(stdout,
"[ERROR] -n 'resolution levels' argument error ! Resolutions must be greater than 1 in order to perform DWT.\n");
return 1;
}
if (parameters->numresolution[1] != parameters->numresolution[0]) {
fprintf(stdout,
"[ERROR] -n 'resolution levels' argument error ! Resolutions in X and Y axis must be the same in this implementation.\n");
return 1;
}
if (parameters->numresolution[2] > parameters->numresolution[0]) {
fprintf(stdout,
"[ERROR] -n 'resolution levels' argument error ! Resolutions in Z axis must be lower than in X-Y axis.\n");
return 1;
}
if (parameters->dcoffset >= 128 && parameters->dcoffset <= -128) {
fprintf(stdout,
"[ERROR] -D 'DC offset' argument error ! Value must be -128<=DCO<=128.\n");
return 1;
}
if (parameters->numresolution[2] != 1) {
parameters->transform_format = TRF_3D_DWT;
/*fprintf(stdout, "[Warning] Resolution level in axial dim > 1 : 3D-DWT will be performed... \n");*/
} else if (parameters->numresolution[2] == 1) {
parameters->transform_format = TRF_2D_DWT;
/*fprintf(stdout, "[Warning] Resolution level in axial dim == 1 : 2D-DWT will be performed... \n");*/
}
if ((parameters->cod_format == J2K_CFMT) &&
(parameters->transform_format != TRF_2D_DWT ||
parameters->encoding_format != ENCOD_2EB)) {
fprintf(stdout,
"[WARNING] Incompatible options -o *.j2k and defined transform or encoding algorithm. Latter will be ignored\n");
parameters->transform_format = TRF_2D_DWT;
parameters->encoding_format = ENCOD_2EB;
}
if ((parameters->cp_disto_alloc || parameters->cp_fixed_alloc ||
parameters->cp_fixed_quality) &&
(!(parameters->cp_disto_alloc ^ parameters->cp_fixed_quality))) {
fprintf(stdout, "[ERROR] Options -r and -q cannot be used together !!\n");
return 1;
} /* mod fixed_quality */
/* if no rate entered, lossless by default */
if (parameters->tcp_numlayers == 0) {
parameters->tcp_rates[0] = 0.0; /* MOD antonin : losslessbug */
parameters->tcp_numlayers++;
parameters->cp_disto_alloc = 1;
}
if ((parameters->cp_tx0 > parameters->volume_offset_x0) ||
(parameters->cp_ty0 > parameters->volume_offset_y0) ||
(parameters->cp_tz0 > parameters->volume_offset_z0)) {
fprintf(stdout,
"[ERROR] Tile offset dimension is unnappropriate --> TX0(%d)<=IMG_X0(%d) TYO(%d)<=IMG_Y0(%d) TZO(%d)<=IMG_Z0(%d)\n",
parameters->cp_tx0, parameters->volume_offset_x0, parameters->cp_ty0,
parameters->volume_offset_y0,
parameters->cp_tz0, parameters->volume_offset_z0);
return 1;
}
for (i = 0; i < parameters->numpocs; i++) {
if (parameters->POC[i].prg == -1) {
fprintf(stdout,
"[ERROR] Unrecognized progression order in option -P (POC n %d) [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n",
i + 1);
}
}
return 0;
}
/* -------------------------------------------------------------------------- */
/**
sample error callback expecting a FILE* client object
*/
void error_callback(const char *msg, void *client_data)
{
FILE *stream = (FILE*)client_data;
fprintf(stream, "[ERROR] %s", msg);
}
/**
sample warning callback expecting a FILE* client object
*/
void warning_callback(const char *msg, void *client_data)
{
FILE *stream = (FILE*)client_data;
fprintf(stream, "[WARNING] %s", msg);
}
/**
sample debug callback expecting a FILE* client object
*/
void info_callback(const char *msg, void *client_data)
{
FILE *stream = (FILE*)client_data;
fprintf(stream, "[INFO] %s", msg);
}
/* -------------------------------------------------------------------------- */
int main(int argc, char **argv)
{
bool bSuccess;
bool delete_comment = true;
opj_cparameters_t parameters; /* compression parameters */
opj_event_mgr_t event_mgr; /* event manager */
opj_volume_t *volume = NULL;
/*
configure the event callbacks (not required)
setting of each callback is optional
*/
memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
event_mgr.error_handler = error_callback;
event_mgr.warning_handler = warning_callback;
event_mgr.info_handler = info_callback;
/* set encoding parameters to default values */
opj_set_default_encoder_parameters(&parameters);
/* parse input and get user encoding parameters */
if (parse_cmdline_encoder(argc, argv, &parameters) == 1) {
return 0;
}
if (parameters.cp_comment == NULL) {
parameters.cp_comment = "Created by OpenJPEG version JP3D";
/* no need to delete parameters.cp_comment on exit */
delete_comment = false;
}
/* encode the destination volume */
/* ---------------------------- */
if (parameters.cod_format == J3D_CFMT || parameters.cod_format == J2K_CFMT) {
int codestream_length, pixels, bitsin;
opj_cio_t *cio = NULL;
FILE *f = NULL;
opj_cinfo_t* cinfo = NULL;
/* decode the source volume */
/* ----------------------- */
switch (parameters.decod_format) {
case PGX_DFMT:
fprintf(stdout, "[INFO] Loading pgx file(s)\n");
volume = pgxtovolume(parameters.infile, &parameters);
if (!volume) {
fprintf(stdout, "[ERROR] Unable to load pgx files\n");
return 1;
}
break;
case BIN_DFMT:
fprintf(stdout, "[INFO] Loading bin file\n");
volume = bintovolume(parameters.infile, parameters.imgfile, &parameters);
if (!volume) {
fprintf(stdout, "[ERROR] Unable to load bin file\n");
return 1;
}
break;
case IMG_DFMT:
fprintf(stdout, "[INFO] Loading img file\n");
volume = imgtovolume(parameters.infile, &parameters);
if (!volume) {
fprintf(stderr, "[ERROR] Unable to load img file\n");
return 1;
}
break;
}
/* get a JP3D or J2K compressor handle */
if (parameters.cod_format == J3D_CFMT) {
cinfo = opj_create_compress(CODEC_J3D);
} else if (parameters.cod_format == J2K_CFMT) {
cinfo = opj_create_compress(CODEC_J2K);
}
/* catch events using our callbacks and give a local context */
opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stdout);
/* setup the encoder parameters using the current volume and using user parameters */
opj_setup_encoder(cinfo, &parameters, volume);
/* open a byte stream for writing */
/* allocate memory for all tiles */
cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);
/* encode the volume */
/*fprintf(stdout, "[INFO] Encode the volume\n");*/
bSuccess = opj_encode(cinfo, cio, volume, parameters.index);
if (!bSuccess) {
opj_cio_close(cio);
fprintf(stdout, "[ERROR] Failed to encode volume\n");
return 1;
}
codestream_length = cio_tell(cio);
pixels = (volume->x1 - volume->x0) * (volume->y1 - volume->y0) *
(volume->z1 - volume->z0);
bitsin = pixels * volume->comps[0].prec;
fprintf(stdout,
"[RESULT] Volume: %d x %d x %d (x %d bpv)\n Codestream: %d B, Ratio: %5.3f bpv, (%5.3f : 1) \n",
(volume->x1 - volume->x0), (volume->y1 - volume->y0), (volume->z1 - volume->z0),
volume->comps[0].prec,
codestream_length, ((double)codestream_length * 8.0 / (double)pixels),
((double)bitsin / (8.0 * (double)codestream_length)));
/* write the buffer to disk */
f = fopen(parameters.outfile, "wb");
if (!f) {
fprintf(stdout, "[ERROR] Failed to open %s for writing\n", parameters.outfile);
return 1;
}
fwrite(cio->buffer, 1, codestream_length, f);
fclose(f);
/* close and free the byte stream */
opj_cio_close(cio);
/* free remaining compression structures */
opj_destroy_compress(cinfo);
} else {
fprintf(stdout, "[ERROR] Cod_format != JP3d !!! \n");
return 1;
}
/* free user parameters structure */
if (delete_comment) {
if (parameters.cp_comment) {
free(parameters.cp_comment);
}
}
if (parameters.cp_matrice) {
free(parameters.cp_matrice);
}
/* free volume data */
opj_volume_destroy(volume);
return 0;
}

View File

@ -0,0 +1,601 @@
/*
* Copyright (c) 2001-2003, David Janssens
* Copyright (c) 2002-2003, Yannick Verschueren
* Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
* Copyright (c) 2006, Mónica Díez García, Image Processing Laboratory, University of Valladolid, Spain
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 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 OWNER 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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include "opj_config.h"
#include "openjp3d.h"
#include "opj_getopt.h"
#include "convert.h"
#ifdef _WIN32
#include <windows.h>
#else
#define stricmp strcasecmp
#define strnicmp strncasecmp
#endif /* _WIN32 */
/* ----------------------------------------------------------------------- */
static double calc_PSNR(opj_volume_t *original, opj_volume_t *decoded)
{
int max, i, k, compno = 0, size;
double sum, total = 0;
int global = 1;
max = (original->comps[compno].prec <= 8) ? 255 : (1 <<
original->comps[compno].prec) - 1;
if (global) {
size = (original->x1 - original->x0) * (original->y1 - original->y0) *
(original->z1 - original->z0);
for (compno = 0; compno < original->numcomps; compno++) {
for (sum = 0, i = 0; i < size; ++i) {
if ((decoded->comps[compno].data[i] < 0) ||
(decoded->comps[compno].data[i] > max)) {
fprintf(stdout, "[WARNING] Data out of range during PSNR computing...\n");
} else {
sum += (original->comps[compno].data[i] - decoded->comps[compno].data[i]) *
(original->comps[compno].data[i] - decoded->comps[compno].data[i]);
}
}
}
sum /= size;
total = ((sum == 0.0) ? 0.0 : 10 * log10(max * max / sum));
} else {
size = (original->x1 - original->x0) * (original->y1 - original->y0);
for (k = 0; k < original->z1 - original->z0; k++) {
int offset = k * size;
for (sum = 0, compno = 0; compno < original->numcomps; compno++) {
for (i = 0; i < size; ++i) {
if ((decoded->comps[compno].data[i + offset] < 0) ||
(decoded->comps[compno].data[i + offset] > max)) {
fprintf(stdout, "[WARNING] Data out of range during PSNR computing...\n");
} else {
sum += (original->comps[compno].data[i + offset] - decoded->comps[compno].data[i
+ offset]) * (original->comps[compno].data[i + offset] -
decoded->comps[compno].data[i + offset]);
}
}
}
sum /= size;
total = total + ((sum == 0.0) ? 0.0 : 10 * log10(max * max / sum));
}
}
if (total == 0) { /* perfect reconstruction, PSNR should return infinity */
return -1.0;
}
return total;
/*return 20 * log10((max - 1) / sqrt(sum));*/
}
static double calc_SSIM(opj_volume_t *original, opj_volume_t *decoded)
{
int max, i, compno = 0, size, sizeM;
double sum;
double mux = 0.0, muy = 0.0, sigmax = 0.0, sigmay = 0.0,
sigmaxy = 0.0/*, structx = 0.0, structy = 0.0*/;
double lcomp, ccomp, scomp;
double C1, C2, C3;
max = (original->comps[compno].prec <= 8) ? 255 : (1 <<
original->comps[compno].prec) - 1;
size = (original->x1 - original->x0) * (original->y1 - original->y0) *
(original->z1 - original->z0);
/*MSSIM*/
/* sizeM = size / (original->z1 - original->z0);*/
sizeM = size;
for (sum = 0, i = 0; i < sizeM; ++i) {
/* First, the luminance of each signal is compared.*/
mux += original->comps[compno].data[i];
muy += decoded->comps[compno].data[i];
}
mux /= sizeM;
muy /= sizeM;
/*We use the standard deviation (the square root of variance) as an estimate of the signal contrast.*/
for (sum = 0, i = 0; i < sizeM; ++i) {
/* First, the luminance of each signal is compared.*/
sigmax += (original->comps[compno].data[i] - mux) *
(original->comps[compno].data[i] - mux);
sigmay += (decoded->comps[compno].data[i] - muy) *
(decoded->comps[compno].data[i] - muy);
sigmaxy += (original->comps[compno].data[i] - mux) *
(decoded->comps[compno].data[i] - muy);
}
sigmax /= sizeM - 1;
sigmay /= sizeM - 1;
sigmaxy /= sizeM - 1;
sigmax = sqrt(sigmax);
sigmay = sqrt(sigmay);
sigmaxy = sqrt(sigmaxy);
/*Third, the signal is normalized (divided) by its own standard deviation, */
/*so that the two signals being compared have unit standard deviation.*/
/*Luminance comparison*/
C1 = (0.01 * max) * (0.01 * max);
lcomp = ((2 * mux * muy) + C1) / ((mux * mux) + (muy * mux) + C1);
/*Constrast comparison*/
C2 = (0.03 * max) * (0.03 * max);
ccomp = ((2 * sigmax * sigmay) + C2) / ((sigmax * sigmax) +
(sigmay * sigmay) + C2);
/*Structure comparison*/
C3 = C2 / 2;
scomp = (sigmaxy + C3) / (sigmax * sigmay + C3);
/*Similarity measure*/
sum = lcomp * ccomp * scomp;
return sum;
}
void decode_help_display()
{
fprintf(stdout, "HELP\n----\n\n");
fprintf(stdout, "- the -h option displays this help information on screen\n\n");
fprintf(stdout, "List of parameters for the JPEG 2000 encoder:\n");
fprintf(stdout, "\n");
fprintf(stdout, " Required arguments \n");
fprintf(stdout, " ---------------------------- \n");
fprintf(stdout, " -i <compressed file> ( *.jp3d, *.j3d )\n");
fprintf(stdout,
" Currently accepts J3D-files. The file type is identified based on its suffix.\n");
fprintf(stdout, " -o <decompressed file> ( *.pgx, *.bin )\n");
fprintf(stdout,
" Currently accepts PGX-files and BIN-files. Binary data is written to the file (not ascii). \n");
fprintf(stdout,
" If a PGX filename is given, there will be as many output files as slices; \n");
fprintf(stdout,
" an indice starting from 0 will then be appended to the output filename,\n");
fprintf(stdout, " just before the \"pgx\" extension.\n");
fprintf(stdout, " -m <characteristics file> ( *.img ) \n");
fprintf(stdout,
" Required only for BIN-files. Ascii data of volume characteristics is written. \n");
fprintf(stdout, "\n");
fprintf(stdout, " Optional \n");
fprintf(stdout, " ---------------------------- \n");
fprintf(stdout, " -h \n ");
fprintf(stdout, " Display the help information\n");
fprintf(stdout, " -r <RFx,RFy,RFz>\n");
fprintf(stdout,
" Set the number of highest resolution levels to be discarded on each dimension. \n");
fprintf(stdout,
" The volume resolution is effectively divided by 2 to the power of the\n");
fprintf(stdout,
" number of discarded levels. The reduce factor is limited by the\n");
fprintf(stdout,
" smallest total number of decomposition levels among tiles.\n");
fprintf(stdout, " -l <number of quality layers to decode>\n");
fprintf(stdout,
" Set the maximum number of quality layers to decode. If there are\n");
fprintf(stdout,
" less quality layers than the specified number, all the quality layers\n");
fprintf(stdout, " are decoded. \n");
fprintf(stdout, " -O original-file \n");
fprintf(stdout,
" This option offers the possibility to compute some quality results \n");
fprintf(stdout,
" for the decompressed volume, like the PSNR value achieved or the global SSIM value. \n");
fprintf(stdout,
" Needs the original file in order to compare with the new one.\n");
fprintf(stdout,
" NOTE: Only valid when -r option is 0,0,0 (both original and decompressed volumes have same resolutions) \n");
fprintf(stdout,
" NOTE: If original file is .BIN file, the volume characteristics file shall be defined with the -m option. \n");
fprintf(stdout, " (i.e. -O original-BIN-file -m original-IMG-file) \n");
fprintf(stdout, " -BE \n");
fprintf(stdout,
" Define that the recovered volume data will be saved with big endian byte order.\n");
fprintf(stdout, " By default, little endian byte order is used.\n");
fprintf(stdout, "\n");
}
/* -------------------------------------------------------------------------- */
int get_file_format(char *filename)
{
int i;
static const char *extension[] = {"pgx", "bin", "j3d", "jp3d", "j2k", "img"};
static const int format[] = { PGX_DFMT, BIN_DFMT, J3D_CFMT, J3D_CFMT, J2K_CFMT, IMG_DFMT};
char * ext = strrchr(filename, '.');
if (ext) {
ext++;
for (i = 0; i < sizeof(format) / sizeof(format[0]); i++) {
if (strnicmp(ext, extension[i], 3) == 0) {
return format[i];
}
}
}
return -1;
}
/* -------------------------------------------------------------------------- */
int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters)
{
/* parse the command line */
while (1) {
int c = opj_getopt(argc, argv, "i:o:O:r:l:B:m:h");
if (c == -1) {
break;
}
switch (c) {
case 'i': { /* input file */
char *infile = opj_optarg;
parameters->decod_format = get_file_format(infile);
switch (parameters->decod_format) {
case J3D_CFMT:
case J2K_CFMT:
break;
default:
fprintf(stdout, "[ERROR] Unknown format for infile %s [only *.j3d]!! \n",
infile);
return 1;
break;
}
strncpy(parameters->infile, infile, MAX_PATH);
fprintf(stdout, "[INFO] Infile: %s \n", parameters->infile);
}
break;
case 'm': { /* img file */
char *imgfile = opj_optarg;
int imgformat = get_file_format(imgfile);
switch (imgformat) {
case IMG_DFMT:
break;
default:
fprintf(stdout,
"[ERROR] Unrecognized format for imgfile : %s [accept only *.img] !!\n\n",
imgfile);
return 1;
break;
}
strncpy(parameters->imgfile, imgfile, MAX_PATH);
fprintf(stdout, "[INFO] Imgfile: %s Format: %d\n", parameters->imgfile,
imgformat);
}
break;
/* ----------------------------------------------------- */
case 'o': { /* output file */
char *outfile = opj_optarg;
parameters->cod_format = get_file_format(outfile);
switch (parameters->cod_format) {
case PGX_DFMT:
case BIN_DFMT:
break;
default:
fprintf(stdout,
"[ERROR] Unrecognized format for outfile : %s [accept only *.pgx or *.bin] !!\n\n",
outfile);
return 1;
break;
}
strncpy(parameters->outfile, outfile, MAX_PATH);
fprintf(stdout, "[INFO] Outfile: %s \n", parameters->outfile);
}
break;
/* ----------------------------------------------------- */
case 'O': { /* Original image for PSNR computing */
char *original = opj_optarg;
parameters->orig_format = get_file_format(original);
switch (parameters->orig_format) {
case PGX_DFMT:
case BIN_DFMT:
break;
default:
fprintf(stdout,
"[ERROR] Unrecognized format for original file : %s [accept only *.pgx or *.bin] !!\n\n",
original);
return 1;
break;
}
strncpy(parameters->original, original, MAX_PATH);
fprintf(stdout, "[INFO] Original file: %s \n", parameters->original);
}
break;
/* ----------------------------------------------------- */
case 'r': { /* reduce option */
/*sscanf(opj_optarg, "%d, %d, %d", &parameters->cp_reduce[0], &parameters->cp_reduce[1], &parameters->cp_reduce[2]);*/
int aux;
aux = sscanf(opj_optarg, "%d,%d,%d", &parameters->cp_reduce[0],
&parameters->cp_reduce[1], &parameters->cp_reduce[2]);
if (aux == 2) {
parameters->cp_reduce[2] = 0;
} else if (aux == 1) {
parameters->cp_reduce[1] = parameters->cp_reduce[0];
parameters->cp_reduce[2] = 0;
} else if (aux == 0) {
parameters->cp_reduce[0] = 0;
parameters->cp_reduce[1] = 0;
parameters->cp_reduce[2] = 0;
}
}
break;
/* ----------------------------------------------------- */
case 'l': { /* layering option */
sscanf(opj_optarg, "%d", &parameters->cp_layer);
}
break;
/* ----------------------------------------------------- */
case 'B': { /* BIGENDIAN vs. LITTLEENDIAN */
parameters->bigendian = 1;
}
break;
/* ----------------------------------------------------- */
case 'L': { /* BIGENDIAN vs. LITTLEENDIAN */
parameters->decod_format = LSE_CFMT;
}
break;
/* ----------------------------------------------------- */
case 'h': { /* display an help description */
decode_help_display();
return 1;
}
break;
/* ----------------------------------------------------- */
default:
fprintf(stdout, "[WARNING] This option is not valid \"-%c %s\"\n", c,
opj_optarg);
break;
}
}
/* check for possible errors */
if ((parameters->infile[0] == 0) || (parameters->outfile[0] == 0)) {
fprintf(stdout,
"[ERROR] At least one required argument is missing\n Check jp3d_to_volume -help for usage information\n");
return 1;
}
return 0;
}
/* -------------------------------------------------------------------------- */
/**
sample error callback expecting a FILE* client object
*/
void error_callback(const char *msg, void *client_data)
{
FILE *stream = (FILE*)client_data;
fprintf(stream, "[ERROR] %s", msg);
}
/**
sample warning callback expecting a FILE* client object
*/
void warning_callback(const char *msg, void *client_data)
{
FILE *stream = (FILE*)client_data;
fprintf(stream, "[WARNING] %s", msg);
}
/**
sample debug callback expecting no client object
*/
void info_callback(const char *msg, void *client_data)
{
fprintf(stdout, "[INFO] %s", msg);
}
/* -------------------------------------------------------------------------- */
int main(int argc, char **argv)
{
opj_dparameters_t parameters; /* decompression parameters */
opj_event_mgr_t event_mgr; /* event manager */
opj_volume_t *volume = NULL;
opj_volume_t *original = NULL;
opj_cparameters_t cparameters; /* original parameters */
FILE *fsrc = NULL;
unsigned char *src = NULL;
int file_length;
int decodeok;
double psnr, ssim;
opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */
opj_cio_t *cio = NULL;
/* configure the event callbacks (not required) */
memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
event_mgr.error_handler = error_callback;
event_mgr.warning_handler = warning_callback;
event_mgr.info_handler = info_callback;
/* set decoding parameters to default values */
opj_set_default_decoder_parameters(&parameters);
/* parse input and get user decoding parameters */
strcpy(parameters.original, "NULL");
strcpy(parameters.imgfile, "NULL");
if (parse_cmdline_decoder(argc, argv, &parameters) == 1) {
return 0;
}
/* read the input file and put it in memory */
/* ---------------------------------------- */
fprintf(stdout, "[INFO] Loading %s file \n",
parameters.decod_format == J3D_CFMT ? ".jp3d" : ".j2k");
fsrc = fopen(parameters.infile, "rb");
if (!fsrc) {
fprintf(stdout, "[ERROR] Failed to open %s for reading\n", parameters.infile);
return 1;
}
fseek(fsrc, 0, SEEK_END);
file_length = ftell(fsrc);
fseek(fsrc, 0, SEEK_SET);
src = (unsigned char *) malloc(file_length);
fread(src, 1, file_length, fsrc);
fclose(fsrc);
/* decode the code-stream */
/* ---------------------- */
if (parameters.decod_format == J3D_CFMT ||
parameters.decod_format == J2K_CFMT) {
/* get a JP3D or J2K decoder handle */
if (parameters.decod_format == J3D_CFMT) {
dinfo = opj_create_decompress(CODEC_J3D);
} else if (parameters.decod_format == J2K_CFMT) {
dinfo = opj_create_decompress(CODEC_J2K);
}
/* catch events using our callbacks and give a local context */
opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
/* setup the decoder decoding parameters using user parameters */
opj_setup_decoder(dinfo, &parameters);
/* open a byte stream */
cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
/* decode the stream and fill the volume structure */
volume = opj_decode(dinfo, cio);
if (!volume) {
fprintf(stdout, "[ERROR] jp3d_to_volume: failed to decode volume!\n");
opj_destroy_decompress(dinfo);
opj_cio_close(cio);
return 1;
}
/* close the byte stream */
opj_cio_close(cio);
}
/* free the memory containing the code-stream */
free(src);
src = NULL;
/* create output volume */
/* ------------------- */
switch (parameters.cod_format) {
case PGX_DFMT: /* PGX */
decodeok = volumetopgx(volume, parameters.outfile);
if (decodeok) {
fprintf(stdout, "[ERROR] Unable to write decoded volume into pgx files\n");
}
break;
case BIN_DFMT: /* BMP */
decodeok = volumetobin(volume, parameters.outfile);
if (decodeok) {
fprintf(stdout, "[ERROR] Unable to write decoded volume into pgx files\n");
}
break;
}
switch (parameters.orig_format) {
case PGX_DFMT: /* PGX */
if (strcmp("NULL", parameters.original) != 0) {
fprintf(stdout, "Loading original file %s \n", parameters.original);
cparameters.subsampling_dx = 1;
cparameters.subsampling_dy = 1;
cparameters.subsampling_dz = 1;
cparameters.volume_offset_x0 = 0;
cparameters.volume_offset_y0 = 0;
cparameters.volume_offset_z0 = 0;
original = pgxtovolume(parameters.original, &cparameters);
}
break;
case BIN_DFMT: /* BMP */
if (strcmp("NULL", parameters.original) != 0 &&
strcmp("NULL", parameters.imgfile) != 0) {
fprintf(stdout, "Loading original file %s %s\n", parameters.original,
parameters.imgfile);
cparameters.subsampling_dx = 1;
cparameters.subsampling_dy = 1;
cparameters.subsampling_dz = 1;
cparameters.volume_offset_x0 = 0;
cparameters.volume_offset_y0 = 0;
cparameters.volume_offset_z0 = 0;
original = bintovolume(parameters.original, parameters.imgfile, &cparameters);
}
break;
}
fprintf(stdout, "[RESULT] Volume: %d x %d x %d (x %d bpv)\n ",
(volume->comps[0].w >> volume->comps[0].factor[0]),
(volume->comps[0].h >> volume->comps[0].factor[1]),
(volume->comps[0].l >> volume->comps[0].factor[2]),
volume->comps[0].prec);
if (original) {
psnr = calc_PSNR(original, volume);
ssim = calc_SSIM(original, volume);
if (psnr < 0.0) {
fprintf(stdout, " PSNR: Inf , SSMI %f -- Perfect reconstruction!\n", ssim);
} else {
fprintf(stdout, " PSNR: %f , SSIM %f \n", psnr, ssim);
}
}
/* free remaining structures */
if (dinfo) {
opj_destroy_decompress(dinfo);
}
/* free volume data structure */
opj_volume_destroy(volume);
return 0;
}

View File

@ -0,0 +1,115 @@
#!/bin/sh
# The next line is executed by /bin/sh, but not tcl \
exec wish "$0" ${1+"$@"}
lappend auto_path /usr/share/tcltk/bwidget1.9.2
namespace eval jp3dVM {
variable _progress 0
variable _afterid ""
variable _status "Compute in progress..."
variable notebook
variable mainframe
variable dataout "Process execution information"
variable status
variable prgtext
variable prgindic
set pwd [pwd]
cd [file dirname [info script]]
variable VMDIR [pwd]
cd $pwd
foreach script {encoder.tcl decoder.tcl} {
namespace inscope :: source $VMDIR/$script
}
}
proc jp3dVM::create { } {
variable notebook
variable mainframe
variable dataout
bind all <F12> { catch {console show} }
# Menu description
set descmenu {
"&File" {} {} 0 {
{command "E&xit" {} "Exit BWidget jp3dVM" {} -command exit}
}
"&Options" {} {} 0 {
{command "&Encode" {} "Show encoder" {}
-command {$jp3dVM::notebook raise [$jp3dVM::notebook page 0]}
}
{command "&Decode" {} "Show decoder" {}
-command {$jp3dVM::notebook raise [$jp3dVM::notebook page 1]}
}
}
"&Help" {} {} 0 {
{command "&About authors..." {} "Show info about authors" {}
-command {MessageDlg .msgdlg -parent . -title "About authors" -message " Copyright @ LPI-UVA 2006 " -type ok -icon info}}
}
}
set mainframe [MainFrame .mainframe \
-menu $descmenu \
-textvariable jp3dVM::status \
-progressvar jp3dVM::prgindic]
$mainframe addindicator -text "JP3D Verification Model 1.0.0"
# NoteBook creation
set frame [$mainframe getframe]
set notebook [NoteBook $frame.nb]
set logo [frame $frame.logo]
#creo imagen logo
image create photo LPIimg -file logoLPI.gif
set logoimg [Label $logo.logoimg -image LPIimg]
set f0 [VMEncoder::create $notebook]
set f1 [VMDecoder::create $notebook]
set tfinfo [TitleFrame $frame.codinfo -text "Program Execution"]
set codinfo [$tfinfo getframe]
set sw [ScrolledWindow $codinfo.sw -relief sunken -borderwidth 2 -scrollbar both]
set sf [ScrollableFrame $codinfo.sf ]
$sw setwidget $sf
set subf [$sf getframe]
set labinfo [label $subf.labinfo -textvariable jp3dVM::dataout -justify left]
pack $labinfo -side left
pack $sw
$notebook compute_size
$notebook raise [$notebook page 0]
pack $logoimg -side left -fill x -expand yes
pack $notebook -expand yes
pack $logo $tfinfo -side left -expand yes
pack $mainframe -fill both -expand yes
update idletasks
}
proc jp3dVM::main {} {
variable VMDIR
lappend ::auto_path [file dirname $VMDIR]
namespace inscope :: package require BWidget
option add *TitleFrame.l.font {helvetica 11 bold italic}
wm withdraw .
wm title . "JP3D Verification Model @ LPI"
jp3dVM::create
BWidget::place . 0 0 center
wm deiconify .
raise .
focus -force .
}
jp3dVM::main
wm geom . [wm geom .]

13
src/bin/jp3d/tcltk/README Normal file
View File

@ -0,0 +1,13 @@
HOWTO USE THE TCL/TK APP IN 'jp3d/tcltk'
----------------------------------------
1. Download the 'BWidget-1.9.2'
http://www.sourceforge.net/projects/tcllib/
2. Install it e.g. in '/usr/local/BWidget-1.9.2/'
3. Add the lappend command in line 4
to jp3d/tcltk/LPI_JP3D_VM.tcl:
#!/bin/sh
# The next line is executed by /bin/sh, but not tcl \
exec wish "$0" ${1+"$@"}
lappend auto_path /usr/local/BWidget-1.9.2

BIN
src/bin/jp3d/tcltk/Thumbs.db Executable file

Binary file not shown.

272
src/bin/jp3d/tcltk/decoder.tcl Executable file
View File

@ -0,0 +1,272 @@
namespace eval VMDecoder {
variable var
variable JP3Ddecoder "../bin/jp3d_to_volume.exe"
#variable JP3Ddecoder "jp3d_to_volume.exe"
}
proc VMDecoder::create { nb } {
variable var
set frameD [$nb insert end VMDecoder -text "Decoder"]
set topfD [frame $frameD.topfD]
set medfD [frame $frameD.medfD]
set bottomfD [frame $frameD.bottomfD]
set srcfD [TitleFrame $topfD.srcfD -text "Source"]
set dstfD [TitleFrame $topfD.dstfD -text "Destination"]
set paramfD [TitleFrame $medfD.paramfD -text "Decoding parameters"]
set infofD [TitleFrame $medfD.infofD -text "Distortion measures"]
set frame1 [$srcfD getframe]
_sourceD $frame1
set frame2 [$dstfD getframe]
_destinationD $frame2
set frame3 [$infofD getframe]
_originalD $frame3
set frame4 [$paramfD getframe]
_paramsD $frame4
set butD [Button $bottomfD.butD -text "Decode!" \
-command "VMDecoder::_decode $frame1 $frame2 $frame3" \
-helptext "Decoding trigger button"]
set butR [Button $bottomfD.butR -text "Save info" \
-command "VMDecoder::_save $frame3" \
-helptext "Save information"]
pack $srcfD $dstfD -side left -fill both -padx 10 -ipadx 5 -expand yes
pack $topfD -pady 4 -fill x
pack $paramfD $infofD -side left -fill both -padx 10 -pady 2 -ipadx 5 -expand yes
pack $medfD -pady 4 -fill x
pack $butD $butR -side left -padx 4 -pady 5 -expand yes
pack $bottomfD -pady 4 -fill x
return $frameD
}
proc fileDialogD {w ent operation} {
variable file
if {$operation == "open"} {
#-----Type names---------Extension(s)---
set types {
{"JP3D Files" {.jp3d} }
{"All files" *}
}
set file [tk_getOpenFile -filetypes $types -parent $w ]
} elseif {$operation == "original"} {
#-----Type names---------Extension(s)---
set types {
{"BIN Raw Image Files" {.bin} }
{"PGX Raw Image Files" {.pgx} }
{"All files" *}
}
set file [tk_getOpenFile -filetypes $types -parent $w ]
} else {
#-----Type names---------Extension(s)---
set types {
{"BIN Raw Image Files" {.bin} }
{"PGX Raw Image Files" {.pgx} }
{"All files" *}
}
set file [tk_getSaveFile -filetypes $types -parent $w -initialfile Untitled -defaultextension "*.bin"]
}
if {[string compare $file ""]} {
$ent delete 0 end
$ent insert end $file
$ent xview moveto 1
}
}
proc VMDecoder::_sourceD { parent } {
variable var
set labsrcD [LabelFrame $parent.labsrcD -text "Select compressed file: " -side top \
-anchor w -relief flat -borderwidth 0]
set subsrcD [$labsrcD getframe]
set listD [entry $subsrcD.entrysrcD -width 40 -textvariable VMDecoder::var(sourceD)]
set labbrw [LabelFrame $parent.labbrw -side top -anchor w -relief flat -borderwidth 0]
set subbrw [$labbrw getframe]
set butbrw [button $subbrw.butbrw -image [Bitmap::get open] \
-relief raised -borderwidth 1 -padx 1 -pady 1 \
-command "fileDialogD . $subsrcD.entrysrcD open"]
pack $listD -side top
pack $butbrw -side top
pack $labsrcD $labbrw -side left -fill both -expand yes
}
proc VMDecoder::_destinationD { parent } {
variable var
set labdstD [LabelFrame $parent.labdstD -text "Save decompressed volume file(s) as: " -side top \
-anchor w -relief flat -borderwidth 0]
set subdstD [$labdstD getframe]
set listD [entry $subdstD.entrydstD -width 40 -textvariable VMDecoder::var(destinationD)]
set labbrw [LabelFrame $parent.labbrw -side top -anchor w -relief flat -borderwidth 0]
set subbrw [$labbrw getframe]
set butbrw [button $subbrw.butbrw -image [Bitmap::get save] \
-relief raised -borderwidth 1 -padx 1 -pady 1 \
-command "fileDialogD . $subdstD.entrydstD save"]
pack $listD -side top
pack $butbrw -side top
pack $labdstD $labbrw -side left -fill both -expand yes
}
proc VMDecoder::_originalD { parent } {
variable var
set laborgD [LabelFrame $parent.laborgD -text "Select original file: " -side top \
-anchor w -relief flat -borderwidth 0]
set suborgD [$laborgD getframe]
set listorgD [entry $suborgD.entryorgD -width 30 -textvariable VMDecoder::var(originalD)]
set labbrw2 [LabelFrame $parent.labbrw2 -side top -anchor w -relief flat -borderwidth 0]
set subbrw2 [$labbrw2 getframe]
set butbrw2 [button $subbrw2.butbrw2 -image [Bitmap::get open] \
-relief raised -borderwidth 1 -padx 1 -pady 1 \
-command "fileDialogD . $suborgD.entryorgD original"]
set infoD [Label $parent.infoD -relief sunken -textvariable VMDecoder::var(decodinfo) -justify left]
pack $listorgD -side left -anchor n
pack $butbrw2 -side left -anchor n
pack $infoD -side bottom -anchor nw -pady 4 -ipadx 150 -ipady 20 -expand yes
pack $laborgD $labbrw2 -side left -fill both
}
proc VMDecoder::_paramsD { parent } {
variable var
########### DECODING #############
set labcod [LabelFrame $parent.labcod -side top -anchor w -relief sunken -borderwidth 1]
set subcod [$labcod getframe]
set frameres [frame $subcod.frameres -borderwidth 1]
set labres [LabelEntry $frameres.labres -label "Resolutions to discard: " -labelwidth 20 -labelanchor w \
-textvariable VMDecoder::var(resdiscard) -editable 1 \
-helptext "Number of highest resolution levels to be discarded on each dimension" ]
set VMDecoder::var(resdiscard) "0,0,0"
set framelayer [frame $subcod.framelayer -borderwidth 1]
set lablayer [LabelEntry $framelayer.lablayer -label "Layers to decode: " -labelwidth 20 -labelanchor w \
-textvariable VMDecoder::var(layer) -editable 1 \
-helptext "Maximum number of quality layers to decode" ]
set VMDecoder::var(layer) "All"
set framebe [frame $subcod.framebe -borderwidth 1]
set chkbe [checkbutton $framebe.chkbe -text "Write decoded file with BigEndian byte order" \
-variable VMDecoder::var(be) -onvalue 1 -offvalue 0 ]
pack $labres -side left -padx 2 -anchor n
pack $lablayer -side left -padx 2 -anchor n
pack $chkbe -side left -padx 2 -anchor w
pack $frameres $framelayer $framebe -side top -anchor w
pack $subcod -anchor n
pack $labcod -side left -fill both -padx 4 -expand yes
}
proc VMDecoder::_decode { framesrc framedst frameinfo} {
variable var
set sourceD [$framesrc.labsrcD.f.entrysrcD get ]
set destinationD [$framedst.labdstD.f.entrydstD get ]
set originD [$frameinfo.laborgD.f.entryorgD get ]
set cond1 [string match *.pgx [string tolower $destinationD]]
set cond2 [string match *\**.pgx [string tolower $destinationD]]
set cond3 [string match *.bin [string tolower $destinationD]]
#comprobamos datos son correctos
if {($cond1 == 1) && ($cond2 == 0)} {
set pgx "*.pgx"
set pattern [string range $destinationD 0 [expr [string length $destinationD]-5]]
set destinationD $pattern$img
} elseif {$sourceD == ""} {
MessageDlg .msgdlg -parent . -message "Error : Source file is not defined !" -type ok -icon error
} elseif {$destinationD == ""} {
MessageDlg .msgdlg -parent . -message "Error : Destination file is not defined !" -type ok -icon error
} else {
#creamos datain a partir de los parametros de entrada
#set dirJP3Ddecoder [mk_relativepath $VMDecoder::JP3Ddecoder]
set dirJP3Ddecoder $VMDecoder::JP3Ddecoder
set datain [concat " $dirJP3Ddecoder -i [mk_relativepath $sourceD] "]
set datain [concat " $datain -o [mk_relativepath $destinationD] "]
if {$originD != ""} {
set datain [concat " $datain -O [mk_relativepath $originD] "]
if {$cond3 == 1} {
set img ".img"
set pattern [string range $originD 0 [expr [string length $originD]-5]]
set pattern $pattern$img
if {[file exists $pattern]} {
set datain [concat " $datain -m [mk_relativepath $pattern] "]
} else {
MessageDlg .msgdlg -parent . -message "Error : IMG file associated to original BIN volume file not found in same directory !" -type ok -icon info
}
}
}
if {$VMDecoder::var(resdiscard) != "0,0,0"} {
set datain [concat " $datain -r $VMDecoder::var(resdiscard) "]
}
if {$VMDecoder::var(layer) != "All" && $VMDecoder::var(layer) > 0} {
set datain [concat " $datain -l $VMDecoder::var(layer) "]
}
if {$VMDecoder::var(be) == 1} {
set datain [concat " $datain -BE"]
}
set VMDecoder::var(progval) 10
ProgressDlg .progress -parent . -title "Wait..." \
-type infinite \
-width 20 \
-textvariable "Compute in progress..."\
-variable VMDecoder::progval \
-stop "Stop" \
-command {destroy .progress}
after 200 set VMDecoder::var(progval) 2
set fp [open "| $datain " r+]
fconfigure $fp -buffering line
set jp3dVM::dataout [concat "EXECUTED PROGRAM:\n\t$datain"]
while {-1 != [gets $fp tmp]} {
set jp3dVM::dataout [concat "$jp3dVM::dataout\n$tmp"]
}
close $fp
destroy .progress
set cond [string first "ERROR" $jp3dVM::dataout]
set cond2 [string first "PSNR" $jp3dVM::dataout]
set cond3 [string first "RESULT" $jp3dVM::dataout]
if {$cond != -1} {
MessageDlg .msgdlg -parent . -message [string range $jp3dVM::dataout [expr $cond-1] end] -type ok -icon error
} elseif {$cond3 != -1} {
if {$cond2 != -1} {
set VMDecoder::var(decodinfo) [string range $jp3dVM::dataout [expr $cond2-1] end]
}
MessageDlg .msgdlg -parent . -message [string range $jp3dVM::dataout [expr $cond3-1] end] -type ok -icon info
}
}
}
proc VMDecoder::_save { frameinfo } {
}

470
src/bin/jp3d/tcltk/encoder.tcl Executable file
View File

@ -0,0 +1,470 @@
namespace eval VMEncoder {
variable var
variable JP3Dencoder "../bin/bin/volume_to_jp3d"
}
proc VMEncoder::create { nb } {
set frame [$nb insert end VMEncoder -text "Encoder"]
set topf [frame $frame.topf]
set midf [frame $frame.midf]
set bottomf [frame $frame.bottomf]
set srcf [TitleFrame $topf.srcf -text "Source"]
set dstf [TitleFrame $topf.dstf -text "Destination"]
set Tparf [TitleFrame $midf.parfT -text "Transform Parameters"]
set Cparf [TitleFrame $midf.parfC -text "Coding Parameters"]
set frame1 [$srcf getframe]
VMEncoder::_sourceE $frame1
set frame2 [$dstf getframe]
VMEncoder::_destinationE $frame2
set frame3 [$Tparf getframe]
VMEncoder::_transformE $frame3
set frame4 [$Cparf getframe]
VMEncoder::_codingE $frame4
set butE [Button $bottomf.butE -text "Encode!" \
-command "VMEncoder::_encode $frame1 $frame2" \
-helptext "Encoding trigger button"]
set butR [Button $bottomf.butR -text "Restore defaults" \
-command "VMEncoder::_reset $frame1 $frame2 $frame3 $frame4" \
-helptext "Reset to default values"]
pack $srcf $dstf -side left -fill y -padx 4 -expand yes
pack $topf -pady 2 -fill x
pack $Tparf $Cparf -side left -fill both -padx 4 -expand yes
pack $midf -pady 2 -fill x
pack $butE $butR -side left -padx 40 -pady 5 -fill y -expand yes
pack $bottomf -pady 2 -fill x
return $frame
}
proc VMEncoder::_sourceE { parent } {
variable var
set labsrc [LabelFrame $parent.labsrc -text "Select volume file to encode: " -side top \
-anchor w -relief flat -borderwidth 0]
set subsrc [$labsrc getframe]
set list [entry $subsrc.entrysrc -width 30 -textvariable VMDecoder::var(source)]
set labbrw [LabelFrame $parent.labbrw -side top -anchor w -relief flat -borderwidth 0]
set subbrw [$labbrw getframe]
set butbrw [button $subbrw.butbrw -image [Bitmap::get open] \
-relief raised -borderwidth 1 -padx 1 -pady 1 \
-command "fileDialogE . $subsrc.entrysrc open"]
pack $list -side top
pack $butbrw -side top
pack $labsrc $labbrw -side left -fill both -expand yes
}
proc VMEncoder::_destinationE { parent } {
variable var
set labdst [LabelFrame $parent.labdst -text "Save compressed volume as: " -side top \
-anchor w -relief flat -borderwidth 0]
set subdst [$labdst getframe]
set list [entry $subdst.entrydst -width 30 -textvariable VMDecoder::var(destination)]
set labbrw [LabelFrame $parent.labbrw -side top -anchor w -relief flat -borderwidth 0]
set subbrw [$labbrw getframe]
set butbrw [button $subbrw.butbrw -image [Bitmap::get save] \
-relief raised -borderwidth 1 -padx 1 -pady 1 \
-command "fileDialogE . $subdst.entrydst save"]
pack $list -side top
pack $butbrw -side top
pack $labdst $labbrw -side left -fill both -expand yes
}
proc VMEncoder::_codingE { parent } {
########### CODING #############
set labcod [LabelFrame $parent.labcod -side top -anchor w -relief sunken -borderwidth 1]
set subcod [$labcod getframe]
set framerate [frame $subcod.framerate -borderwidth 1]
set labrate [LabelEntry $framerate.labrate -label "Rates: " -labelwidth 9 -labelanchor w \
-textvariable VMEncoder::var(rate) -editable 1 \
-helptext "Compression ratios for different layers (R1, R2, R3,...). If R=1, lossless coding" ]
set VMEncoder::var(rate) "1"
set framecblk [frame $subcod.framecblk -borderwidth 1]
set labcblk [LabelEntry $framecblk.labcblk -label "Codeblock: " -labelwidth 9 -labelanchor w \
-textvariable VMEncoder::var(cblksize) -editable 1 \
-helptext "Codeblock size (X, Y, Z)" ]
set VMEncoder::var(cblksize) "64,64,64"
set frametile [frame $subcod.frametile -borderwidth 1]
set labtile [LabelEntry $frametile.labtile -label "Tile size: " -labelwidth 9 -labelanchor w \
-textvariable VMEncoder::var(tilesize) -editable 1 \
-helptext "Tile size (X, Y, Z)" ]
set VMEncoder::var(tilesize) "512,512,512"
set framesop [frame $subcod.framesop -borderwidth 1]
set chksop [checkbutton $framesop.chksop -text "Write SOP marker" \
-variable VMEncoder::var(sop) -onvalue 1 -offvalue 0 ]
set frameeph [frame $subcod.frameeph -borderwidth 1]
set chkeph [checkbutton $frameeph.chkeph -text "Write EPH marker" \
-variable VMEncoder::var(eph) -onvalue 1 -offvalue 0 ]
set framepoc [frame $subcod.framepoc -borderwidth 1]
set labpoc [label $framepoc.labpoc -text "Progression order: " ]
set progorder [ComboBox $framepoc.progorder \
-text {Choose a progression order} \
-width 10 \
-textvariable VMEncoder::var(progorder) \
-values {"LRCP" "RLCP" "RPCL" "PCRL" "CPRL"} \
-helptext "Progression order"]
set VMEncoder::var(progorder) "LRCP"
pack $labrate -side left -padx 2 -anchor n
pack $labcblk -side left -padx 2 -anchor n
pack $labpoc $progorder -side left -padx 2 -anchor w
#pack $labtile -side left -padx 2 -anchor n
pack $chksop -side left -padx 2 -anchor w
pack $chkeph -side left -padx 2 -anchor w
########### ENTROPY CODING #############
set labent [LabelFrame $parent.labent -text "Entropy Coding" -side top -anchor w -relief sunken -borderwidth 1]
set subent [$labent getframe]
foreach entval {2EB 3EB} entropy {2D_EBCOT 3D_EBCOT} {
set rad [radiobutton $subent.$entval \
-text $entropy \
-variable VMEncoder::var(encoding) \
-command "disableGR $entval $labcblk $progorder $labrate $chksop $chkeph" \
-value $entval ]
pack $rad -anchor w
}
$subent.2EB select
pack $subent -padx 2 -anchor n
pack $framerate $framecblk $framepoc $framesop $frameeph -side top -anchor w
pack $subcod -anchor n
pack $labent $labcod -side left -fill both -padx 4 -expand yes
}
proc VMEncoder::_transformE { parent } {
variable var
########### TRANSFORM #############
set labtrf [LabelFrame $parent.labtrf -text "Transform" -side top -anchor w -relief sunken -borderwidth 1]
set subtrf [$labtrf getframe]
set labres [LabelFrame $parent.labres -side top -anchor w -relief sunken -borderwidth 1]
set subres [$labres getframe]
########### ATK #############
set frameatk [frame $subres.frameatk -borderwidth 1]
set labatk [label $frameatk.labatk -text "Wavelet kernel: " -anchor w]
set atk [ComboBox $frameatk.atk \
-textvariable VMEncoder::var(atk) \
-width 20 \
-text {Choose a wavelet kernel} \
-editable false \
-values {"R5.3" "I9.7"} ]
set VMEncoder::var(atk) "R5.3"
pack $labatk $atk -side left -anchor w
########### RESOLUTIONS #############
set frameres1 [frame $subres.frameres1 -borderwidth 1]
set labresolution [label $frameres1.labresol -text "Resolutions: " -anchor w ]
set frameres2 [frame $subres.frameres2 -borderwidth 1]
set labresX [label $frameres2.labresX -text " X" -anchor w ]
set labresY [label $frameres2.labresY -text " Y" -anchor w ]
set labresZ [label $frameres2.labresZ -text " Z" -anchor w ]
set resX [SpinBox $frameres2.spinresX \
-range {1 6 1} -textvariable VMEncoder::var(resX) \
-helptext "Number of resolutions in X" \
-width 3 \
-editable false ]
set resY [SpinBox $frameres2.spinresY \
-range {1 6 1} -textvariable VMEncoder::var(resY) \
-helptext "Number of resolutions in Y" \
-width 3 \
-editable false ]
set resZ [SpinBox $frameres2.spinresZ \
-range {1 6 1} -textvariable VMEncoder::var(resZ) \
-helptext "Number of resolutions in Z" \
-width 3 \
-editable false \
-state disabled ]
set VMEncoder::var(resX) 3
set VMEncoder::var(resY) 3
set VMEncoder::var(resZ) 3
########### TRF #############
foreach trfval {2DWT 3DWT} trf {2D-DWT 3D-DWT} {
set rad [radiobutton $subtrf.$trfval -text $trf \
-variable VMEncoder::var(transform) \
-command "disable3RLS $trfval $atk $resX $resY $resZ"\
-value $trfval ]
pack $rad -anchor w
}
$subtrf.2DWT select
pack $subtrf -side left -padx 2 -pady 4
pack $labresolution -padx 2 -side left -anchor w
pack $labresX $resX -padx 2 -side left -anchor w
pack $labresY $resY -padx 2 -side left -anchor w
pack $labresZ $resZ -padx 2 -side left -anchor w
pack $frameres1 -side top -fill x
pack $frameres2 $frameatk -side top -padx 2 -pady 4 -anchor n
pack $subres -side left -padx 2 -pady 4
pack $labtrf $labres -side left -fill both -padx 4 -expand yes
}
proc VMEncoder::_encode { framesrc framedst } {
variable var
set source [$framesrc.labsrc.f.entrysrc get ]
set destination [$framedst.labdst.f.entrydst get ]
set cond1 [string match *.pgx [string tolower $source]]
set cond2 [string match *-*.pgx [string tolower $source]]
set cond3 [string match *.bin [string tolower $source]]
set img ".img"
set pattern [string range $source 0 [expr [string length $source]-5]]
set pattern $pattern$img
set exist [file exists $pattern]
#comprobamos datos son correctos
if {($cond1 == 1) && ($cond2 == 0)} {
MessageDlg .msgdlg -parent . -message "Info : Really want to encode an slice instead of a volume?.\n For a group of .pgx slices, name must contain a - denoting a sequential index!" -type ok -icon info
}
if {$source == ""} {
MessageDlg .msgdlg -parent . -message "Error : Source file is not defined !" -type ok -icon error
} elseif {$destination == ""} {
MessageDlg .msgdlg -parent . -message "Error : Destination file is not defined !" -type ok -icon error
} elseif { ($VMEncoder::var(transform) != "3RLS") && ($VMEncoder::var(atk) == "Choose a wavelet transformation kernel") } {
MessageDlg .msgdlg -parent . -title "Info" -message "Please choose a wavelet transformation kernel"\
-type ok -icon warning
} elseif {($exist == 0) && ($cond1 == 0) && ($cond3 == 1)} {
MessageDlg .msgdlg -parent . -message "Error : IMG file associated to BIN volume file not found in same directory !" -type ok -icon info
} else {
#creamos datain a partir de los parametros de entrada
# set dirJP3Dencoder [mk_relativepath $VMEncoder::JP3Dencoder]
set dirJP3Dencoder $VMEncoder::JP3Dencoder
set datain [concat " $dirJP3Dencoder -i [mk_relativepath $source] "]
if {$cond3 == 1} {
set datain [concat " $datain -m [mk_relativepath $pattern] "]
}
set datain [concat " $datain -o [mk_relativepath $destination] "]
if {$VMEncoder::var(encoding) != "2EB"} {
set datain [concat " $datain -C $VMEncoder::var(encoding) "]
}
if {$VMEncoder::var(transform) == "2DWT"} {
set datain [concat " $datain -n $VMEncoder::var(resX),$VMEncoder::var(resY) "]
} elseif {$VMEncoder::var(transform) == "3DWT"} {
set datain [concat " $datain -n $VMEncoder::var(resX),$VMEncoder::var(resY),$VMEncoder::var(resZ) "]
}
set datain [concat " $datain -r $VMEncoder::var(rate) "]
if {$VMEncoder::var(atk) == "I9.7"} {
set datain [concat " $datain -I "]
}
if {$VMEncoder::var(sop) == 1} {
set datain [concat " $datain -SOP "]
}
if {$VMEncoder::var(eph) == 1} {
set datain [concat " $datain -EPH "]
}
if {$VMEncoder::var(progorder) != "LRCP"} {
set datain [concat " $datain -p $VMEncoder::var(progorder) "]
}
if {$VMEncoder::var(cblksize) != "64,64,64"} {
set datain [concat " $datain -b $VMEncoder::var(cblksize) "]
}
#Making this work would be great !!!
set VMEncoder::var(progval) 10
ProgressDlg .progress -parent . -title "Wait..." \
-type infinite \
-width 20 \
-textvariable "Compute in progress..."\
-variable VMEncoder::progval \
-stop "Stop" \
-command {destroy .progress}
after 200 set VMEncoder::var(progval) 2
set fp [open "| $datain " r+]
fconfigure $fp -buffering line
set jp3dVM::dataout [concat "EXECUTED PROGRAM:\n\t$datain"]
while {-1 != [gets $fp tmp]} {
set jp3dVM::dataout [concat "$jp3dVM::dataout\n$tmp"]
}
destroy .progress
set cond [string first "ERROR" $jp3dVM::dataout]
set cond2 [string first "RESULT" $jp3dVM::dataout]
if {$cond != -1} {
MessageDlg .msgdlg -parent . -message [string range $jp3dVM::dataout [expr $cond-1] end] -type ok -icon error
} elseif {$cond2 != -1} {
MessageDlg .msgdlg -parent . -message [string range $jp3dVM::dataout [expr $cond2+7] end] -type ok -icon info
close $fp
} else {
#Must do something with this !!! [pid $fp]
close $fp
}
}
}
proc VMEncoder::_reset { framesrc framedst frametrf framecod} {
variable var
#Restore defaults values
set VMEncoder::var(transform) 2DWT
set VMEncoder::var(encoding) 2EB
set VMEncoder::var(atk) "R5.3"
set VMEncoder::var(progorder) "LRCP"
set atk $frametrf.labres.f.frameatk.atk
set resX $frametrf.labres.f.frameres2.spinresX
set resY $frametrf.labres.f.frameres2.spinresY
set resZ $frametrf.labres.f.frameres2.spinresZ
disable3RLS 2DWT $atk $resX $resY $resZ
set labcblk $framecod.labcod.f.framecblk.labcblk
set progorder $framecod.labcod.f.framepoc.progorder
set labrate $framecod.labcod.f.framerate.labrate
set chksop $framecod.labcod.f.framesop.chksop
set chkeph $framecod.labcod.f.frameeph.chkeph
disableGR 3EB $labcblk $progorder $labrate $chksop $chkeph
$framesrc.labsrc.f.entrysrc delete 0 end
$framedst.labdst.f.entrydst delete 0 end
}
proc fileDialogE {w ent operation} {
variable file
variable i j
if {$operation == "open"} {
set types {
{"Source Image Files" {.pgx .bin} }
{"All files" *}
}
set file [tk_getOpenFile -filetypes $types -parent $w]
if {[string compare $file ""]} {
$ent delete 0 end
$ent insert end $file
$ent xview moveto 1
}
} else {
set types {
{"JP3D Files" {.jp3d} }
{"JPEG2000 Files" {.j2k} }
{"All files" *}
}
set file [tk_getSaveFile -filetypes $types -parent $w \
-initialfile Untitled -defaultextension .jp3d]
if {[string compare $file ""]} {
$ent delete 0 end
$ent insert end $file
$ent xview moveto 1
}
}
}
proc mk_relativepath {abspath} {
set mydir [split [string trimleft [pwd] {/}] {/}]
set abspathcomps [split [string trimleft $abspath {/}] {/}]
set i 0
while {$i<[llength $mydir]} {
if {![string compare [lindex $abspathcomps $i] [lindex $mydir $i]]} {
incr i
} else {
break
}
}
set h [expr [llength $mydir]-$i]
set j [expr [llength $abspathcomps]-$i]
if {!$h} {
set relpath "./"
} else {
set relpath ""
while { $h > 0 } {
set relpath "../$relpath"
incr h -1
}
}
set h [llength $abspathcomps]
while { $h > $i } {
set relpath [concat $relpath[lindex $abspathcomps [expr [llength $abspathcomps]-$j]]/]
incr h -1
incr j -1
}
return [string trim $relpath {/}]
}
proc disable3RLS {flag atk resX resY resZ} {
if {$flag == "3RLS"} {
$atk configure -state disabled
$resX configure -state disabled
$resY configure -state disabled
$resZ configure -state disabled
} elseif {$flag == "2DWT"} {
$atk configure -state normal
$resX configure -state normal
$resY configure -state normal
$resZ configure -state disabled
} elseif {$flag == "3DWT"} {
$atk configure -state normal
$resX configure -state normal
$resY configure -state normal
$resZ configure -state normal
}
}
proc disableGR {flag labcblk progorder labrate chksop chkeph} {
if {$flag == "2EB"} {
$labcblk configure -state normal
$progorder configure -state normal
$labrate configure -state normal
$chksop configure -state normal
$chkeph configure -state normal
set VMEncoder::var(cblksize) "64,64,64"
set VMEncoder::var(tilesize) "512,512,512"
} elseif {$flag == "3EB"} {
$labcblk configure -state normal
$progorder configure -state normal
$labrate configure -state normal
$chksop configure -state normal
$chkeph configure -state normal
set VMEncoder::var(cblksize) "64,64,64"
set VMEncoder::var(tilesize) "512,512,512"
} else {
$labcblk configure -state disabled
$progorder configure -state disabled
$labrate configure -state disabled
$chksop configure -state disabled
$chkeph configure -state disabled
}
}

BIN
src/bin/jp3d/tcltk/logoLPI.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

679
src/bin/jp3d/windirent.h Normal file
View File

@ -0,0 +1,679 @@
/*
* uce-dirent.h - operating system independent dirent implementation
*
* Copyright (C) 1998-2002 Toni Ronkko
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* ``Software''), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*
* May 28 1998, Toni Ronkko <tronkko@messi.uku.fi>
*
* $Id: uce-dirent.h,v 1.7 2002/05/13 10:48:35 tr Exp $
*
* $Log: uce-dirent.h,v $
* Revision 1.7 2002/05/13 10:48:35 tr
* embedded some source code directly to the header so that no source
* modules need to be included in the MS Visual C project using the
* interface, removed all the dependencies to other headers of the `uce'
* library so that the header can be made public
*
* Revision 1.6 2002/04/12 16:22:04 tr
* Unified Compiling Environment (UCE) replaced `std' library
*
* Revision 1.5 2001/07/20 16:33:40 tr
* moved to `std' library and re-named defines accordingly
*
* Revision 1.4 2001/07/10 16:47:18 tronkko
* revised comments
*
* Revision 1.3 2001/01/11 13:16:43 tr
* using ``uce-machine.h'' for finding out defines such as `FREEBSD'
*
* Revision 1.2 2000/10/08 16:00:41 tr
* copy of FreeBSD man page
*
* Revision 1.1 2000/07/10 05:53:16 tr
* Initial revision
*
* Revision 1.2 1998/07/19 18:29:14 tr
* Added error reporting capabilities and some asserts.
*
* Revision 1.1 1998/07/04 16:27:51 tr
* Initial revision
*
*
* MSVC 1.0 scans automatic dependencies incorrectly when your project
* contains this very header. The problem is that MSVC cannot handle
* include directives inside #if..#endif block those are never entered.
* Since this header ought to compile in many different operating systems,
* there had to be several conditional blocks that are compiled only in
* operating systems for what they were designed for. MSVC 1.0 cannot
* handle inclusion of sys/dir.h in a part that is compiled only in Apollo
* operating system. To fix the problem you need to insert DIR.H into
* SYSINCL.DAT located in MSVC\BIN directory and restart visual C++.
* Consult manuals for more informaton about the problem.
*
* Since many UNIX systems have dirent.h we assume to have one also.
* However, if your UNIX system does not have dirent.h you can download one
* for example at: http://ftp.uni-mannheim.de/ftp/GNU/dirent/dirent.tar.gz.
* You can also see if you have one of dirent.h, direct.h, dir.h, ndir.h,
* sys/dir.h and sys/ndir.h somewhere. Try defining HAVE_DIRENT_H,
* HAVE_DIRECT_H, HAVE_DIR_H, HAVE_NDIR_H, HAVE_SYS_DIR_H and
* HAVE_SYS_NDIR_H according to the files found.
*/
#ifndef DIRENT_H
#define DIRENT_H
#define DIRENT_H_INCLUDED
/* find out platform */
#if defined(MSDOS) /* MS-DOS */
#elif defined(__MSDOS__) /* Turbo C/Borland */
# define MSDOS
#elif defined(__DOS__) /* Watcom */
# define MSDOS
#endif
#if defined(WIN32) /* MS-Windows */
#elif defined(__NT__) /* Watcom */
# define WIN32
#elif defined(_WIN32) /* Microsoft */
# define WIN32
#elif defined(__WIN32__) /* Borland */
# define WIN32
#endif
/*
* See what kind of dirent interface we have unless autoconf has already
* determinated that.
*/
#if !defined(HAVE_DIRENT_H) && !defined(HAVE_DIRECT_H) && !defined(HAVE_SYS_DIR_H) && !defined(HAVE_NDIR_H) && !defined(HAVE_SYS_NDIR_H) && !defined(HAVE_DIR_H)
# if defined(_MSC_VER) /* Microsoft C/C++ */
/* no dirent.h */
# elif defined(__MINGW32__) /* MinGW */
/* no dirent.h */
# elif defined(__BORLANDC__) /* Borland C/C++ */
# define HAVE_DIRENT_H
# define VOID_CLOSEDIR
# elif defined(__TURBOC__) /* Borland Turbo C */
/* no dirent.h */
# elif defined(__WATCOMC__) /* Watcom C/C++ */
# define HAVE_DIRECT_H
# elif defined(__apollo) /* Apollo */
# define HAVE_SYS_DIR_H
# elif defined(__hpux) /* HP-UX */
# define HAVE_DIRENT_H
# elif defined(__alpha) || defined(__alpha__) /* Alpha OSF1 */
# error "not implemented"
# elif defined(__sgi) /* Silicon Graphics */
# define HAVE_DIRENT_H
# elif defined(sun) || defined(_sun) /* Sun Solaris */
# define HAVE_DIRENT_H
# elif defined(__FreeBSD__) /* FreeBSD */
# define HAVE_DIRENT_H
# elif defined(__linux__) /* Linux */
# define HAVE_DIRENT_H
# elif defined(__GNUC__) /* GNU C/C++ */
# define HAVE_DIRENT_H
# else
# error "not implemented"
# endif
#endif
/* include proper interface headers */
#if defined(HAVE_DIRENT_H)
# include <dirent.h>
# ifdef FREEBSD
# define NAMLEN(dp) ((int)((dp)->d_namlen))
# else
# define NAMLEN(dp) ((int)(strlen((dp)->d_name)))
# endif
#elif defined(HAVE_NDIR_H)
# include <ndir.h>
# define NAMLEN(dp) ((int)((dp)->d_namlen))
#elif defined(HAVE_SYS_NDIR_H)
# include <sys/ndir.h>
# define NAMLEN(dp) ((int)((dp)->d_namlen))
#elif defined(HAVE_DIRECT_H)
# include <direct.h>
# define NAMLEN(dp) ((int)((dp)->d_namlen))
#elif defined(HAVE_DIR_H)
# include <dir.h>
# define NAMLEN(dp) ((int)((dp)->d_namlen))
#elif defined(HAVE_SYS_DIR_H)
# include <sys/types.h>
# include <sys/dir.h>
# ifndef dirent
# define dirent direct
# endif
# define NAMLEN(dp) ((int)((dp)->d_namlen))
#elif defined(MSDOS) || defined(WIN32)
/* figure out type of underlaying directory interface to be used */
# if defined(WIN32)
# define DIRENT_WIN32_INTERFACE
# elif defined(MSDOS)
# define DIRENT_MSDOS_INTERFACE
# else
# error "missing native dirent interface"
# endif
/*** WIN32 specifics ***/
# if defined(DIRENT_WIN32_INTERFACE)
# include <windows.h>
# if !defined(DIRENT_MAXNAMLEN)
# define DIRENT_MAXNAMLEN (MAX_PATH)
# endif
/*** MS-DOS specifics ***/
# elif defined(DIRENT_MSDOS_INTERFACE)
# include <dos.h>
/* Borland defines file length macros in dir.h */
# if defined(__BORLANDC__)
# include <dir.h>
# if !defined(DIRENT_MAXNAMLEN)
# define DIRENT_MAXNAMLEN ((MAXFILE)+(MAXEXT))
# endif
# if !defined(_find_t)
# define _find_t find_t
# endif
/* Turbo C defines ffblk structure in dir.h */
# elif defined(__TURBOC__)
# include <dir.h>
# if !defined(DIRENT_MAXNAMLEN)
# define DIRENT_MAXNAMLEN ((MAXFILE)+(MAXEXT))
# endif
# define DIRENT_USE_FFBLK
/* MSVC */
# elif defined(_MSC_VER)
# if !defined(DIRENT_MAXNAMLEN)
# define DIRENT_MAXNAMLEN (12)
# endif
/* Watcom */
# elif defined(__WATCOMC__)
# if !defined(DIRENT_MAXNAMLEN)
# if defined(__OS2__) || defined(__NT__)
# define DIRENT_MAXNAMLEN (255)
# else
# define DIRENT_MAXNAMLEN (12)
# endif
# endif
# endif
# endif
/*** generic MS-DOS and MS-Windows stuff ***/
# if !defined(NAME_MAX) && defined(DIRENT_MAXNAMLEN)
# define NAME_MAX DIRENT_MAXNAMLEN
# endif
# if NAME_MAX < DIRENT_MAXNAMLEN
# error "assertion failed: NAME_MAX >= DIRENT_MAXNAMLEN"
# endif
/*
* Substitute for real dirent structure. Note that `d_name' field is a
* true character array although we have it copied in the implementation
* dependent data. We could save some memory if we had declared `d_name'
* as a pointer referring the name within implementation dependent data.
* We have not done that since some code may rely on sizeof(d_name) to be
* something other than four. Besides, directory entries are typically so
* small that it takes virtually no time to copy them from place to place.
*/
typedef struct dirent {
char d_name[NAME_MAX + 1];
/*** Operating system specific part ***/
# if defined(DIRENT_WIN32_INTERFACE) /*WIN32*/
WIN32_FIND_DATA data;
# elif defined(DIRENT_MSDOS_INTERFACE) /*MSDOS*/
# if defined(DIRENT_USE_FFBLK)
struct ffblk data;
# else
struct _find_t data;
# endif
# endif
} dirent;
/* DIR substitute structure containing directory name. The name is
* essential for the operation of ``rewinndir'' function. */
typedef struct DIR {
char *dirname; /* directory being scanned */
dirent current; /* current entry */
int dirent_filled; /* is current un-processed? */
/*** Operating system specific part ***/
# if defined(DIRENT_WIN32_INTERFACE)
HANDLE search_handle;
# elif defined(DIRENT_MSDOS_INTERFACE)
# endif
} DIR;
# ifdef __cplusplus
extern "C" {
# endif
/* supply prototypes for dirent functions */
static DIR *opendir(const char *dirname);
static struct dirent *readdir(DIR *dirp);
static int closedir(DIR *dirp);
static void rewinddir(DIR *dirp);
/*
* Implement dirent interface as static functions so that the user does not
* need to change his project in any way to use dirent function. With this
* it is sufficient to include this very header from source modules using
* dirent functions and the functions will be pulled in automatically.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
/* use ffblk instead of _find_t if requested */
#if defined(DIRENT_USE_FFBLK)
# define _A_ARCH (FA_ARCH)
# define _A_HIDDEN (FA_HIDDEN)
# define _A_NORMAL (0)
# define _A_RDONLY (FA_RDONLY)
# define _A_SUBDIR (FA_DIREC)
# define _A_SYSTEM (FA_SYSTEM)
# define _A_VOLID (FA_LABEL)
# define _dos_findnext(dest) findnext(dest)
# define _dos_findfirst(name,flags,dest) findfirst(name,dest,flags)
#endif
static int _initdir(DIR *p);
static const char *_getdirname(const struct dirent *dp);
static void _setdirname(struct DIR *dirp);
/*
* <function name="opendir">
* <intro>open directory stream for reading
* <syntax>DIR *opendir (const char *dirname);
*
* <desc>Open named directory stream for read and return pointer to the
* internal working area that is used for retrieving individual directory
* entries. The internal working area has no fields of your interest.
*
* <ret>Returns a pointer to the internal working area or NULL in case the
* directory stream could not be opened. Global `errno' variable will set
* in case of error as follows:
*
* <table>
* [EACESS |Permission denied.
* [EMFILE |Too many open files used by the process.
* [ENFILE |Too many open files in system.
* [ENOENT |Directory does not exist.
* [ENOMEM |Insufficient memory.
* [ENOTDIR |dirname does not refer to directory. This value is not
* reliable on MS-DOS and MS-Windows platforms. Many
* implementations return ENOENT even when the name refers to a
* file.]
* </table>
* </function>
*/
static DIR *opendir(const char *dirname)
{
DIR *dirp;
assert(dirname != NULL);
dirp = (DIR*)malloc(sizeof(struct DIR));
if (dirp != NULL) {
char *p;
/* allocate room for directory name */
dirp->dirname = (char*) malloc(strlen(dirname) + 1 + strlen("\\*.*"));
if (dirp->dirname == NULL) {
/* failed to duplicate directory name. errno set by malloc() */
free(dirp);
return NULL;
}
/* Copy directory name while appending directory separator and "*.*".
* Directory separator is not appended if the name already ends with
* drive or directory separator. Directory separator is assumed to be
* '/' or '\' and drive separator is assumed to be ':'. */
strcpy(dirp->dirname, dirname);
p = strchr(dirp->dirname, '\0');
if (dirp->dirname < p &&
*(p - 1) != '\\' && *(p - 1) != '/' && *(p - 1) != ':') {
strcpy(p++, "\\");
}
# ifdef DIRENT_WIN32_INTERFACE
strcpy(p, "*"); /*scan files with and without extension in win32*/
# else
strcpy(p, "*.*"); /*scan files with and without extension in DOS*/
# endif
/* open stream */
if (_initdir(dirp) == 0) {
/* initialization failed */
free(dirp->dirname);
free(dirp);
return NULL;
}
}
return dirp;
}
/*
* <function name="readdir">
* <intro>read a directory entry
* <syntax>struct dirent *readdir (DIR *dirp);
*
* <desc>Read individual directory entry and return pointer to a structure
* containing the name of the entry. Individual directory entries returned
* include normal files, sub-directories, pseudo-directories "." and ".."
* and also volume labels, hidden files and system files in MS-DOS and
* MS-Windows. You might want to use stat(2) function to determinate which
* one are you dealing with. Many dirent implementations already contain
* equivalent information in dirent structure but you cannot depend on
* this.
*
* The dirent structure contains several system dependent fields that
* generally have no interest to you. The only interesting one is char
* d_name[] that is also portable across different systems. The d_name
* field contains the name of the directory entry without leading path.
* While d_name is portable across different systems the actual storage
* capacity of d_name varies from system to system and there is no portable
* way to find out it at compile time as different systems define the
* capacity of d_name with different macros and some systems do not define
* capacity at all (besides actual declaration of the field). If you really
* need to find out storage capacity of d_name then you might want to try
* NAME_MAX macro. The NAME_MAX is defined in POSIX standard although
* there are many MS-DOS and MS-Windows implementations those do not define
* it. There are also systems that declare d_name as "char d_name[1]" and
* then allocate suitable amount of memory at run-time. Thanks to Alain
* Decamps (Alain.Decamps@advalvas.be) for pointing it out to me.
*
* This all leads to the fact that it is difficult to allocate space
* for the directory names when the very same program is being compiled on
* number of operating systems. Therefore I suggest that you always
* allocate space for directory names dynamically.
*
* <ret>
* Returns a pointer to a structure containing name of the directory entry
* in `d_name' field or NULL if there was an error. In case of an error the
* global `errno' variable will set as follows:
*
* <table>
* [EBADF |dir parameter refers to an invalid directory stream. This value
* is not set reliably on all implementations.]
* </table>
* </function>
*/
static struct dirent *
readdir(DIR *dirp)
{
assert(dirp != NULL);
if (dirp == NULL) {
errno = EBADF;
return NULL;
}
#if defined(DIRENT_WIN32_INTERFACE)
if (dirp->search_handle == INVALID_HANDLE_VALUE) {
/* directory stream was opened/rewound incorrectly or it ended normally */
errno = EBADF;
return NULL;
}
#endif
if (dirp->dirent_filled != 0) {
/*
* Directory entry has already been retrieved and there is no need to
* retrieve a new one. Directory entry will be retrieved in advance
* when the user calls readdir function for the first time. This is so
* because real dirent has separate functions for opening and reading
* the stream whereas Win32 and DOS dirents open the stream
* automatically when we retrieve the first file. Therefore, we have to
* save the first file when opening the stream and later we have to
* return the saved entry when the user tries to read the first entry.
*/
dirp->dirent_filled = 0;
} else {
/* fill in entry and return that */
#if defined(DIRENT_WIN32_INTERFACE)
if (FindNextFile(dirp->search_handle, &dirp->current.data) == FALSE) {
/* Last file has been processed or an error occurred */
FindClose(dirp->search_handle);
dirp->search_handle = INVALID_HANDLE_VALUE;
errno = ENOENT;
return NULL;
}
# elif defined(DIRENT_MSDOS_INTERFACE)
if (_dos_findnext(&dirp->current.data) != 0) {
/* _dos_findnext and findnext will set errno to ENOENT when no
* more entries could be retrieved. */
return NULL;
}
# endif
_setdirname(dirp);
assert(dirp->dirent_filled == 0);
}
return &dirp->current;
}
/*
* <function name="closedir">
* <intro>close directory stream.
* <syntax>int closedir (DIR *dirp);
*
* <desc>Close directory stream opened by the `opendir' function. Close of
* directory stream invalidates the DIR structure as well as previously read
* dirent entry.
*
* <ret>The function typically returns 0 on success and -1 on failure but
* the function may be declared to return void on same systems. At least
* Borland C/C++ and some UNIX implementations use void as a return type.
* The dirent wrapper tries to define VOID_CLOSEDIR whenever closedir is
* known to return nothing. The very same definition is made by the GNU
* autoconf if you happen to use it.
*
* The global `errno' variable will set to EBADF in case of error.
* </function>
*/
static int
closedir(DIR *dirp)
{
int retcode = 0;
/* make sure that dirp points to legal structure */
assert(dirp != NULL);
if (dirp == NULL) {
errno = EBADF;
return -1;
}
/* free directory name and search handles */
if (dirp->dirname != NULL) {
free(dirp->dirname);
}
#if defined(DIRENT_WIN32_INTERFACE)
if (dirp->search_handle != INVALID_HANDLE_VALUE) {
if (FindClose(dirp->search_handle) == FALSE) {
/* Unknown error */
retcode = -1;
errno = EBADF;
}
}
#endif
/* clear dirp structure to make sure that it cannot be used anymore*/
memset(dirp, 0, sizeof(*dirp));
# if defined(DIRENT_WIN32_INTERFACE)
dirp->search_handle = INVALID_HANDLE_VALUE;
# endif
free(dirp);
return retcode;
}
/*
* <function name="rewinddir">
* <intro>rewind directory stream to the beginning
* <syntax>void rewinddir (DIR *dirp);
*
* <desc>Rewind directory stream to the beginning so that the next call of
* readdir() returns the very first directory entry again. However, note
* that next call of readdir() may not return the same directory entry as it
* did in first time. The directory stream may have been affected by newly
* created files.
*
* Almost every dirent implementation ensure that rewinddir will update
* the directory stream to reflect any changes made to the directory entries
* since the previous ``opendir'' or ``rewinddir'' call. Keep an eye on
* this if your program depends on the feature. I know at least one dirent
* implementation where you are required to close and re-open the stream to
* see the changes.
*
* <ret>Returns nothing. If something went wrong while rewinding, you will
* notice it later when you try to retrieve the first directory entry.
*/
static void
rewinddir(DIR *dirp)
{
/* make sure that dirp is legal */
assert(dirp != NULL);
if (dirp == NULL) {
errno = EBADF;
return;
}
assert(dirp->dirname != NULL);
/* close previous stream */
#if defined(DIRENT_WIN32_INTERFACE)
if (dirp->search_handle != INVALID_HANDLE_VALUE) {
if (FindClose(dirp->search_handle) == FALSE) {
/* Unknown error */
errno = EBADF;
}
}
#endif
/* re-open previous stream */
if (_initdir(dirp) == 0) {
/* initialization failed but we cannot deal with error. User will notice
* error later when she tries to retrieve first directory enty. */
/*EMPTY*/;
}
}
/*
* Open native directory stream object and retrieve first file.
* Be sure to close previous stream before opening new one.
*/
static int
_initdir(DIR *dirp)
{
assert(dirp != NULL);
assert(dirp->dirname != NULL);
dirp->dirent_filled = 0;
# if defined(DIRENT_WIN32_INTERFACE)
/* Open stream and retrieve first file */
dirp->search_handle = FindFirstFile(dirp->dirname, &dirp->current.data);
if (dirp->search_handle == INVALID_HANDLE_VALUE) {
/* something went wrong but we don't know what. GetLastError() could
* give us more information about the error, but then we should map
* the error code into errno. */
errno = ENOENT;
return 0;
}
# elif defined(DIRENT_MSDOS_INTERFACE)
if (_dos_findfirst(dirp->dirname,
_A_SUBDIR | _A_RDONLY | _A_ARCH | _A_SYSTEM | _A_HIDDEN,
&dirp->current.data) != 0) {
/* _dos_findfirst and findfirst will set errno to ENOENT when no
* more entries could be retrieved. */
return 0;
}
# endif
/* initialize DIR and it's first entry */
_setdirname(dirp);
dirp->dirent_filled = 1;
return 1;
}
/*
* Return implementation dependent name of the current directory entry.
*/
static const char *
_getdirname(const struct dirent *dp)
{
#if defined(DIRENT_WIN32_INTERFACE)
return dp->data.cFileName;
#elif defined(DIRENT_USE_FFBLK)
return dp->data.ff_name;
#else
return dp->data.name;
#endif
}
/*
* Copy name of implementation dependent directory entry to the d_name field.
*/
static void
_setdirname(struct DIR *dirp)
{
/* make sure that d_name is long enough */
assert(strlen(_getdirname(&dirp->current)) <= NAME_MAX);
strncpy(dirp->current.d_name,
_getdirname(&dirp->current),
NAME_MAX);
dirp->current.d_name[NAME_MAX] = '\0'; /*char d_name[NAME_MAX+1]*/
}
# ifdef __cplusplus
}
# endif
# define NAMLEN(dp) ((int)(strlen((dp)->d_name)))
#else
# error "missing dirent interface"
#endif
#endif /*DIRENT_H*/

View File

@ -13,7 +13,7 @@ add_executable(opj_jpip_addxml opj_jpip_addxml.c)
# Install exe
install(TARGETS opj_jpip_addxml
EXPORT OpenJPEGTargets
DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Applications
DESTINATION ${OPENJPEG_INSTALL_BIN_DIR} COMPONENT Applications
)
if(BUILD_JPIP_SERVER)
@ -38,7 +38,7 @@ if(BUILD_JPIP_SERVER)
# Install exe
install(TARGETS opj_server
EXPORT OpenJPEGTargets
DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Applications
DESTINATION ${OPENJPEG_INSTALL_BIN_DIR} COMPONENT Applications
)
endif()
@ -52,19 +52,19 @@ add_executable(${exe} ${exe}.c)
target_link_libraries(${exe} openjpip)
install(TARGETS ${exe}
EXPORT OpenJPEGTargets
DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Applications
DESTINATION ${OPENJPEG_INSTALL_BIN_DIR} COMPONENT Applications
)
endforeach()
# Build the two java clients:
find_package(Java 1.8 COMPONENTS Development) # javac, jar
find_package(Java 1.5 COMPONENTS Development) # javac, jar
# User can override this:
if(NOT DEFINED JAVA_SOURCE_VERSION)
set(JAVA_SOURCE_VERSION 1.8)
set(JAVA_SOURCE_VERSION 1.5)
endif()
if(NOT DEFINED JAVA_TARGET_VERSION)
set(JAVA_TARGET_VERSION 1.8)
set(JAVA_TARGET_VERSION 1.5)
endif()
# Only build the java viewer if dev is found:
@ -123,7 +123,7 @@ if(Java_Development_FOUND AND Java_JAVAC_EXECUTABLE)
)
install(FILES ${LIBRARY_OUTPUT_PATH}/opj_jpip_viewer.jar
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR} COMPONENT JavaModule
DESTINATION ${OPENJPEG_INSTALL_SHARE_DIR} COMPONENT JavaModule
)
else()
# opj_viewer (simple, no xerces)
@ -153,9 +153,9 @@ if(Java_Development_FOUND AND Java_JAVAC_EXECUTABLE)
)
install(FILES ${LIBRARY_OUTPUT_PATH}/opj_jpip_viewer.jar
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR} COMPONENT JavaModule
DESTINATION ${OPENJPEG_INSTALL_SHARE_DIR} COMPONENT JavaModule
)
endif()
else()
message(WARNING "No java compiler found. Won't be able to build java viewer")
message(WARNING "No java compiler found. Wont be able to build java viewer")
endif()

View File

@ -92,7 +92,7 @@ Server:
For shutting down JPIP server:
%GET http://hostname/myFCGI?quitJPIP
Notice, http://hostname/myFCGI is the HTTP server URI (myFCGI refers to opj_server by the server setting)
Request message "quitJPIP" can be changed in Makefile, modify -DQUIT_SIGNAL=\"quitJPIP\"
Requst message "quitJPIP" can be changed in Makfile, modify -DQUIT_SIGNAL=\"quitJPIP\"
Client:
1. Launch image decoding server, and keep it alive as long as image viewers are open

View File

@ -79,7 +79,7 @@ int main(int argc, char *argv[])
long fsize, boxsize;
if (argc < 3) {
fprintf(stderr, "USAGE: %s modifying.jp2 adding.xml\n", argv[0]);
fprintf(stderr, "USAGE: %s modifing.jp2 adding.xml\n", argv[0]);
return -1;
}

View File

@ -49,14 +49,12 @@ static int jpip_to_jp2(char *argv[])
dec = init_jpipdecoder(OPJ_TRUE);
if (!(fread_jpip(argv[1], dec))) {
destroy_jpipdecoder(&dec);
return 1;
}
decode_jpip(dec);
if (!(fwrite_jp2k(argv[2], dec))) {
destroy_jpipdecoder(&dec);
return 1;
}
@ -85,14 +83,12 @@ static int jpip_to_j2k(char *argv[])
dec = init_jpipdecoder(OPJ_FALSE);
if (!(fread_jpip(argv[1], dec))) {
destroy_jpipdecoder(&dec);
return 1;
}
decode_jpip(dec);
if (!(fwrite_jp2k(argv[2], dec))) {
destroy_jpipdecoder(&dec);
return 1;
}

View File

@ -0,0 +1,62 @@
# jpwl apps
# First thing define the common source:
set(common_SRCS
convert.c
index.c
${OPENJPEG_SOURCE_DIR}/src/bin/common/color.c
${OPENJPEG_SOURCE_DIR}/src/bin/common/opj_getopt.c
)
# Headers file are located here:
include_directories(
${OPENJPEG_BINARY_DIR}/src/lib/openjp2 # opj_config.h
${OPENJPEG_BINARY_DIR}/src/bin/common # opj_apps_config.h
${OPENJPEG_SOURCE_DIR}/src/lib/openmj2
${OPENJPEG_SOURCE_DIR}/src/bin/common
${LCMS_INCLUDE_DIRNAME}
${Z_INCLUDE_DIRNAME}
${PNG_INCLUDE_DIRNAME}
${TIFF_INCLUDE_DIRNAME}
)
if(WIN32)
if(BUILD_SHARED_LIBS)
add_definitions(-DOPJ_EXPORTS)
else()
add_definitions(-DOPJ_STATIC)
endif()
endif()
add_definitions(-DOPJ_USE_LEGACY)
foreach(exe decompress compress)
set(jpwl_exe opj_jpwl_${exe})
set(jp2_exe opj_${exe})
add_executable(${jpwl_exe}
#../jp2/${jp2_exe}.c
${jpwl_exe}.c
${common_SRCS}
)
set_property(
TARGET ${jpwl_exe}
APPEND PROPERTY COMPILE_DEFINITIONS USE_JPWL
)
target_link_libraries(${jpwl_exe} openjpwl
${LCMS_LIBNAME} ${PNG_LIBNAME} ${TIFF_LIBNAME})
# To support universal exe:
if(ZLIB_FOUND AND APPLE)
target_link_libraries(${jpwl_exe} z)
else(ZLIB_FOUND AND APPLE)
target_link_libraries(${jpwl_exe} ${Z_LIBNAME})
endif()
if(UNIX)
target_link_libraries(${jpwl_exe} m)
endif()
install(TARGETS ${jpwl_exe}
DESTINATION ${OPENJPEG_INSTALL_BIN_DIR} COMPONENT Applications
)
endforeach()

3748
src/bin/jpwl/convert.c Normal file

File diff suppressed because it is too large Load Diff

90
src/bin/jpwl/convert.h Normal file
View File

@ -0,0 +1,90 @@
/*
* The copyright in this software is being made available under the 2-clauses
* BSD License, included below. This software may be subject to other third
* party and contributor rights, including patent rights, and no such rights
* are granted under this license.
*
* Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
* Copyright (c) 2002-2014, Professor Benoit Macq
* Copyright (c) 2001-2003, David Janssens
* Copyright (c) 2002-2003, Yannick Verschueren
* Copyright (c) 2003-2007, Francois-Olivier Devaux
* Copyright (c) 2003-2014, Antonin Descampe
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 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 OWNER 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.
*/
#ifndef __J2K_CONVERT_H
#define __J2K_CONVERT_H
/**@name RAW image encoding parameters */
/*@{*/
typedef struct raw_cparameters {
/** width of the raw image */
int rawWidth;
/** height of the raw image */
int rawHeight;
/** components of the raw image */
int rawComp;
/** bit depth of the raw image */
int rawBitDepth;
/** signed/unsigned raw image */
opj_bool rawSigned;
/*@}*/
} raw_cparameters_t;
/* TGA conversion */
opj_image_t* tgatoimage(const char *filename, opj_cparameters_t *parameters);
int imagetotga(opj_image_t * image, const char *outfile);
/* BMP conversion */
opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters);
int imagetobmp(opj_image_t *image, const char *outfile);
/* TIFF conversion*/
opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters);
int imagetotif(opj_image_t *image, const char *outfile);
/**
Load a single image component encoded in PGX file format
@param filename Name of the PGX file to load
@param parameters *List ?*
@return Returns a greyscale image if successful, returns NULL otherwise
*/
opj_image_t* pgxtoimage(const char *filename, opj_cparameters_t *parameters);
int imagetopgx(opj_image_t *image, const char *outfile);
opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters);
int imagetopnm(opj_image_t *image, const char *outfile);
/* RAW conversion */
int imagetoraw(opj_image_t * image, const char *outfile);
opj_image_t* rawtoimage(const char *filename, opj_cparameters_t *parameters,
raw_cparameters_t *raw_cp);
/* PNG conversion*/
extern int imagetopng(opj_image_t *image, const char *write_idf);
extern opj_image_t* pngtoimage(const char *filename,
opj_cparameters_t *parameters);
#endif /* __J2K_CONVERT_H */

454
src/bin/jpwl/index.c Normal file
View File

@ -0,0 +1,454 @@
/*
* The copyright in this software is being made available under the 2-clauses
* BSD License, included below. This software may be subject to other third
* party and contributor rights, including patent rights, and no such rights
* are granted under this license.
*
* Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
* Copyright (c) 2002-2014, Professor Benoit Macq
* Copyright (c) 2003-2007, Francois-Olivier Devaux
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 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 OWNER 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 <stdio.h>
#include <math.h>
#include <string.h>
#include "openjpeg.h"
#include "index.h"
/* ------------------------------------------------------------------------------------ */
/**
Write a structured index to a file
@param cstr_info Codestream information
@param index Index filename
@return Returns 0 if successful, returns 1 otherwise
*/
int write_index_file(opj_codestream_info_t *cstr_info, char *index)
{
int tileno, compno, layno, resno, precno, pack_nb, x, y;
FILE *stream = NULL;
double total_disto = 0;
/* UniPG>> */
int tilepartno;
char disto_on, numpix_on;
#ifdef USE_JPWL
if (!strcmp(index, JPWL_PRIVATEINDEX_NAME)) {
return 0;
}
#endif /* USE_JPWL */
/* <<UniPG */
if (!cstr_info) {
return 1;
}
stream = fopen(index, "w");
if (!stream) {
fprintf(stderr, "failed to open index file [%s] for writing\n", index);
return 1;
}
if (cstr_info->tile[0].distotile) {
disto_on = 1;
} else {
disto_on = 0;
}
if (cstr_info->tile[0].numpix) {
numpix_on = 1;
} else {
numpix_on = 0;
}
fprintf(stream, "%d %d\n", cstr_info->image_w, cstr_info->image_h);
fprintf(stream, "%d\n", cstr_info->prog);
fprintf(stream, "%d %d\n", cstr_info->tile_x, cstr_info->tile_y);
fprintf(stream, "%d %d\n", cstr_info->tw, cstr_info->th);
fprintf(stream, "%d\n", cstr_info->numcomps);
fprintf(stream, "%d\n", cstr_info->numlayers);
fprintf(stream, "%d\n", cstr_info->numdecompos[0]); /* based on component 0 */
for (resno = cstr_info->numdecompos[0]; resno >= 0; resno--) {
fprintf(stream, "[%d,%d] ",
(1 << cstr_info->tile[0].pdx[resno]),
(1 << cstr_info->tile[0].pdx[resno])); /* based on tile 0 and component 0 */
}
fprintf(stream, "\n");
/* UniPG>> */
fprintf(stream, "%d\n", cstr_info->main_head_start);
/* <<UniPG */
fprintf(stream, "%d\n", cstr_info->main_head_end);
fprintf(stream, "%d\n", cstr_info->codestream_size);
fprintf(stream, "\nINFO ON TILES\n");
fprintf(stream, "tileno start_pos end_hd end_tile nbparts");
if (disto_on) {
fprintf(stream, " disto");
}
if (numpix_on) {
fprintf(stream, " nbpix");
}
if (disto_on && numpix_on) {
fprintf(stream, " disto/nbpix");
}
fprintf(stream, "\n");
for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
fprintf(stream, "%4d %9d %9d %9d %9d",
cstr_info->tile[tileno].tileno,
cstr_info->tile[tileno].start_pos,
cstr_info->tile[tileno].end_header,
cstr_info->tile[tileno].end_pos,
cstr_info->tile[tileno].num_tps);
if (disto_on) {
fprintf(stream, " %9e", cstr_info->tile[tileno].distotile);
}
if (numpix_on) {
fprintf(stream, " %9d", cstr_info->tile[tileno].numpix);
}
if (disto_on && numpix_on) {
fprintf(stream, " %9e", cstr_info->tile[tileno].distotile /
cstr_info->tile[tileno].numpix);
}
fprintf(stream, "\n");
}
for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
int start_pos, end_ph_pos, end_pos;
double disto = 0;
int max_numdecompos = 0;
pack_nb = 0;
for (compno = 0; compno < cstr_info->numcomps; compno++) {
if (max_numdecompos < cstr_info->numdecompos[compno]) {
max_numdecompos = cstr_info->numdecompos[compno];
}
}
fprintf(stream, "\nTILE %d DETAILS\n", tileno);
fprintf(stream,
"part_nb tileno start_pack num_packs start_pos end_tph_pos end_pos\n");
for (tilepartno = 0; tilepartno < cstr_info->tile[tileno].num_tps; tilepartno++)
fprintf(stream, "%4d %9d %9d %9d %9d %11d %9d\n",
tilepartno, tileno,
cstr_info->tile[tileno].tp[tilepartno].tp_start_pack,
cstr_info->tile[tileno].tp[tilepartno].tp_numpacks,
cstr_info->tile[tileno].tp[tilepartno].tp_start_pos,
cstr_info->tile[tileno].tp[tilepartno].tp_end_header,
cstr_info->tile[tileno].tp[tilepartno].tp_end_pos
);
if (cstr_info->prog == LRCP) { /* LRCP */
fprintf(stream,
"LRCP\npack_nb tileno layno resno compno precno start_pos end_ph_pos end_pos");
if (disto_on) {
fprintf(stream, " disto");
}
fprintf(stream, "\n");
for (layno = 0; layno < cstr_info->numlayers; layno++) {
for (resno = 0; resno < max_numdecompos + 1; resno++) {
for (compno = 0; compno < cstr_info->numcomps; compno++) {
int prec_max;
if (resno > cstr_info->numdecompos[compno]) {
break;
}
prec_max = cstr_info->tile[tileno].pw[resno] *
cstr_info->tile[tileno].ph[resno];
for (precno = 0; precno < prec_max; precno++) {
start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
disto = cstr_info->tile[tileno].packet[pack_nb].disto;
fprintf(stream, "%4d %6d %7d %5d %6d %6d %6d %6d %7d",
pack_nb, tileno, layno, resno, compno, precno, start_pos, end_ph_pos, end_pos);
if (disto_on) {
fprintf(stream, " %8e", disto);
}
fprintf(stream, "\n");
total_disto += disto;
pack_nb++;
}
}
}
}
} /* LRCP */
else if (cstr_info->prog == RLCP) { /* RLCP */
fprintf(stream,
"RLCP\npack_nb tileno resno layno compno precno start_pos end_ph_pos end_pos\n");
if (disto_on) {
fprintf(stream, " disto");
}
fprintf(stream, "\n");
for (resno = 0; resno < max_numdecompos + 1; resno++) {
for (layno = 0; layno < cstr_info->numlayers; layno++) {
for (compno = 0; compno < cstr_info->numcomps; compno++) {
int prec_max;
if (resno > cstr_info->numdecompos[compno]) {
break;
}
prec_max = cstr_info->tile[tileno].pw[resno] *
cstr_info->tile[tileno].ph[resno];
for (precno = 0; precno < prec_max; precno++) {
start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
disto = cstr_info->tile[tileno].packet[pack_nb].disto;
fprintf(stream, "%4d %6d %5d %7d %6d %6d %9d %9d %7d",
pack_nb, tileno, resno, layno, compno, precno, start_pos, end_ph_pos, end_pos);
if (disto_on) {
fprintf(stream, " %8e", disto);
}
fprintf(stream, "\n");
total_disto += disto;
pack_nb++;
}
}
}
}
} /* RLCP */
else if (cstr_info->prog == RPCL) { /* RPCL */
fprintf(stream,
"RPCL\npack_nb tileno resno precno compno layno start_pos end_ph_pos end_pos");
if (disto_on) {
fprintf(stream, " disto");
}
fprintf(stream, "\n");
for (resno = 0; resno < max_numdecompos + 1; resno++) {
int numprec = cstr_info->tile[tileno].pw[resno] *
cstr_info->tile[tileno].ph[resno];
for (precno = 0; precno < numprec; precno++) {
/* I suppose components have same XRsiz, YRsiz */
int x0 = cstr_info->tile_Ox + tileno - (int)floor((float)tileno /
(float)cstr_info->tw) * cstr_info->tw * cstr_info->tile_x;
int y0 = cstr_info->tile_Ox + (int)floor((float)tileno /
(float)cstr_info->tw) * cstr_info->tile_y;
int x1 = x0 + cstr_info->tile_x;
int y1 = y0 + cstr_info->tile_y;
for (compno = 0; compno < cstr_info->numcomps; compno++) {
int pcnx = cstr_info->tile[tileno].pw[resno];
int pcx = (int) pow(2, cstr_info->tile[tileno].pdx[resno] +
cstr_info->numdecompos[compno] - resno);
int pcy = (int) pow(2, cstr_info->tile[tileno].pdy[resno] +
cstr_info->numdecompos[compno] - resno);
int precno_x = precno - (int) floor((float)precno / (float)pcnx) * pcnx;
int precno_y = (int) floor((float)precno / (float)pcnx);
if (resno > cstr_info->numdecompos[compno]) {
break;
}
for (y = y0; y < y1; y++) {
if (precno_y * pcy == y) {
for (x = x0; x < x1; x++) {
if (precno_x * pcx == x) {
for (layno = 0; layno < cstr_info->numlayers; layno++) {
start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
disto = cstr_info->tile[tileno].packet[pack_nb].disto;
fprintf(stream, "%4d %6d %5d %6d %6d %7d %9d %9d %7d",
pack_nb, tileno, resno, precno, compno, layno, start_pos, end_ph_pos, end_pos);
if (disto_on) {
fprintf(stream, " %8e", disto);
}
fprintf(stream, "\n");
total_disto += disto;
pack_nb++;
}
}
}/* x = x0..x1 */
}
} /* y = y0..y1 */
} /* precno */
} /* compno */
} /* resno */
} /* RPCL */
else if (cstr_info->prog == PCRL) { /* PCRL */
/* I suppose components have same XRsiz, YRsiz */
int x0 = cstr_info->tile_Ox + tileno - (int)floor((float)tileno /
(float)cstr_info->tw) * cstr_info->tw * cstr_info->tile_x;
int y0 = cstr_info->tile_Ox + (int)floor((float)tileno /
(float)cstr_info->tw) * cstr_info->tile_y;
int x1 = x0 + cstr_info->tile_x;
int y1 = y0 + cstr_info->tile_y;
/* Count the maximum number of precincts */
int max_numprec = 0;
for (resno = 0; resno < max_numdecompos + 1; resno++) {
int numprec = cstr_info->tile[tileno].pw[resno] *
cstr_info->tile[tileno].ph[resno];
if (numprec > max_numprec) {
max_numprec = numprec;
}
}
fprintf(stream,
"PCRL\npack_nb tileno precno compno resno layno start_pos end_ph_pos end_pos");
if (disto_on) {
fprintf(stream, " disto");
}
fprintf(stream, "\n");
for (precno = 0; precno < max_numprec; precno++) {
for (compno = 0; compno < cstr_info->numcomps; compno++) {
for (resno = 0; resno < cstr_info->numdecompos[compno] + 1; resno++) {
int numprec = cstr_info->tile[tileno].pw[resno] *
cstr_info->tile[tileno].ph[resno];
int pcnx = cstr_info->tile[tileno].pw[resno];
int pcx = (int) pow(2, cstr_info->tile[tileno].pdx[resno] +
cstr_info->numdecompos[compno] - resno);
int pcy = (int) pow(2, cstr_info->tile[tileno].pdy[resno] +
cstr_info->numdecompos[compno] - resno);
int precno_x = precno - (int) floor((float)precno / (float)pcnx) * pcnx;
int precno_y = (int) floor((float)precno / (float)pcnx);
if (precno >= numprec) {
continue;
}
for (y = y0; y < y1; y++) {
if (precno_y * pcy == y) {
for (x = x0; x < x1; x++) {
if (precno_x * pcx == x) {
for (layno = 0; layno < cstr_info->numlayers; layno++) {
start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
disto = cstr_info->tile[tileno].packet[pack_nb].disto;
fprintf(stream, "%4d %6d %6d %6d %5d %7d %9d %9d %7d",
pack_nb, tileno, precno, compno, resno, layno, start_pos, end_ph_pos, end_pos);
if (disto_on) {
fprintf(stream, " %8e", disto);
}
fprintf(stream, "\n");
total_disto += disto;
pack_nb++;
}
}
}/* x = x0..x1 */
}
} /* y = y0..y1 */
} /* resno */
} /* compno */
} /* precno */
} /* PCRL */
else { /* CPRL */
/* Count the maximum number of precincts */
int max_numprec = 0;
for (resno = 0; resno < max_numdecompos + 1; resno++) {
int numprec = cstr_info->tile[tileno].pw[resno] *
cstr_info->tile[tileno].ph[resno];
if (numprec > max_numprec) {
max_numprec = numprec;
}
}
fprintf(stream,
"CPRL\npack_nb tileno compno precno resno layno start_pos end_ph_pos end_pos");
if (disto_on) {
fprintf(stream, " disto");
}
fprintf(stream, "\n");
for (compno = 0; compno < cstr_info->numcomps; compno++) {
/* I suppose components have same XRsiz, YRsiz */
int x0 = cstr_info->tile_Ox + tileno - (int)floor((float)tileno /
(float)cstr_info->tw) * cstr_info->tw * cstr_info->tile_x;
int y0 = cstr_info->tile_Ox + (int)floor((float)tileno /
(float)cstr_info->tw) * cstr_info->tile_y;
int x1 = x0 + cstr_info->tile_x;
int y1 = y0 + cstr_info->tile_y;
for (precno = 0; precno < max_numprec; precno++) {
for (resno = 0; resno < cstr_info->numdecompos[compno] + 1; resno++) {
int numprec = cstr_info->tile[tileno].pw[resno] *
cstr_info->tile[tileno].ph[resno];
int pcnx = cstr_info->tile[tileno].pw[resno];
int pcx = (int) pow(2, cstr_info->tile[tileno].pdx[resno] +
cstr_info->numdecompos[compno] - resno);
int pcy = (int) pow(2, cstr_info->tile[tileno].pdy[resno] +
cstr_info->numdecompos[compno] - resno);
int precno_x = precno - (int) floor((float)precno / (float)pcnx) * pcnx;
int precno_y = (int) floor((float)precno / (float)pcnx);
if (precno >= numprec) {
continue;
}
for (y = y0; y < y1; y++) {
if (precno_y * pcy == y) {
for (x = x0; x < x1; x++) {
if (precno_x * pcx == x) {
for (layno = 0; layno < cstr_info->numlayers; layno++) {
start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
disto = cstr_info->tile[tileno].packet[pack_nb].disto;
fprintf(stream, "%4d %6d %6d %6d %5d %7d %9d %9d %7d",
pack_nb, tileno, compno, precno, resno, layno, start_pos, end_ph_pos, end_pos);
if (disto_on) {
fprintf(stream, " %8e", disto);
}
fprintf(stream, "\n");
total_disto += disto;
pack_nb++;
}
}
}/* x = x0..x1 */
}
} /* y = y0..y1 */
} /* resno */
} /* precno */
} /* compno */
} /* CPRL */
} /* tileno */
if (disto_on) {
fprintf(stream, "%8e\n", cstr_info->D_max); /* SE max */
fprintf(stream, "%.8e\n", total_disto); /* SE totale */
}
/* UniPG>> */
/* print the markers' list */
if (cstr_info->marknum) {
fprintf(stream, "\nMARKER LIST\n");
fprintf(stream, "%d\n", cstr_info->marknum);
fprintf(stream, "type\tstart_pos length\n");
for (x = 0; x < cstr_info->marknum; x++) {
fprintf(stream, "%X\t%9d %9d\n", cstr_info->marker[x].type,
cstr_info->marker[x].pos, cstr_info->marker[x].len);
}
}
/* <<UniPG */
fclose(stream);
fprintf(stderr, "Generated index file %s\n", index);
return 0;
}

54
src/bin/jpwl/index.h Normal file
View File

@ -0,0 +1,54 @@
/*
* The copyright in this software is being made available under the 2-clauses
* BSD License, included below. This software may be subject to other third
* party and contributor rights, including patent rights, and no such rights
* are granted under this license.
*
* Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
* Copyright (c) 2002-2014, Professor Benoit Macq
* Copyright (c) 2003-2007, Francois-Olivier Devaux
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 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 OWNER 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.
*/
#ifndef __J2K_INDEX_H
#define __J2K_INDEX_H
#ifdef __cplusplus
extern "C" {
#endif
/**
Write a structured index to a file
@param cstr_info Codestream information
@param index Index filename
@return Returns 0 if successful, returns 1 otherwise
*/
int write_index_file(opj_codestream_info_t *cstr_info, char *index);
#ifdef __cplusplus
}
#endif
#endif /* __J2K_INDEX_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,895 @@
/*
* The copyright in this software is being made available under the 2-clauses
* BSD License, included below. This software may be subject to other third
* party and contributor rights, including patent rights, and no such rights
* are granted under this license.
*
* Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
* Copyright (c) 2002-2014, Professor Benoit Macq
* Copyright (c) 2001-2003, David Janssens
* Copyright (c) 2002-2003, Yannick Verschueren
* Copyright (c) 2003-2007, Francois-Olivier Devaux
* Copyright (c) 2003-2014, Antonin Descampe
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* Copyright (c) 2006-2007, Parvatha Elangovan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 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 OWNER 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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#ifdef _WIN32
#include "windirent.h"
#else
#include <dirent.h>
#endif /* _WIN32 */
#ifdef _WIN32
#include <windows.h>
#else
#include <strings.h>
#define _stricmp strcasecmp
#define _strnicmp strncasecmp
#endif /* _WIN32 */
#include "opj_apps_config.h"
#include "openjpeg.h"
#include "opj_getopt.h"
#include "convert.h"
#include "index.h"
#ifdef OPJ_HAVE_LIBLCMS2
#include <lcms2.h>
#endif
#ifdef OPJ_HAVE_LIBLCMS1
#include <lcms.h>
#endif
#include "color.h"
#include "format_defs.h"
typedef struct dircnt {
/** Buffer for holding images read from Directory*/
char *filename_buf;
/** Pointer to the buffer*/
char **filename;
} dircnt_t;
typedef struct img_folder {
/** The directory path of the folder containing input images*/
char *imgdirpath;
/** Output format*/
const char *out_format;
/** Enable option*/
char set_imgdir;
/** Enable Cod Format for output*/
char set_out_format;
} img_fol_t;
void decode_help_display(void)
{
fprintf(stdout, "HELP for j2k_to_image\n----\n\n");
fprintf(stdout, "- the -h option displays this help information on screen\n\n");
/* UniPG>> */
fprintf(stdout, "List of parameters for the JPEG 2000 "
#ifdef USE_JPWL
"+ JPWL "
#endif /* USE_JPWL */
"decoder:\n");
/* <<UniPG */
fprintf(stdout, "\n");
fprintf(stdout, "\n");
fprintf(stdout, " -ImgDir \n");
fprintf(stdout, " Image file Directory path \n");
fprintf(stdout, " -OutFor \n");
fprintf(stdout, " REQUIRED only if -ImgDir is used\n");
fprintf(stdout, " Need to specify only format without filename <BMP> \n");
fprintf(stdout,
" Currently accepts PGM, PPM, PNM, PGX, PNG, BMP, TIF, RAW and TGA formats\n");
fprintf(stdout, " -i <compressed file>\n");
fprintf(stdout,
" REQUIRED only if an Input image directory not specified\n");
fprintf(stdout,
" Currently accepts J2K-files, JP2-files and JPT-files. The file type\n");
fprintf(stdout, " is identified based on its suffix.\n");
fprintf(stdout, " -o <decompressed file>\n");
fprintf(stdout, " REQUIRED\n");
fprintf(stdout,
" Currently accepts PGM, PPM, PNM, PGX, PNG, BMP, TIF, RAW and TGA files\n");
fprintf(stdout,
" Binary data is written to the file (not ascii). If a PGX\n");
fprintf(stdout,
" filename is given, there will be as many output files as there are\n");
fprintf(stdout,
" components: an indice starting from 0 will then be appended to the\n");
fprintf(stdout,
" output filename, just before the \"pgx\" extension. If a PGM filename\n");
fprintf(stdout,
" is given and there are more than one component, only the first component\n");
fprintf(stdout, " will be written to the file.\n");
fprintf(stdout, " -r <reduce factor>\n");
fprintf(stdout,
" Set the number of highest resolution levels to be discarded. The\n");
fprintf(stdout,
" image resolution is effectively divided by 2 to the power of the\n");
fprintf(stdout,
" number of discarded levels. The reduce factor is limited by the\n");
fprintf(stdout,
" smallest total number of decomposition levels among tiles.\n");
fprintf(stdout, " -l <number of quality layers to decode>\n");
fprintf(stdout,
" Set the maximum number of quality layers to decode. If there are\n");
fprintf(stdout,
" less quality layers than the specified number, all the quality layers\n");
fprintf(stdout, " are decoded.\n");
fprintf(stdout, " -x \n");
fprintf(stdout, " Create an index file *.Idx (-x index_name.Idx) \n");
fprintf(stdout, "\n");
/* UniPG>> */
#ifdef USE_JPWL
fprintf(stdout, " -W <options>\n");
fprintf(stdout,
" Activates the JPWL correction capability, if the codestream complies.\n");
fprintf(stdout,
" Options can be a comma separated list of <param=val> tokens:\n");
fprintf(stdout, " c, c=numcomps\n");
fprintf(stdout,
" numcomps is the number of expected components in the codestream\n");
fprintf(stdout, " (search of first EPB rely upon this, default is %d)\n",
JPWL_EXPECTED_COMPONENTS);
#endif /* USE_JPWL */
/* <<UniPG */
fprintf(stdout, "\n");
}
/* -------------------------------------------------------------------------- */
int get_num_images(char *imgdirpath)
{
DIR *dir;
struct dirent* content;
int num_images = 0;
/*Reading the input images from given input directory*/
dir = opendir(imgdirpath);
if (!dir) {
fprintf(stderr, "Could not open Folder %s\n", imgdirpath);
return 0;
}
while ((content = readdir(dir)) != NULL) {
if (strcmp(".", content->d_name) == 0 || strcmp("..", content->d_name) == 0) {
continue;
}
num_images++;
}
return num_images;
}
int load_images(dircnt_t *dirptr, char *imgdirpath)
{
DIR *dir;
struct dirent* content;
int i = 0;
/*Reading the input images from given input directory*/
dir = opendir(imgdirpath);
if (!dir) {
fprintf(stderr, "Could not open Folder %s\n", imgdirpath);
return 1;
} else {
fprintf(stderr, "Folder opened successfully\n");
}
while ((content = readdir(dir)) != NULL) {
if (strcmp(".", content->d_name) == 0 || strcmp("..", content->d_name) == 0) {
continue;
}
strcpy(dirptr->filename[i], content->d_name);
i++;
}
return 0;
}
int get_file_format(char *filename)
{
unsigned int i;
static const char *extension[] = {"pgx", "pnm", "pgm", "ppm", "bmp", "tif", "raw", "tga", "png", "j2k", "jp2", "jpt", "j2c", "jpc" };
static const int format[] = { PGX_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, BMP_DFMT, TIF_DFMT, RAW_DFMT, TGA_DFMT, PNG_DFMT, J2K_CFMT, JP2_CFMT, JPT_CFMT, J2K_CFMT, J2K_CFMT };
char * ext = strrchr(filename, '.');
if (ext == NULL) {
return -1;
}
ext++;
if (ext) {
for (i = 0; i < sizeof(format) / sizeof(*format); i++) {
if (_strnicmp(ext, extension[i], 3) == 0) {
return format[i];
}
}
}
return -1;
}
char get_next_file(int imageno, dircnt_t *dirptr, img_fol_t *img_fol,
opj_dparameters_t *parameters)
{
char image_filename[OPJ_PATH_LEN], infilename[OPJ_PATH_LEN],
outfilename[OPJ_PATH_LEN], temp_ofname[OPJ_PATH_LEN];
char *temp_p, temp1[OPJ_PATH_LEN] = "";
strcpy(image_filename, dirptr->filename[imageno]);
fprintf(stderr, "File Number %d \"%s\"\n", imageno, image_filename);
parameters->decod_format = get_file_format(image_filename);
if (parameters->decod_format == -1) {
return 1;
}
sprintf(infilename, "%s/%s", img_fol->imgdirpath, image_filename);
strncpy(parameters->infile, infilename, sizeof(infilename));
/*Set output file*/
strcpy(temp_ofname, strtok(image_filename, "."));
while ((temp_p = strtok(NULL, ".")) != NULL) {
strcat(temp_ofname, temp1);
sprintf(temp1, ".%s", temp_p);
}
if (img_fol->set_out_format == 1) {
sprintf(outfilename, "%s/%s.%s", img_fol->imgdirpath, temp_ofname,
img_fol->out_format);
strncpy(parameters->outfile, outfilename, sizeof(outfilename));
}
return 0;
}
/* -------------------------------------------------------------------------- */
int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,
img_fol_t *img_fol, char *indexfilename)
{
/* parse the command line */
int totlen, c;
opj_option_t long_option[] = {
{"ImgDir", REQ_ARG, NULL, 'y'},
{"OutFor", REQ_ARG, NULL, 'O'},
};
const char optlist[] = "i:o:r:l:x:"
/* UniPG>> */
#ifdef USE_JPWL
"W:"
#endif /* USE_JPWL */
/* <<UniPG */
"h" ;
totlen = sizeof(long_option);
img_fol->set_out_format = 0;
do {
c = opj_getopt_long(argc, argv, optlist, long_option, totlen);
if (c == -1) {
break;
}
switch (c) {
case 'i': { /* input file */
char *infile = opj_optarg;
parameters->decod_format = get_file_format(infile);
switch (parameters->decod_format) {
case J2K_CFMT:
case JP2_CFMT:
case JPT_CFMT:
break;
default:
fprintf(stderr,
"!! Unrecognized format for infile : %s [accept only *.j2k, *.jp2, *.jpc or *.jpt] !!\n\n",
infile);
return 1;
}
strncpy(parameters->infile, infile, sizeof(parameters->infile) - 1);
}
break;
/* ----------------------------------------------------- */
case 'o': { /* output file */
char *outfile = opj_optarg;
parameters->cod_format = get_file_format(outfile);
switch (parameters->cod_format) {
case PGX_DFMT:
case PXM_DFMT:
case BMP_DFMT:
case TIF_DFMT:
case RAW_DFMT:
case TGA_DFMT:
case PNG_DFMT:
break;
default:
fprintf(stderr,
"Unknown output format image %s [only *.pnm, *.pgm, *.ppm, *.pgx, *.bmp, *.tif, *.raw or *.tga]!! \n",
outfile);
return 1;
}
strncpy(parameters->outfile, outfile, sizeof(parameters->outfile) - 1);
}
break;
/* ----------------------------------------------------- */
case 'O': { /* output format */
char outformat[50];
char *of = opj_optarg;
sprintf(outformat, ".%s", of);
img_fol->set_out_format = 1;
parameters->cod_format = get_file_format(outformat);
switch (parameters->cod_format) {
case PGX_DFMT:
img_fol->out_format = "pgx";
break;
case PXM_DFMT:
img_fol->out_format = "ppm";
break;
case BMP_DFMT:
img_fol->out_format = "bmp";
break;
case TIF_DFMT:
img_fol->out_format = "tif";
break;
case RAW_DFMT:
img_fol->out_format = "raw";
break;
case TGA_DFMT:
img_fol->out_format = "raw";
break;
case PNG_DFMT:
img_fol->out_format = "png";
break;
default:
fprintf(stderr,
"Unknown output format image %s [only *.pnm, *.pgm, *.ppm, *.pgx, *.bmp, *.tif, *.raw or *.tga]!! \n",
outformat);
return 1;
break;
}
}
break;
/* ----------------------------------------------------- */
case 'r': { /* reduce option */
sscanf(opj_optarg, "%d", &parameters->cp_reduce);
}
break;
/* ----------------------------------------------------- */
case 'l': { /* layering option */
sscanf(opj_optarg, "%d", &parameters->cp_layer);
}
break;
/* ----------------------------------------------------- */
case 'h': /* display an help description */
decode_help_display();
return 1;
/* ------------------------------------------------------ */
case 'y': { /* Image Directory path */
img_fol->imgdirpath = (char*)malloc(strlen(opj_optarg) + 1);
strcpy(img_fol->imgdirpath, opj_optarg);
img_fol->set_imgdir = 1;
}
break;
/* ----------------------------------------------------- */
case 'x': { /* Creation of index file */
char *index = opj_optarg;
strncpy(indexfilename, index, OPJ_PATH_LEN);
}
break;
/* ----------------------------------------------------- */
/* UniPG>> */
#ifdef USE_JPWL
case 'W': { /* activate JPWL correction */
char *token = NULL;
token = strtok(opj_optarg, ",");
while (token != NULL) {
/* search expected number of components */
if (*token == 'c') {
static int compno;
compno = JPWL_EXPECTED_COMPONENTS; /* predefined no. of components */
if (sscanf(token, "c=%d", &compno) == 1) {
/* Specified */
if ((compno < 1) || (compno > 256)) {
fprintf(stderr, "ERROR -> invalid number of components c = %d\n", compno);
return 1;
}
parameters->jpwl_exp_comps = compno;
} else if (!strcmp(token, "c")) {
/* default */
parameters->jpwl_exp_comps = compno; /* auto for default size */
} else {
fprintf(stderr, "ERROR -> invalid components specified = %s\n", token);
return 1;
};
}
/* search maximum number of tiles */
if (*token == 't') {
static int tileno;
tileno = JPWL_MAXIMUM_TILES; /* maximum no. of tiles */
if (sscanf(token, "t=%d", &tileno) == 1) {
/* Specified */
if ((tileno < 1) || (tileno > JPWL_MAXIMUM_TILES)) {
fprintf(stderr, "ERROR -> invalid number of tiles t = %d\n", tileno);
return 1;
}
parameters->jpwl_max_tiles = tileno;
} else if (!strcmp(token, "t")) {
/* default */
parameters->jpwl_max_tiles = tileno; /* auto for default size */
} else {
fprintf(stderr, "ERROR -> invalid tiles specified = %s\n", token);
return 1;
};
}
/* next token or bust */
token = strtok(NULL, ",");
};
parameters->jpwl_correct = OPJ_TRUE;
fprintf(stdout, "JPWL correction capability activated\n");
fprintf(stdout, "- expecting %d components\n", parameters->jpwl_exp_comps);
}
break;
#endif /* USE_JPWL */
/* <<UniPG */
/* ----------------------------------------------------- */
default:
fprintf(stderr, "WARNING -> this option is not valid \"-%c %s\"\n", c,
opj_optarg);
break;
}
} while (c != -1);
/* check for possible errors */
if (img_fol->set_imgdir == 1) {
if (!(parameters->infile[0] == 0)) {
fprintf(stderr, "Error: options -ImgDir and -i cannot be used together !!\n");
return 1;
}
if (img_fol->set_out_format == 0) {
fprintf(stderr,
"Error: When -ImgDir is used, -OutFor <FORMAT> must be used !!\n");
fprintf(stderr,
"Only one format allowed! Valid format PGM, PPM, PNM, PGX, BMP, TIF, RAW and TGA!!\n");
return 1;
}
if (!((parameters->outfile[0] == 0))) {
fprintf(stderr, "Error: options -ImgDir and -o cannot be used together !!\n");
return 1;
}
} else {
if ((parameters->infile[0] == 0) || (parameters->outfile[0] == 0)) {
fprintf(stderr, "Example: %s -i image.j2k -o image.pgm\n", argv[0]);
fprintf(stderr, " Try: %s -h\n", argv[0]);
return 1;
}
}
return 0;
}
/* -------------------------------------------------------------------------- */
/**
sample error callback expecting a FILE* client object
*/
void error_callback(const char *msg, void *client_data)
{
FILE *stream = (FILE*)client_data;
fprintf(stream, "[ERROR] %s", msg);
}
/**
sample warning callback expecting a FILE* client object
*/
void warning_callback(const char *msg, void *client_data)
{
FILE *stream = (FILE*)client_data;
fprintf(stream, "[WARNING] %s", msg);
}
/**
sample debug callback expecting no client object
*/
void info_callback(const char *msg, void *client_data)
{
(void)client_data;
fprintf(stdout, "[INFO] %s", msg);
}
/* -------------------------------------------------------------------------- */
int main(int argc, char **argv)
{
opj_dparameters_t parameters; /* decompression parameters */
img_fol_t img_fol;
opj_event_mgr_t event_mgr; /* event manager */
opj_image_t *image = NULL;
FILE *fsrc = NULL;
unsigned char *src = NULL;
int file_length;
int num_images;
int i, imageno;
dircnt_t *dirptr = NULL;
opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */
opj_cio_t *cio = NULL;
opj_codestream_info_t cstr_info; /* Codestream information structure */
char indexfilename[OPJ_PATH_LEN]; /* index file name */
/* configure the event callbacks (not required) */
memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
event_mgr.error_handler = error_callback;
event_mgr.warning_handler = warning_callback;
event_mgr.info_handler = info_callback;
/* set decoding parameters to default values */
opj_set_default_decoder_parameters(&parameters);
/* Initialize indexfilename and img_fol */
*indexfilename = 0;
memset(&img_fol, 0, sizeof(img_fol_t));
/* parse input and get user encoding parameters */
if (parse_cmdline_decoder(argc, argv, &parameters, &img_fol,
indexfilename) == 1) {
return 1;
}
/* Initialize reading of directory */
if (img_fol.set_imgdir == 1) {
num_images = get_num_images(img_fol.imgdirpath);
dirptr = (dircnt_t*)malloc(sizeof(dircnt_t));
if (dirptr) {
dirptr->filename_buf = (char*)malloc(num_images * OPJ_PATH_LEN * sizeof(
char)); /* Stores at max 10 image file names*/
dirptr->filename = (char**) malloc(num_images * sizeof(char*));
if (!dirptr->filename_buf) {
return 1;
}
for (i = 0; i < num_images; i++) {
dirptr->filename[i] = dirptr->filename_buf + i * OPJ_PATH_LEN;
}
}
if (load_images(dirptr, img_fol.imgdirpath) == 1) {
return 1;
}
if (num_images == 0) {
fprintf(stdout, "Folder is empty\n");
return 1;
}
} else {
num_images = 1;
}
/*Encoding image one by one*/
for (imageno = 0; imageno < num_images ; imageno++) {
image = NULL;
fprintf(stderr, "\n");
if (img_fol.set_imgdir == 1) {
if (get_next_file(imageno, dirptr, &img_fol, &parameters)) {
fprintf(stderr, "skipping file...\n");
continue;
}
}
/* read the input file and put it in memory */
/* ---------------------------------------- */
fsrc = fopen(parameters.infile, "rb");
if (!fsrc) {
fprintf(stderr, "ERROR -> failed to open %s for reading\n", parameters.infile);
return 1;
}
fseek(fsrc, 0, SEEK_END);
file_length = ftell(fsrc);
fseek(fsrc, 0, SEEK_SET);
src = (unsigned char *) malloc(file_length);
if (fread(src, 1, file_length, fsrc) != (size_t)file_length) {
free(src);
fclose(fsrc);
fprintf(stderr,
"\nERROR: fread return a number of element different from the expected.\n");
return 1;
}
fclose(fsrc);
/* decode the code-stream */
/* ---------------------- */
switch (parameters.decod_format) {
case J2K_CFMT: {
/* JPEG-2000 codestream */
/* get a decoder handle */
dinfo = opj_create_decompress(CODEC_J2K);
/* catch events using our callbacks and give a local context */
opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
/* setup the decoder decoding parameters using user parameters */
opj_setup_decoder(dinfo, &parameters);
/* open a byte stream */
cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
/* decode the stream and fill the image structure */
if (*indexfilename) { /* If need to extract codestream information*/
image = opj_decode_with_info(dinfo, cio, &cstr_info);
} else {
image = opj_decode(dinfo, cio);
}
if (!image) {
fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
opj_destroy_decompress(dinfo);
opj_cio_close(cio);
free(src);
return 1;
}
/* close the byte stream */
opj_cio_close(cio);
/* Write the index to disk */
if (*indexfilename) {
opj_bool bSuccess;
bSuccess = write_index_file(&cstr_info, indexfilename);
if (bSuccess) {
fprintf(stderr, "Failed to output index file\n");
}
}
}
break;
case JP2_CFMT: {
/* JPEG 2000 compressed image data */
/* get a decoder handle */
dinfo = opj_create_decompress(CODEC_JP2);
/* catch events using our callbacks and give a local context */
opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
/* setup the decoder decoding parameters using the current image and user parameters */
opj_setup_decoder(dinfo, &parameters);
/* open a byte stream */
cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
/* decode the stream and fill the image structure */
if (*indexfilename) { /* If need to extract codestream information*/
image = opj_decode_with_info(dinfo, cio, &cstr_info);
} else {
image = opj_decode(dinfo, cio);
}
if (!image) {
fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
opj_destroy_decompress(dinfo);
opj_cio_close(cio);
free(src);
return 1;
}
/* close the byte stream */
opj_cio_close(cio);
/* Write the index to disk */
if (*indexfilename) {
opj_bool bSuccess;
bSuccess = write_index_file(&cstr_info, indexfilename);
if (bSuccess) {
fprintf(stderr, "Failed to output index file\n");
}
}
}
break;
case JPT_CFMT: {
/* JPEG 2000, JPIP */
/* get a decoder handle */
dinfo = opj_create_decompress(CODEC_JPT);
/* catch events using our callbacks and give a local context */
opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
/* setup the decoder decoding parameters using user parameters */
opj_setup_decoder(dinfo, &parameters);
/* open a byte stream */
cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
/* decode the stream and fill the image structure */
if (*indexfilename) { /* If need to extract codestream information*/
image = opj_decode_with_info(dinfo, cio, &cstr_info);
} else {
image = opj_decode(dinfo, cio);
}
if (!image) {
fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
opj_destroy_decompress(dinfo);
opj_cio_close(cio);
free(src);
return 1;
}
/* close the byte stream */
opj_cio_close(cio);
/* Write the index to disk */
if (*indexfilename) {
opj_bool bSuccess;
bSuccess = write_index_file(&cstr_info, indexfilename);
if (bSuccess) {
fprintf(stderr, "Failed to output index file\n");
}
}
}
break;
default:
fprintf(stderr, "skipping file..\n");
continue;
}
/* free the memory containing the code-stream */
free(src);
src = NULL;
if (image->color_space == CLRSPC_SYCC) {
color_sycc_to_rgb(image);
}
if (image->icc_profile_buf) {
#if defined(OPJ_HAVE_LIBLCMS1) || defined(OPJ_HAVE_LIBLCMS2)
color_apply_icc_profile(image);
#endif
free(image->icc_profile_buf);
image->icc_profile_buf = NULL;
image->icc_profile_len = 0;
}
/* create output image */
/* ------------------- */
switch (parameters.cod_format) {
case PXM_DFMT: /* PNM PGM PPM */
if (imagetopnm(image, parameters.outfile)) {
fprintf(stdout, "Outfile %s not generated\n", parameters.outfile);
} else {
fprintf(stdout, "Generated Outfile %s\n", parameters.outfile);
}
break;
case PGX_DFMT: /* PGX */
if (imagetopgx(image, parameters.outfile)) {
fprintf(stdout, "Outfile %s not generated\n", parameters.outfile);
} else {
fprintf(stdout, "Generated Outfile %s\n", parameters.outfile);
}
break;
case BMP_DFMT: /* BMP */
if (imagetobmp(image, parameters.outfile)) {
fprintf(stdout, "Outfile %s not generated\n", parameters.outfile);
} else {
fprintf(stdout, "Generated Outfile %s\n", parameters.outfile);
}
break;
#ifdef OPJ_HAVE_LIBTIFF
case TIF_DFMT: /* TIFF */
if (imagetotif(image, parameters.outfile)) {
fprintf(stdout, "Outfile %s not generated\n", parameters.outfile);
} else {
fprintf(stdout, "Generated Outfile %s\n", parameters.outfile);
}
break;
#endif /* OPJ_HAVE_LIBTIFF */
case RAW_DFMT: /* RAW */
if (imagetoraw(image, parameters.outfile)) {
fprintf(stdout, "Error generating raw file. Outfile %s not generated\n",
parameters.outfile);
} else {
fprintf(stdout, "Successfully generated Outfile %s\n", parameters.outfile);
}
break;
case TGA_DFMT: /* TGA */
if (imagetotga(image, parameters.outfile)) {
fprintf(stdout, "Error generating tga file. Outfile %s not generated\n",
parameters.outfile);
} else {
fprintf(stdout, "Successfully generated Outfile %s\n", parameters.outfile);
}
break;
#ifdef OPJ_HAVE_LIBPNG
case PNG_DFMT: /* PNG */
if (imagetopng(image, parameters.outfile)) {
fprintf(stdout, "Error generating png file. Outfile %s not generated\n",
parameters.outfile);
} else {
fprintf(stdout, "Successfully generated Outfile %s\n", parameters.outfile);
}
break;
#endif /* OPJ_HAVE_LIBPNG */
/* Can happen if output file is TIFF or PNG
* and OPJ_HAVE_LIBTIF or OPJ_HAVE_LIBPNG is undefined
*/
default:
fprintf(stderr, "Outfile %s not generated\n", parameters.outfile);
}
/* free remaining structures */
if (dinfo) {
opj_destroy_decompress(dinfo);
}
/* free codestream information structure */
if (*indexfilename) {
opj_destroy_cstr_info(&cstr_info);
}
/* free image data structure */
opj_image_destroy(image);
}
return 0;
}
/*end main*/

680
src/bin/jpwl/windirent.h Normal file
View File

@ -0,0 +1,680 @@
/*
* uce-dirent.h - operating system independent dirent implementation
*
* Copyright (C) 1998-2002 Toni Ronkko
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* ``Software''), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*
* May 28 1998, Toni Ronkko <tronkko@messi.uku.fi>
*
* $Id: uce-dirent.h,v 1.7 2002/05/13 10:48:35 tr Exp $
*
* $Log: uce-dirent.h,v $
* Revision 1.7 2002/05/13 10:48:35 tr
* embedded some source code directly to the header so that no source
* modules need to be included in the MS Visual C project using the
* interface, removed all the dependencies to other headers of the `uce'
* library so that the header can be made public
*
* Revision 1.6 2002/04/12 16:22:04 tr
* Unified Compiling Environment (UCE) replaced `std' library
*
* Revision 1.5 2001/07/20 16:33:40 tr
* moved to `std' library and re-named defines accordingly
*
* Revision 1.4 2001/07/10 16:47:18 tronkko
* revised comments
*
* Revision 1.3 2001/01/11 13:16:43 tr
* using ``uce-machine.h'' for finding out defines such as `FREEBSD'
*
* Revision 1.2 2000/10/08 16:00:41 tr
* copy of FreeBSD man page
*
* Revision 1.1 2000/07/10 05:53:16 tr
* Initial revision
*
* Revision 1.2 1998/07/19 18:29:14 tr
* Added error reporting capabilities and some asserts.
*
* Revision 1.1 1998/07/04 16:27:51 tr
* Initial revision
*
*
* MSVC 1.0 scans automatic dependencies incorrectly when your project
* contains this very header. The problem is that MSVC cannot handle
* include directives inside #if..#endif block those are never entered.
* Since this header ought to compile in many different operating systems,
* there had to be several conditional blocks that are compiled only in
* operating systems for what they were designed for. MSVC 1.0 cannot
* handle inclusion of sys/dir.h in a part that is compiled only in Apollo
* operating system. To fix the problem you need to insert DIR.H into
* SYSINCL.DAT located in MSVC\BIN directory and restart visual C++.
* Consult manuals for more informaton about the problem.
*
* Since many UNIX systems have dirent.h we assume to have one also.
* However, if your UNIX system does not have dirent.h you can download one
* for example at: http://ftp.uni-mannheim.de/ftp/GNU/dirent/dirent.tar.gz.
* You can also see if you have one of dirent.h, direct.h, dir.h, ndir.h,
* sys/dir.h and sys/ndir.h somewhere. Try defining HAVE_DIRENT_H,
* HAVE_DIRECT_H, HAVE_DIR_H, HAVE_NDIR_H, HAVE_SYS_DIR_H and
* HAVE_SYS_NDIR_H according to the files found.
*/
#ifndef DIRENT_H
#define DIRENT_H
#define DIRENT_H_INCLUDED
/* find out platform */
#if defined(MSDOS) /* MS-DOS */
#elif defined(__MSDOS__) /* Turbo C/Borland */
# define MSDOS
#elif defined(__DOS__) /* Watcom */
# define MSDOS
#endif
#if defined(WIN32) /* MS-Windows */
#elif defined(__NT__) /* Watcom */
# define WIN32
#elif defined(_WIN32) /* Microsoft */
# define WIN32
#elif defined(__WIN32__) /* Borland */
# define WIN32
#endif
/*
* See what kind of dirent interface we have unless autoconf has already
* determinated that.
*/
#if !defined(HAVE_DIRENT_H) && !defined(HAVE_DIRECT_H) && !defined(HAVE_SYS_DIR_H) && !defined(HAVE_NDIR_H) && !defined(HAVE_SYS_NDIR_H) && !defined(HAVE_DIR_H)
# if defined(_MSC_VER) /* Microsoft C/C++ */
/* no dirent.h */
# elif defined(__MINGW32__) /* MinGW */
/* no dirent.h */
# elif defined(__BORLANDC__) /* Borland C/C++ */
# define HAVE_DIRENT_H
# define VOID_CLOSEDIR
# elif defined(__TURBOC__) /* Borland Turbo C */
/* no dirent.h */
# elif defined(__WATCOMC__) /* Watcom C/C++ */
# define HAVE_DIRECT_H
# elif defined(__apollo) /* Apollo */
# define HAVE_SYS_DIR_H
# elif defined(__hpux) /* HP-UX */
# define HAVE_DIRENT_H
# elif (defined(__alpha) || defined(__alpha__)) && !defined(__linux__) /* Alpha OSF1 */
# error "not implemented"
# elif defined(__sgi) /* Silicon Graphics */
# define HAVE_DIRENT_H
# elif defined(sun) || defined(__sun) /* Sun Solaris */
# define HAVE_DIRENT_H
# elif defined(__FreeBSD__) /* FreeBSD */
# define HAVE_DIRENT_H
# elif defined(__linux__) /* Linux */
# define HAVE_DIRENT_H
# elif defined(__GNUC__) /* GNU C/C++ */
# define HAVE_DIRENT_H
# else
# error "not implemented"
# endif
#endif
/* include proper interface headers */
#if defined(HAVE_DIRENT_H)
# include <dirent.h>
# ifdef FREEBSD
# define NAMLEN(dp) ((int)((dp)->d_namlen))
# else
# define NAMLEN(dp) ((int)(strlen((dp)->d_name)))
# endif
#elif defined(HAVE_NDIR_H)
# include <ndir.h>
# define NAMLEN(dp) ((int)((dp)->d_namlen))
#elif defined(HAVE_SYS_NDIR_H)
# include <sys/ndir.h>
# define NAMLEN(dp) ((int)((dp)->d_namlen))
#elif defined(HAVE_DIRECT_H)
# include <direct.h>
# define NAMLEN(dp) ((int)((dp)->d_namlen))
#elif defined(HAVE_DIR_H)
# include <dir.h>
# define NAMLEN(dp) ((int)((dp)->d_namlen))
#elif defined(HAVE_SYS_DIR_H)
# include <sys/types.h>
# include <sys/dir.h>
# ifndef dirent
# define dirent direct
# endif
# define NAMLEN(dp) ((int)((dp)->d_namlen))
#elif defined(MSDOS) || defined(WIN32)
/* figure out type of underlaying directory interface to be used */
# if defined(WIN32)
# define DIRENT_WIN32_INTERFACE
# elif defined(MSDOS)
# define DIRENT_MSDOS_INTERFACE
# else
# error "missing native dirent interface"
# endif
/*** WIN32 specifics ***/
# if defined(DIRENT_WIN32_INTERFACE)
# include <windows.h>
# if !defined(DIRENT_MAXNAMLEN)
# define DIRENT_MAXNAMLEN (MAX_PATH)
# endif
/*** MS-DOS specifics ***/
# elif defined(DIRENT_MSDOS_INTERFACE)
# include <dos.h>
/* Borland defines file length macros in dir.h */
# if defined(__BORLANDC__)
# include <dir.h>
# if !defined(DIRENT_MAXNAMLEN)
# define DIRENT_MAXNAMLEN ((MAXFILE)+(MAXEXT))
# endif
# if !defined(_find_t)
# define _find_t find_t
# endif
/* Turbo C defines ffblk structure in dir.h */
# elif defined(__TURBOC__)
# include <dir.h>
# if !defined(DIRENT_MAXNAMLEN)
# define DIRENT_MAXNAMLEN ((MAXFILE)+(MAXEXT))
# endif
# define DIRENT_USE_FFBLK
/* MSVC */
# elif defined(_MSC_VER)
# if !defined(DIRENT_MAXNAMLEN)
# define DIRENT_MAXNAMLEN (12)
# endif
/* Watcom */
# elif defined(__WATCOMC__)
# if !defined(DIRENT_MAXNAMLEN)
# if defined(__OS2__) || defined(__NT__)
# define DIRENT_MAXNAMLEN (255)
# else
# define DIRENT_MAXNAMLEN (12)
# endif
# endif
# endif
# endif
/*** generic MS-DOS and MS-Windows stuff ***/
# if !defined(NAME_MAX) && defined(DIRENT_MAXNAMLEN)
# define NAME_MAX DIRENT_MAXNAMLEN
# endif
# if NAME_MAX < DIRENT_MAXNAMLEN
# error "assertion failed: NAME_MAX >= DIRENT_MAXNAMLEN"
# endif
/*
* Substitute for real dirent structure. Note that `d_name' field is a
* true character array although we have it copied in the implementation
* dependent data. We could save some memory if we had declared `d_name'
* as a pointer referring the name within implementation dependent data.
* We have not done that since some code may rely on sizeof(d_name) to be
* something other than four. Besides, directory entries are typically so
* small that it takes virtually no time to copy them from place to place.
*/
typedef struct dirent {
char d_name[NAME_MAX + 1];
/*** Operating system specific part ***/
# if defined(DIRENT_WIN32_INTERFACE) /*WIN32*/
WIN32_FIND_DATA data;
# elif defined(DIRENT_MSDOS_INTERFACE) /*MSDOS*/
# if defined(DIRENT_USE_FFBLK)
struct ffblk data;
# else
struct _find_t data;
# endif
# endif
} dirent;
/* DIR substitute structure containing directory name. The name is
* essential for the operation of ``rewinndir'' function. */
typedef struct DIR {
char *dirname; /* directory being scanned */
dirent current; /* current entry */
int dirent_filled; /* is current un-processed? */
/*** Operating system specific part ***/
# if defined(DIRENT_WIN32_INTERFACE)
HANDLE search_handle;
# elif defined(DIRENT_MSDOS_INTERFACE)
# endif
} DIR;
# ifdef __cplusplus
extern "C" {
# endif
/* supply prototypes for dirent functions */
static DIR *opendir(const char *dirname);
static struct dirent *readdir(DIR *dirp);
static int closedir(DIR *dirp);
static void rewinddir(DIR *dirp);
/*
* Implement dirent interface as static functions so that the user does not
* need to change his project in any way to use dirent function. With this
* it is sufficient to include this very header from source modules using
* dirent functions and the functions will be pulled in automatically.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
/* use ffblk instead of _find_t if requested */
#if defined(DIRENT_USE_FFBLK)
# define _A_ARCH (FA_ARCH)
# define _A_HIDDEN (FA_HIDDEN)
# define _A_NORMAL (0)
# define _A_RDONLY (FA_RDONLY)
# define _A_SUBDIR (FA_DIREC)
# define _A_SYSTEM (FA_SYSTEM)
# define _A_VOLID (FA_LABEL)
# define _dos_findnext(dest) findnext(dest)
# define _dos_findfirst(name,flags,dest) findfirst(name,dest,flags)
#endif
static int _initdir(DIR *p);
static const char *_getdirname(const struct dirent *dp);
static void _setdirname(struct DIR *dirp);
/*
* <function name="opendir">
* <intro>open directory stream for reading
* <syntax>DIR *opendir (const char *dirname);
*
* <desc>Open named directory stream for read and return pointer to the
* internal working area that is used for retrieving individual directory
* entries. The internal working area has no fields of your interest.
*
* <ret>Returns a pointer to the internal working area or NULL in case the
* directory stream could not be opened. Global `errno' variable will set
* in case of error as follows:
*
* <table>
* [EACESS |Permission denied.
* [EMFILE |Too many open files used by the process.
* [ENFILE |Too many open files in system.
* [ENOENT |Directory does not exist.
* [ENOMEM |Insufficient memory.
* [ENOTDIR |dirname does not refer to directory. This value is not
* reliable on MS-DOS and MS-Windows platforms. Many
* implementations return ENOENT even when the name refers to a
* file.]
* </table>
* </function>
*/
static DIR *opendir(const char *dirname)
{
DIR *dirp;
assert(dirname != NULL);
dirp = (DIR*)malloc(sizeof(struct DIR));
if (dirp != NULL) {
char *p;
/* allocate room for directory name */
dirp->dirname = (char*) malloc(strlen(dirname) + 1 + strlen("\\*.*"));
if (dirp->dirname == NULL) {
/* failed to duplicate directory name. errno set by malloc() */
free(dirp);
return NULL;
}
/* Copy directory name while appending directory separator and "*.*".
* Directory separator is not appended if the name already ends with
* drive or directory separator. Directory separator is assumed to be
* '/' or '\' and drive separator is assumed to be ':'. */
strcpy(dirp->dirname, dirname);
p = strchr(dirp->dirname, '\0');
if (dirp->dirname < p &&
*(p - 1) != '\\' && *(p - 1) != '/' && *(p - 1) != ':') {
strcpy(p++, "\\");
}
# ifdef DIRENT_WIN32_INTERFACE
strcpy(p, "*"); /*scan files with and without extension in win32*/
# else
strcpy(p, "*.*"); /*scan files with and without extension in DOS*/
# endif
/* open stream */
if (_initdir(dirp) == 0) {
/* initialization failed */
free(dirp->dirname);
free(dirp);
return NULL;
}
}
return dirp;
}
/*
* <function name="readdir">
* <intro>read a directory entry
* <syntax>struct dirent *readdir (DIR *dirp);
*
* <desc>Read individual directory entry and return pointer to a structure
* containing the name of the entry. Individual directory entries returned
* include normal files, sub-directories, pseudo-directories "." and ".."
* and also volume labels, hidden files and system files in MS-DOS and
* MS-Windows. You might want to use stat(2) function to determinate which
* one are you dealing with. Many dirent implementations already contain
* equivalent information in dirent structure but you cannot depend on
* this.
*
* The dirent structure contains several system dependent fields that
* generally have no interest to you. The only interesting one is char
* d_name[] that is also portable across different systems. The d_name
* field contains the name of the directory entry without leading path.
* While d_name is portable across different systems the actual storage
* capacity of d_name varies from system to system and there is no portable
* way to find out it at compile time as different systems define the
* capacity of d_name with different macros and some systems do not define
* capacity at all (besides actual declaration of the field). If you really
* need to find out storage capacity of d_name then you might want to try
* NAME_MAX macro. The NAME_MAX is defined in POSIX standard although
* there are many MS-DOS and MS-Windows implementations those do not define
* it. There are also systems that declare d_name as "char d_name[1]" and
* then allocate suitable amount of memory at run-time. Thanks to Alain
* Decamps (Alain.Decamps@advalvas.be) for pointing it out to me.
*
* This all leads to the fact that it is difficult to allocate space
* for the directory names when the very same program is being compiled on
* number of operating systems. Therefore I suggest that you always
* allocate space for directory names dynamically.
*
* <ret>
* Returns a pointer to a structure containing name of the directory entry
* in `d_name' field or NULL if there was an error. In case of an error the
* global `errno' variable will set as follows:
*
* <table>
* [EBADF |dir parameter refers to an invalid directory stream. This value
* is not set reliably on all implementations.]
* </table>
* </function>
*/
static struct dirent *
readdir(DIR *dirp)
{
assert(dirp != NULL);
if (dirp == NULL) {
errno = EBADF;
return NULL;
}
#if defined(DIRENT_WIN32_INTERFACE)
if (dirp->search_handle == INVALID_HANDLE_VALUE) {
/* directory stream was opened/rewound incorrectly or it ended normally */
errno = EBADF;
return NULL;
}
#endif
if (dirp->dirent_filled != 0) {
/*
* Directory entry has already been retrieved and there is no need to
* retrieve a new one. Directory entry will be retrieved in advance
* when the user calls readdir function for the first time. This is so
* because real dirent has separate functions for opening and reading
* the stream whereas Win32 and DOS dirents open the stream
* automatically when we retrieve the first file. Therefore, we have to
* save the first file when opening the stream and later we have to
* return the saved entry when the user tries to read the first entry.
*/
dirp->dirent_filled = 0;
} else {
/* fill in entry and return that */
#if defined(DIRENT_WIN32_INTERFACE)
if (FindNextFile(dirp->search_handle, &dirp->current.data) == FALSE) {
/* Last file has been processed or an error occurred */
FindClose(dirp->search_handle);
dirp->search_handle = INVALID_HANDLE_VALUE;
errno = ENOENT;
return NULL;
}
# elif defined(DIRENT_MSDOS_INTERFACE)
if (_dos_findnext(&dirp->current.data) != 0) {
/* _dos_findnext and findnext will set errno to ENOENT when no
* more entries could be retrieved. */
return NULL;
}
# endif
_setdirname(dirp);
assert(dirp->dirent_filled == 0);
}
return &dirp->current;
}
/*
* <function name="closedir">
* <intro>close directory stream.
* <syntax>int closedir (DIR *dirp);
*
* <desc>Close directory stream opened by the `opendir' function. Close of
* directory stream invalidates the DIR structure as well as previously read
* dirent entry.
*
* <ret>The function typically returns 0 on success and -1 on failure but
* the function may be declared to return void on same systems. At least
* Borland C/C++ and some UNIX implementations use void as a return type.
* The dirent wrapper tries to define VOID_CLOSEDIR whenever closedir is
* known to return nothing. The very same definition is made by the GNU
* autoconf if you happen to use it.
*
* The global `errno' variable will set to EBADF in case of error.
* </function>
*/
static int
closedir(DIR *dirp)
{
int retcode = 0;
/* make sure that dirp points to legal structure */
assert(dirp != NULL);
if (dirp == NULL) {
errno = EBADF;
return -1;
}
/* free directory name and search handles */
if (dirp->dirname != NULL) {
free(dirp->dirname);
}
#if defined(DIRENT_WIN32_INTERFACE)
if (dirp->search_handle != INVALID_HANDLE_VALUE) {
if (FindClose(dirp->search_handle) == FALSE) {
/* Unknown error */
retcode = -1;
errno = EBADF;
}
}
#endif
/* clear dirp structure to make sure that it cannot be used anymore*/
memset(dirp, 0, sizeof(*dirp));
# if defined(DIRENT_WIN32_INTERFACE)
dirp->search_handle = INVALID_HANDLE_VALUE;
# endif
free(dirp);
return retcode;
}
/*
* <function name="rewinddir">
* <intro>rewind directory stream to the beginning
* <syntax>void rewinddir (DIR *dirp);
*
* <desc>Rewind directory stream to the beginning so that the next call of
* readdir() returns the very first directory entry again. However, note
* that next call of readdir() may not return the same directory entry as it
* did in first time. The directory stream may have been affected by newly
* created files.
*
* Almost every dirent implementation ensure that rewinddir will update
* the directory stream to reflect any changes made to the directory entries
* since the previous ``opendir'' or ``rewinddir'' call. Keep an eye on
* this if your program depends on the feature. I know at least one dirent
* implementation where you are required to close and re-open the stream to
* see the changes.
*
* <ret>Returns nothing. If something went wrong while rewinding, you will
* notice it later when you try to retrieve the first directory entry.
*/
static void
rewinddir(DIR *dirp)
{
/* make sure that dirp is legal */
assert(dirp != NULL);
if (dirp == NULL) {
errno = EBADF;
return;
}
assert(dirp->dirname != NULL);
/* close previous stream */
#if defined(DIRENT_WIN32_INTERFACE)
if (dirp->search_handle != INVALID_HANDLE_VALUE) {
if (FindClose(dirp->search_handle) == FALSE) {
/* Unknown error */
errno = EBADF;
}
}
#endif
/* re-open previous stream */
if (_initdir(dirp) == 0) {
/* initialization failed but we cannot deal with error. User will notice
* error later when she tries to retrieve first directory enty. */
/*EMPTY*/;
}
}
/*
* Open native directory stream object and retrieve first file.
* Be sure to close previous stream before opening new one.
*/
static int
_initdir(DIR *dirp)
{
assert(dirp != NULL);
assert(dirp->dirname != NULL);
dirp->dirent_filled = 0;
# if defined(DIRENT_WIN32_INTERFACE)
/* Open stream and retrieve first file */
dirp->search_handle = FindFirstFile(dirp->dirname, &dirp->current.data);
if (dirp->search_handle == INVALID_HANDLE_VALUE) {
/* something went wrong but we don't know what. GetLastError() could
* give us more information about the error, but then we should map
* the error code into errno. */
errno = ENOENT;
return 0;
}
# elif defined(DIRENT_MSDOS_INTERFACE)
if (_dos_findfirst(dirp->dirname,
_A_SUBDIR | _A_RDONLY | _A_ARCH | _A_SYSTEM | _A_HIDDEN,
&dirp->current.data) != 0) {
/* _dos_findfirst and findfirst will set errno to ENOENT when no
* more entries could be retrieved. */
return 0;
}
# endif
/* initialize DIR and it's first entry */
_setdirname(dirp);
dirp->dirent_filled = 1;
return 1;
}
/*
* Return implementation dependent name of the current directory entry.
*/
static const char *
_getdirname(const struct dirent *dp)
{
#if defined(DIRENT_WIN32_INTERFACE)
return dp->data.cFileName;
#elif defined(DIRENT_USE_FFBLK)
return dp->data.ff_name;
#else
return dp->data.name;
#endif
}
/*
* Copy name of implementation dependent directory entry to the d_name field.
*/
static void
_setdirname(struct DIR *dirp)
{
/* make sure that d_name is long enough */
assert(strlen(_getdirname(&dirp->current)) <= NAME_MAX);
strncpy(dirp->current.d_name,
_getdirname(&dirp->current),
NAME_MAX);
dirp->current.d_name[NAME_MAX] = '\0'; /*char d_name[NAME_MAX+1]*/
}
# ifdef __cplusplus
}
# endif
# define NAMLEN(dp) ((int)(strlen((dp)->d_name)))
#else
# error "missing dirent interface"
#endif
#endif /*DIRENT_H*/

View File

@ -0,0 +1,47 @@
# Makefile for the MJ2 codecs of the OpenJPEG library: frames_to_mj2, mj2_to_frames, extract_j2k_from_mj2 and wrap_j2k_in_mj2
set(common_SRCS ${OPENJPEG_SOURCE_DIR}/src/bin/common/opj_getopt.c)
if(WIN32)
if(BUILD_SHARED_LIBS)
add_definitions(-DOPJ_EXPORTS)
else()
add_definitions(-DOPJ_STATIC)
endif()
endif()
# Headers file are located here:
include_directories(
${OPENJPEG_BINARY_DIR}/src/lib/openjp2 # opj_config.h
${OPENJPEG_BINARY_DIR}/src/bin/common # opj_apps_config.h
${OPENJPEG_SOURCE_DIR}/src/lib/openmj2
${OPENJPEG_SOURCE_DIR}/src/bin/common
${LCMS_INCLUDE_DIRNAME}
)
foreach(exe
opj_mj2_wrap
opj_mj2_extract
opj_mj2_decompress
opj_mj2_compress
)
add_definitions(-DOPJ_USE_LEGACY)
add_executable(${exe}
${exe}.c
${common_SRCS}
${MJ2_SRCS}
${OPENJPEG_SOURCE_DIR}/src/bin/common/color.c
)
set_property(
TARGET ${exe}
APPEND PROPERTY COMPILE_DEFINITIONS USE_MJ2
)
target_link_libraries(${exe} ${LCMS_LIBNAME} openmj2)
if(UNIX)
target_link_libraries(${exe} m)
endif()
install(TARGETS ${exe}
DESTINATION ${OPENJPEG_INSTALL_BIN_DIR})
endforeach()

2858
src/bin/mj2/meta_out.c Normal file

File diff suppressed because it is too large Load Diff

14
src/bin/mj2/meta_out.h Normal file
View File

@ -0,0 +1,14 @@
/* meta_out.h */
/* Dump MJ2, JP2 metadata (partial so far) to xml file */
/* Callable from mj2_to_metadata */
/* Contributed to Open JPEG by Glenn Pearson, U.S. National Library of Medicine */
#define BOOL int
#define FALSE 0
#define TRUE 1
void xml_write_init(BOOL n, BOOL t, BOOL r, BOOL d);
int xml_write_struct(FILE *file, FILE *xmlout, opj_mj2_t * movie,
unsigned int sampleframe, char* stringDTD, opj_event_mgr_t *event_mgr);

View File

@ -0,0 +1,349 @@
/* mj2_to_metadata.c */
/* Dump MJ2, JP2 metadata (partial so far) to xml file */
/* Contributed to Open JPEG by Glenn Pearson, contract software developer, U.S. National Library of Medicine.
The base code in this file was developed by the author as part of a video archiving
project for the U.S. National Library of Medicine, Bethesda, MD.
It is the policy of NLM (and U.S. government) to not assert copyright.
A non-exclusive copy of this code has been contributed to the Open JPEG project.
Except for copyright, inclusion of the code within Open JPEG for distribution and use
can be bound by the Open JPEG open-source license and disclaimer, expressed elsewhere.
*/
#include "opj_includes.h"
#include "mj2.h"
#include "mj2_to_metadata.h"
#include <string.h>
#include "opj_getopt.h"
/* -------------------------------------------------------------------------- */
/**
sample error callback expecting a FILE* client object
*/
void error_callback(const char *msg, void *client_data)
{
FILE *stream = (FILE*)client_data;
fprintf(stream, "[ERROR] %s", msg);
}
/**
sample warning callback expecting a FILE* client object
*/
void warning_callback(const char *msg, void *client_data)
{
FILE *stream = (FILE*)client_data;
fprintf(stream, "[WARNING] %s", msg);
}
/**
sample debug callback expecting a FILE* client object
*/
void info_callback(const char *msg, void *client_data)
{
FILE *stream = (FILE*)client_data;
fprintf(stream, "[INFO] %s", msg);
}
/* -------------------------------------------------------------------------- */
/* ------------- */
void help_display()
{
/* "1234567890123456789012345678901234567890123456789012345678901234567890123456789" */
fprintf(stdout, " Help for the 'mj2_to_metadata' Program\n");
fprintf(stdout, " ======================================\n");
fprintf(stdout, "The -h option displays this information on screen.\n\n");
fprintf(stdout,
"mj2_to_metadata generates an XML file from a Motion JPEG 2000 file.\n");
fprintf(stdout,
"The generated XML shows the structural, but not (yet) curatorial,\n");
fprintf(stdout,
"metadata from the movie header and from the JPEG 2000 image and tile\n");
fprintf(stdout,
"headers of a sample frame. Excluded: low-level packed-bits image data.\n\n");
fprintf(stdout, "By Default\n");
fprintf(stdout, "----------\n");
fprintf(stdout,
"The metadata includes the jp2 image and tile headers of the first frame.\n");
fprintf(stdout, "\n");
fprintf(stdout,
"Metadata values are shown in 'raw' form (e.g., hexadecimal) as stored in the\n");
fprintf(stdout,
"file, and, if apt, in a 'derived' form that is more quickly grasped.\n");
fprintf(stdout, "\n");
fprintf(stdout,
"Notes explaining the XML are embedded as terse comments. These include\n");
fprintf(stdout, " meaning of non-obvious tag abbreviations;\n");
fprintf(stdout, " range and precision of valid values;\n");
fprintf(stdout, " interpretations of values, such as enumerations; and\n");
fprintf(stdout, " current implementation limitations.\n");
fprintf(stdout, "\n");
fprintf(stdout,
"The sample-size and chunk-offset tables, each with 1 row per frame, are not reported.\n");
fprintf(stdout, "\n");
fprintf(stdout,
"The file is self-contained and no verification (e.g., against a DTD) is requested.\n");
fprintf(stdout, "\n");
fprintf(stdout, "Required Parameters (except with -h)\n");
fprintf(stdout, "------------------------------------\n");
fprintf(stdout,
"[Caution: file strings that contain spaces should be wrapped with quotes.]\n");
fprintf(stdout,
"-i input.mj2 : where 'input' is any source file name or path.\n");
fprintf(stdout,
" MJ2 files created with 'frames_to_mj2' are supported so far.\n");
fprintf(stdout,
" These are silent, single-track, 'MJ2 Simple Profile' videos.\n");
fprintf(stdout,
"-o output.xml : where 'output' is any destination file name or path.\n");
fprintf(stdout, "\n");
fprintf(stdout, "Optional Parameters\n");
fprintf(stdout, "-------------------\n");
fprintf(stdout, "-h : Display this help information.\n");
fprintf(stdout, "-n : Suppress all mj2_to_metadata notes.\n");
fprintf(stdout,
"-t : Include sample-size and chunk-offset tables.\n");
fprintf(stdout,
"-f n : where n > 0. Include jp2 header info for frame n [default=1].\n");
fprintf(stdout, "-f 0 : No jp2 header info.\n");
fprintf(stdout,
"-r : Suppress all 'raw' data for which a 'derived' form exists.\n");
fprintf(stdout, "-d : Suppress all 'derived' data.\n");
fprintf(stdout,
" (If both -r and -d given, -r will be ignored.)\n");
fprintf(stdout,
"-v string : Verify against the DTD file located by the string.\n");
fprintf(stdout,
" Prepend quoted 'string' with either SYSTEM or PUBLIC keyword.\n");
fprintf(stdout,
" Thus, for the distributed DTD placed in the same directory as\n");
fprintf(stdout,
" the output file: -v \"SYSTEM mj2_to_metadata.dtd\"\n");
fprintf(stdout,
" \"PUBLIC\" is used with an access protocol (e.g., http:) + URL.\n");
/* More to come */
fprintf(stdout, "\n");
/* "1234567890123456789012345678901234567890123456789012345678901234567890123456789" */
}
/* ------------- */
int main(int argc, char *argv[])
{
opj_dinfo_t* dinfo;
opj_event_mgr_t event_mgr; /* event manager */
FILE *file, *xmlout;
/* char xmloutname[50]; */
opj_mj2_t *movie;
char* infile = 0;
char* outfile = 0;
char* s, S1, S2, S3;
int len;
unsigned int sampleframe = 1; /* First frame */
char* stringDTD = NULL;
BOOL notes = TRUE;
BOOL sampletables = FALSE;
BOOL raw = TRUE;
BOOL derived = TRUE;
mj2_dparameters_t parameters;
while (TRUE) {
/* ':' after letter means it takes an argument */
int c = getopt(argc, argv, "i:o:f:v:hntrd");
/* FUTURE: Reserve 'p' for pruning file (which will probably make -t redundant) */
if (c == -1) {
break;
}
switch (c) {
case 'i': /* IN file */
infile = optarg;
s = optarg;
while (*s) {
s++; /* Run to filename end */
}
s--;
S3 = *s;
s--;
S2 = *s;
s--;
S1 = *s;
if ((S1 == 'm' && S2 == 'j' && S3 == '2')
|| (S1 == 'M' && S2 == 'J' && S3 == '2')) {
break;
}
fprintf(stderr, "Input file name must have .mj2 extension, not .%c%c%c.\n", S1,
S2, S3);
return 1;
/* ----------------------------------------------------- */
case 'o': /* OUT file */
outfile = optarg;
while (*outfile) {
outfile++; /* Run to filename end */
}
outfile--;
S3 = *outfile;
outfile--;
S2 = *outfile;
outfile--;
S1 = *outfile;
outfile = optarg;
if ((S1 == 'x' && S2 == 'm' && S3 == 'l')
|| (S1 == 'X' && S2 == 'M' && S3 == 'L')) {
break;
}
fprintf(stderr,
"Output file name must have .xml extension, not .%c%c%c\n", S1, S2, S3);
return 1;
/* ----------------------------------------------------- */
case 'f': /* Choose sample frame. 0 = none */
sscanf(optarg, "%u", &sampleframe);
break;
/* ----------------------------------------------------- */
case 'v': /* Verification by DTD. */
stringDTD = optarg;
/* We will not insist upon last 3 chars being "dtd", since non-file
access protocol may be used. */
if (strchr(stringDTD, '"') != NULL) {
fprintf(stderr,
"-D's string must not contain any embedded double-quote characters.\n");
return 1;
}
if (strncmp(stringDTD, "PUBLIC ", 7) == 0 ||
strncmp(stringDTD, "SYSTEM ", 7) == 0) {
break;
}
fprintf(stderr, "-D's string must start with \"PUBLIC \" or \"SYSTEM \"\n");
return 1;
/* ----------------------------------------------------- */
case 'n': /* Suppress comments */
notes = FALSE;
break;
/* ----------------------------------------------------- */
case 't': /* Show sample size and chunk offset tables */
sampletables = TRUE;
break;
/* ----------------------------------------------------- */
case 'h': /* Display an help description */
help_display();
return 0;
/* ----------------------------------------------------- */
case 'r': /* Suppress raw data */
raw = FALSE;
break;
/* ----------------------------------------------------- */
case 'd': /* Suppress derived data */
derived = FALSE;
break;
/* ----------------------------------------------------- */
default:
return 1;
} /* switch */
} /* while */
if (!raw && !derived) {
raw = TRUE; /* At least one of 'raw' and 'derived' must be true */
}
/* Error messages */
/* -------------- */
if (!infile || !outfile) {
fprintf(stderr,
"Correct usage: mj2_to_metadata -i mj2-file -o xml-file (plus options)\n");
return 1;
}
/* was:
if (argc != 3) {
printf("Bad syntax: Usage: MJ2_to_metadata inputfile.mj2 outputfile.xml\n");
printf("Example: MJ2_to_metadata foreman.mj2 foreman.xml\n");
return 1;
}
*/
len = strlen(infile);
if (infile[0] == ' ') {
infile++; /* There may be a leading blank if user put space after -i */
}
file = fopen(infile, "rb"); /* was: argv[1] */
if (!file) {
fprintf(stderr, "Failed to open %s for reading.\n", infile); /* was: argv[1] */
return 1;
}
len = strlen(outfile);
if (outfile[0] == ' ') {
outfile++; /* There may be a leading blank if user put space after -o */
}
// Checking output file
xmlout = fopen(outfile, "w"); /* was: argv[2] */
if (!xmlout) {
fprintf(stderr, "Failed to open %s for writing.\n", outfile); /* was: argv[2] */
return 1;
}
// Leave it open
/*
configure the event callbacks (not required)
setting of each callback is optional
*/
memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
event_mgr.error_handler = error_callback;
event_mgr.warning_handler = warning_callback;
event_mgr.info_handler = info_callback;
/* get a MJ2 decompressor handle */
dinfo = mj2_create_decompress();
/* catch events using our callbacks and give a local context */
opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
/* setup the decoder decoding parameters using user parameters */
movie = (opj_mj2_t*) dinfo->mj2_handle;
mj2_setup_decoder(dinfo->mj2_handle, &parameters);
if (mj2_read_struct(file, movie)) { // Creating the movie structure
fclose(xmlout);
return 1;
}
xml_write_init(notes, sampletables, raw, derived);
xml_write_struct(file, xmlout, movie, sampleframe, stringDTD, &event_mgr);
fclose(xmlout);
fprintf(stderr, "Metadata correctly extracted to XML file \n");;
/* free remaining structures */
if (dinfo) {
mj2_destroy_decompress((opj_mj2_t*)dinfo->mj2_handle);
}
return 0;
}

View File

@ -0,0 +1,425 @@
<!--
Preliminary DTD for Open JPEG "mj2_to_metadata" function.
Last revised: April 20, 2005
Author: Glenn Pearson, at U.S. National Library of Medicine.
See mj2_to_metadata.c regarding copyright, license, disclaimer status.
While the vocabulary of this DTD is based on the relevant portions of the
ISO/IEC JPEG 200 standard, the detailed representation is the author's own.
It is neither an ISO/IEC nor NLM official or consensus representation.
Furthermore, it deviates from a pure representation of the ISO/IEC standard
in these aspects:
- it is incomplete in a number of ways (which to some extent may be
addressed over time);
- it has extensions for "derived" data and "statistics";
- it is more flexible. That is, some elements are marked as optional
not because they are optional in an MJ2 file, but because reporting
of them is optional based on current or projected mj2_to_metadata
command-line flags.
-->
<!ELEMENT MJ2_File (JP2?, FileType?, MovieBox?)>
<!ELEMENT JP2 EMPTY>
<!ATTLIST JP2 BoxType CDATA #FIXED "jP[space][space]">
<!ATTLIST JP2 Signature CDATA #FIXED "0x0d0a870a">
<!ELEMENT FileType (Brand, MinorVersion, CompatibilityList)>
<!ATTLIST FileType BoxType CDATA #FIXED "ftyp">
<!ELEMENT Brand (#PCDATA)> <!-- 4 characters max -->
<!ELEMENT MinorVersion (#PCDATA)> <!-- 4 chararcters max -->
<!ELEMENT CompatibilityList (CompatibleBrand)*>
<!ATTLIST CompatibilityList Count CDATA #REQUIRED> <!-- Count >= 0 -->
<!ELEMENT CompatibleBrand (#PCDATA)> <!-- 4 characters max -->
<!ELEMENT MovieBox (MovieHeader, Statistics?, Track*)>
<!ATTLIST MovieBox BoxType CDATA #FIXED "moov">
<!ELEMENT MovieHeader (CreationTime, ModificationTime, Timescale, Rate, Duration, Volume, TransformationMatrix)>
<!ATTLIST MovieHeader BoxType CDATA #FIXED "mvhd">
<!ELEMENT CreationTime (InSeconds?,AsLocalTime?)>
<!ELEMENT InSeconds (#PCDATA)>
<!ELEMENT AsLocalTime (#PCDATA)>
<!ELEMENT ModificationTime (InSeconds?,AsLocalTime?)>
<!ELEMENT Timescale (#PCDATA)> <!-- Timescale defines time units in one second -->
<!ELEMENT Rate (AsHex | (AsHex, AsDecimal) | AsDecimal)> <!-- Decimal is Approximation; Optional on input. -->
<!ELEMENT AsHex (#PCDATA)>
<!ELEMENT AsDecimal (#PCDATA)>
<!ELEMENT Duration (InTimeUnits | (InTimeUnits, InSeconds) | InSeconds)> <!-- InSeconds Optional on input. -->
<!ELEMENT InTimeUnits (#PCDATA)>
<!ELEMENT Volume (AsHex | (AsHex, AsDecimal) | AsDecimal)> <!-- hex default = 0x0100 -->
<!-- Fixed 8.8 value of audio volume. Full, normal value is 1.0 (0x0100) -->
<!ELEMENT TransformationMatrix (TMa,TMb,TMu,TMc,TMd,TMv,TMx,TMy,TMw)> <!-- for video -->
<!-- 3 x 3 Video Transformation Matrix {a,b,u,c,d,v,x,y,w}. Required: u=0, v=0, w=1 -->
<!-- Maps decompressed point (p,q) to rendered point (ap + cq + x, bp + dq + y) -->
<!-- Stored as Fixed Point Hex: all are 16.16, except u,v,w are 2.30 -->
<!-- Unity = 0x00010000,0,0,0,0x00010000,0,0,0,0x40000000 -->
<!ELEMENT TMa (#PCDATA)>
<!ELEMENT TMb (#PCDATA)>
<!ELEMENT TMu (#PCDATA)> <!--Always "0x00000000" -->
<!ELEMENT TMc (#PCDATA)>
<!ELEMENT TMd (#PCDATA)>
<!ELEMENT TMv (#PCDATA)> <!--Always "0x00000000" -->
<!ELEMENT TMx (#PCDATA)>
<!ELEMENT TMy (#PCDATA)>
<!ELEMENT TMw (#PCDATA)> <!--Always "0x40000000" -->
<!ELEMENT Statistics (TracksFound)>
<!ELEMENT TracksFound (Video,Audio,Hint)>
<!ELEMENT Video (#PCDATA)>
<!ELEMENT Audio (#PCDATA)>
<!ELEMENT Hint (#PCDATA)>
<!-- For now, output info on at most one video track -->
<!ELEMENT Track (TrackHeader, TrackReferenceContainer?, EditListContainer?, Media, JP2_Frame?)> <!-- JP2_Frame is mj2_to_metadata extension -->
<!ATTLIST Track BoxType CDATA #FIXED "trak">
<!ATTLIST Track Instance CDATA #REQUIRED>
<!ELEMENT TrackHeader (TrackID, TrackLayer?, Volume?, TransformationMatrix?, Width?, Height?)>
<!ATTLIST TrackHeader BoxType CDATA #FIXED "tkhd">
<!-- Not shown here: CreationTime, ModificationTime, Duration. -->
<!-- These 3 fields are reported under MediaHeader below. When reading these 3, -->
<!-- m2j_to_metadata currently doesn't distinguish between TrackHeader and MediaHeader source. -->
<!-- If both found, value read from MediaHeader is used. -->
<!ELEMENT TrackID (#PCDATA)>
<!ELEMENT TrackLayer (#PCDATA)> <!-- front-to-back ordering of video tracks. 0 = normal, -1 is closer, etc. -->
<!-- "Volume" element described above; here it is for particular audio track. Full, normal (default = 0x0100) -->
<!-- "TransformationMatrix" element described above; matrix here is applied before MovieHeader one. -->
<!ELEMENT Width (AsHex | (AsHex, AsDecimal) | AsDecimal)>
<!ELEMENT Height (AsHex | (AsHex, AsDecimal) | AsDecimal)>
<!-- AsHex, AsDecimal already defined above -->
<!-- Width and Height are for the presentation; frames will be scaled to this -->
<!-- /TrackHeader -->
<!ELEMENT TrackReferenceContainer ANY> <!-- TO DO: TrackReferenceContainer 'tref' just used in hint track -->
<!ELEMENT EditListContainer ANY> <!-- TO DO: EditListContainer 'edts', contains EditList 'elst' with media-time, segment-duration, media-rate -->
<!ELEMENT Media (MediaHeader, HandlerReference,MediaInfoContainer)>
<!ATTLIST Media BoxType CDATA #FIXED "mdia">
<!ELEMENT MediaHeader (CreationTime,ModificationTime,Timescale,Duration,Language)>
<!ATTLIST MediaHeader BoxType CDATA #FIXED "mdhd">
<!-- Elements already defined above: CreationTime, ModificationTime, Timescale, Duration -->
<!ELEMENT Language (#PCDATA)> <!-- 3 chars max. There's an enumeration available -->
<!ELEMENT HandlerReference (HandlerType)>
<!ATTLIST HandlerReference BoxType CDATA #FIXED "hdlr">
<!ELEMENT HandlerType (#PCDATA)>
<!ATTLIST HandlerType Code ( vide | soun | hint ) "vide">
<!-- make the media headers multiple? -->
<!ELEMENT MediaInfoContainer ((VideoMediaHeader | SoundMediaHeader | HintMediaHeader), DataInfo, SampleTable)>
<!ATTLIST MediaInfoContainer BoxType CDATA #FIXED "minf">
<!ELEMENT VideoMediaHeader (GraphicsMode, Opcolor)>
<!ATTLIST VideoMediaHeader BoxType CDATA #FIXED "vmhd">
<!ELEMENT GraphicsMode (#PCDATA)>
<!-- Enumerated values of graphics mode: -->
<!-- 0x00 = copy (over existing image); -->
<!-- 0x24 = transparent; 'blue-screen' this image using opcolor; -->
<!-- 0x100 = alpha; alpha-blend this image -->
<!-- 0x101 = whitealpha; alpha-blend this image, which has been blended with white; -->
<!-- 0x102 = blackalpha; alpha-blend this image, which has been blended with black. -->
<!ELEMENT Opcolor (Red,Green,Blue)>
<!ELEMENT Red (#PCDATA)>
<!ELEMENT Green (#PCDATA)>
<!ELEMENT Blue (#PCDATA)>
<!ELEMENT SoundMediaHeader (Balance)>
<!ATTLIST SoundMediaHeader BoxType CDATA #FIXED "smhd">
<!ELEMENT Balance (#PCDATA)>
<!-- Fixed Point 8.8, fixes mono track in stereo space. -->
<!-- 0.0 = center, -1.0 = full left, 1.0 = full right -->
<!ELEMENT HintMediaHeader (MaxPDU_Size, AvgPDU_Size, MaxBitRate, AvgBitRate, SlidingAvgBitRate)>
<!ATTLIST HintMediaHeader BoxType CDATA #FIXED "hmhd">
<!ELEMENT MaxPDU_Size (#PCDATA)>
<!-- Size in bytes of largest PDU in this hint stream. -->
<!ELEMENT AvgPDU_Size (#PCDATA)>
<!-- Average size in bytes of a PDU over the entire presentation. -->
<!ELEMENT MaxBitRate (#PCDATA)>
<!-- Maximum rate in bits per second over any window of 1 second. -->
<!ELEMENT AvgBitRate (#PCDATA)>
<!-- Averate rate in bits per second over the entire presentation. -->
<!ELEMENT SlidingAvgBit (#PCDATA)>
<!-- Maximum rate in bits per second over any window of one minute. -->
<!ELEMENT DataInfo (DataReference)>
<!ATTLIST DataInfo BoxType CDATA #FIXED "dinf">
<!ELEMENT DataReference (DataEntryUrlBox | DataEntryUrnBox )*>
<!ATTLIST DataReference BoxType CDATA #FIXED "dref">
<!ATTLIST DataReference URL_Count CDATA #REQUIRED>
<!ATTLIST DataReference URN_Count CDATA #REQUIRED> <!-- table w. flags, URLs, URNs -->
<!-- // Data structure does not distinguish between single URL, single URN, or DREF table or URLs & URNs.
// We could infer those, but for now just present everything as a DREF table.
-->
<!-- No entries here mean that file is self-contained, as required by Simple Profile. -->
<!ELEMENT DataEntryUrlBox (Location)>
<!ATTLIST DataEntryUrlBox BoxType CDATA #FIXED "url[space]"> <!-- table w. flags, URLs, URNs -->
<!-- Only the first 16 bytes of URL location are recorded in mj2_to_metadata data structure. -->
<!ELEMENT DataEntryUrnBox (Name, Location?)>
<!ATTLIST DataEntryUrnBox BoxType CDATA #FIXED "urn[space]\">
<!-- Only the first 16 bytes each of URN name and optional location are recorded in mj2_to_metadata data structure. -->
<!ELEMENT SampleTable (VisualSampleEntry,TimeToSample,SampleToChunk,SampleSize,ChunkOffset)> <!-- structure doesn't do non-visual sample entry yet -->
<!ATTLIST SampleTable BoxType CDATA #FIXED "stbl"> <!-- to add: entry count -->
<!-- Next are instances of generic SampleDescription BoxType=\"stsd\" -->
<!-- There could be multiple instances of this, but "entry_count" is just a local at read-time.
And it's used wrong, too, as count of just visual type, when it's really all 3 types.
This is referred to as "smj2" within mj2.c -->
<!ELEMENT VisualSampleEntry (WidthAsInteger, HeightAsInteger, HorizontalRes, VerticalRes, CompressorName, Depth, JP2Header?, FieldCoding?, MJP2_Profile?, MJP2_Prefix?, MJP2_SubSampling?, MJP2_OriginalFormat?)>
<!ATTLIST VisualSampleEntry BoxType CDATA #FIXED "mjp2">
<!-- If multiple instances of this, only first is shown here. -->
<!ELEMENT WidthAsInteger (#PCDATA)>
<!ELEMENT HeightAsInteger (#PCDATA)>
<!ELEMENT HorizontalRes (AsHex | (AsHex, AsDecimal) | AsDecimal)>
<!ELEMENT VerticalRes (AsHex | (AsHex, AsDecimal) | AsDecimal)>
<!-- Typical value for both resolution is 72 (0x00480000) -->
<!ELEMENT CompressorName (#PCDATA)>
<!-- Compressor name for debugging. Standard restricts max length to 31 bytes. -->
<!-- Usually blank or \"Motion JPEG2000\" -->
<!ELEMENT Depth (#PCDATA)>
<!-- Depth is: -->
<!-- 0x20: alpha channels present (color or grayscale) -->
<!-- 0x28: grayscale without alpha -->
<!-- 0x18: color without alpha -->
<!-- TODO somewhere: tk->jp2_struct.numcomps -->
<!ELEMENT JP2Header (ImageHeader, ColourSpecification)>
<!ATTLIST JP2Header BoxType CDATA #FIXED "jp2h">
<!ELEMENT ImageHeader (HEIGHT, WIDTH, NC, BPC, C, UnkC, IPR)>
<!ATTLIST ImageHeader BoxType CDATA #FIXED "ihdr">
<!ELEMENT HEIGHT (#PCDATA)> <!-- If 2 fields/frame, total deinterlaced height -->
<!ELEMENT WIDTH (#PCDATA)>
<!ELEMENT NC (#PCDATA)> <!-- number of components -->
<!ELEMENT BPC (AsHex | (AsHex,BitsPerPixel,Signed) | (BitsPerPixel,Signed))>
<!ELEMENT BitsPerPixel (#PCDATA)>
<!ELEMENT Signed (#PCDATA)>
<!ELEMENT C (#PCDATA)> <!-- Compression type. Only "7" defined -->
<!ELEMENT UnkC (#PCDATA)> <!-- Colourspace Unknown. 1 = unknown, 0 = known -->
<!ELEMENT IPR (#PCDATA)> <!-- 1 = frame has Intellectual Prop. box; otherwise 0 -->
<!ELEMENT ColourSpecification (METH, PREC, APPROX, EnumCS)>
<!ATTLIST ColourSpecification BoxType CDATA #FIXED "colr">
<!ELEMENT METH (#PCDATA)> <!-- 1 = EnumCS field; 2 = PROFILE field (not yet generated) -->
<!ELEMENT PREC (#PCDATA)> <!-- precedence must be 0 so far -->
<!ELEMENT APPROX (#PCDATA)> <!-- colourspace approximation must be 0 so far -->
<!ELEMENT EnumCS (#PCDATA)> <!-- Valid enumerated MJ2 colourspaces: 16 (sRGB), 17 (grey sRGB), 18 (YCC) -->
<!-- Following subboxes are optional -->
<!ELEMENT FieldCoding (FieldCount, FieldOrder)>
<!ATTLIST FieldCoding BoxType CDATA #FIXED "fiel">
<!ELEMENT FieldCount (#PCDATA)>
<!-- Must be either 1 or 2 -->
<!ELEMENT FieldOrder (#PCDATA)>
<!-- When FieldCount=2, FieldOrder means: -->
<!-- 0: Field coding unknown -->
<!-- 1: Field with topmost line is stored first in sample; fields are in temporal order -->
<!-- 6: Field with topmost line is stored second in sample; fields are in temporal order -->
<!-- Defaults: FieldCount=1, FieldOrder=0 if FieldCoding box not present -->
<!-- Current implementation doesn't retain whether box was actually present. -->
<!ELEMENT MJP2_Profile (CompatibleBrand*)>
<!ATTLIST MJP2_Profile BoxType CDATA #FIXED "jp2p">
<!ATTLIST MJP2_Profile Count CDATA #REQUIRED>
<!ELEMENT MJP2_Prefix (Data*)>
<!ATTLIST MJP2_Prefix BoxType CDATA #FIXED "jp2x">
<!ATTLIST MJP2_Prefix Count CDATA #REQUIRED>
<!-- We'll probably need better formatting than this -->
<!ELEMENT Data (#PCDATA)> <!-- Multiple. Each entry is single byte -->
<!ELEMENT MJP2_SubSampling (HorizontalSub, VerticalSub, HorizontalOffset, VerticalOffset)>
<!ATTLIST MJP2_SubSampling BoxType CDATA #FIXED "jsub">
<!-- These values are all 1 byte -->
<!-- Typical subsample value is 2 for 4:2:0 -->
<!ELEMENT HorizontalSub (#PCDATA)>
<!ELEMENT VerticalSub (#PCDATA)>
<!ELEMENT HorizontalOffset (#PCDATA)>
<!ELEMENT VerticalOffset (#PCDATA)>
<!ELEMENT MJP2_OriginalFormat (OriginalFieldCount, OriginalFieldOrder)>
<!ATTLIST MJP2_OriginalFormat BoxType CDATA #FIXED "orfo"> <!-- Part III Appx. 2 -->
<!ELEMENT OriginalFieldCount (#PCDATA)>
<!-- In original material before encoding. Must be either 1 or 2 -->
<!ELEMENT OriginalFieldOrder (#PCDATA)>
<!-- When FieldCount=2, FieldOrder means: -->
<!-- 0: Field coding unknown -->
<!-- 11: Topmost line came from the earlier field; -->
<!-- 16: Topmost line came form the later field. -->
<!-- Defaults: FieldCount=1, FieldOrder=0 if FieldCoding box not present -->
<!-- Current implementation doesn't retain whether box was actually present. -->
<!-- mj2_to_metadata's data structure doesn't record Audio and Hint sample data currently. -->
<!-- Within SampleTable: -->
<!ELEMENT TimeToSample (SampleStatistics, SampleEntries)>
<!ATTLIST TimeToSample BoxType CDATA #FIXED "stts">
<!ELEMENT SampleStatistics (TotalSamples)> <!-- Not part of standard -->
<!ELEMENT TotalSamples (#PCDATA)>
<!-- For video, gives the total frames in the track, by summing all entries in the Sample Table -->
<!ELEMENT SampleEntries (Table*)>
<!ATTLIST SampleEntries EntryCount CDATA #REQUIRED>
<!ELEMENT Table EMPTY> <!-- Multiple. Attributes have values -->
<!ATTLIST Table Entry CDATA #REQUIRED>
<!ATTLIST Table SampleCount CDATA #REQUIRED>
<!ATTLIST Table SampleDelta CDATA #REQUIRED>
<!-- Within SampleTable: -->
<!ELEMENT SampleToChunk (FirstChunk,SamplesPerChunk,SampleDescrIndex)>
<!ATTLIST SampleToChunk BoxType CDATA #FIXED "stsc">
<!ATTLIST SampleToChunk Count CDATA #REQUIRED>
<!ELEMENT FirstChunk (#PCDATA)>
<!ELEMENT SamplesPerChunk (#PCDATA)>
<!ELEMENT SampleDescrIndex (#PCDATA)>
<!ELEMENT SampleSize (Sample_Size,Sample_Count,EntrySize*)>
<!ATTLIST SampleSize BoxType CDATA #FIXED "stsz">
<!ELEMENT Sample_Size (#PCDATA)>
<!ELEMENT Sample_Count (#PCDATA)>
<!ELEMENT EntrySize (#PCDATA)> <!-- appears multiply, but only with mj2_to_metadata option -t -->
<!ATTLIST EntrySize Num CDATA #REQUIRED>
<!ELEMENT ChunkOffset (EntryCount, Chunk_Offset*)>
<!ATTLIST ChunkOffset BoxType CDATA #FIXED "stco">
<!ELEMENT EntryCount (#PCDATA)>
<!ELEMENT Chunk_Offset (#PCDATA)> <!-- appears multiply, but only with mj2_to_metadata option -t -->
<!ATTLIST Chunk_Offset Num CDATA #REQUIRED>
<!-- </SampleTable> </MediaInfoContainer> </Media> -->
<!-- TO DO: optional UserData 'udat', can contain multiple Copyright 'cprt' -->
<!-- Optional, and only for Visual Track: given individual frame -->
<!ELEMENT JP2_Frame (MainHeader, TilePartHeaders)>
<!ATTLIST JP2_Frame Num CDATA #REQUIRED>
<!ELEMENT MainHeader (StartOfCodestream,ImageAndFileSize,CodingStyleDefault,QuantizationDefault,QuantizationComponent*,RegionOfInterest?,ProgressionOrderChange*)>
<!ELEMENT StartOfCodestream EMPTY>
<!ATTLIST StartOfCodestream Marker CDATA #FIXED "SOC">
<!ELEMENT ImageAndFileSize (Xsiz,Ysiz,XOsiz,YOsiz,XTsiz,YTsiz,XTOsiz,YTOsiz,Csiz,Component+)>
<!ATTLIST ImageAndFileSize Marker CDATA #FIXED "SIZ">
<!ELEMENT Xsiz (#PCDATA)>
<!ELEMENT Ysiz (#PCDATA)> <!-- Xsiz, Ysiz is the size of the reference grid. -->
<!ELEMENT XOsiz (#PCDATA)>
<!ELEMENT YOsiz (#PCDATA)> <!-- XOsiz, YOsiz are offsets from grid origin to image origin. -->
<!ELEMENT XTsiz (#PCDATA)>
<!ELEMENT YTsiz (#PCDATA)> <!-- XTsiz, YTsiz is the size of one tile with respect to the grid. -->
<!ELEMENT XTOsiz (#PCDATA)>
<!ELEMENT YTOsiz (#PCDATA)> <!-- XTOsiz, YTOsiz are offsets from grid origin to first tile origin. -->
<!ELEMENT Csiz (#PCDATA)> <!-- Csiz is the number of components in the image. -->
<!-- For image components next -->
<!ELEMENT Component (Ssiz,XRsiz,YRsiz,WidthOfData,HeightOfData)>
<!ATTLIST Component Num CDATA #REQUIRED>
<!ELEMENT Ssiz (AsHex | (AsHex,Signed,PrecisionInBits) | (Signed,PrecisionInBits))>
<!-- Signed already defined -->
<!ELEMENT PrecisionInBits (#PCDATA)> <!-- Bits per pixel (bpp) or pixel depth. -->
<!ELEMENT XRsiz (#PCDATA)>
<!ELEMENT YRsiz (#PCDATA)> <!-- XRsiz, YRsiz denote pixel-sample-spacing on the grid, per Part I Annex B. -->
<!ELEMENT WidthOfData (#PCDATA)>
<!ELEMENT HeightOfData (#PCDATA)> <!-- WidthOfData and HeightOfData are calculated values, e.g.: w = roundup((Xsiz - XOsiz)/ XRsiz) -->
<!-- -->
<!ELEMENT CodingStyleDefault (Scod,SGcod,SPcod)>
<!ATTLIST CodingStyleDefault Marker CDATA #FIXED "COD">
<!ELEMENT Scod (#PCDATA)>
<!-- For Scod, specific bits mean (where bit 0 is lowest or rightmost): -->
<!-- bit 0: Defines entropy coder precincts -->
<!-- 0 = (PPx=15, PPy=15); 1 = precincts defined below. -->
<!-- bit 1: 1 = SOP marker may be used; 0 = not. -->
<!-- bit 2: 1 = EPH marker may be used; 0 = not. -->
<!ELEMENT SGcod (ProgressionOrder,NumberOfLayers,MultipleComponentTransformation)>
<!ELEMENT ProgressionOrder (#PCDATA)>
<!-- Defined Progression Order Values are: -->
<!-- 0 = LRCP; 1 = RLCP; 2 = RPCL; 3 = PCRL; 4 = CPRL -->
<!-- where L = "layer", R = "resolution level", C = "component", P = "position". -->
<!ELEMENT NumberOfLayers (#PCDATA)>
<!ELEMENT MultipleComponentTransformation (#PCDATA)>
<!-- For MCT, 0 = none, 1 = transform first 3 components for efficiency, per Part I Annex G -->
<!ELEMENT SPcod (NumberOfDecompositionLevels,CodeblockWidth,CodeblockHeight,CodeblockStyle,Transformation)>
<!ELEMENT NumberOfDecompositionLevels (#PCDATA)>
<!ELEMENT CodeblockWidth (#PCDATA)> <!-- CBW and CBH are non-negative, and summed cannot exceed 8 -->
<!ELEMENT CodeblockHeight (#PCDATA)> <!-- Codeblock dimension is 2^(value + 2) -->
<!ELEMENT CodeblockStyle (#PCDATA)>
<!-- For CodeblockStyle, bits mean (with value 1=feature on, 0=off): -->
<!-- bit 0: Selective arithmetic coding bypass. -->
<!-- bit 1: Reset context probabilities on coding pass boundaries. -->
<!-- bit 2: Termination on each coding pass. -->
<!-- bit 3: Vertically causal context. -->
<!-- bit 4: Predictable termination. -->
<!-- bit 5: Segmentation symbols are used. -->
<!ELEMENT Transformation (#PCDATA)> <!-- For Transformation, 0="9-7 irreversible filter", 1="5-3 reversible filter" -->
<!-- mj2_to_metadata implementation always reports component[0] as using default COD, -->
<!-- and any other component, with main-header style values different from [0], as COC. -->
<!ELEMENT QuantizationDefault (Sqcd,SPqcd)>
<!ATTLIST QuantizationDefault Marker CDATA #FIXED "QCD">
<!ELEMENT Sqcd (AsHex | (AsHex,QuantizationStyle,NumberOfGuardBits) | (QuantizationStyle,NumberOfGuardBits))>
<!ELEMENT QuantizationStyle (#PCDATA)> <!-- Default quantization style for all components. -->
<!-- Quantization style (in Sqcd's low 5 bits) may be: -->
<!-- 0 = No quantization. SPqcd size = 8 bits-->
<!-- 1 = Scalar derived (values signaled for N(L)LL subband only). Use Eq. E.5. SPqcd size = 16. -->
<!-- 2 = Scalar expounded (values signaled for each subband). SPqcd size = 16. -->
<!ELEMENT NumberOfGuardBits (#PCDATA)> <!-- 0-7 guard bits allowed (stored in Sqcd's high 3 bits) -->
<!ELEMENT SPqcd (ReversibleStepSizeValue | QuantizationStepSizeValues )> <!-- TO DO: Irreversible choices -->
<!ELEMENT ReversibleStepSizeValue (DynamicRangeExponent+)>
<!-- Current mj2_to_metadata implementation dumps entire internal table, -->
<!-- until an exponent with zero value is reached. -->
<!-- Exponent epsilon(b) of reversible dynamic range. -->
<!-- Hex value is as stored, in high-order 5 bits. -->
<!ELEMENT DynamicRangeExponent (AsHex | (AsHex, AsDecimal) | AsDecimal)>
<!ATTLIST DynamicRangeExponent Subband CDATA #REQUIRED>
<!ELEMENT QuantizationStepSizeValues (QuantizationValues+, CalculatedExponent*)> <!-- Calculated exponents iff only subband 0 reported -->
<!ELEMENT QuantizationValues (AsHex | (AsHex,Exponent,Mantissa) | (Exponent,Mantissa))>
<!ATTLIST QuantizationValues Subband CDATA #REQUIRED>
<!ELEMENT Exponent (#PCDATA)>
<!ELEMENT Mantissa (#PCDATA)>
<!ELEMENT CalculatedExponent (#PCDATA)>
<!ATTLIST CalculatedExponent Subband CDATA #REQUIRED>
<!-- /QuantizationDefault -->
<!-- mj2_to_metadata implementation always reports component[0] as using default QCD, -->
<!-- and any other component, with main-header quantization values different from [0], as QCC. -->
<!ELEMENT QuantizationComponent (Sqcc,SPqcc)>
<!ATTLIST QuantizationComponent Marker CDATA #FIXED "QCC">
<!ATTLIST QuantizationComponent Component CDATA #REQUIRED>
<!ELEMENT Sqcc (AsHex | (AsHex,QuantizationStyle,NumberOfGuardBits) | (QuantizationStyle,NumberOfGuardBits))>
<!ELEMENT SPqcc (ReversibleStepSizeValue | QuantizationStepSizeValues )> <!-- TO DO: Irreversible choices -->
<!-- /QuantizationComponent -->
<!-- Don't know if MJ2 files can have regions of interest. Assume yes -->
<!ELEMENT RegionOfInterest (Srgn,Crgn,Sprgn)> <!-- Optional in main header, at most 1 per component -->
<!ATTLIST RegionOfInterest Marker CDATA #FIXED "RGN">
<!ELEMENT Srgn (#PCDATA)> <!-- ROI style. Only style=0 defined: Implicit ROI (max. shift) -->
<!ELEMENT Crgn (#PCDATA)> <!-- Zero-based component number. -->
<!ELEMENT SPrgn (#PCDATA)> <!-- Implicit ROI shift, i.e., binary shifting of ROI coefficients above background. -->
<!-- </RegionOfInterest> -->
<!ELEMENT ProgressionOrderChange (Progression+)> <!-- Optional in main header, at most 1 per component (but impl allows more?) -->
<!ATTLIST ProgressionOrderChange Marker CDATA #REQUIRED>
<!ELEMENT Progression (RSpoc,CSpoc,LYEpoc,REpoc,CEpoc,Ppoc)>
<!ATTLIST Progression Num CDATA #REQUIRED>
<!ELEMENT RSpoc (#PCDATA)> <!-- Resolution level index (inclusive) for progression start. Range: 0 to 33 -->
<!ELEMENT CSpoc (#PCDATA)> <!-- Component index (inclusive) for progression start. -->
<!ELEMENT LYEpoc (#PCDATA)> <!-- Layer index (exclusive) for progression end. -->
<!ELEMENT REpoc (#PCDATA)> <!-- Resolution level index (exclusive) for progression end. Range: RSpoc to 33 -->
<!ELEMENT CEpoc (#PCDATA)> <!-- Component index (exclusive) for progression end. Minimum: CSpoc -->
<!ELEMENT Ppoc (#PCDATA)> <!-- Defined Progression Order Values are: -->
<!-- 0 = LRCP; 1 = RLCP; 2 = RPCL; 3 = PCRL; 4 = CPRL -->
<!-- where L = "layer", R = "resolution level", C = "component", P = "position". -->
<!-- </Progression>, </ProgressionOrderChange -->
<!-- /MainHeader -->
<!ELEMENT TilePartHeaders (TilePartHeader+)>
<!ATTLIST TilePartHeaders Count CDATA #REQUIRED>
<!ELEMENT TilePartHeader (StartOfTilePart,CodingStyleDefault,QuantizationDefault,QuantizationComponent*,RegionOfInterest?,ProgressionOrderChange*,StartOfData)>
<!ATTLIST TilePartHeader Num CDATA #REQUIRED>
<!ATTLIST TilePartHeader ID CDATA #REQUIRED>
<!ELEMENT StartOfTilePart EMPTY>
<!ATTLIST StartOfTilePart Marker CDATA #FIXED "SOT">
<!-- CodingStyleDefault, QuantizationDefault, QuantizationComponent already defined -->
<!-- mj2_to_metadata implementation always reports component[0] as using default QCD, -->
<!-- and any other component, with tile-part-header quantization values different from [0], as QCC. -->
<!ELEMENT StartOfData EMPTY> <!-- always empty for now -->
<!ATTLIST StartOfData Marker CDATA #FIXED "SOD">
<!-- Tile-part bitstream, not shown, follows tile-part header and SOD marker. -->
<!-- /TilePartHeader, /TilePartHeaders, /JP2_Frame -->
<!-- </Track> -->
<!-- to come:
<MovieExtends mvek> // possibly not in Simple Profile
<UserDataBox udat> contains <CopyrightBox cprt>
-->
<!-- /MovieBox -->
<!-- To come:
<mdat>
<moof> // probably not in Simple Profile
<free>
<skip>
-->
<!-- </MJ2_File> -->

View File

@ -0,0 +1,9 @@
/* mj2_to_metadata.h */
/* Dump MJ2, JP2 metadata (partial so far) to xml file */
/* Contributed to Open JPEG by Glenn Pearson, U.S. National Library of Medicine */
#define BOOL int
#define FALSE 0
#define TRUE 1
#include "meta_out.h"

View File

@ -0,0 +1,29 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mj2_to_metadata", "mj2_to_metadata.vcproj", "{69BE42AB-E7CE-4DA1-BBD2-39FEA2C91E0B}"
ProjectSection(ProjectDependencies) = postProject
{0B1B7713-35B6-40A7-9BFF-A7D0EB06A8BD} = {0B1B7713-35B6-40A7-9BFF-A7D0EB06A8BD}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibOpenJPEG", "..\LibOpenJPEG.vcproj", "{0B1B7713-35B6-40A7-9BFF-A7D0EB06A8BD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{69BE42AB-E7CE-4DA1-BBD2-39FEA2C91E0B}.Debug|Win32.ActiveCfg = Debug|Win32
{69BE42AB-E7CE-4DA1-BBD2-39FEA2C91E0B}.Debug|Win32.Build.0 = Debug|Win32
{69BE42AB-E7CE-4DA1-BBD2-39FEA2C91E0B}.Release|Win32.ActiveCfg = Release|Win32
{69BE42AB-E7CE-4DA1-BBD2-39FEA2C91E0B}.Release|Win32.Build.0 = Release|Win32
{0B1B7713-35B6-40A7-9BFF-A7D0EB06A8BD}.Debug|Win32.ActiveCfg = Debug|Win32
{0B1B7713-35B6-40A7-9BFF-A7D0EB06A8BD}.Debug|Win32.Build.0 = Debug|Win32
{0B1B7713-35B6-40A7-9BFF-A7D0EB06A8BD}.Release|Win32.ActiveCfg = Release|Win32
{0B1B7713-35B6-40A7-9BFF-A7D0EB06A8BD}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,349 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Name="mj2_to_metadata"
ProjectGUID="{69BE42AB-E7CE-4DA1-BBD2-39FEA2C91E0B}"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\mj2_to_metadata___Win32_Debug0"
IntermediateDirectory=".\mj2_to_metadata___Win32_Debug0"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\mj2_to_metadata___Win32_Debug0/mj2_to_metadata.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../libopenjpeg"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;OPJ_STATIC;_CRT_SECURE_NO_DEPRECATE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
PrecompiledHeaderFile=".\mj2_to_metadata___Win32_Debug0/mj2_to_metadata.pch"
AssemblerListingLocation=".\mj2_to_metadata___Win32_Debug0/"
ObjectFile=".\mj2_to_metadata___Win32_Debug0/"
ProgramDataBaseFileName=".\mj2_to_metadata___Win32_Debug0/"
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="2057"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile=".\mj2_to_metadata___Win32_Debug0/mj2_to_metadata.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
IgnoreDefaultLibraryNames="LIBCMT"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\mj2_to_metadata___Win32_Debug0/mj2_to_metadata.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\mj2_to_metadata___Win32_Debug0/mj2_to_metadata.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/mj2_to_metadata.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="../libopenjpeg"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;OPJ_STATIC;_CRT_SECURE_NO_DEPRECATE"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
PrecompiledHeaderFile=".\Release/mj2_to_metadata.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="true"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="2057"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Release/mj2_to_metadata.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
IgnoreDefaultLibraryNames="libcmtd"
ProgramDatabaseFile=".\Release/mj2_to_metadata.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Release/mj2_to_metadata.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="MJ2"
>
<Filter
Name="MJ2 Header Files"
>
<File
RelativePath="compat\opj_getopt.h"
>
</File>
<File
RelativePath="meta_out.h"
>
</File>
<File
RelativePath="mj2.h"
>
</File>
<File
RelativePath="mj2_convert.h"
>
</File>
<File
RelativePath="mj2_to_metadata.h"
>
</File>
</Filter>
<Filter
Name="MJ2 Source Files"
>
<File
RelativePath="compat\opj_getopt.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="meta_out.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="mj2.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="mj2_convert.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="mj2_to_metadata.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Filter>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

Binary file not shown.

View File

@ -0,0 +1,852 @@
/*
* Copyright (c) 2003-2004, Francois-Olivier Devaux
* Copyright (c) 2002-2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 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 OWNER 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "opj_apps_config.h"
#include "openjpeg.h"
#include "j2k_lib.h"
#include "cio.h"
#include "j2k.h"
#include "jp2.h"
#include "mj2.h"
#include "mj2_convert.h"
#include "opj_getopt.h"
/**
Size of memory first allocated for MOOV box
*/
#define TEMP_BUF 10000
/* -------------------------------------------------------------------------- */
/**
sample error callback expecting a FILE* client object
*/
static void error_callback(const char *msg, void *client_data)
{
FILE *stream = (FILE*)client_data;
fprintf(stream, "[ERROR] %s", msg);
}
/**
sample warning callback expecting a FILE* client object
*/
static void warning_callback(const char *msg, void *client_data)
{
FILE *stream = (FILE*)client_data;
fprintf(stream, "[WARNING] %s", msg);
}
/* -------------------------------------------------------------------------- */
static void help_display()
{
fprintf(stdout, "HELP for frames_to_mj2\n----\n\n");
fprintf(stdout, "- the -h option displays this help information on screen\n\n");
fprintf(stdout, "List of parameters for the MJ2 encoder:\n");
fprintf(stdout, "\n");
fprintf(stdout, "REMARKS:\n");
fprintf(stdout, "---------\n");
fprintf(stdout, "\n");
fprintf
(stdout, "The markers written to the main_header are : SOC SIZ COD QCD COM.\n");
fprintf
(stdout, "COD and QCD never appear in the tile_header.\n");
fprintf(stdout, "\n");
fprintf(stdout, "By default:\n");
fprintf(stdout, "------------\n");
fprintf(stdout, "\n");
fprintf(stdout, " * Lossless\n");
fprintf(stdout, " * 1 tile\n");
fprintf(stdout, " * Size of precinct : 2^15 x 2^15 (means 1 precinct)\n");
fprintf(stdout, " * Size of code-block : 64 x 64\n");
fprintf(stdout, " * Number of resolutions: 6\n");
fprintf(stdout, " * No SOP marker in the codestream\n");
fprintf(stdout, " * No EPH marker in the codestream\n");
fprintf(stdout, " * No sub-sampling in x or y direction\n");
fprintf(stdout, " * No mode switch activated\n");
fprintf(stdout, " * Progression order: LRCP\n");
fprintf(stdout, " * No index file\n");
fprintf(stdout, " * No ROI upshifted\n");
fprintf(stdout, " * No offset of the origin of the image\n");
fprintf(stdout, " * No offset of the origin of the tiles\n");
fprintf(stdout, " * Reversible DWT 5-3\n");
fprintf(stdout, "\n");
fprintf(stdout, "Parameters:\n");
fprintf(stdout, "------------\n");
fprintf(stdout, "\n");
fprintf
(stdout, "Required Parameters (except with -h):\n");
fprintf
(stdout, "-i : source file (-i source.yuv) \n");
fprintf
(stdout, "-o : destination file (-o dest.mj2) \n");
fprintf
(stdout, "Optional Parameters:\n");
fprintf(stdout, "-h : display the help information \n");
fprintf(stdout,
"-r : different compression ratios for successive layers (-r 20,10,5)\n");
fprintf(stdout,
" - The rate specified for each quality level is the desired \n");
fprintf(stdout, " compression factor.\n");
fprintf(stdout, " Example: -r 20,10,1 means quality 1: compress 20x, \n");
fprintf(stdout,
" quality 2: compress 10x and quality 3: compress lossless\n");
fprintf(stdout, " (options -r and -q cannot be used together)\n");
fprintf(stdout, "-q : different psnr for successive layers (-q 30,40,50) \n");
fprintf(stdout, " (options -r and -q cannot be used together)\n");
fprintf(stdout, "-n : number of resolutions (-n 3) \n");
fprintf(stdout, "-b : size of code block (-b 32,32) \n");
fprintf(stdout, "-c : size of precinct (-c 128,128) \n");
fprintf(stdout, "-t : size of tile (-t 512,512) \n");
fprintf
(stdout, "-p : progression order (-p LRCP) [LRCP, RLCP, RPCL, PCRL, CPRL] \n");
fprintf
(stdout, "-s : subsampling factor (-s 2,2) [-s X,Y] \n");
fprintf(stdout, " Remark: subsampling bigger than 2 can produce error\n");
fprintf
(stdout, "-S : write SOP marker before each packet \n");
fprintf
(stdout, "-E : write EPH marker after each header packet \n");
fprintf
(stdout, "-M : mode switch (-M 3) [1=BYPASS(LAZY) 2=RESET 4=RESTART(TERMALL)\n");
fprintf
(stdout, " 8=VSC 16=ERTERM(SEGTERM) 32=SEGMARK(SEGSYM)] \n");
fprintf
(stdout, " Indicate multiple modes by adding their values. \n");
fprintf
(stdout, " Example: RESTART(4) + RESET(2) + SEGMARK(32) = -M 38\n");
fprintf
(stdout, "-R : c=%%d,U=%%d : quantization indices upshifted \n");
fprintf
(stdout, " for component c=%%d [%%d = 0,1,2]\n");
fprintf
(stdout, " with a value of U=%%d [0 <= %%d <= 37] (i.e. -ROI:c=0,U=25) \n");
fprintf
(stdout, "-d : offset of the origin of the image (-d 150,300) \n");
fprintf
(stdout, "-T : offset of the origin of the tiles (-T 100,75) \n");
fprintf(stdout, "-I : use the irreversible DWT 9-7 (-I) \n");
fprintf(stdout, "-W : image width, height and the dx and dy subsampling \n");
fprintf(stdout, " of the Cb and Cr components for YUV files \n");
fprintf(stdout,
" (default is '352,288,2,2' for CIF format's 352x288 and 4:2:0)\n");
fprintf(stdout, "-F : video frame rate (set to 25 by default)\n");
fprintf(stdout, "-D : depth, precision in bits [8 .. 16]; default:8\n");
fprintf(stdout, "-C : comment\n");
fprintf(stdout, "\n");
fprintf(stdout, "IMPORTANT:\n");
fprintf(stdout, "-----------\n");
fprintf(stdout, "\n");
fprintf(stdout, "The index file has the structure below:\n");
fprintf(stdout, "---------------------------------------\n");
fprintf(stdout, "\n");
fprintf(stdout, "Image_height Image_width\n");
fprintf(stdout, "progression order\n");
fprintf(stdout, "Tiles_size_X Tiles_size_Y\n");
fprintf(stdout, "Components_nb\n");
fprintf(stdout, "Layers_nb\n");
fprintf(stdout, "decomposition_levels\n");
fprintf(stdout, "[Precincts_size_X_res_Nr Precincts_size_Y_res_Nr]...\n");
fprintf(stdout, " [Precincts_size_X_res_0 Precincts_size_Y_res_0]\n");
fprintf(stdout, "Main_header_end_position\n");
fprintf(stdout, "Codestream_size\n");
fprintf(stdout,
"Tile_0 start_pos end_Theader end_pos TotalDisto NumPix MaxMSE\n");
fprintf(stdout,
"Tile_1 '' '' '' '' '' ''\n");
fprintf(stdout, "...\n");
fprintf(stdout,
"Tile_Nt '' '' '' '' '' ''\n");
fprintf(stdout,
"Tpacket_0 Tile layer res. comp. prec. start_pos end_pos disto\n");
fprintf(stdout, "...\n");
fprintf(stdout,
"Tpacket_Np '' '' '' '' '' '' '' ''\n");
fprintf(stdout, "MaxDisto\n");
fprintf(stdout, "TotalDisto\n\n");
}
static OPJ_PROG_ORDER give_progression(const char progression[5])
{
if (progression[0] == 'L' && progression[1] == 'R'
&& progression[2] == 'C' && progression[3] == 'P') {
return LRCP;
} else {
if (progression[0] == 'R' && progression[1] == 'L'
&& progression[2] == 'C' && progression[3] == 'P') {
return RLCP;
} else {
if (progression[0] == 'R' && progression[1] == 'P'
&& progression[2] == 'C' && progression[3] == 'L') {
return RPCL;
} else {
if (progression[0] == 'P' && progression[1] == 'C'
&& progression[2] == 'R' && progression[3] == 'L') {
return PCRL;
} else {
if (progression[0] == 'C' && progression[1] == 'P'
&& progression[2] == 'R' && progression[3] == 'L') {
return CPRL;
} else {
return PROG_UNKNOWN;
}
}
}
}
}
}
int main(int argc, char **argv)
{
mj2_cparameters_t mj2_parameters; /* MJ2 compression parameters */
opj_cparameters_t *j2k_parameters; /* J2K compression parameters */
opj_event_mgr_t event_mgr; /* event manager */
opj_cio_t *cio;
int value;
opj_mj2_t *movie;
opj_image_t *img;
int i, j;
char *s, S1, S2, S3;
unsigned char *buf;
int x1, y1, len;
long mdat_initpos, offset;
FILE *mj2file;
int sampleno;
opj_cinfo_t* cinfo;
opj_bool bSuccess;
int numframes;
int prec = 8;/* DEFAULT */
double total_time = 0;
memset(&mj2_parameters, 0, sizeof(mj2_cparameters_t));
/* default value */
/* ------------- */
mj2_parameters.w = 352; /* CIF default value*/
mj2_parameters.h = 288; /* CIF default value*/
mj2_parameters.CbCr_subsampling_dx = 2; /* CIF default value*/
mj2_parameters.CbCr_subsampling_dy = 2; /* CIF default value*/
mj2_parameters.frame_rate = 25;
mj2_parameters.prec = 8; /* DEFAULT */
mj2_parameters.enumcs = ENUMCS_SYCC; /* FIXME: ENUMCS_YUV420 */
mj2_parameters.meth = 1; /* enumerated color space */
/*
configure the event callbacks (not required)
setting of each callback is optionnal
*/
memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
event_mgr.error_handler = error_callback;
event_mgr.warning_handler = warning_callback;
event_mgr.info_handler = NULL;
/* set J2K encoding parameters to default values */
opj_set_default_encoder_parameters(&mj2_parameters.j2k_parameters);
j2k_parameters = &mj2_parameters.j2k_parameters;
/* Create comment for codestream */
if (j2k_parameters->cp_comment == NULL) {
const char comment[] = "Created by OpenJPEG version ";
const size_t clen = strlen(comment);
const char *version = opj_version();
j2k_parameters->cp_comment = (char*)malloc(clen + strlen(version) + 1);
sprintf(j2k_parameters->cp_comment, "%s%s", comment, version);
}
while (1) {
int c = opj_getopt(argc, argv,
"i:o:r:q:f:t:n:c:b:p:s:d:P:S:E:M:R:T:C:I:W:F:D:h");
if (c == -1) {
break;
}
switch (c) {
case 'i': { /* IN fill */
char *infile = opj_optarg;
s = opj_optarg;
while (*s) {
s++;
}
s--;
S3 = *s;
s--;
S2 = *s;
s--;
S1 = *s;
if ((S1 == 'y' && S2 == 'u' && S3 == 'v')
|| (S1 == 'Y' && S2 == 'U' && S3 == 'V')) {
mj2_parameters.decod_format = YUV_DFMT;
} else {
fprintf(stderr,
"!! Unrecognized format for infile : %c%c%c [accept only *.yuv] !!\n\n",
S1, S2, S3);
return 1;
}
strncpy(mj2_parameters.infile, infile, sizeof(mj2_parameters.infile) - 1);
}
break;
/* ----------------------------------------------------- */
case 'o': { /* OUT fill */
char *outfile = opj_optarg;
while (*outfile) {
outfile++;
}
outfile--;
S3 = *outfile;
outfile--;
S2 = *outfile;
outfile--;
S1 = *outfile;
outfile = opj_optarg;
if ((S1 == 'm' && S2 == 'j' && S3 == '2')
|| (S1 == 'M' && S2 == 'J' && S3 == '2')) {
mj2_parameters.cod_format = MJ2_CFMT;
} else {
fprintf(stderr,
"Unknown output format image *.%c%c%c [only *.mj2]!! \n",
S1, S2, S3);
return 1;
}
strncpy(mj2_parameters.outfile, outfile, sizeof(mj2_parameters.outfile) - 1);
}
break;
/* ----------------------------------------------------- */
case 'r': { /* rates rates/distorsion */
float rate;
s = opj_optarg;
while (sscanf(s, "%f", &rate) == 1) {
j2k_parameters->tcp_rates[j2k_parameters->tcp_numlayers] = rate * 2;
j2k_parameters->tcp_numlayers++;
while (*s && *s != ',') {
s++;
}
if (!*s) {
break;
}
s++;
}
j2k_parameters->cp_disto_alloc = 1;
}
break;
/* ----------------------------------------------------- */
case 'q': /* add fixed_quality */
s = opj_optarg;
while (sscanf(s, "%f",
&j2k_parameters->tcp_distoratio[j2k_parameters->tcp_numlayers]) == 1) {
j2k_parameters->tcp_numlayers++;
while (*s && *s != ',') {
s++;
}
if (!*s) {
break;
}
s++;
}
j2k_parameters->cp_fixed_quality = 1;
break;
/* dda */
/* ----------------------------------------------------- */
case 'f': { /* mod fixed_quality (before : -q) */
int *row = NULL, *col = NULL;
int numlayers = 0, numresolution = 0, matrix_width = 0;
s = opj_optarg;
sscanf(s, "%d", &numlayers);
s++;
if (numlayers > 9) {
s++;
}
j2k_parameters->tcp_numlayers = numlayers;
numresolution = j2k_parameters->numresolution;
matrix_width = numresolution * 3;
j2k_parameters->cp_matrice = (int *) malloc(numlayers * matrix_width * sizeof(
int));
s = s + 2;
for (i = 0; i < numlayers; i++) {
row = &j2k_parameters->cp_matrice[i * matrix_width];
col = row;
j2k_parameters->tcp_rates[i] = 1;
sscanf(s, "%d,", &col[0]);
s += 2;
if (col[0] > 9) {
s++;
}
col[1] = 0;
col[2] = 0;
for (j = 1; j < numresolution; j++) {
col += 3;
sscanf(s, "%d,%d,%d", &col[0], &col[1], &col[2]);
s += 6;
if (col[0] > 9) {
s++;
}
if (col[1] > 9) {
s++;
}
if (col[2] > 9) {
s++;
}
}
if (i < numlayers - 1) {
s++;
}
}
j2k_parameters->cp_fixed_alloc = 1;
}
break;
/* ----------------------------------------------------- */
case 't': /* tiles */
sscanf(opj_optarg, "%d,%d", &j2k_parameters->cp_tdx, &j2k_parameters->cp_tdy);
j2k_parameters->tile_size_on = OPJ_TRUE;
break;
/* ----------------------------------------------------- */
case 'n': /* resolution */
sscanf(opj_optarg, "%d", &j2k_parameters->numresolution);
break;
/* ----------------------------------------------------- */
case 'c': { /* precinct dimension */
char sep;
int res_spec = 0;
char *s = opj_optarg;
do {
sep = 0;
sscanf(s, "[%d,%d]%c", &j2k_parameters->prcw_init[res_spec],
&j2k_parameters->prch_init[res_spec], &sep);
j2k_parameters->csty |= 0x01;
res_spec++;
s = strpbrk(s, "]") + 2;
} while (sep == ',');
j2k_parameters->res_spec = res_spec;
}
break;
/* ----------------------------------------------------- */
case 'b': { /* code-block dimension */
int cblockw_init = 0, cblockh_init = 0;
sscanf(opj_optarg, "%d,%d", &cblockw_init, &cblockh_init);
if (cblockw_init * cblockh_init > 4096 || cblockw_init > 1024
|| cblockw_init < 4 || cblockh_init > 1024 || cblockh_init < 4) {
fprintf(stderr,
"!! Size of code_block error (option -b) !!\n\nRestriction :\n"
" * width*height<=4096\n * 4<=width,height<= 1024\n\n");
return 1;
}
j2k_parameters->cblockw_init = cblockw_init;
j2k_parameters->cblockh_init = cblockh_init;
}
break;
/* ----------------------------------------------------- */
case 'p': { /* progression order */
char progression[5];
strncpy(progression, opj_optarg, 5);
j2k_parameters->prog_order = give_progression(progression);
if (j2k_parameters->prog_order == -1) {
fprintf(stderr, "Unrecognized progression order "
"[LRCP, RLCP, RPCL, PCRL, CPRL] !!\n");
return 1;
}
}
break;
/* ----------------------------------------------------- */
case 's': { /* subsampling factor */
if (sscanf(opj_optarg, "%d,%d", &j2k_parameters->subsampling_dx,
&j2k_parameters->subsampling_dy) != 2) {
fprintf(stderr, "'-s' sub-sampling argument error ! [-s dx,dy]\n");
return 1;
}
}
break;
/* ----------------------------------------------------- */
case 'd': { /* coordonnate of the reference grid */
if (sscanf(opj_optarg, "%d,%d", &j2k_parameters->image_offset_x0,
&j2k_parameters->image_offset_y0) != 2) {
fprintf(stderr, "-d 'coordonnate of the reference grid' argument "
"error !! [-d x0,y0]\n");
return 1;
}
}
break;
/* ----------------------------------------------------- */
case 'h': /* Display an help description */
help_display();
return 0;
break;
/* ----------------------------------------------------- */
case 'P': { /* POC */
int numpocs = 0; /* number of progression order change (POC) default 0 */
opj_poc_t *POC = NULL; /* POC : used in case of Progression order change */
char *s = opj_optarg;
POC = j2k_parameters->POC;
while (sscanf(s, "T%d=%d,%d,%d,%d,%d,%4s", &POC[numpocs].tile,
&POC[numpocs].resno0, &POC[numpocs].compno0,
&POC[numpocs].layno1, &POC[numpocs].resno1,
&POC[numpocs].compno1, POC[numpocs].progorder) == 7) {
POC[numpocs].prg1 = give_progression(POC[numpocs].progorder);
numpocs++;
while (*s && *s != '/') {
s++;
}
if (!*s) {
break;
}
s++;
}
j2k_parameters->numpocs = numpocs;
}
break;
/* ------------------------------------------------------ */
case 'S': /* SOP marker */
j2k_parameters->csty |= 0x02;
break;
/* ------------------------------------------------------ */
case 'E': /* EPH marker */
j2k_parameters->csty |= 0x04;
break;
/* ------------------------------------------------------ */
case 'M': /* Mode switch pas tous au point !! */
if (sscanf(opj_optarg, "%d", &value) == 1) {
for (i = 0; i <= 5; i++) {
int cache = value & (1 << i);
if (cache) {
j2k_parameters->mode |= (1 << i);
}
}
}
break;
/* ------------------------------------------------------ */
case 'R': { /* ROI */
if (sscanf(opj_optarg, "OI:c=%d,U=%d", &j2k_parameters->roi_compno,
&j2k_parameters->roi_shift) != 2) {
fprintf(stderr, "ROI error !! [-ROI:c='compno',U='shift']\n");
return 1;
}
}
break;
/* ------------------------------------------------------ */
case 'T': { /* Tile offset */
if (sscanf(opj_optarg, "%d,%d", &j2k_parameters->cp_tx0,
&j2k_parameters->cp_ty0) != 2) {
fprintf(stderr, "-T 'tile offset' argument error !! [-T X0,Y0]");
return 1;
}
}
break;
/* ------------------------------------------------------ */
case 'C': { /* Add a comment */
j2k_parameters->cp_comment = (char*)malloc(strlen(opj_optarg) + 1);
if (j2k_parameters->cp_comment) {
strcpy(j2k_parameters->cp_comment, opj_optarg);
}
}
break;
/* ------------------------------------------------------ */
case 'I': { /* reversible or not */
j2k_parameters->irreversible = 1;
}
break;
/* ------------------------------------------------------ */
case 'W': /* Width and Height and Cb and Cr subsampling in case of YUV format files */
if (sscanf
(opj_optarg, "%d,%d,%d,%d", &mj2_parameters.w, &mj2_parameters.h,
&mj2_parameters.CbCr_subsampling_dx,
&mj2_parameters.CbCr_subsampling_dy) != 4) {
fprintf(stderr, "-W argument error");
return 1;
}
break;
/* ------------------------------------------------------ */
case 'F': /* Video frame rate */
if (sscanf(opj_optarg, "%d", &mj2_parameters.frame_rate) != 1) {
fprintf(stderr, "-F argument error");
return 1;
}
break;
/* ------------------------------------------------------ */
case 'D': /* Depth: the precision */
if (sscanf(opj_optarg, "%d", &prec) != 1) {
prec = 0;
}
break;
default:
return 1;
}
}
/* Error messages */
/* -------------- */
if (!mj2_parameters.cod_format || !mj2_parameters.decod_format) {
fprintf(stderr,
"Usage: %s -i yuv-file -o mj2-file (+ options)\n", argv[0]);
return 1;
}
if (prec < 1 || prec > 16) {
fprintf(stderr, "Error: Depth %d must be in the range 8 .. 16\n", prec);
return 1;
}
if ((j2k_parameters->cp_disto_alloc || j2k_parameters->cp_fixed_alloc ||
j2k_parameters->cp_fixed_quality)
&& (!(j2k_parameters->cp_disto_alloc ^ j2k_parameters->cp_fixed_alloc ^
j2k_parameters->cp_fixed_quality))) {
fprintf(stderr, "Error: options -r -q and -f cannot be used together !!\n");
return 1;
} /* mod fixed_quality */
/* if no rate entered, lossless by default */
if (j2k_parameters->tcp_numlayers == 0) {
j2k_parameters->tcp_rates[0] = 0; /* MOD antonin : losslessbug */
j2k_parameters->tcp_numlayers++;
j2k_parameters->cp_disto_alloc = 1;
}
if ((j2k_parameters->cp_tx0 > j2k_parameters->image_offset_x0) ||
(j2k_parameters->cp_ty0 > j2k_parameters->image_offset_y0)) {
fprintf(stderr,
"Error: Tile offset dimension is unnappropriate --> TX0(%d)<=IMG_X0(%d) TYO(%d)<=IMG_Y0(%d) \n",
j2k_parameters->cp_tx0, j2k_parameters->image_offset_x0, j2k_parameters->cp_ty0,
j2k_parameters->image_offset_y0);
return 1;
}
for (i = 0; i < j2k_parameters->numpocs; i++) {
if (j2k_parameters->POC[i].prg == -1) {
fprintf(stderr,
"Unrecognized progression order in option -P (POC n %d) [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n",
i + 1);
}
}
if (j2k_parameters->cp_tdx > mj2_parameters.Dim[0] ||
j2k_parameters->cp_tdy > mj2_parameters.Dim[1]) {
fprintf(stderr,
"Error: Tile offset dimension is unnappropriate --> TX0(%d)<=IMG_X0(%d) TYO(%d)<=IMG_Y0(%d) \n",
j2k_parameters->cp_tdx, mj2_parameters.Dim[0], j2k_parameters->cp_tdy,
mj2_parameters.Dim[1]);
return 1;
}
/* to respect profile - 0 */
/* ---------------------- */
x1 = !mj2_parameters.Dim[0] ? (mj2_parameters.w - 1) *
j2k_parameters->subsampling_dx
+ 1 : mj2_parameters.Dim[0] + (mj2_parameters.w - 1) *
j2k_parameters->subsampling_dx + 1;
y1 = !mj2_parameters.Dim[1] ? (mj2_parameters.h - 1) *
j2k_parameters->subsampling_dy
+ 1 : mj2_parameters.Dim[1] + (mj2_parameters.h - 1) *
j2k_parameters->subsampling_dy + 1;
mj2_parameters.numcomps = 3; /* YUV files only have 3 components */
mj2_parameters.prec = prec;
j2k_parameters->tcp_mct = 0;
mj2file = fopen(mj2_parameters.outfile, "wb");
if (!mj2file) {
fprintf(stderr, "failed to open %s for writing\n", argv[2]);
return 1;
}
/* get a MJ2 decompressor handle */
cinfo = mj2_create_compress();
movie = (opj_mj2_t*)cinfo->mj2_handle;
/* catch events using our callbacks and give a local context */
opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr);
/* setup encoder parameters */
mj2_setup_encoder(movie, &mj2_parameters);
movie->tk[0].num_samples =
yuv_num_frames(&movie->tk[0], mj2_parameters.infile);
if (movie->tk[0].num_samples == 0) {
return 1;
}
/* One sample per chunk*/
movie->tk[0].chunk = (mj2_chunk_t*)
malloc(movie->tk[0].num_samples * sizeof(mj2_chunk_t));
movie->tk[0].sample = (mj2_sample_t*)
malloc(movie->tk[0].num_samples * sizeof(mj2_sample_t));
if (mj2_init_stdmovie(movie)) {
fprintf(stderr, "Error with movie initialization");
return 1;
}
/* Writing JP, FTYP and MDAT boxes */
/* Assuming that the JP and FTYP boxes won't be longer than 300 bytes:*/
buf = (unsigned char*)
malloc(300 * sizeof(unsigned char));
cio = opj_cio_open((opj_common_ptr)movie->cinfo, buf, 300);
mj2_write_jp(cio);
mj2_write_ftyp(movie, cio);
mdat_initpos = cio_tell(cio);
cio_skip(cio, 4);
cio_write(cio, MJ2_MDAT, 4);
fwrite(buf, cio_tell(cio), 1, mj2file);
offset = cio_tell(cio);
opj_cio_close(cio);
free(buf);
for (i = 0; i < movie->num_stk + movie->num_htk + movie->num_vtk; i++) {
if (movie->tk[i].track_type != 0) {
fprintf(stderr, "Unable to write sound or hint tracks\n");
} else {
mj2_tk_t *tk;
int buflen = 0;
tk = &movie->tk[i];
tk->num_chunks = tk->num_samples;
numframes = tk->num_samples;
tk->depth = prec;
fprintf(stderr, "Video Track number %d\n", i);
img = mj2_image_create(tk, j2k_parameters);
buflen = 2 * (tk->w * tk->h * 8);
buf = (unsigned char *) malloc(buflen * sizeof(unsigned char));
for (sampleno = 0; sampleno < numframes; sampleno++) {
double init_time = opj_clock();
double elapsed_time;
if (yuvtoimage(tk, img, sampleno, j2k_parameters,
mj2_parameters.infile)) {
fprintf(stderr, "Error with frame number %d in YUV file\n", sampleno);
return 1;
}
/* setup the encoder parameters using the current image and user parameters */
opj_setup_encoder(cinfo, j2k_parameters, img);
cio = opj_cio_open((opj_common_ptr)movie->cinfo, buf, buflen);
cio_skip(cio, 4);
cio_write(cio, JP2_JP2C, 4); /* JP2C*/
/* encode the image */
bSuccess = opj_encode(cinfo, cio, img, NULL);
if (!bSuccess) {
opj_cio_close(cio);
fprintf(stderr, "failed to encode image\n");
return 1;
}
len = cio_tell(cio) - 8;
cio_seek(cio, 0);
cio_write(cio, len + 8, 4);
opj_cio_close(cio);
tk->sample[sampleno].sample_size = len + 8;
tk->sample[sampleno].offset = offset;
tk->chunk[sampleno].offset = offset; /* There is one sample per chunk */
fwrite(buf, 1, len + 8, mj2file);
offset += len + 8;
elapsed_time = opj_clock() - init_time;
fprintf(stderr, "Frame number %d/%d encoded in %.2f mseconds\n",
sampleno + 1, numframes, elapsed_time * 1000);
total_time += elapsed_time;
} /* for(sampleno */
free(buf);
opj_image_destroy(img);
}
}/* for(i */
fseek(mj2file, mdat_initpos, SEEK_SET);
buf = (unsigned char*) malloc(4 * sizeof(unsigned char));
/* Init a cio to write box length variable in a little endian way */
cio = opj_cio_open(NULL, buf, 4);
cio_write(cio, offset - mdat_initpos, 4);
fwrite(buf, 4, 1, mj2file);
fseek(mj2file, 0, SEEK_END);
free(buf);
/* Writing MOOV box */
buf = (unsigned char*)
malloc((TEMP_BUF + numframes * 20) * sizeof(unsigned char));
cio = opj_cio_open(movie->cinfo, buf, (TEMP_BUF + numframes * 20));
mj2_write_moov(movie, cio);
fwrite(buf, cio_tell(cio), 1, mj2file);
free(buf);
fprintf(stdout, "Total encoding time: %.2f s for %d frames (%.1f fps)\n",
total_time, numframes, (float)numframes / total_time);
/* Ending program */
fclose(mj2file);
/* free remaining compression structures */
mj2_destroy_compress(movie);
free(cinfo);
if (j2k_parameters->cp_comment) {
free(j2k_parameters->cp_comment);
}
if (j2k_parameters->cp_matrice) {
free(j2k_parameters->cp_matrice);
}
opj_cio_close(cio);
return 0;
}

View File

@ -0,0 +1,258 @@
/*
* Copyright (c) 2003-2004, Francois-Olivier Devaux
* Copyright (c) 2002-2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 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 OWNER 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "opj_apps_config.h"
#include "openjpeg.h"
#include "j2k_lib.h"
#include "cio.h"
#include "j2k.h"
#include "jp2.h"
#include "mj2.h"
#include "mj2_convert.h"
#ifdef OPJ_HAVE_LIBLCMS2
#include <lcms2.h>
#endif
#ifdef OPJ_HAVE_LIBLCMS1
#include <lcms.h>
#endif
#include "color.h"
/* -------------------------------------------------------------------------- */
/**
sample error callback expecting a FILE* client object
*/
static void error_callback(const char *msg, void *client_data)
{
FILE *stream = (FILE*)client_data;
fprintf(stream, "[ERROR] %s", msg);
}
/**
sample warning callback expecting a FILE* client object
*/
static void warning_callback(const char *msg, void *client_data)
{
FILE *stream = (FILE*)client_data;
fprintf(stream, "[WARNING] %s", msg);
}
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
mj2_dparameters_t mj2_parameters; /* decompression parameters */
opj_dinfo_t* dinfo;
opj_event_mgr_t event_mgr; /* event manager */
opj_cio_t *cio = NULL;
unsigned int tnum, snum;
opj_mj2_t *movie;
mj2_tk_t *track;
mj2_sample_t *sample;
unsigned char* frame_codestream;
FILE *file, *outfile;
char outfilename[50];
opj_image_t *img = NULL;
unsigned int max_codstrm_size = 0;
double total_time = 0;
unsigned int numframes = 0;
if (argc != 3) {
printf("Usage: %s inputfile.mj2 outputfile.yuv\n", argv[0]);
return 1;
}
file = fopen(argv[1], "rb");
if (!file) {
fprintf(stderr, "failed to open %s for reading\n", argv[1]);
return 1;
}
/* Checking output file */
outfile = fopen(argv[2], "w");
if (!file) {
fprintf(stderr, "failed to open %s for writing\n", argv[2]);
return 1;
}
fclose(outfile);
/*
configure the event callbacks (not required)
setting of each callback is optional
*/
memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
event_mgr.error_handler = error_callback;
event_mgr.warning_handler = warning_callback;
event_mgr.info_handler = NULL;
/* get a MJ2 decompressor handle */
dinfo = mj2_create_decompress();
movie = (opj_mj2_t*)dinfo->mj2_handle;
/* catch events using our callbacks and give a local context */
opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
memset(&mj2_parameters, 0, sizeof(mj2_dparameters_t));
/* set J2K decoding parameters to default values */
opj_set_default_decoder_parameters(&mj2_parameters.j2k_parameters);
/* setup the decoder decoding parameters using user parameters */
mj2_setup_decoder(movie, &mj2_parameters);
if (mj2_read_struct(file, movie)) { /* Creating the movie structure */
return 1;
}
/* Decode first video track */
for (tnum = 0;
tnum < (unsigned int)(movie->num_htk + movie->num_stk + movie->num_vtk);
tnum++) {
if (movie->tk[tnum].track_type == 0) {
break;
}
}
if (movie->tk[tnum].track_type != 0) {
printf("Error. Movie does not contain any video track\n");
return 1;
}
track = &movie->tk[tnum];
/* Output info on first video tracl */
fprintf(stdout,
"The first video track contains %d frames.\nWidth: %d, Height: %d \n\n",
track->num_samples, track->w, track->h);
max_codstrm_size = track->sample[0].sample_size - 8;
frame_codestream = (unsigned char*) malloc(max_codstrm_size * sizeof(
unsigned char));
numframes = track->num_samples;
for (snum = 0; snum < numframes; snum++) {
double init_time = opj_clock();
double elapsed_time;
sample = &track->sample[snum];
if (sample->sample_size - 8 > max_codstrm_size) {
max_codstrm_size = sample->sample_size - 8;
if ((frame_codestream = (unsigned char*)
realloc(frame_codestream, max_codstrm_size)) == NULL) {
printf("Error reallocation memory\n");
return 1;
};
}
fseek(file, sample->offset + 8, SEEK_SET);
fread(frame_codestream, sample->sample_size - 8, 1,
file); /* Assuming that jp and ftyp markers size do */
/* open a byte stream */
cio = opj_cio_open((opj_common_ptr)dinfo, frame_codestream,
sample->sample_size - 8);
img = opj_decode(dinfo, cio); /* Decode J2K to image */
#ifdef WANT_SYCC_TO_RGB
if (img->color_space == CLRSPC_SYCC) {
color_sycc_to_rgb(img);
}
#endif
if (img->icc_profile_buf) {
#if defined(OPJ_HAVE_LIBLCMS1) || defined(OPJ_HAVE_LIBLCMS2)
color_apply_icc_profile(img);
#endif
free(img->icc_profile_buf);
img->icc_profile_buf = NULL;
img->icc_profile_len = 0;
}
if (((img->numcomps == 3) && (img->comps[0].dx == img->comps[1].dx / 2)
&& (img->comps[0].dx == img->comps[2].dx / 2) && (img->comps[0].dx == 1))
|| (img->numcomps == 1)) {
if (!imagetoyuv(img, argv[2])) { /* Convert image to YUV */
return 1;
}
} else if ((img->numcomps == 3) &&
(img->comps[0].dx == 1) && (img->comps[1].dx == 1) &&
(img->comps[2].dx == 1)) { /* If YUV 4:4:4 input --> to bmp */
fprintf(stdout,
"The frames will be output in a bmp format (output_1.bmp, ...)\n");
sprintf(outfilename, "output_%d.bmp", snum);
if (imagetobmp(img, outfilename)) { /* Convert image to BMP */
return 1;
}
} else {
fprintf(stdout,
"Image component dimensions are unknown. Unable to output image\n");
fprintf(stdout,
"The frames will be output in a j2k file (output_1.j2k, ...)\n");
sprintf(outfilename, "output_%d.j2k", snum);
outfile = fopen(outfilename, "wb");
if (!outfile) {
fprintf(stderr, "failed to open %s for writing\n", outfilename);
return 1;
}
fwrite(frame_codestream, sample->sample_size - 8, 1, outfile);
fclose(outfile);
}
/* close the byte stream */
opj_cio_close(cio);
/* free image data structure */
opj_image_destroy(img);
elapsed_time = opj_clock() - init_time;
fprintf(stderr, "Frame number %d/%d decoded in %.2f mseconds\n", snum + 1,
numframes, elapsed_time * 1000);
total_time += elapsed_time;
}
free(frame_codestream);
fclose(file);
/* free remaining structures */
if (dinfo) {
mj2_destroy_decompress((opj_mj2_t*)dinfo->mj2_handle);
}
free(dinfo);
fprintf(stdout, "%d frame(s) correctly decompressed\n", snum);
fprintf(stdout, "Total decoding time: %.2f seconds (%.1f fps)\n", total_time,
(float)numframes / total_time);
return 0;
}

View File

@ -0,0 +1,162 @@
/*
* The copyright in this software is being made available under the 2-clauses
* BSD License, included below. This software may be subject to other third
* party and contributor rights, including patent rights, and no such rights
* are granted under this license.
*
* Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
* Copyright (c) 2002-2014, Professor Benoit Macq
* Copyright (c) 2003-2007, Francois-Olivier Devaux
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 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 OWNER 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "openjpeg.h"
#include "cio.h"
#include "j2k.h"
#include "jp2.h"
#include "mj2.h"
/* -------------------------------------------------------------------------- */
/**
sample error callback expecting a FILE* client object
*/
void error_callback(const char *msg, void *client_data)
{
FILE *stream = (FILE*)client_data;
fprintf(stream, "[ERROR] %s", msg);
}
/**
sample warning callback expecting a FILE* client object
*/
void warning_callback(const char *msg, void *client_data)
{
FILE *stream = (FILE*)client_data;
fprintf(stream, "[WARNING] %s", msg);
}
/**
sample debug callback expecting a FILE* client object
*/
void info_callback(const char *msg, void *client_data)
{
FILE *stream = (FILE*)client_data;
fprintf(stream, "[INFO] %s", msg);
}
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
opj_dinfo_t* dinfo;
opj_event_mgr_t event_mgr; /* event manager */
int tnum;
unsigned int snum;
opj_mj2_t *movie;
mj2_tk_t *track;
mj2_sample_t *sample;
unsigned char* frame_codestream;
FILE *file, *outfile;
char outfilename[50];
mj2_dparameters_t parameters;
if (argc != 3) {
printf("Usage: %s mj2filename output_location\n", argv[0]);
printf("Example: %s foreman.mj2 output/foreman\n", argv[0]);
return 1;
}
file = fopen(argv[1], "rb");
if (!file) {
fprintf(stderr, "failed to open %s for reading\n", argv[1]);
return 1;
}
/*
configure the event callbacks (not required)
setting of each callback is optional
*/
memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
event_mgr.error_handler = error_callback;
event_mgr.warning_handler = warning_callback;
event_mgr.info_handler = info_callback;
/* get a MJ2 decompressor handle */
dinfo = mj2_create_decompress();
/* catch events using our callbacks and give a local context */
opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
/* setup the decoder decoding parameters using user parameters */
memset(&parameters, 0, sizeof(mj2_dparameters_t));
movie = (opj_mj2_t*) dinfo->mj2_handle;
mj2_setup_decoder(movie, &parameters);
if (mj2_read_struct(file, movie)) { /* Creating the movie structure*/
return 1;
}
/* Decode first video track */
tnum = 0;
while (movie->tk[tnum].track_type != 0) {
tnum ++;
}
track = &movie->tk[tnum];
fprintf(stdout, "Extracting %d frames from file...\n", track->num_samples);
for (snum = 0; snum < track->num_samples; snum++) {
sample = &track->sample[snum];
frame_codestream = (unsigned char*) malloc(sample->sample_size -
8); /* Skipping JP2C marker*/
fseek(file, sample->offset + 8, SEEK_SET);
fread(frame_codestream, sample->sample_size - 8, 1,
file); /* Assuming that jp and ftyp markers size do*/
sprintf(outfilename, "%s_%05d.j2k", argv[2], snum);
outfile = fopen(outfilename, "wb");
if (!outfile) {
fprintf(stderr, "failed to open %s for writing\n", outfilename);
return 1;
}
fwrite(frame_codestream, sample->sample_size - 8, 1, outfile);
fclose(outfile);
free(frame_codestream);
}
fclose(file);
fprintf(stdout, "%d frames correctly extracted\n", snum);
/* free remaining structures */
if (dinfo) {
mj2_destroy_decompress((opj_mj2_t*)dinfo->mj2_handle);
}
return 0;
}

537
src/bin/mj2/opj_mj2_wrap.c Normal file
View File

@ -0,0 +1,537 @@
/*
* The copyright in this software is being made available under the 2-clauses
* BSD License, included below. This software may be subject to other third
* party and contributor rights, including patent rights, and no such rights
* are granted under this license.
*
* Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
* Copyright (c) 2002-2014, Professor Benoit Macq
* Copyright (c) 2003-2007, Francois-Olivier Devaux
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 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 OWNER 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "openjpeg.h"
#include "cio.h"
#include "j2k.h"
#include "jp2.h"
#include "mj2.h"
static int int_ceildiv(int a, int b)
{
return (a + b - 1) / b;
}
/**
Size of memory first allocated for MOOV box
*/
#define TEMP_BUF 10000
#define J2K_CODESTREAM_MAGIC "\xff\x4f\xff\x51"
/* -------------------------------------------------------------------------- */
static int test_image(const char *fname, mj2_cparameters_t *cp)
{
FILE *reader;
opj_image_t *image;
unsigned char *src;
opj_dinfo_t *dinfo;
opj_cio_t *cio;
opj_dparameters_t dparameters;
int success;
long src_len;
success = 0;
if ((reader = fopen(fname, "rb")) == NULL) {
return success;
}
fseek(reader, 0, SEEK_END);
src_len = ftell(reader);
fseek(reader, 0, SEEK_SET);
src = (unsigned char*) malloc(src_len);
fread(src, 1, src_len, reader);
fclose(reader);
if (memcmp(src, J2K_CODESTREAM_MAGIC, 4) != 0) {
free(src);
return success;
}
memset(&dparameters, 0, sizeof(opj_dparameters_t));
opj_set_default_decoder_parameters(&dparameters);
dinfo = opj_create_decompress(CODEC_J2K);
opj_setup_decoder(dinfo, &dparameters);
cio = opj_cio_open((opj_common_ptr)dinfo, src, src_len);
image = opj_decode(dinfo, cio);
free(src);
cio->buffer = NULL;
opj_cio_close(cio);
if (image == NULL) {
goto fin;
}
cp->numcomps = image->numcomps;
cp->w = image->comps[0].w;
cp->h = image->comps[0].h;
cp->prec = image->comps[0].prec;
if (image->numcomps > 2) {
if ((image->comps[0].dx == 1)
&& (image->comps[1].dx == 2)
&& (image->comps[2].dx == 2)
&& (image->comps[0].dy == 1)
&& (image->comps[1].dy == 2)
&& (image->comps[2].dy == 2)) { /* horizontal and vertical*/
/* Y420*/
cp->enumcs = ENUMCS_SYCC;
cp->CbCr_subsampling_dx = 2;
cp->CbCr_subsampling_dy = 2;
} else if ((image->comps[0].dx == 1)
&& (image->comps[1].dx == 2)
&& (image->comps[2].dx == 2)
&& (image->comps[0].dy == 1)
&& (image->comps[1].dy == 1)
&& (image->comps[2].dy == 1)) { /* horizontal only*/
/* Y422*/
cp->enumcs = ENUMCS_SYCC;
cp->CbCr_subsampling_dx = 2;
cp->CbCr_subsampling_dy = 1;
} else if ((image->comps[0].dx == 1)
&& (image->comps[1].dx == 1)
&& (image->comps[2].dx == 1)
&& (image->comps[0].dy == 1)
&& (image->comps[1].dy == 1)
&& (image->comps[2].dy == 1)) {
/* Y444 or RGB */
if (image->color_space == CLRSPC_SRGB) {
cp->enumcs = ENUMCS_SRGB;
/* cp->CbCr_subsampling_dx = 0; */
/* cp->CbCr_subsampling_dy = 0; */
} else {
cp->enumcs = ENUMCS_SYCC;
cp->CbCr_subsampling_dx = 1;
cp->CbCr_subsampling_dy = 1;
}
} else {
goto fin;
}
} else {
cp->enumcs = ENUMCS_GRAY;
/* cp->CbCr_subsampling_dx = 0; */
/* cp->CbCr_subsampling_dy = 0; */
}
if (image->icc_profile_buf) {
cp->meth = 2;
free(image->icc_profile_buf);
image->icc_profile_buf = NULL;
} else {
cp->meth = 1;
}
success = 1;
fin:
if (dinfo) {
opj_destroy_decompress(dinfo);
}
if (image) {
opj_image_destroy(image);
}
return success;
}
/**
sample error callback expecting a FILE* client object
*/
static void error_callback(const char *msg, void *client_data)
{
FILE *stream = (FILE*)client_data;
fprintf(stream, "[ERROR] %s", msg);
}
/**
sample warning callback expecting a FILE* client object
*/
static void warning_callback(const char *msg, void *client_data)
{
FILE *stream = (FILE*)client_data;
fprintf(stream, "[WARNING] %s", msg);
}
/**
sample debug callback expecting a FILE* client object
*/
static void info_callback(const char *msg, void *client_data)
{
FILE *stream = (FILE*)client_data;
fprintf(stream, "[INFO] %s", msg);
}
/* -------------------------------------------------------------------------- */
static void read_siz_marker(FILE *file, opj_image_t *image)
{
int len, i;
char buf, buf2[2];
unsigned char *siz_buffer;
opj_cio_t *cio;
fseek(file, 0, SEEK_SET);
do {
fread(&buf, 1, 1, file);
if (buf == (char)0xff) {
fread(&buf, 1, 1, file);
}
} while (!(buf == (char)0x51));
fread(buf2, 2, 1, file); /* Lsiz */
len = ((buf2[0]) << 8) + buf2[1];
siz_buffer = (unsigned char*) malloc(len * sizeof(unsigned char));
fread(siz_buffer, len, 1, file);
cio = opj_cio_open(NULL, siz_buffer, len);
cio_read(cio, 2); /* Rsiz (capabilities) */
image->x1 = cio_read(cio, 4); /* Xsiz */
image->y1 = cio_read(cio, 4); /* Ysiz */
image->x0 = cio_read(cio, 4); /* X0siz */
image->y0 = cio_read(cio, 4); /* Y0siz */
cio_skip(cio, 16); /* XTsiz, YTsiz, XT0siz, YT0siz */
image->numcomps = cio_read(cio, 2); /* Csiz */
image->comps =
(opj_image_comp_t *) malloc(image->numcomps * sizeof(opj_image_comp_t));
for (i = 0; i < image->numcomps; i++) {
int tmp;
tmp = cio_read(cio, 1); /* Ssiz_i */
image->comps[i].prec = (tmp & 0x7f) + 1;
image->comps[i].sgnd = tmp >> 7;
image->comps[i].dx = cio_read(cio, 1); /* XRsiz_i */
image->comps[i].dy = cio_read(cio, 1); /* YRsiz_i */
image->comps[i].resno_decoded = 0; /* number of resolution decoded */
image->comps[i].factor = 0; /* reducing factor by component */
}
fseek(file, 0, SEEK_SET);
opj_cio_close(cio);
free(siz_buffer);
}
static void setparams(opj_mj2_t *movie, opj_image_t *image)
{
int i, depth_0, depth, sign;
movie->tk[0].w = int_ceildiv(image->x1 - image->x0, image->comps[0].dx);
movie->tk[0].h = int_ceildiv(image->y1 - image->y0, image->comps[0].dy);
mj2_init_stdmovie(movie);
movie->tk[0].depth = image->comps[0].prec;
if (image->numcomps == 3) {
if ((image->comps[0].dx == 1)
&& (image->comps[1].dx == 1)
&& (image->comps[2].dx == 1)) {
movie->tk[0].CbCr_subsampling_dx = 1;
} else if ((image->comps[0].dx == 1)
&& (image->comps[1].dx == 2)
&& (image->comps[2].dx == 2)) {
movie->tk[0].CbCr_subsampling_dx = 2;
} else {
fprintf(stderr, "Image component sizes are incoherent\n");
}
if ((image->comps[0].dy == 1)
&& (image->comps[1].dy == 1)
&& (image->comps[2].dy == 1)) {
movie->tk[0].CbCr_subsampling_dy = 1;
} else if ((image->comps[0].dy == 1)
&& (image->comps[1].dy == 2)
&& (image->comps[2].dy == 2)) {
movie->tk[0].CbCr_subsampling_dy = 2;
} else {
fprintf(stderr, "Image component sizes are incoherent\n");
}
}
movie->tk[0].sample_rate = 25;
movie->tk[0].jp2_struct.numcomps = image->numcomps; /* NC */
/* Init Standard jp2 structure */
movie->tk[0].jp2_struct.comps =
(opj_jp2_comps_t *) malloc(movie->tk[0].jp2_struct.numcomps * sizeof(
opj_jp2_comps_t));
movie->tk[0].jp2_struct.precedence = 0; /* PRECEDENCE*/
movie->tk[0].jp2_struct.approx = 0; /* APPROX*/
movie->tk[0].jp2_struct.brand = JP2_JP2; /* BR */
movie->tk[0].jp2_struct.minversion = 0; /* MinV */
movie->tk[0].jp2_struct.numcl = 1;
movie->tk[0].jp2_struct.cl = (unsigned int *) malloc(
movie->tk[0].jp2_struct.numcl * sizeof(int));
movie->tk[0].jp2_struct.cl[0] = JP2_JP2; /* CL0 : JP2 */
movie->tk[0].jp2_struct.C = 7; /* C : Always 7*/
movie->tk[0].jp2_struct.UnkC =
0; /* UnkC, colorspace specified in colr box*/
movie->tk[0].jp2_struct.IPR = 0; /* IPR, no intellectual property*/
movie->tk[0].jp2_struct.w = int_ceildiv(image->x1 - image->x0,
image->comps[0].dx);
movie->tk[0].jp2_struct.h = int_ceildiv(image->y1 - image->y0,
image->comps[0].dy);
depth_0 = image->comps[0].prec - 1;
sign = image->comps[0].sgnd;
movie->tk[0].jp2_struct.bpc = depth_0 + (sign << 7);
for (i = 1; i < image->numcomps; i++) {
depth = image->comps[i].prec - 1;
sign = image->comps[i].sgnd;
if (depth_0 != depth) {
movie->tk[0].jp2_struct.bpc = 255;
}
}
for (i = 0; i < image->numcomps; i++)
movie->tk[0].jp2_struct.comps[i].bpcc =
image->comps[i].prec - 1 + (image->comps[i].sgnd << 7);
if ((image->numcomps == 1 || image->numcomps == 3)
&& (movie->tk[0].jp2_struct.bpc != 255)) {
movie->tk[0].jp2_struct.meth = 1;
} else {
movie->tk[0].jp2_struct.meth = 2;
}
if (image->numcomps == 1) {
movie->tk[0].jp2_struct.enumcs = 17; /* Grayscale */
}
else if ((image->comps[0].dx == 1)
&& (image->comps[1].dx == 1)
&& (image->comps[2].dx == 1)
&& (image->comps[0].dy == 1)
&& (image->comps[1].dy == 1)
&& (image->comps[2].dy == 1)) {
movie->tk[0].jp2_struct.enumcs = 16; /* RGB */
}
else if ((image->comps[0].dx == 1)
&& (image->comps[1].dx == 2)
&& (image->comps[2].dx == 2)
&& (image->comps[0].dy == 1)
&& (image->comps[1].dy == 2)
&& (image->comps[2].dy == 2)) {
movie->tk[0].jp2_struct.enumcs = 18; /* YUV */
}
else {
movie->tk[0].jp2_struct.enumcs = 0; /* Unknown profile */
}
}
int main(int argc, char *argv[])
{
opj_cinfo_t* cinfo;
opj_event_mgr_t event_mgr; /* event manager */
unsigned int snum;
opj_mj2_t *movie;
mj2_sample_t *sample;
unsigned char* frame_codestream;
FILE *mj2file, *j2kfile;
char *j2kfilename;
unsigned char *buf;
int offset, mdat_initpos;
opj_image_t img;
opj_cio_t *cio;
mj2_cparameters_t parameters;
if (argc != 3) {
printf("Usage: %s source_location mj2_filename\n", argv[0]);
printf("Example: %s input/input output.mj2\n", argv[0]);
return 1;
}
mj2file = fopen(argv[2], "wb");
if (!mj2file) {
fprintf(stderr, "failed to open %s for writing\n", argv[2]);
return 1;
}
memset(&img, 0, sizeof(opj_image_t));
/*
configure the event callbacks (not required)
setting of each callback is optional
*/
memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
event_mgr.error_handler = error_callback;
event_mgr.warning_handler = warning_callback;
event_mgr.info_handler = info_callback;
/* get a MJ2 decompressor handle */
cinfo = mj2_create_compress();
/* catch events using our callbacks and give a local context */
opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr);
/* setup the decoder encoding parameters using user parameters */
memset(&parameters, 0, sizeof(mj2_cparameters_t));
movie = (opj_mj2_t*) cinfo->mj2_handle;
j2kfilename = (char*)malloc(strlen(argv[1]) + 12);/* max. '%6d' */
sprintf(j2kfilename, "%s_00001.j2k", argv[1]);
if (test_image(j2kfilename, &parameters) == 0) {
goto fin;
}
parameters.frame_rate = 25; /* DEFAULT */
mj2_setup_encoder(movie, &parameters);
/* Writing JP, FTYP and MDAT boxes
Assuming that the JP and FTYP boxes won't be longer than 300 bytes */
buf = (unsigned char*) malloc(300 * sizeof(unsigned char));
cio = opj_cio_open(movie->cinfo, buf, 300);
mj2_write_jp(cio);
mj2_write_ftyp(movie, cio);
mdat_initpos = cio_tell(cio);
cio_skip(cio, 4);
cio_write(cio, MJ2_MDAT, 4);
fwrite(buf, cio_tell(cio), 1, mj2file);
free(buf);
/* Insert each j2k codestream in a JP2C box */
snum = 0;
offset = 0;
while (1) {
mj2_sample_t * new_sample;
mj2_chunk_t * new_chunk;
sample = &movie->tk[0].sample[snum];
sprintf(j2kfilename, "%s_%05d.j2k", argv[1], snum);
j2kfile = fopen(j2kfilename, "rb");
if (!j2kfile) {
if (snum == 0) { /* Could not open a single codestream */
fprintf(stderr, "failed to open %s for reading\n", j2kfilename);
return 1;
} else { /* Tried to open a inexistent codestream */
fprintf(stdout, "%d frames are being added to the MJ2 file\n", snum);
break;
}
}
/* Calculating offset for samples and chunks */
offset += cio_tell(cio);
sample->offset = offset;
movie->tk[0].chunk[snum].offset =
offset; /* There will be one sample per chunk */
/* Calculating sample size */
fseek(j2kfile, 0, SEEK_END);
sample->sample_size = ftell(j2kfile) +
8; /* Sample size is codestream + JP2C box header */
fseek(j2kfile, 0, SEEK_SET);
/* Reading siz marker of j2k image for the first codestream */
if (snum == 0) {
read_siz_marker(j2kfile, &img);
}
/* Writing JP2C box header */
frame_codestream = (unsigned char*) malloc(sample->sample_size + 8);
cio = opj_cio_open(movie->cinfo, frame_codestream, sample->sample_size);
cio_write(cio, sample->sample_size, 4); /* Sample size */
cio_write(cio, JP2_JP2C, 4); /* JP2C */
/* Writing codestream from J2K file to MJ2 file */
fread(frame_codestream + 8, sample->sample_size - 8, 1, j2kfile);
fwrite(frame_codestream, sample->sample_size, 1, mj2file);
cio_skip(cio, sample->sample_size - 8);
/* Ending loop */
fclose(j2kfile);
snum++;
new_sample = (mj2_sample_t*)
realloc(movie->tk[0].sample, (snum + 1) * sizeof(mj2_sample_t));
new_chunk = (mj2_chunk_t*)
realloc(movie->tk[0].chunk, (snum + 1) * sizeof(mj2_chunk_t));
if (new_sample && new_chunk) {
movie->tk[0].sample = new_sample;
movie->tk[0].chunk = new_chunk;
} else {
fprintf(stderr, "Failed to allocate enough memory to read %s\n", j2kfilename);
return 1;
}
free(frame_codestream);
}
/* Writing the MDAT box length in header */
offset += cio_tell(cio);
buf = (unsigned char*) malloc(4 * sizeof(unsigned char));
cio = opj_cio_open(movie->cinfo, buf, 4);
cio_write(cio, offset - mdat_initpos, 4);
fseek(mj2file, (long)mdat_initpos, SEEK_SET);
fwrite(buf, 4, 1, mj2file);
fseek(mj2file, 0, SEEK_END);
free(buf);
/* Setting movie parameters */
movie->tk[0].num_samples = snum;
movie->tk[0].num_chunks = snum;
setparams(movie, &img);
/* Writing MOOV box */
buf = (unsigned char*) malloc((TEMP_BUF + snum * 20) * sizeof(unsigned char));
cio = opj_cio_open(movie->cinfo, buf, (TEMP_BUF + snum * 20));
mj2_write_moov(movie, cio);
fwrite(buf, cio_tell(cio), 1, mj2file);
/* Ending program */
free(img.comps);
opj_cio_close(cio);
fin:
fclose(mj2file);
mj2_destroy_compress(movie);
free(j2kfilename);
return 0;
}

3
src/bin/mj2/readme.txt Normal file
View File

@ -0,0 +1,3 @@
Attention : the motion jpeg 2000 files currently only work with OpenJPEG v0.97 that you can find here :
http://www.openjpeg.org/openjpeg_v097.tar.gz

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,16 @@
# Part 1 & 2:
add_subdirectory(openjp2)
# optionals components:
if(BUILD_JPWL)
add_subdirectory(openjpwl)
endif()
if(BUILD_MJ2)
add_subdirectory(openmj2)
endif()
if(BUILD_JPIP)
add_subdirectory(openjpip)
endif()
if(BUILD_JP3D)
add_subdirectory(openjp3d)
endif()

View File

@ -2,7 +2,7 @@ include_regular_expression("^.*$")
#
install( FILES ${CMAKE_CURRENT_BINARY_DIR}/opj_config.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${OPENJPEG_INSTALL_SUBDIR} COMPONENT Headers)
DESTINATION ${OPENJPEG_INSTALL_INCLUDE_DIR} COMPONENT Headers)
include_directories(
${${OPENJPEG_NAMESPACE}_BINARY_DIR}/src/lib/openjp2 # opj_config.h and opj_config_private.h
@ -19,7 +19,6 @@ set(OPENJPEG_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/dwt.h
${CMAKE_CURRENT_SOURCE_DIR}/event.c
${CMAKE_CURRENT_SOURCE_DIR}/event.h
${CMAKE_CURRENT_SOURCE_DIR}/ht_dec.c
${CMAKE_CURRENT_SOURCE_DIR}/image.c
${CMAKE_CURRENT_SOURCE_DIR}/image.h
${CMAKE_CURRENT_SOURCE_DIR}/invert.c
@ -98,46 +97,43 @@ else()
add_library(openjp2_static STATIC ${OPENJPEG_SRCS})
set_target_properties(openjp2_static PROPERTIES OUTPUT_NAME ${OPENJPEG_LIBRARY_NAME})
set(INSTALL_LIBS ${OPENJPEG_LIBRARY_NAME} openjp2_static)
target_include_directories(openjp2_static PUBLIC $<INSTALL_INTERFACE:${OPENJPEG_INSTALL_INCLUDE_DIR}>)
else()
add_library(${OPENJPEG_LIBRARY_NAME} ${OPENJPEG_SRCS})
set(INSTALL_LIBS ${OPENJPEG_LIBRARY_NAME})
endif()
endif()
target_include_directories(${OPENJPEG_LIBRARY_NAME} PUBLIC $<INSTALL_INTERFACE:${OPENJPEG_INSTALL_INCLUDE_DIR}>)
if(UNIX)
target_link_libraries(${OPENJPEG_LIBRARY_NAME} m)
endif()
set_target_properties(${OPENJPEG_LIBRARY_NAME} PROPERTIES ${OPENJPEG_LIBRARY_PROPERTIES})
if(NOT ${CMAKE_VERSION} VERSION_LESS "2.8.12")
if(${CMAKE_VERSION} VERSION_GREATER "2.8.11")
target_compile_options(${OPENJPEG_LIBRARY_NAME} PRIVATE ${OPENJP2_COMPILE_OPTIONS})
endif()
# Install library
install(TARGETS ${INSTALL_LIBS}
EXPORT OpenJPEGTargets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Applications
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Libraries
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Libraries
RUNTIME DESTINATION ${OPENJPEG_INSTALL_BIN_DIR} COMPONENT Applications
LIBRARY DESTINATION ${OPENJPEG_INSTALL_LIB_DIR} COMPONENT Libraries
ARCHIVE DESTINATION ${OPENJPEG_INSTALL_LIB_DIR} COMPONENT Libraries
)
# Install includes files
install(FILES openjpeg.h opj_stdint.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${OPENJPEG_INSTALL_SUBDIR} COMPONENT Headers
DESTINATION ${OPENJPEG_INSTALL_INCLUDE_DIR} COMPONENT Headers
)
if(BUILD_DOC)
# install man page of the library
install(
FILES ${OPENJPEG_SOURCE_DIR}/doc/man/man3/libopenjp2.3
DESTINATION ${CMAKE_INSTALL_MANDIR}/man3)
DESTINATION ${OPENJPEG_INSTALL_MAN_DIR}/man3)
endif()
if(BUILD_LUTS_GENERATOR)
# internal utility to generate t1_luts.h and t1_ht_luts.h (part of the jp2 lib)
# internal utility to generate t1_luts.h (part of the jp2 lib)
# no need to install:
add_executable(t1_generate_luts t1_generate_luts.c t1_ht_generate_luts.c)
add_executable(t1_generate_luts t1_generate_luts.c)
if(UNIX)
target_link_libraries(t1_generate_luts m)
endif()
@ -202,7 +198,7 @@ if(OPJ_USE_THREAD AND Threads_FOUND AND CMAKE_USE_PTHREADS_INIT)
TARGET_LINK_LIBRARIES(${OPENJPEG_LIBRARY_NAME} ${CMAKE_THREAD_LIBS_INIT})
endif(OPJ_USE_THREAD AND Threads_FOUND AND CMAKE_USE_PTHREADS_INIT)
if(BUILD_UNIT_TESTS AND UNIX)
if(BUILD_UNIT_TESTS)
add_executable(bench_dwt bench_dwt.c)
if(UNIX)
target_link_libraries(bench_dwt m ${OPENJPEG_LIBRARY_NAME})
@ -218,4 +214,4 @@ if(BUILD_UNIT_TESTS AND UNIX)
if(OPJ_USE_THREAD AND Threads_FOUND AND CMAKE_USE_PTHREADS_INIT)
target_link_libraries(test_sparse_array ${CMAKE_THREAD_LIBS_INIT})
endif(OPJ_USE_THREAD AND Threads_FOUND AND CMAKE_USE_PTHREADS_INIT)
endif(BUILD_UNIT_TESTS AND UNIX)
endif(BUILD_UNIT_TESTS)

View File

@ -49,8 +49,7 @@ void init_tilec(opj_tcd_tilecomp_t * l_tilec,
OPJ_INT32 y0,
OPJ_INT32 x1,
OPJ_INT32 y1,
OPJ_UINT32 numresolutions,
OPJ_BOOL irreversible)
OPJ_UINT32 numresolutions)
{
opj_tcd_resolution_t* l_res;
OPJ_UINT32 resno, l_level_no;
@ -65,16 +64,9 @@ void init_tilec(opj_tcd_tilecomp_t * l_tilec,
(size_t)(l_tilec->y1 - l_tilec->y0);
l_tilec->data = (OPJ_INT32*) opj_malloc(sizeof(OPJ_INT32) * nValues);
for (i = 0; i < nValues; i++) {
OPJ_INT32 val = getValue((OPJ_UINT32)i);
if (irreversible) {
OPJ_FLOAT32 fVal = (OPJ_FLOAT32)val;
memcpy(&l_tilec->data[i], &fVal, sizeof(OPJ_FLOAT32));
} else {
l_tilec->data[i] = val;
}
l_tilec->data[i] = getValue((OPJ_UINT32)i);
}
l_tilec->numresolutions = numresolutions;
l_tilec->minimum_num_resolutions = numresolutions;
l_tilec->resolutions = (opj_tcd_resolution_t*) opj_calloc(
l_tilec->numresolutions,
sizeof(opj_tcd_resolution_t));
@ -106,9 +98,9 @@ void free_tilec(opj_tcd_tilecomp_t * l_tilec)
void usage(void)
{
printf(
"bench_dwt [-decode|encode] [-I] [-size value] [-check] [-display]\n");
"bench_dwt [-size value] [-check] [-display] [-num_resolutions val]\n");
printf(
" [-num_resolutions val] [-offset x y] [-num_threads val]\n");
" [-offset x y] [-num_threads val]\n");
exit(1);
}
@ -139,17 +131,6 @@ OPJ_FLOAT64 opj_clock(void)
#endif
}
static OPJ_FLOAT64 opj_wallclock(void)
{
#ifdef _WIN32
return opj_clock();
#else
struct timeval tv;
gettimeofday(&tv, NULL);
return (OPJ_FLOAT64)tv.tv_sec + 1e-6 * (OPJ_FLOAT64)tv.tv_usec;
#endif
}
int main(int argc, char** argv)
{
int num_threads = 0;
@ -165,24 +146,16 @@ int main(int argc, char** argv)
OPJ_BOOL check = OPJ_FALSE;
OPJ_INT32 size = 16384 - 1;
OPJ_FLOAT64 start, stop;
OPJ_FLOAT64 start_wc, stop_wc;
OPJ_UINT32 offset_x = ((OPJ_UINT32)size + 1) / 2 - 1;
OPJ_UINT32 offset_y = ((OPJ_UINT32)size + 1) / 2 - 1;
OPJ_UINT32 num_resolutions = 6;
OPJ_BOOL bench_decode = OPJ_TRUE;
OPJ_BOOL irreversible = OPJ_FALSE;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-encode") == 0) {
bench_decode = OPJ_FALSE;
} else if (strcmp(argv[i], "-decode") == 0) {
bench_decode = OPJ_TRUE;
} else if (strcmp(argv[i], "-display") == 0) {
if (strcmp(argv[i], "-display") == 0) {
display = OPJ_TRUE;
check = OPJ_TRUE;
} else if (strcmp(argv[i], "-check") == 0) {
check = OPJ_TRUE;
} else if (strcmp(argv[i], "-I") == 0) {
irreversible = OPJ_TRUE;
} else if (strcmp(argv[i], "-size") == 0 && i + 1 < argc) {
size = atoi(argv[i + 1]);
i ++;
@ -206,29 +179,18 @@ int main(int argc, char** argv)
}
}
if (irreversible && check) {
/* Due to irreversible inverse DWT not being symmetric of forward */
/* See BUG_WEIRD_TWO_INVK in dwt.c */
printf("-I and -check aren't compatible\n");
exit(1);
}
tp = opj_thread_pool_create(num_threads);
init_tilec(&tilec, (OPJ_INT32)offset_x, (OPJ_INT32)offset_y,
(OPJ_INT32)offset_x + size, (OPJ_INT32)offset_y + size,
num_resolutions, irreversible);
num_resolutions);
if (display) {
printf("Before\n");
k = 0;
for (j = 0; j < tilec.y1 - tilec.y0; j++) {
for (i = 0; i < tilec.x1 - tilec.x0; i++) {
if (irreversible) {
printf("%f ", ((OPJ_FLOAT32*)tilec.data)[k]);
} else {
printf("%d ", tilec.data[k]);
}
printf("%d ", tilec.data[k]);
k ++;
}
printf("\n");
@ -261,87 +223,45 @@ int main(int argc, char** argv)
image_comp.dy = 1;
start = opj_clock();
start_wc = opj_wallclock();
if (bench_decode) {
if (irreversible) {
opj_dwt_decode_real(&tcd, &tilec, tilec.numresolutions);
} else {
opj_dwt_decode(&tcd, &tilec, tilec.numresolutions);
}
} else {
if (irreversible) {
opj_dwt_encode_real(&tcd, &tilec);
} else {
opj_dwt_encode(&tcd, &tilec);
}
}
opj_dwt_decode(&tcd, &tilec, tilec.numresolutions);
stop = opj_clock();
stop_wc = opj_wallclock();
printf("time for %s: total = %.03f s, wallclock = %.03f s\n",
bench_decode ? "dwt_decode" : "dwt_encode",
stop - start,
stop_wc - start_wc);
printf("time for dwt_decode: %.03f s\n", stop - start);
if (display) {
if (bench_decode) {
if (display || check) {
if (display) {
printf("After IDWT\n");
} else {
printf("After FDWT\n");
}
k = 0;
for (j = 0; j < tilec.y1 - tilec.y0; j++) {
for (i = 0; i < tilec.x1 - tilec.x0; i++) {
if (irreversible) {
printf("%f ", ((OPJ_FLOAT32*)tilec.data)[k]);
} else {
printf("%d ", tilec.data[k]);
}
k ++;
}
printf("\n");
}
}
if ((display || check) && !irreversible) {
if (bench_decode) {
opj_dwt_encode(&tcd, &tilec);
} else {
opj_dwt_decode(&tcd, &tilec, tilec.numresolutions);
}
if (display && !irreversible) {
if (bench_decode) {
printf("After FDWT\n");
} else {
printf("After IDWT\n");
}
k = 0;
for (j = 0; j < tilec.y1 - tilec.y0; j++) {
for (i = 0; i < tilec.x1 - tilec.x0; i++) {
if (irreversible) {
printf("%f ", ((OPJ_FLOAT32*)tilec.data)[k]);
} else {
printf("%d ", tilec.data[k]);
}
printf("%d ", tilec.data[k]);
k ++;
}
printf("\n");
}
}
}
opj_dwt_encode(&tilec);
if (display) {
printf("After FDWT\n");
k = 0;
for (j = 0; j < tilec.y1 - tilec.y0; j++) {
for (i = 0; i < tilec.x1 - tilec.x0; i++) {
printf("%d ", tilec.data[k]);
k ++;
}
printf("\n");
}
}
if (check) {
size_t idx;
size_t nValues = (size_t)(tilec.x1 - tilec.x0) *
(size_t)(tilec.y1 - tilec.y0);
for (idx = 0; idx < nValues; idx++) {
if (tilec.data[idx] != getValue((OPJ_UINT32)idx)) {
printf("Difference found at idx = %u\n", (OPJ_UINT32)idx);
exit(1);
if (check) {
size_t idx;
size_t nValues = (size_t)(tilec.x1 - tilec.x0) *
(size_t)(tilec.y1 - tilec.y0);
for (idx = 0; i < (OPJ_INT32)nValues; i++) {
if (tilec.data[idx] != getValue((OPJ_UINT32)idx)) {
printf("Difference found at idx = %u\n", (OPJ_UINT32)idx);
exit(1);
}
}
}
}

View File

@ -43,6 +43,12 @@
/** @name Local static functions */
/*@{*/
/**
Write a bit
@param bio BIO handle
@param b Bit to write (0 or 1)
*/
static void opj_bio_putbit(opj_bio_t *bio, OPJ_UINT32 b);
/**
Read a bit
@param bio BIO handle
@ -94,6 +100,16 @@ static OPJ_BOOL opj_bio_bytein(opj_bio_t *bio)
return OPJ_TRUE;
}
static void opj_bio_putbit(opj_bio_t *bio, OPJ_UINT32 b)
{
if (bio->ct == 0) {
opj_bio_byteout(
bio); /* MSD: why not check the return value of this function ? */
}
bio->ct--;
bio->buf |= b << bio->ct;
}
static OPJ_UINT32 opj_bio_getbit(opj_bio_t *bio)
{
if (bio->ct == 0) {
@ -146,16 +162,6 @@ void opj_bio_init_dec(opj_bio_t *bio, OPJ_BYTE *bp, OPJ_UINT32 len)
bio->ct = 0;
}
void opj_bio_putbit(opj_bio_t *bio, OPJ_UINT32 b)
{
if (bio->ct == 0) {
opj_bio_byteout(
bio); /* MSD: why not check the return value of this function ? */
}
bio->ct--;
bio->buf |= b << bio->ct;
}
void opj_bio_write(opj_bio_t *bio, OPJ_UINT32 v, OPJ_UINT32 n)
{
OPJ_INT32 i;

View File

@ -106,14 +106,6 @@ Write bits
@param n Number of bits to write
*/
void opj_bio_write(opj_bio_t *bio, OPJ_UINT32 v, OPJ_UINT32 n);
/**
Write a bit
@param bio BIO handle
@param b Bit to write (0 or 1)
*/
void opj_bio_putbit(opj_bio_t *bio, OPJ_UINT32 b);
/**
Read bits
@param bio BIO handle

View File

@ -118,7 +118,7 @@ typedef struct opj_stream_private {
opj_stream_seek_fn m_seek_fn;
/**
* Actual data stored into the stream if read from. Data is read by chunk of fixed size.
* Actual data stored into the stream if readed from. Data is read by chunk of fixed size.
* you should never access this data directly.
*/
OPJ_BYTE * m_stored_data;

File diff suppressed because it is too large Load Diff

View File

@ -56,11 +56,9 @@ DWT.C are used by some function in TCD.C.
/**
Forward 5-3 wavelet transform in 2-D.
Apply a reversible DWT transform to a component of an image.
@param p_tcd TCD handle
@param tilec Tile component information (current tile)
*/
OPJ_BOOL opj_dwt_encode(opj_tcd_t *p_tcd,
opj_tcd_tilecomp_t * tilec);
OPJ_BOOL opj_dwt_encode(opj_tcd_tilecomp_t * tilec);
/**
Inverse 5-3 wavelet transform in 2-D.
@ -73,6 +71,12 @@ OPJ_BOOL opj_dwt_decode(opj_tcd_t *p_tcd,
opj_tcd_tilecomp_t* tilec,
OPJ_UINT32 numres);
/**
Get the gain of a subband for the reversible 5-3 DWT.
@param orient Number that identifies the subband (0->LL, 1->HL, 2->LH, 3->HH)
@return Returns 0 if orient = 0, returns 1 if orient = 1 or 2, returns 2 otherwise
*/
OPJ_UINT32 opj_dwt_getgain(OPJ_UINT32 orient) ;
/**
Get the norm of a wavelet function of a subband at a specified level for the reversible 5-3 DWT.
@param level Level of the wavelet function
@ -83,11 +87,9 @@ OPJ_FLOAT64 opj_dwt_getnorm(OPJ_UINT32 level, OPJ_UINT32 orient);
/**
Forward 9-7 wavelet transform in 2-D.
Apply an irreversible DWT transform to a component of an image.
@param p_tcd TCD handle
@param tilec Tile component information (current tile)
*/
OPJ_BOOL opj_dwt_encode_real(opj_tcd_t *p_tcd,
opj_tcd_tilecomp_t * tilec);
OPJ_BOOL opj_dwt_encode_real(opj_tcd_tilecomp_t * tilec);
/**
Inverse 9-7 wavelet transform in 2-D.
Apply an irreversible inverse DWT transform to a component of an image.
@ -99,6 +101,12 @@ OPJ_BOOL opj_dwt_decode_real(opj_tcd_t *p_tcd,
opj_tcd_tilecomp_t* OPJ_RESTRICT tilec,
OPJ_UINT32 numres);
/**
Get the gain of a subband for the irreversible 9-7 DWT.
@param orient Number that identifies the subband (0->LL, 1->HL, 2->LH, 3->HH)
@return Returns the gain of the 9-7 wavelet transform
*/
OPJ_UINT32 opj_dwt_getgain_real(OPJ_UINT32 orient);
/**
Get the norm of a wavelet function of a subband at a specified level for the irreversible 9-7 DWT
@param level Level of the wavelet function

File diff suppressed because it is too large Load Diff

View File

@ -48,8 +48,8 @@ opj_image_t* OPJ_CALLCONV opj_image_create(OPJ_UINT32 numcmpts,
image->color_space = clrspc;
image->numcomps = numcmpts;
/* allocate memory for the per-component information */
image->comps = (opj_image_comp_t*)opj_calloc(image->numcomps,
sizeof(opj_image_comp_t));
image->comps = (opj_image_comp_t*)opj_calloc(1,
image->numcomps * sizeof(opj_image_comp_t));
if (!image->comps) {
/* TODO replace with event manager, breaks API */
/* fprintf(stderr,"Unable to allocate memory for image.\n"); */
@ -66,6 +66,7 @@ opj_image_t* OPJ_CALLCONV opj_image_create(OPJ_UINT32 numcmpts,
comp->x0 = cmptparms[compno].x0;
comp->y0 = cmptparms[compno].y0;
comp->prec = cmptparms[compno].prec;
comp->bpp = cmptparms[compno].bpp;
comp->sgnd = cmptparms[compno].sgnd;
if (comp->h != 0 &&
(OPJ_SIZE_T)comp->w > SIZE_MAX / comp->h / sizeof(OPJ_INT32)) {

File diff suppressed because it is too large Load Diff

View File

@ -61,8 +61,6 @@ The functions in J2K.C have for goal to read/write the several parts of the code
#define J2K_CCP_CBLKSTY_VSC 0x08 /**< Vertically stripe causal context */
#define J2K_CCP_CBLKSTY_PTERM 0x10 /**< Predictable termination */
#define J2K_CCP_CBLKSTY_SEGSYM 0x20 /**< Segmentation symbols are used */
#define J2K_CCP_CBLKSTY_HT 0x40 /**< (high throughput) HT codeblocks */
#define J2K_CCP_CBLKSTY_HTMIXED 0x80 /**< MIXED mode HT codeblocks */
#define J2K_CCP_QNTSTY_NOQNT 0
#define J2K_CCP_QNTSTY_SIQNT 1
#define J2K_CCP_QNTSTY_SEQNT 2
@ -73,11 +71,9 @@ The functions in J2K.C have for goal to read/write the several parts of the code
#define J2K_MS_SOT 0xff90 /**< SOT marker value */
#define J2K_MS_SOD 0xff93 /**< SOD marker value */
#define J2K_MS_EOC 0xffd9 /**< EOC marker value */
#define J2K_MS_CAP 0xff50 /**< CAP marker value */
#define J2K_MS_SIZ 0xff51 /**< SIZ marker value */
#define J2K_MS_COD 0xff52 /**< COD marker value */
#define J2K_MS_COC 0xff53 /**< COC marker value */
#define J2K_MS_CPF 0xff59 /**< CPF marker value */
#define J2K_MS_RGN 0xff5e /**< RGN marker value */
#define J2K_MS_QCD 0xff5c /**< QCD marker value */
#define J2K_MS_QCC 0xff5d /**< QCC marker value */
@ -113,9 +109,6 @@ The functions in J2K.C have for goal to read/write the several parts of the code
#define J2K_MAX_POCS 32 /**< Maximum number of POCs */
#define J2K_TCD_MATRIX_MAX_LAYER_COUNT 10
#define J2K_TCD_MATRIX_MAX_RESOLUTION_COUNT 10
/* ----------------------------------------------------------------------- */
/**
@ -275,7 +268,7 @@ typedef struct opj_tcp {
OPJ_UINT32 ppt_data_size;
/** size of ppt_data*/
OPJ_UINT32 ppt_len;
/** PSNR values */
/** add fixed_quality */
OPJ_FLOAT32 distoratio[100];
/** tile-component coding parameters */
opj_tccp_t *tccps;
@ -317,14 +310,6 @@ typedef struct opj_tcp {
} opj_tcp_t;
/**
Rate allocation strategy
*/
typedef enum {
RATE_DISTORTION_RATIO = 0, /** allocation by rate/distortion */
FIXED_DISTORTION_RATIO = 1, /** allocation by fixed distortion ratio (PSNR) (fixed quality) */
FIXED_LAYER = 2, /** allocation by fixed layer (number of passes per layer / resolution / subband) */
} J2K_QUALITY_LAYER_ALLOCATION_STRATEGY;
typedef struct opj_encoding_param {
@ -336,8 +321,12 @@ typedef struct opj_encoding_param {
OPJ_INT32 *m_matrice;
/** Flag determining tile part generation*/
OPJ_BYTE m_tp_flag;
/** Quality layer allocation strategy */
J2K_QUALITY_LAYER_ALLOCATION_STRATEGY m_quality_layer_alloc_strategy;
/** allocation by rate/distortion */
OPJ_BITFIELD m_disto_alloc : 1;
/** allocation by fixed layer */
OPJ_BITFIELD m_fixed_alloc : 1;
/** add fixed_quality */
OPJ_BITFIELD m_fixed_quality : 1;
/** Enabling Tile part generation*/
OPJ_BITFIELD m_tp_on : 1;
}
@ -409,8 +398,6 @@ typedef struct opj_cp {
}
m_specific_param;
/** OPJ_TRUE if entire bit stream must be decoded, OPJ_FALSE if partial bitstream decoding allowed */
OPJ_BOOL strict;
/* UniPG>> */
#ifdef USE_JPWL
@ -495,10 +482,6 @@ typedef struct opj_j2k_dec {
* SOD reader function. FIXME NOT USED for the moment
*/
OPJ_BOOL m_last_tile_part;
OPJ_UINT32 m_numcomps_to_decode;
OPJ_UINT32 *m_comps_indices_to_decode;
/** to tell that a tile can be decoded. */
OPJ_BITFIELD m_can_decode : 1;
OPJ_BITFIELD m_discard_tiles : 1;
@ -516,12 +499,6 @@ typedef struct opj_j2k_enc {
/** Tile part number currently coding, taking into account POC. m_current_tile_part_number holds the total number of tile parts while encoding the last tile part.*/
OPJ_UINT32 m_current_tile_part_number; /*cur_tp_num */
/* whether to generate TLM markers */
OPJ_BOOL m_TLM;
/* whether the Ttlmi field in a TLM marker is a byte (otherwise a uint16) */
OPJ_BOOL m_Ttlmi_is_byte;
/**
locate the start position of the TLM marker
after encoding the tilepart, a jump (in j2k_write_sod) is done to the TLM marker to store the value of its length.
@ -550,17 +527,8 @@ typedef struct opj_j2k_enc {
OPJ_BYTE * m_header_tile_data;
/* size of the encoded_data */
OPJ_UINT32 m_header_tile_data_size;
/* whether to generate PLT markers */
OPJ_BOOL m_PLT;
/* reserved bytes in m_encoded_tile_size for PLT markers */
OPJ_UINT32 m_reserved_bytes_for_PLT;
/** Number of components */
OPJ_UINT32 m_nb_comps;
} opj_j2k_enc_t;
@ -605,16 +573,15 @@ typedef struct opj_j2k {
/** the current tile coder/decoder **/
struct opj_tcd * m_tcd;
/** Number of threads to use */
int m_num_threads;
/** Thread pool */
opj_thread_pool_t* m_tp;
/** Image width coming from JP2 IHDR box. 0 from a pure codestream */
OPJ_UINT32 ihdr_w;
/** Image height coming from JP2 IHDR box. 0 from a pure codestream */
OPJ_UINT32 ihdr_h;
/** Set to 1 by the decoder initialization if OPJ_DPARAMETERS_DUMP_FLAG is set */
OPJ_UINT32 enumcs;
unsigned int dump_state;
}
opj_j2k_t;
@ -634,8 +601,6 @@ Decoding parameters are returned in j2k->cp.
*/
void opj_j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters);
void opj_j2k_decoder_set_strict_mode(opj_j2k_t *j2k, OPJ_BOOL strict);
OPJ_BOOL opj_j2k_set_threads(opj_j2k_t *j2k, OPJ_UINT32 num_threads);
/**
@ -742,21 +707,6 @@ OPJ_BOOL opj_j2k_read_tile_header(opj_j2k_t * p_j2k,
opj_event_mgr_t * p_manager);
/** Sets the indices of the components to decode.
*
* @param p_j2k the jpeg2000 codec.
* @param numcomps Number of components to decode.
* @param comps_indices Array of num_compts indices (numbering starting at 0)
* corresponding to the components to decode.
* @param p_manager Event manager
*
* @return OPJ_TRUE in case of success.
*/
OPJ_BOOL opj_j2k_set_decoded_components(opj_j2k_t *p_j2k,
OPJ_UINT32 numcomps,
const OPJ_UINT32* comps_indices,
opj_event_mgr_t * p_manager);
/**
* Sets the given area to be decoded. This function should be called right after opj_read_header and before any tile header reading.
*
@ -858,19 +808,6 @@ OPJ_BOOL opj_j2k_set_decoded_resolution_factor(opj_j2k_t *p_j2k,
OPJ_UINT32 res_factor,
opj_event_mgr_t * p_manager);
/**
* Specify extra options for the encoder.
*
* @param p_j2k the jpeg2000 codec.
* @param p_options options
* @param p_manager the user event manager
*
* @see opj_encoder_set_extra_options() for more details.
*/
OPJ_BOOL opj_j2k_encoder_set_extra_options(
opj_j2k_t *p_j2k,
const char* const* p_options,
opj_event_mgr_t * p_manager);
/**
* Writes a tile.

View File

@ -331,14 +331,14 @@ static OPJ_BOOL opj_jp2_read_colr(opj_jp2_t *jp2,
/**
* Sets up the procedures to do on writing header after the codestream.
* Developers wanting to extend the library can add their own writing procedures.
* Developpers wanting to extend the library can add their own writing procedures.
*/
static OPJ_BOOL opj_jp2_setup_end_header_writing(opj_jp2_t *jp2,
opj_event_mgr_t * p_manager);
/**
* Sets up the procedures to do on reading header after the codestream.
* Developers wanting to extend the library can add their own writing procedures.
* Developpers wanting to extend the library can add their own writing procedures.
*/
static OPJ_BOOL opj_jp2_setup_end_header_reading(opj_jp2_t *jp2,
opj_event_mgr_t * p_manager);
@ -388,13 +388,13 @@ static OPJ_BOOL opj_jp2_read_boxhdr(opj_jp2_box_t *box,
/**
* Sets up the validation ,i.e. adds the procedures to launch to make sure the codec parameters
* are valid. Developers wanting to extend the library can add their own validation procedures.
* are valid. Developpers wanting to extend the library can add their own validation procedures.
*/
static OPJ_BOOL opj_jp2_setup_encoding_validation(opj_jp2_t *jp2,
opj_event_mgr_t * p_manager);
/**
* Sets up the procedures to do on writing header. Developers wanting to extend the library can add their own writing procedures.
* Sets up the procedures to do on writing header. Developpers wanting to extend the library can add their own writing procedures.
*/
static OPJ_BOOL opj_jp2_setup_header_writing(opj_jp2_t *jp2,
opj_event_mgr_t * p_manager);
@ -457,14 +457,14 @@ static OPJ_BOOL opj_jp2_read_boxhdr_char(opj_jp2_box_t *box,
/**
* Sets up the validation ,i.e. adds the procedures to launch to make sure the codec parameters
* are valid. Developers wanting to extend the library can add their own validation procedures.
* are valid. Developpers wanting to extend the library can add their own validation procedures.
*/
static OPJ_BOOL opj_jp2_setup_decoding_validation(opj_jp2_t *jp2,
opj_event_mgr_t * p_manager);
/**
* Sets up the procedures to do on reading header.
* Developers wanting to extend the library can add their own writing procedures.
* Developpers wanting to extend the library can add their own writing procedures.
*/
static OPJ_BOOL opj_jp2_setup_header_reading(opj_jp2_t *jp2,
opj_event_mgr_t * p_manager);
@ -586,12 +586,6 @@ static OPJ_BOOL opj_jp2_read_ihdr(opj_jp2_t *jp2,
opj_read_bytes(p_image_header_data, &(jp2->numcomps), 2); /* NC */
p_image_header_data += 2;
if (jp2->h < 1 || jp2->w < 1 || jp2->numcomps < 1) {
opj_event_msg(p_manager, EVT_ERROR,
"Wrong values for: w(%d) h(%d) numcomps(%d) (ihdr)\n",
jp2->w, jp2->h, jp2->numcomps);
return OPJ_FALSE;
}
if ((jp2->numcomps - 1U) >=
16384U) { /* unsigned underflow is well defined: 1U <= jp2->numcomps <= 16384U */
opj_event_msg(p_manager, EVT_ERROR, "Invalid number of components (ihdr)\n");
@ -1011,7 +1005,7 @@ static OPJ_BOOL opj_jp2_check_color(opj_image_t *image, opj_jp2_color_t *color,
if (!pcol_usage[i]) {
is_sane = 0U;
opj_event_msg(p_manager, EVT_WARNING,
"Component mapping seems wrong. Trying to correct.\n");
"Component mapping seems wrong. Trying to correct.\n", i);
break;
}
}
@ -1085,7 +1079,7 @@ static OPJ_BOOL opj_jp2_apply_pclr(opj_image_t *image,
/* Palette mapping: */
new_comps[i].data = (OPJ_INT32*)
opj_image_data_alloc(sizeof(OPJ_INT32) * old_comps[cmp].w * old_comps[cmp].h);
opj_image_data_alloc(old_comps[cmp].w * old_comps[cmp].h * sizeof(OPJ_INT32));
if (!new_comps[i].data) {
while (i > 0) {
-- i;
@ -1108,10 +1102,11 @@ static OPJ_BOOL opj_jp2_apply_pclr(opj_image_t *image,
pcol = cmap[i].pcol;
src = old_comps[cmp].data;
assert(src); /* verified above */
max = new_comps[i].w * new_comps[i].h;
max = new_comps[pcol].w * new_comps[pcol].h;
/* Direct use: */
if (cmap[i].mtyp == 0) {
assert(cmp == 0);
dst = new_comps[i].data;
assert(dst);
for (j = 0; j < max; ++j) {
@ -1136,9 +1131,9 @@ static OPJ_BOOL opj_jp2_apply_pclr(opj_image_t *image,
}
max = image->numcomps;
for (j = 0; j < max; ++j) {
if (old_comps[j].data) {
opj_image_data_free(old_comps[j].data);
for (i = 0; i < max; ++i) {
if (old_comps[i].data) {
opj_image_data_free(old_comps[i].data);
}
}
@ -1199,8 +1194,8 @@ static OPJ_BOOL opj_jp2_read_pclr(opj_jp2_t *jp2,
return OPJ_FALSE;
}
entries = (OPJ_UINT32*) opj_malloc(sizeof(OPJ_UINT32) * nr_channels *
nr_entries);
entries = (OPJ_UINT32*) opj_malloc((size_t)nr_channels * nr_entries * sizeof(
OPJ_UINT32));
if (!entries) {
return OPJ_FALSE;
}
@ -1590,7 +1585,9 @@ static OPJ_BOOL opj_jp2_read_colr(opj_jp2_t *jp2,
"COLR BOX meth value is not a regular value (%d), "
"so we will ignore the entire Colour Specification box. \n", jp2->meth);
}
if (jp2->color.jp2_has_colr) {
jp2->j2k->enumcs = jp2->enumcs;
}
return OPJ_TRUE;
}
@ -1610,11 +1607,6 @@ OPJ_BOOL opj_jp2_decode(opj_jp2_t *jp2,
return OPJ_FALSE;
}
if (jp2->j2k->m_specific_param.m_decoder.m_numcomps_to_decode) {
/* Bypass all JP2 component transforms */
return OPJ_TRUE;
}
if (!jp2->ignore_pclr_cmap_cdef) {
if (!opj_jp2_check_color(p_image, &(jp2->color), p_manager)) {
return OPJ_FALSE;
@ -1901,11 +1893,6 @@ void opj_jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters)
OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG;
}
void opj_jp2_decoder_set_strict_mode(opj_jp2_t *jp2, OPJ_BOOL strict)
{
opj_j2k_decoder_set_strict_mode(jp2->j2k, strict);
}
OPJ_BOOL opj_jp2_set_threads(opj_jp2_t *jp2, OPJ_UINT32 num_threads)
{
return opj_j2k_set_threads(jp2->j2k, num_threads);
@ -3082,16 +3069,6 @@ void opj_jp2_destroy(opj_jp2_t *jp2)
}
}
OPJ_BOOL opj_jp2_set_decoded_components(opj_jp2_t *p_jp2,
OPJ_UINT32 numcomps,
const OPJ_UINT32* comps_indices,
opj_event_mgr_t * p_manager)
{
return opj_j2k_set_decoded_components(p_jp2->j2k,
numcomps, comps_indices,
p_manager);
}
OPJ_BOOL opj_jp2_set_decode_area(opj_jp2_t *p_jp2,
opj_image_t* p_image,
OPJ_INT32 p_start_x, OPJ_INT32 p_start_y,
@ -3123,11 +3100,6 @@ OPJ_BOOL opj_jp2_get_tile(opj_jp2_t *p_jp2,
return OPJ_FALSE;
}
if (p_jp2->j2k->m_specific_param.m_decoder.m_numcomps_to_decode) {
/* Bypass all JP2 component transforms */
return OPJ_TRUE;
}
if (!opj_jp2_check_color(p_image, &(p_jp2->color), p_manager)) {
return OPJ_FALSE;
}
@ -3245,18 +3217,6 @@ OPJ_BOOL opj_jp2_set_decoded_resolution_factor(opj_jp2_t *p_jp2,
return opj_j2k_set_decoded_resolution_factor(p_jp2->j2k, res_factor, p_manager);
}
/* ----------------------------------------------------------------------- */
OPJ_BOOL opj_jp2_encoder_set_extra_options(
opj_jp2_t *p_jp2,
const char* const* p_options,
opj_event_mgr_t * p_manager)
{
return opj_j2k_encoder_set_extra_options(p_jp2->j2k, p_options, p_manager);
}
/* ----------------------------------------------------------------------- */
/* JPIP specific */
#ifdef USE_JPIP

View File

@ -235,21 +235,6 @@ Decoding parameters are returned in jp2->j2k->cp.
*/
void opj_jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters);
/**
Set the strict mode parameter. When strict mode is enabled, the entire
bitstream must be decoded or an error is returned. When it is disabled,
the decoder will decode partial bitstreams.
@param jp2 JP2 decompressor handle
@param strict OPJ_TRUE for strict mode
*/
void opj_jp2_decoder_set_strict_mode(opj_jp2_t *jp2, OPJ_BOOL strict);
/** Allocates worker threads for the compressor/decompressor.
*
* @param jp2 JP2 decompressor handle
* @param num_threads Number of threads.
* @return OPJ_TRUE in case of success.
*/
OPJ_BOOL opj_jp2_set_threads(opj_jp2_t *jp2, OPJ_UINT32 num_threads);
/**
@ -342,21 +327,6 @@ OPJ_BOOL opj_jp2_read_header(opj_stream_private_t *p_stream,
opj_image_t ** p_image,
opj_event_mgr_t * p_manager);
/** Sets the indices of the components to decode.
*
* @param jp2 JP2 decompressor handle
* @param numcomps Number of components to decode.
* @param comps_indices Array of num_compts indices (numbering starting at 0)
* corresponding to the components to decode.
* @param p_manager Event manager;
*
* @return OPJ_TRUE in case of success.
*/
OPJ_BOOL opj_jp2_set_decoded_components(opj_jp2_t *jp2,
OPJ_UINT32 numcomps,
const OPJ_UINT32* comps_indices,
opj_event_mgr_t * p_manager);
/**
* Reads a tile header.
* @param p_jp2 the jpeg2000 codec.
@ -468,20 +438,6 @@ OPJ_BOOL opj_jp2_set_decoded_resolution_factor(opj_jp2_t *p_jp2,
OPJ_UINT32 res_factor,
opj_event_mgr_t * p_manager);
/**
* Specify extra options for the encoder.
*
* @param p_jp2 the jpeg2000 codec.
* @param p_options options
* @param p_manager the user event manager
*
* @see opj_encoder_set_extra_options() for more details.
*/
OPJ_BOOL opj_jp2_encoder_set_extra_options(
opj_jp2_t *p_jp2,
const char* const* p_options,
opj_event_mgr_t * p_manager);
/* TODO MSD: clean these 3 functions */
/**

View File

@ -1,9 +1,9 @@
prefix=@CMAKE_INSTALL_PREFIX@
bindir=@bindir@
mandir=@mandir@
docdir=@docdir@
libdir=@libdir@
includedir=@includedir@
bindir=${prefix}/@OPENJPEG_INSTALL_BIN_DIR@
mandir=${prefix}/@OPENJPEG_INSTALL_MAN_DIR@
docdir=${prefix}/@OPENJPEG_INSTALL_DOC_DIR@
libdir=${prefix}/@OPENJPEG_INSTALL_LIB_DIR@
includedir=${prefix}/@OPENJPEG_INSTALL_INCLUDE_DIR@
Name: openjp2
Description: JPEG2000 library (Part 1 and 2)
@ -12,4 +12,3 @@ Version: @OPENJPEG_VERSION@
Libs: -L${libdir} -lopenjp2
Libs.private: -lm
Cflags: -I${includedir}
Cflags.private: -DOPJ_STATIC

View File

@ -183,7 +183,7 @@ void opj_mct_decode(
OPJ_INT32* OPJ_RESTRICT c2,
OPJ_SIZE_T n)
{
OPJ_SIZE_T i;
OPJ_UINT32 i;
for (i = 0; i < n; ++i) {
OPJ_INT32 y = c0[i];
OPJ_INT32 u = c1[i];
@ -209,72 +209,175 @@ OPJ_FLOAT64 opj_mct_getnorm(OPJ_UINT32 compno)
/* <summary> */
/* Forward irreversible MCT. */
/* </summary> */
#ifdef __SSE4_1__
void opj_mct_encode_real(
OPJ_FLOAT32* OPJ_RESTRICT c0,
OPJ_FLOAT32* OPJ_RESTRICT c1,
OPJ_FLOAT32* OPJ_RESTRICT c2,
OPJ_INT32* OPJ_RESTRICT c0,
OPJ_INT32* OPJ_RESTRICT c1,
OPJ_INT32* OPJ_RESTRICT c2,
OPJ_SIZE_T n)
{
OPJ_SIZE_T i;
#ifdef __SSE__
const __m128 YR = _mm_set1_ps(0.299f);
const __m128 YG = _mm_set1_ps(0.587f);
const __m128 YB = _mm_set1_ps(0.114f);
const __m128 UR = _mm_set1_ps(-0.16875f);
const __m128 UG = _mm_set1_ps(-0.331260f);
const __m128 UB = _mm_set1_ps(0.5f);
const __m128 VR = _mm_set1_ps(0.5f);
const __m128 VG = _mm_set1_ps(-0.41869f);
const __m128 VB = _mm_set1_ps(-0.08131f);
for (i = 0; i < (n >> 3); i ++) {
__m128 r, g, b, y, u, v;
const OPJ_SIZE_T len = n;
r = _mm_load_ps(c0);
g = _mm_load_ps(c1);
b = _mm_load_ps(c2);
y = _mm_add_ps(_mm_add_ps(_mm_mul_ps(r, YR), _mm_mul_ps(g, YG)),
_mm_mul_ps(b, YB));
u = _mm_add_ps(_mm_add_ps(_mm_mul_ps(r, UR), _mm_mul_ps(g, UG)),
_mm_mul_ps(b, UB));
v = _mm_add_ps(_mm_add_ps(_mm_mul_ps(r, VR), _mm_mul_ps(g, VG)),
_mm_mul_ps(b, VB));
_mm_store_ps(c0, y);
_mm_store_ps(c1, u);
_mm_store_ps(c2, v);
c0 += 4;
c1 += 4;
c2 += 4;
const __m128i ry = _mm_set1_epi32(2449);
const __m128i gy = _mm_set1_epi32(4809);
const __m128i by = _mm_set1_epi32(934);
const __m128i ru = _mm_set1_epi32(1382);
const __m128i gu = _mm_set1_epi32(2714);
/* const __m128i bu = _mm_set1_epi32(4096); */
/* const __m128i rv = _mm_set1_epi32(4096); */
const __m128i gv = _mm_set1_epi32(3430);
const __m128i bv = _mm_set1_epi32(666);
const __m128i mulround = _mm_shuffle_epi32(_mm_cvtsi32_si128(4096),
_MM_SHUFFLE(1, 0, 1, 0));
r = _mm_load_ps(c0);
g = _mm_load_ps(c1);
b = _mm_load_ps(c2);
y = _mm_add_ps(_mm_add_ps(_mm_mul_ps(r, YR), _mm_mul_ps(g, YG)),
_mm_mul_ps(b, YB));
u = _mm_add_ps(_mm_add_ps(_mm_mul_ps(r, UR), _mm_mul_ps(g, UG)),
_mm_mul_ps(b, UB));
v = _mm_add_ps(_mm_add_ps(_mm_mul_ps(r, VR), _mm_mul_ps(g, VG)),
_mm_mul_ps(b, VB));
_mm_store_ps(c0, y);
_mm_store_ps(c1, u);
_mm_store_ps(c2, v);
c0 += 4;
c1 += 4;
c2 += 4;
for (i = 0; i < (len & ~3U); i += 4) {
__m128i lo, hi;
__m128i y, u, v;
__m128i r = _mm_load_si128((const __m128i *) & (c0[i]));
__m128i g = _mm_load_si128((const __m128i *) & (c1[i]));
__m128i b = _mm_load_si128((const __m128i *) & (c2[i]));
lo = r;
hi = _mm_shuffle_epi32(r, _MM_SHUFFLE(3, 3, 1, 1));
lo = _mm_mul_epi32(lo, ry);
hi = _mm_mul_epi32(hi, ry);
lo = _mm_add_epi64(lo, mulround);
hi = _mm_add_epi64(hi, mulround);
lo = _mm_srli_epi64(lo, 13);
hi = _mm_slli_epi64(hi, 32 - 13);
y = _mm_blend_epi16(lo, hi, 0xCC);
lo = g;
hi = _mm_shuffle_epi32(g, _MM_SHUFFLE(3, 3, 1, 1));
lo = _mm_mul_epi32(lo, gy);
hi = _mm_mul_epi32(hi, gy);
lo = _mm_add_epi64(lo, mulround);
hi = _mm_add_epi64(hi, mulround);
lo = _mm_srli_epi64(lo, 13);
hi = _mm_slli_epi64(hi, 32 - 13);
y = _mm_add_epi32(y, _mm_blend_epi16(lo, hi, 0xCC));
lo = b;
hi = _mm_shuffle_epi32(b, _MM_SHUFFLE(3, 3, 1, 1));
lo = _mm_mul_epi32(lo, by);
hi = _mm_mul_epi32(hi, by);
lo = _mm_add_epi64(lo, mulround);
hi = _mm_add_epi64(hi, mulround);
lo = _mm_srli_epi64(lo, 13);
hi = _mm_slli_epi64(hi, 32 - 13);
y = _mm_add_epi32(y, _mm_blend_epi16(lo, hi, 0xCC));
_mm_store_si128((__m128i *) & (c0[i]), y);
/*lo = b;
hi = _mm_shuffle_epi32(b, _MM_SHUFFLE(3, 3, 1, 1));
lo = _mm_mul_epi32(lo, mulround);
hi = _mm_mul_epi32(hi, mulround);*/
lo = _mm_cvtepi32_epi64(_mm_shuffle_epi32(b, _MM_SHUFFLE(3, 2, 2, 0)));
hi = _mm_cvtepi32_epi64(_mm_shuffle_epi32(b, _MM_SHUFFLE(3, 2, 3, 1)));
lo = _mm_slli_epi64(lo, 12);
hi = _mm_slli_epi64(hi, 12);
lo = _mm_add_epi64(lo, mulround);
hi = _mm_add_epi64(hi, mulround);
lo = _mm_srli_epi64(lo, 13);
hi = _mm_slli_epi64(hi, 32 - 13);
u = _mm_blend_epi16(lo, hi, 0xCC);
lo = r;
hi = _mm_shuffle_epi32(r, _MM_SHUFFLE(3, 3, 1, 1));
lo = _mm_mul_epi32(lo, ru);
hi = _mm_mul_epi32(hi, ru);
lo = _mm_add_epi64(lo, mulround);
hi = _mm_add_epi64(hi, mulround);
lo = _mm_srli_epi64(lo, 13);
hi = _mm_slli_epi64(hi, 32 - 13);
u = _mm_sub_epi32(u, _mm_blend_epi16(lo, hi, 0xCC));
lo = g;
hi = _mm_shuffle_epi32(g, _MM_SHUFFLE(3, 3, 1, 1));
lo = _mm_mul_epi32(lo, gu);
hi = _mm_mul_epi32(hi, gu);
lo = _mm_add_epi64(lo, mulround);
hi = _mm_add_epi64(hi, mulround);
lo = _mm_srli_epi64(lo, 13);
hi = _mm_slli_epi64(hi, 32 - 13);
u = _mm_sub_epi32(u, _mm_blend_epi16(lo, hi, 0xCC));
_mm_store_si128((__m128i *) & (c1[i]), u);
/*lo = r;
hi = _mm_shuffle_epi32(r, _MM_SHUFFLE(3, 3, 1, 1));
lo = _mm_mul_epi32(lo, mulround);
hi = _mm_mul_epi32(hi, mulround);*/
lo = _mm_cvtepi32_epi64(_mm_shuffle_epi32(r, _MM_SHUFFLE(3, 2, 2, 0)));
hi = _mm_cvtepi32_epi64(_mm_shuffle_epi32(r, _MM_SHUFFLE(3, 2, 3, 1)));
lo = _mm_slli_epi64(lo, 12);
hi = _mm_slli_epi64(hi, 12);
lo = _mm_add_epi64(lo, mulround);
hi = _mm_add_epi64(hi, mulround);
lo = _mm_srli_epi64(lo, 13);
hi = _mm_slli_epi64(hi, 32 - 13);
v = _mm_blend_epi16(lo, hi, 0xCC);
lo = g;
hi = _mm_shuffle_epi32(g, _MM_SHUFFLE(3, 3, 1, 1));
lo = _mm_mul_epi32(lo, gv);
hi = _mm_mul_epi32(hi, gv);
lo = _mm_add_epi64(lo, mulround);
hi = _mm_add_epi64(hi, mulround);
lo = _mm_srli_epi64(lo, 13);
hi = _mm_slli_epi64(hi, 32 - 13);
v = _mm_sub_epi32(v, _mm_blend_epi16(lo, hi, 0xCC));
lo = b;
hi = _mm_shuffle_epi32(b, _MM_SHUFFLE(3, 3, 1, 1));
lo = _mm_mul_epi32(lo, bv);
hi = _mm_mul_epi32(hi, bv);
lo = _mm_add_epi64(lo, mulround);
hi = _mm_add_epi64(hi, mulround);
lo = _mm_srli_epi64(lo, 13);
hi = _mm_slli_epi64(hi, 32 - 13);
v = _mm_sub_epi32(v, _mm_blend_epi16(lo, hi, 0xCC));
_mm_store_si128((__m128i *) & (c2[i]), v);
}
n &= 7;
#endif
for (i = 0; i < n; ++i) {
OPJ_FLOAT32 r = c0[i];
OPJ_FLOAT32 g = c1[i];
OPJ_FLOAT32 b = c2[i];
OPJ_FLOAT32 y = 0.299f * r + 0.587f * g + 0.114f * b;
OPJ_FLOAT32 u = -0.16875f * r - 0.331260f * g + 0.5f * b;
OPJ_FLOAT32 v = 0.5f * r - 0.41869f * g - 0.08131f * b;
for (; i < len; ++i) {
OPJ_INT32 r = c0[i];
OPJ_INT32 g = c1[i];
OPJ_INT32 b = c2[i];
OPJ_INT32 y = opj_int_fix_mul(r, 2449) + opj_int_fix_mul(g,
4809) + opj_int_fix_mul(b, 934);
OPJ_INT32 u = -opj_int_fix_mul(r, 1382) - opj_int_fix_mul(g,
2714) + opj_int_fix_mul(b, 4096);
OPJ_INT32 v = opj_int_fix_mul(r, 4096) - opj_int_fix_mul(g,
3430) - opj_int_fix_mul(b, 666);
c0[i] = y;
c1[i] = u;
c2[i] = v;
}
}
#else
void opj_mct_encode_real(
OPJ_INT32* OPJ_RESTRICT c0,
OPJ_INT32* OPJ_RESTRICT c1,
OPJ_INT32* OPJ_RESTRICT c2,
OPJ_SIZE_T n)
{
OPJ_UINT32 i;
for (i = 0; i < n; ++i) {
OPJ_INT32 r = c0[i];
OPJ_INT32 g = c1[i];
OPJ_INT32 b = c2[i];
OPJ_INT32 y = opj_int_fix_mul(r, 2449) + opj_int_fix_mul(g,
4809) + opj_int_fix_mul(b, 934);
OPJ_INT32 u = -opj_int_fix_mul(r, 1382) - opj_int_fix_mul(g,
2714) + opj_int_fix_mul(b, 4096);
OPJ_INT32 v = opj_int_fix_mul(r, 4096) - opj_int_fix_mul(g,
3430) - opj_int_fix_mul(b, 666);
c0[i] = y;
c1[i] = u;
c2[i] = v;
}
}
#endif
/* <summary> */
/* Inverse irreversible MCT. */
@ -285,7 +388,7 @@ void opj_mct_decode_real(
OPJ_FLOAT32* OPJ_RESTRICT c2,
OPJ_SIZE_T n)
{
OPJ_SIZE_T i;
OPJ_UINT32 i;
#ifdef __SSE__
__m128 vrv, vgu, vgv, vbu;
vrv = _mm_set1_ps(1.402f);
@ -457,7 +560,7 @@ void opj_calculate_norms(OPJ_FLOAT64 * pNorms,
for (j = 0; j < pNbComps; ++j) {
lCurrentValue = lMatrix[lIndex];
lIndex += pNbComps;
lNorms[i] += (OPJ_FLOAT64) lCurrentValue * lCurrentValue;
lNorms[i] += lCurrentValue * lCurrentValue;
}
lNorms[i] = sqrt(lNorms[i]);
}

View File

@ -85,9 +85,8 @@ Apply an irreversible multi-component transform to an image
@param c2 Samples blue component
@param n Number of samples for each component
*/
void opj_mct_encode_real(OPJ_FLOAT32* OPJ_RESTRICT c0,
OPJ_FLOAT32* OPJ_RESTRICT c1,
OPJ_FLOAT32* OPJ_RESTRICT c2, OPJ_SIZE_T n);
void opj_mct_encode_real(OPJ_INT32* OPJ_RESTRICT c0, OPJ_INT32* OPJ_RESTRICT c1,
OPJ_INT32* OPJ_RESTRICT c2, OPJ_SIZE_T n);
/**
Apply an irreversible multi-component inverse transform to an image
@param c0 Samples for luminance component

View File

@ -46,6 +46,27 @@
/** @name Local static functions */
/*@{*/
/**
Output a byte, doing bit-stuffing if necessary.
After a 0xff byte, the next byte must be smaller than 0x90.
@param mqc MQC handle
*/
static void opj_mqc_byteout(opj_mqc_t *mqc);
/**
Renormalize mqc->a and mqc->c while encoding, so that mqc->a stays between 0x8000 and 0x10000
@param mqc MQC handle
*/
static void opj_mqc_renorme(opj_mqc_t *mqc);
/**
Encode the most probable symbol
@param mqc MQC handle
*/
static void opj_mqc_codemps(opj_mqc_t *mqc);
/**
Encode the most least symbol
@param mqc MQC handle
*/
static void opj_mqc_codelps(opj_mqc_t *mqc);
/**
Fill mqc->c with 1's for flushing
@param mqc MQC handle
@ -161,6 +182,80 @@ static const opj_mqc_state_t mqc_states[47 * 2] = {
==========================================================
*/
static void opj_mqc_byteout(opj_mqc_t *mqc)
{
/* bp is initialized to start - 1 in opj_mqc_init_enc() */
/* but this is safe, see opj_tcd_code_block_enc_allocate_data() */
assert(mqc->bp >= mqc->start - 1);
if (*mqc->bp == 0xff) {
mqc->bp++;
*mqc->bp = (OPJ_BYTE)(mqc->c >> 20);
mqc->c &= 0xfffff;
mqc->ct = 7;
} else {
if ((mqc->c & 0x8000000) == 0) {
mqc->bp++;
*mqc->bp = (OPJ_BYTE)(mqc->c >> 19);
mqc->c &= 0x7ffff;
mqc->ct = 8;
} else {
(*mqc->bp)++;
if (*mqc->bp == 0xff) {
mqc->c &= 0x7ffffff;
mqc->bp++;
*mqc->bp = (OPJ_BYTE)(mqc->c >> 20);
mqc->c &= 0xfffff;
mqc->ct = 7;
} else {
mqc->bp++;
*mqc->bp = (OPJ_BYTE)(mqc->c >> 19);
mqc->c &= 0x7ffff;
mqc->ct = 8;
}
}
}
}
static void opj_mqc_renorme(opj_mqc_t *mqc)
{
do {
mqc->a <<= 1;
mqc->c <<= 1;
mqc->ct--;
if (mqc->ct == 0) {
opj_mqc_byteout(mqc);
}
} while ((mqc->a & 0x8000) == 0);
}
static void opj_mqc_codemps(opj_mqc_t *mqc)
{
mqc->a -= (*mqc->curctx)->qeval;
if ((mqc->a & 0x8000) == 0) {
if (mqc->a < (*mqc->curctx)->qeval) {
mqc->a = (*mqc->curctx)->qeval;
} else {
mqc->c += (*mqc->curctx)->qeval;
}
*mqc->curctx = (*mqc->curctx)->nmps;
opj_mqc_renorme(mqc);
} else {
mqc->c += (*mqc->curctx)->qeval;
}
}
static void opj_mqc_codelps(opj_mqc_t *mqc)
{
mqc->a -= (*mqc->curctx)->qeval;
if (mqc->a < (*mqc->curctx)->qeval) {
mqc->c += (*mqc->curctx)->qeval;
} else {
mqc->a = (*mqc->curctx)->qeval;
}
*mqc->curctx = (*mqc->curctx)->nlps;
opj_mqc_renorme(mqc);
}
static void opj_mqc_setbits(opj_mqc_t *mqc)
{
OPJ_UINT32 tempc = mqc->c + mqc->a;
@ -208,6 +303,14 @@ void opj_mqc_init_enc(opj_mqc_t *mqc, OPJ_BYTE *bp)
mqc->end_of_byte_stream_counter = 0;
}
void opj_mqc_encode(opj_mqc_t *mqc, OPJ_UINT32 d)
{
if ((*mqc->curctx)->mps == d) {
opj_mqc_codemps(mqc);
} else {
opj_mqc_codelps(mqc);
}
}
void opj_mqc_flush(opj_mqc_t *mqc)
{
@ -226,6 +329,8 @@ void opj_mqc_flush(opj_mqc_t *mqc)
}
}
#define BYPASS_CT_INIT 0xDEADBEEF
void opj_mqc_bypass_init_enc(opj_mqc_t *mqc)
{
/* This function is normally called after at least one opj_mqc_flush() */
@ -370,43 +475,6 @@ void opj_mqc_erterm_enc(opj_mqc_t *mqc)
}
}
static INLINE void opj_mqc_renorme(opj_mqc_t *mqc)
{
opj_mqc_renorme_macro(mqc, mqc->a, mqc->c, mqc->ct);
}
/**
Encode the most probable symbol
@param mqc MQC handle
*/
static INLINE void opj_mqc_codemps(opj_mqc_t *mqc)
{
opj_mqc_codemps_macro(mqc, mqc->curctx, mqc->a, mqc->c, mqc->ct);
}
/**
Encode the most least symbol
@param mqc MQC handle
*/
static INLINE void opj_mqc_codelps(opj_mqc_t *mqc)
{
opj_mqc_codelps_macro(mqc, mqc->curctx, mqc->a, mqc->c, mqc->ct);
}
/**
Encode a symbol using the MQ-coder
@param mqc MQC handle
@param d The symbol to be encoded (0 or 1)
*/
static INLINE void opj_mqc_encode(opj_mqc_t *mqc, OPJ_UINT32 d)
{
if ((*mqc->curctx)->mps == d) {
opj_mqc_codemps(mqc);
} else {
opj_mqc_codelps(mqc);
}
}
void opj_mqc_segmark_enc(opj_mqc_t *mqc)
{
OPJ_UINT32 i;
@ -489,36 +557,4 @@ void opj_mqc_setstate(opj_mqc_t *mqc, OPJ_UINT32 ctxno, OPJ_UINT32 msb,
mqc->ctxs[ctxno] = &mqc_states[msb + (OPJ_UINT32)(prob << 1)];
}
void opj_mqc_byteout(opj_mqc_t *mqc)
{
/* bp is initialized to start - 1 in opj_mqc_init_enc() */
/* but this is safe, see opj_tcd_code_block_enc_allocate_data() */
assert(mqc->bp >= mqc->start - 1);
if (*mqc->bp == 0xff) {
mqc->bp++;
*mqc->bp = (OPJ_BYTE)(mqc->c >> 20);
mqc->c &= 0xfffff;
mqc->ct = 7;
} else {
if ((mqc->c & 0x8000000) == 0) {
mqc->bp++;
*mqc->bp = (OPJ_BYTE)(mqc->c >> 19);
mqc->c &= 0x7ffff;
mqc->ct = 8;
} else {
(*mqc->bp)++;
if (*mqc->bp == 0xff) {
mqc->c &= 0x7ffffff;
mqc->bp++;
*mqc->bp = (OPJ_BYTE)(mqc->c >> 20);
mqc->c &= 0xfffff;
mqc->ct = 7;
} else {
mqc->bp++;
*mqc->bp = (OPJ_BYTE)(mqc->c >> 19);
mqc->c &= 0x7ffff;
mqc->ct = 8;
}
}
}
}

View File

@ -96,8 +96,6 @@ typedef struct opj_mqc {
OPJ_BYTE backup[OPJ_COMMON_CBLK_DATA_EXTRA];
} opj_mqc_t;
#define BYPASS_CT_INIT 0xDEADBEEF
#include "mqc_inl.h"
/** @name Exported functions */
@ -137,7 +135,12 @@ Set the current context used for coding/decoding
@param ctxno Number that identifies the context
*/
#define opj_mqc_setcurctx(mqc, ctxno) (mqc)->curctx = &(mqc)->ctxs[(OPJ_UINT32)(ctxno)]
/**
Encode a symbol using the MQ-coder
@param mqc MQC handle
@param d The symbol to be encoded (0 or 1)
*/
void opj_mqc_encode(opj_mqc_t *mqc, OPJ_UINT32 d);
/**
Flush the encoder, so that all remaining data is written
@param mqc MQC handle

View File

@ -156,13 +156,13 @@ static INLINE OPJ_UINT32 opj_mqc_raw_decode(opj_mqc_t *mqc)
} \
}
#define DOWNLOAD_MQC_VARIABLES(mqc, curctx, a, c, ct) \
#define DOWNLOAD_MQC_VARIABLES(mqc, curctx, c, a, ct) \
register const opj_mqc_state_t **curctx = mqc->curctx; \
register OPJ_UINT32 c = mqc->c; \
register OPJ_UINT32 a = mqc->a; \
register OPJ_UINT32 ct = mqc->ct
#define UPLOAD_MQC_VARIABLES(mqc, curctx, a, c, ct) \
#define UPLOAD_MQC_VARIABLES(mqc, curctx, c, a, ct) \
mqc->curctx = curctx; \
mqc->c = c; \
mqc->a = a; \
@ -193,90 +193,4 @@ Decode a symbol
#define opj_mqc_decode(d, mqc) \
opj_mqc_decode_macro(d, mqc, mqc->curctx, mqc->a, mqc->c, mqc->ct)
/**
Output a byte, doing bit-stuffing if necessary.
After a 0xff byte, the next byte must be smaller than 0x90.
@param mqc MQC handle
*/
void opj_mqc_byteout(opj_mqc_t *mqc);
/**
Renormalize mqc->a and mqc->c while encoding, so that mqc->a stays between 0x8000 and 0x10000
@param mqc MQC handle
@param a_ value of mqc->a
@param c_ value of mqc->c_
@param ct_ value of mqc->ct_
*/
#define opj_mqc_renorme_macro(mqc, a_, c_, ct_) \
{ \
do { \
a_ <<= 1; \
c_ <<= 1; \
ct_--; \
if (ct_ == 0) { \
mqc->c = c_; \
opj_mqc_byteout(mqc); \
c_ = mqc->c; \
ct_ = mqc->ct; \
} \
} while( (a_ & 0x8000) == 0); \
}
#define opj_mqc_codemps_macro(mqc, curctx, a, c, ct) \
{ \
a -= (*curctx)->qeval; \
if ((a & 0x8000) == 0) { \
if (a < (*curctx)->qeval) { \
a = (*curctx)->qeval; \
} else { \
c += (*curctx)->qeval; \
} \
*curctx = (*curctx)->nmps; \
opj_mqc_renorme_macro(mqc, a, c, ct); \
} else { \
c += (*curctx)->qeval; \
} \
}
#define opj_mqc_codelps_macro(mqc, curctx, a, c, ct) \
{ \
a -= (*curctx)->qeval; \
if (a < (*curctx)->qeval) { \
c += (*curctx)->qeval; \
} else { \
a = (*curctx)->qeval; \
} \
*curctx = (*curctx)->nlps; \
opj_mqc_renorme_macro(mqc, a, c, ct); \
}
#define opj_mqc_encode_macro(mqc, curctx, a, c, ct, d) \
{ \
if ((*curctx)->mps == (d)) { \
opj_mqc_codemps_macro(mqc, curctx, a, c, ct); \
} else { \
opj_mqc_codelps_macro(mqc, curctx, a, c, ct); \
} \
}
#define opj_mqc_bypass_enc_macro(mqc, c, ct, d) \
{\
if (ct == BYPASS_CT_INIT) {\
ct = 8;\
}\
ct--;\
c = c + ((d) << ct);\
if (ct == 0) {\
*mqc->bp = (OPJ_BYTE)c;\
ct = 8;\
/* If the previous byte was 0xff, make sure that the next msb is 0 */ \
if (*mqc->bp == 0xff) {\
ct = 7;\
}\
mqc->bp++;\
c = 0;\
}\
}
#endif /* OPJ_MQC_INL_H */

View File

@ -89,16 +89,14 @@ OPJ_BOOL OPJ_CALLCONV opj_set_error_handler(opj_codec_t * p_codec,
/* ---------------------------------------------------------------------- */
static OPJ_SIZE_T opj_read_from_file(void * p_buffer, OPJ_SIZE_T p_nb_bytes,
void * p_user_data)
FILE * p_file)
{
FILE* p_file = (FILE*)p_user_data;
OPJ_SIZE_T l_nb_read = fread(p_buffer, 1, p_nb_bytes, (FILE*)p_file);
OPJ_SIZE_T l_nb_read = fread(p_buffer, 1, p_nb_bytes, p_file);
return l_nb_read ? l_nb_read : (OPJ_SIZE_T) - 1;
}
static OPJ_UINT64 opj_get_data_length_from_file(void * p_user_data)
static OPJ_UINT64 opj_get_data_length_from_file(FILE * p_file)
{
FILE* p_file = (FILE*)p_user_data;
OPJ_OFF_T file_length = 0;
OPJ_FSEEK(p_file, 0, SEEK_END);
@ -109,38 +107,29 @@ static OPJ_UINT64 opj_get_data_length_from_file(void * p_user_data)
}
static OPJ_SIZE_T opj_write_from_file(void * p_buffer, OPJ_SIZE_T p_nb_bytes,
void * p_user_data)
FILE * p_file)
{
FILE* p_file = (FILE*)p_user_data;
return fwrite(p_buffer, 1, p_nb_bytes, p_file);
}
static OPJ_OFF_T opj_skip_from_file(OPJ_OFF_T p_nb_bytes, void * p_user_data)
static OPJ_OFF_T opj_skip_from_file(OPJ_OFF_T p_nb_bytes, FILE * p_user_data)
{
FILE* p_file = (FILE*)p_user_data;
if (OPJ_FSEEK(p_file, p_nb_bytes, SEEK_CUR)) {
if (OPJ_FSEEK(p_user_data, p_nb_bytes, SEEK_CUR)) {
return -1;
}
return p_nb_bytes;
}
static OPJ_BOOL opj_seek_from_file(OPJ_OFF_T p_nb_bytes, void * p_user_data)
static OPJ_BOOL opj_seek_from_file(OPJ_OFF_T p_nb_bytes, FILE * p_user_data)
{
FILE* p_file = (FILE*)p_user_data;
if (OPJ_FSEEK(p_file, p_nb_bytes, SEEK_SET)) {
if (OPJ_FSEEK(p_user_data, p_nb_bytes, SEEK_SET)) {
return OPJ_FALSE;
}
return OPJ_TRUE;
}
static void opj_close_from_file(void* p_user_data)
{
FILE* p_file = (FILE*)p_user_data;
fclose(p_file);
}
/* ---------------------------------------------------------------------- */
#ifdef _WIN32
#ifndef OPJ_STATIC
@ -219,10 +208,6 @@ opj_codec_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT p_format)
l_codec->m_codec_data.m_decompression.opj_setup_decoder =
(void (*)(void *, opj_dparameters_t *)) opj_j2k_setup_decoder;
l_codec->m_codec_data.m_decompression.opj_decoder_set_strict_mode =
(void (*)(void *, OPJ_BOOL)) opj_j2k_decoder_set_strict_mode;
l_codec->m_codec_data.m_decompression.opj_read_tile_header =
(OPJ_BOOL(*)(void *,
OPJ_UINT32*,
@ -260,12 +245,6 @@ opj_codec_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT p_format)
OPJ_UINT32 res_factor,
struct opj_event_mgr * p_manager)) opj_j2k_set_decoded_resolution_factor;
l_codec->m_codec_data.m_decompression.opj_set_decoded_components =
(OPJ_BOOL(*)(void * p_codec,
OPJ_UINT32 numcomps,
const OPJ_UINT32 * comps_indices,
struct opj_event_mgr * p_manager)) opj_j2k_set_decoded_components;
l_codec->opj_set_threads =
(OPJ_BOOL(*)(void * p_codec, OPJ_UINT32 num_threads)) opj_j2k_set_threads;
@ -330,9 +309,6 @@ opj_codec_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT p_format)
l_codec->m_codec_data.m_decompression.opj_setup_decoder =
(void (*)(void *, opj_dparameters_t *)) opj_jp2_setup_decoder;
l_codec->m_codec_data.m_decompression.opj_decoder_set_strict_mode =
(void (*)(void *, OPJ_BOOL)) opj_jp2_decoder_set_strict_mode;
l_codec->m_codec_data.m_decompression.opj_set_decode_area =
(OPJ_BOOL(*)(void *,
opj_image_t*,
@ -351,12 +327,6 @@ opj_codec_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT p_format)
OPJ_UINT32 res_factor,
opj_event_mgr_t * p_manager)) opj_jp2_set_decoded_resolution_factor;
l_codec->m_codec_data.m_decompression.opj_set_decoded_components =
(OPJ_BOOL(*)(void * p_codec,
OPJ_UINT32 numcomps,
const OPJ_UINT32 * comps_indices,
struct opj_event_mgr * p_manager)) opj_jp2_set_decoded_components;
l_codec->opj_set_threads =
(OPJ_BOOL(*)(void * p_codec, OPJ_UINT32 num_threads)) opj_jp2_set_threads;
@ -433,26 +403,6 @@ OPJ_BOOL OPJ_CALLCONV opj_setup_decoder(opj_codec_t *p_codec,
return OPJ_FALSE;
}
OPJ_API OPJ_BOOL OPJ_CALLCONV opj_decoder_set_strict_mode(opj_codec_t *p_codec,
OPJ_BOOL strict)
{
if (p_codec) {
opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec;
if (! l_codec->is_decompressor) {
opj_event_msg(&(l_codec->m_event_mgr), EVT_ERROR,
"Codec provided to the opj_decoder_set_strict_mode function is not a decompressor handler.\n");
return OPJ_FALSE;
}
l_codec->m_codec_data.m_decompression.opj_decoder_set_strict_mode(
l_codec->m_codec,
strict);
return OPJ_TRUE;
}
return OPJ_FALSE;
}
OPJ_BOOL OPJ_CALLCONV opj_read_header(opj_stream_t *p_stream,
opj_codec_t *p_codec,
opj_image_t **p_image)
@ -476,36 +426,6 @@ OPJ_BOOL OPJ_CALLCONV opj_read_header(opj_stream_t *p_stream,
return OPJ_FALSE;
}
OPJ_BOOL OPJ_CALLCONV opj_set_decoded_components(opj_codec_t *p_codec,
OPJ_UINT32 numcomps,
const OPJ_UINT32* comps_indices,
OPJ_BOOL apply_color_transforms)
{
if (p_codec) {
opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec;
if (! l_codec->is_decompressor) {
opj_event_msg(&(l_codec->m_event_mgr), EVT_ERROR,
"Codec provided to the opj_set_decoded_components function is not a decompressor handler.\n");
return OPJ_FALSE;
}
if (apply_color_transforms) {
opj_event_msg(&(l_codec->m_event_mgr), EVT_ERROR,
"apply_color_transforms = OPJ_TRUE is not supported.\n");
return OPJ_FALSE;
}
return l_codec->m_codec_data.m_decompression.opj_set_decoded_components(
l_codec->m_codec,
numcomps,
comps_indices,
&(l_codec->m_event_mgr));
}
return OPJ_FALSE;
}
OPJ_BOOL OPJ_CALLCONV opj_decode(opj_codec_t *p_codec,
opj_stream_t *p_stream,
opj_image_t* p_image)
@ -690,14 +610,6 @@ opj_codec_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT p_format)
struct opj_image *,
struct opj_event_mgr *)) opj_j2k_setup_encoder;
l_codec->m_codec_data.m_compression.opj_encoder_set_extra_options = (OPJ_BOOL(
*)(void *,
const char* const*,
struct opj_event_mgr *)) opj_j2k_encoder_set_extra_options;
l_codec->opj_set_threads =
(OPJ_BOOL(*)(void * p_codec, OPJ_UINT32 num_threads)) opj_j2k_set_threads;
l_codec->m_codec = opj_j2k_create_compress();
if (! l_codec->m_codec) {
opj_free(l_codec);
@ -736,14 +648,6 @@ opj_codec_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT p_format)
struct opj_image *,
struct opj_event_mgr *)) opj_jp2_setup_encoder;
l_codec->m_codec_data.m_compression.opj_encoder_set_extra_options = (OPJ_BOOL(
*)(void *,
const char* const*,
struct opj_event_mgr *)) opj_jp2_encoder_set_extra_options;
l_codec->opj_set_threads =
(OPJ_BOOL(*)(void * p_codec, OPJ_UINT32 num_threads)) opj_jp2_set_threads;
l_codec->m_codec = opj_jp2_create(OPJ_FALSE);
if (! l_codec->m_codec) {
opj_free(l_codec);
@ -772,11 +676,11 @@ void OPJ_CALLCONV opj_set_default_encoder_parameters(opj_cparameters_t
parameters->cp_cinema = OPJ_OFF; /* DEPRECATED */
parameters->rsiz = OPJ_PROFILE_NONE;
parameters->max_comp_size = 0;
parameters->numresolution = OPJ_COMP_PARAM_DEFAULT_NUMRESOLUTION;
parameters->numresolution = 6;
parameters->cp_rsiz = OPJ_STD_RSIZ; /* DEPRECATED */
parameters->cblockw_init = OPJ_COMP_PARAM_DEFAULT_CBLOCKW;
parameters->cblockh_init = OPJ_COMP_PARAM_DEFAULT_CBLOCKH;
parameters->prog_order = OPJ_COMP_PARAM_DEFAULT_PROG_ORDER;
parameters->cblockw_init = 64;
parameters->cblockh_init = 64;
parameters->prog_order = OPJ_LRCP;
parameters->roi_compno = -1; /* no ROI */
parameters->subsampling_dx = 1;
parameters->subsampling_dy = 1;
@ -842,27 +746,6 @@ OPJ_BOOL OPJ_CALLCONV opj_setup_encoder(opj_codec_t *p_codec,
return OPJ_FALSE;
}
/* ----------------------------------------------------------------------- */
OPJ_BOOL OPJ_CALLCONV opj_encoder_set_extra_options(opj_codec_t *p_codec,
const char* const* options)
{
if (p_codec) {
opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec;
if (! l_codec->is_decompressor) {
return l_codec->m_codec_data.m_compression.opj_encoder_set_extra_options(
l_codec->m_codec,
options,
&(l_codec->m_event_mgr));
}
}
return OPJ_FALSE;
}
/* ----------------------------------------------------------------------- */
OPJ_BOOL OPJ_CALLCONV opj_start_compress(opj_codec_t *p_codec,
opj_image_t * p_image,
opj_stream_t *p_stream)
@ -1112,14 +995,15 @@ opj_stream_t* OPJ_CALLCONV opj_stream_create_file_stream(
return NULL;
}
opj_stream_set_user_data(l_stream, p_file, opj_close_from_file);
opj_stream_set_user_data(l_stream, p_file,
(opj_stream_free_user_data_fn) fclose);
opj_stream_set_user_data_length(l_stream,
opj_get_data_length_from_file(p_file));
opj_stream_set_read_function(l_stream, opj_read_from_file);
opj_stream_set_read_function(l_stream, (opj_stream_read_fn) opj_read_from_file);
opj_stream_set_write_function(l_stream,
(opj_stream_write_fn) opj_write_from_file);
opj_stream_set_skip_function(l_stream, opj_skip_from_file);
opj_stream_set_seek_function(l_stream, opj_seek_from_file);
opj_stream_set_skip_function(l_stream, (opj_stream_skip_fn) opj_skip_from_file);
opj_stream_set_seek_function(l_stream, (opj_stream_seek_fn) opj_seek_from_file);
return l_stream;
}

View File

@ -76,15 +76,9 @@ Most compilers implement their own version of this keyword ...
#define OPJ_DEPRECATED(func) func
#endif
#if defined(__GNUC__) && __GNUC__ >= 6
#define OPJ_DEPRECATED_STRUCT_MEMBER(memb, msg) __attribute__ ((deprecated(msg))) memb
#else
#define OPJ_DEPRECATED_STRUCT_MEMBER(memb, msg) memb
#endif
#if defined(OPJ_STATIC) || !defined(_WIN32)
/* http://gcc.gnu.org/wiki/Visibility */
# if !defined(_WIN32) && __GNUC__ >= 4
# if __GNUC__ >= 4
# if defined(OPJ_STATIC) /* static library uses "hidden" */
# define OPJ_API __attribute__ ((visibility ("hidden")))
# else
@ -210,11 +204,11 @@ typedef size_t OPJ_SIZE_T;
#define OPJ_PROFILE_BC_MULTI 0x0200 /** Multi Tile Broadcast profile defined in 15444-1 AMD3 */
#define OPJ_PROFILE_BC_MULTI_R 0x0300 /** Multi Tile Reversible Broadcast profile defined in 15444-1 AMD3 */
#define OPJ_PROFILE_IMF_2K 0x0400 /** 2K Single Tile Lossy IMF profile defined in 15444-1 AMD 8 */
#define OPJ_PROFILE_IMF_4K 0x0500 /** 4K Single Tile Lossy IMF profile defined in 15444-1 AMD 8 */
#define OPJ_PROFILE_IMF_8K 0x0600 /** 8K Single Tile Lossy IMF profile defined in 15444-1 AMD 8 */
#define OPJ_PROFILE_IMF_2K_R 0x0700 /** 2K Single/Multi Tile Reversible IMF profile defined in 15444-1 AMD 8 */
#define OPJ_PROFILE_IMF_4K 0x0401 /** 4K Single Tile Lossy IMF profile defined in 15444-1 AMD 8 */
#define OPJ_PROFILE_IMF_8K 0x0402 /** 8K Single Tile Lossy IMF profile defined in 15444-1 AMD 8 */
#define OPJ_PROFILE_IMF_2K_R 0x0403 /** 2K Single/Multi Tile Reversible IMF profile defined in 15444-1 AMD 8 */
#define OPJ_PROFILE_IMF_4K_R 0x0800 /** 4K Single/Multi Tile Reversible IMF profile defined in 15444-1 AMD 8 */
#define OPJ_PROFILE_IMF_8K_R 0x0900 /** 8K Single/Multi Tile Reversible IMF profile defined in 15444-1 AMD 8 */
#define OPJ_PROFILE_IMF_8K_R 0x0801 /** 8K Single/Multi Tile Reversible IMF profile defined in 15444-1 AMD 8 */
/**
* JPEG 2000 Part-2 extensions
@ -231,36 +225,6 @@ typedef size_t OPJ_SIZE_T;
#define OPJ_IS_IMF(v) (((v) >= OPJ_PROFILE_IMF_2K)&&((v) <= ((OPJ_PROFILE_IMF_8K_R) | (0x009b))))
#define OPJ_IS_PART2(v) ((v) & OPJ_PROFILE_PART2)
#define OPJ_GET_IMF_PROFILE(v) ((v) & 0xff00) /** Extract IMF profile without mainlevel/sublevel */
#define OPJ_GET_IMF_MAINLEVEL(v) ((v) & 0xf) /** Extract IMF main level */
#define OPJ_GET_IMF_SUBLEVEL(v) (((v) >> 4) & 0xf) /** Extract IMF sub level */
#define OPJ_IMF_MAINLEVEL_MAX 11 /** Maximum main level */
/** Max. Components Sampling Rate (MSamples/sec) per IMF main level */
#define OPJ_IMF_MAINLEVEL_1_MSAMPLESEC 65 /** MSamples/sec for IMF main level 1 */
#define OPJ_IMF_MAINLEVEL_2_MSAMPLESEC 130 /** MSamples/sec for IMF main level 2 */
#define OPJ_IMF_MAINLEVEL_3_MSAMPLESEC 195 /** MSamples/sec for IMF main level 3 */
#define OPJ_IMF_MAINLEVEL_4_MSAMPLESEC 260 /** MSamples/sec for IMF main level 4 */
#define OPJ_IMF_MAINLEVEL_5_MSAMPLESEC 520 /** MSamples/sec for IMF main level 5 */
#define OPJ_IMF_MAINLEVEL_6_MSAMPLESEC 1200 /** MSamples/sec for IMF main level 6 */
#define OPJ_IMF_MAINLEVEL_7_MSAMPLESEC 2400 /** MSamples/sec for IMF main level 7 */
#define OPJ_IMF_MAINLEVEL_8_MSAMPLESEC 4800 /** MSamples/sec for IMF main level 8 */
#define OPJ_IMF_MAINLEVEL_9_MSAMPLESEC 9600 /** MSamples/sec for IMF main level 9 */
#define OPJ_IMF_MAINLEVEL_10_MSAMPLESEC 19200 /** MSamples/sec for IMF main level 10 */
#define OPJ_IMF_MAINLEVEL_11_MSAMPLESEC 38400 /** MSamples/sec for IMF main level 11 */
/** Max. compressed Bit Rate (Mbits/s) per IMF sub level */
#define OPJ_IMF_SUBLEVEL_1_MBITSSEC 200 /** Mbits/s for IMF sub level 1 */
#define OPJ_IMF_SUBLEVEL_2_MBITSSEC 400 /** Mbits/s for IMF sub level 2 */
#define OPJ_IMF_SUBLEVEL_3_MBITSSEC 800 /** Mbits/s for IMF sub level 3 */
#define OPJ_IMF_SUBLEVEL_4_MBITSSEC 1600 /** Mbits/s for IMF sub level 4 */
#define OPJ_IMF_SUBLEVEL_5_MBITSSEC 3200 /** Mbits/s for IMF sub level 5 */
#define OPJ_IMF_SUBLEVEL_6_MBITSSEC 6400 /** Mbits/s for IMF sub level 6 */
#define OPJ_IMF_SUBLEVEL_7_MBITSSEC 12800 /** Mbits/s for IMF sub level 7 */
#define OPJ_IMF_SUBLEVEL_8_MBITSSEC 25600 /** Mbits/s for IMF sub level 8 */
#define OPJ_IMF_SUBLEVEL_9_MBITSSEC 51200 /** Mbits/s for IMF sub level 9 */
/**
* JPEG 2000 codestream and component size limits in cinema profiles
* */
@ -354,10 +318,6 @@ typedef void (*opj_msg_callback)(const char *msg, void *client_data);
==========================================================
*/
#ifndef OPJ_UINT32_SEMANTICALLY_BUT_INT32
#define OPJ_UINT32_SEMANTICALLY_BUT_INT32 OPJ_INT32
#endif
/**
* Progression order changes
*
@ -373,10 +333,10 @@ typedef struct opj_poc {
OPJ_PROG_ORDER prg1, prg;
/** Progression order string*/
OPJ_CHAR progorder[5];
/** Tile number (starting at 1) */
/** Tile number */
OPJ_UINT32 tile;
/** Start and end values for Tile width and height*/
OPJ_UINT32_SEMANTICALLY_BUT_INT32 tx0, tx1, ty0, ty1;
OPJ_INT32 tx0, tx1, ty0, ty1;
/** Start value, initialised in pi_initialise_encode*/
OPJ_UINT32 layS, resS, compS, prcS;
/** End value, initialised in pi_initialise_encode */
@ -405,7 +365,7 @@ typedef struct opj_cparameters {
int cp_disto_alloc;
/** allocation by fixed layer */
int cp_fixed_alloc;
/** allocation by fixed quality (PSNR) */
/** add fixed_quality */
int cp_fixed_quality;
/** fixed layer */
int *cp_matrice;
@ -455,9 +415,9 @@ typedef struct opj_cparameters {
char infile[OPJ_PATH_LEN];
/** output file name */
char outfile[OPJ_PATH_LEN];
/** DEPRECATED. Index generation is now handled with the opj_encode_with_info() function. Set to NULL */
/** DEPRECATED. Index generation is now handeld with the opj_encode_with_info() function. Set to NULL */
int index_on;
/** DEPRECATED. Index generation is now handled with the opj_encode_with_info() function. Set to NULL */
/** DEPRECATED. Index generation is now handeld with the opj_encode_with_info() function. Set to NULL */
char index[OPJ_PATH_LEN];
/** subimage encoding: origin image offset in x direction */
int image_offset_x0;
@ -588,7 +548,7 @@ typedef struct opj_dparameters {
/** Verbose mode */
OPJ_BOOL m_verbose;
/** tile number of the decoded tile */
/** tile number ot the decoded tile*/
OPJ_UINT32 tile_index;
/** Nb of tile to decode */
OPJ_UINT32 nb_tile_to_decode;
@ -687,10 +647,10 @@ typedef struct opj_image_comp {
OPJ_UINT32 x0;
/** y component offset compared to the whole image */
OPJ_UINT32 y0;
/** precision: number of bits per component per pixel */
/** precision */
OPJ_UINT32 prec;
/** obsolete: use prec instead */
OPJ_DEPRECATED_STRUCT_MEMBER(OPJ_UINT32 bpp, "Use prec instead");
/** image depth in bits */
OPJ_UINT32 bpp;
/** signed (1) / unsigned (0) */
OPJ_UINT32 sgnd;
/** number of decoded resolution */
@ -744,10 +704,10 @@ typedef struct opj_image_comptparm {
OPJ_UINT32 x0;
/** y component offset compared to the whole image */
OPJ_UINT32 y0;
/** precision: number of bits per component per pixel */
/** precision */
OPJ_UINT32 prec;
/** obsolete: use prec instead */
OPJ_DEPRECATED_STRUCT_MEMBER(OPJ_UINT32 bpp, "Use prec instead");
/** image depth in bits */
OPJ_UINT32 bpp;
/** signed (1) / unsigned (0) */
OPJ_UINT32 sgnd;
} opj_image_cmptparm_t;
@ -829,9 +789,9 @@ typedef struct opj_tile_info {
int pdy[33];
/** information concerning packets inside tile */
opj_packet_info_t *packet;
/** number of pixels of the tile */
/** add fixed_quality */
int numpix;
/** distortion of the tile */
/** add fixed_quality */
double distotile;
/** number of markers */
int marknum;
@ -1218,8 +1178,7 @@ OPJ_API void OPJ_CALLCONV opj_stream_set_skip_function(opj_stream_t* p_stream,
opj_stream_skip_fn p_function);
/**
* Sets the given function to be used as a seek function, the stream is then seekable,
* using SEEK_SET behavior.
* Sets the given function to be used as a seek function, the stream is then seekable.
* @param p_stream the stream to modify
* @param p_function the function to use a skip function.
*/
@ -1345,20 +1304,6 @@ OPJ_API void OPJ_CALLCONV opj_set_default_decoder_parameters(
OPJ_API OPJ_BOOL OPJ_CALLCONV opj_setup_decoder(opj_codec_t *p_codec,
opj_dparameters_t *parameters);
/**
* Set strict decoding parameter for this decoder. If strict decoding is enabled, partial bit
* streams will fail to decode. If strict decoding is disabled, the decoder will decode partial
* bitstreams as much as possible without erroring
*
* @param p_codec decompressor handler
* @param strict OPJ_TRUE to enable strict decoding, OPJ_FALSE to disable
*
* @return true if the decoder is correctly set
*/
OPJ_API OPJ_BOOL OPJ_CALLCONV opj_decoder_set_strict_mode(opj_codec_t *p_codec,
OPJ_BOOL strict);
/**
* Allocates worker threads for the compressor/decompressor.
*
@ -1368,14 +1313,12 @@ OPJ_API OPJ_BOOL OPJ_CALLCONV opj_decoder_set_strict_mode(opj_codec_t *p_codec,
* number, or "ALL_CPUS". If OPJ_NUM_THREADS is set and this function is called,
* this function will override the behaviour of the environment variable.
*
* This function must be called after opj_setup_decoder() and
* before opj_read_header() for the decoding side, or after opj_setup_encoder()
* and before opj_start_compress() for the encoding side.
* Note: currently only has effect on the decompressor.
*
* @param p_codec decompressor or compressor handler
* @param p_codec decompressor handler
* @param num_threads number of threads.
*
* @return OPJ_TRUE if the function is successful.
* @return OPJ_TRUE if the decoder is correctly set
*/
OPJ_API OPJ_BOOL OPJ_CALLCONV opj_codec_set_threads(opj_codec_t *p_codec,
int num_threads);
@ -1393,37 +1336,6 @@ OPJ_API OPJ_BOOL OPJ_CALLCONV opj_read_header(opj_stream_t *p_stream,
opj_codec_t *p_codec,
opj_image_t **p_image);
/** Restrict the number of components to decode.
*
* This function should be called after opj_read_header().
*
* This function enables to restrict the set of decoded components to the
* specified indices.
* Note that the current implementation (apply_color_transforms == OPJ_FALSE)
* is such that neither the multi-component transform at codestream level,
* nor JP2 channel transformations will be applied.
* Consequently the indices are relative to the codestream.
*
* Note: opj_decode_tile_data() should not be used together with opj_set_decoded_components().
*
* @param p_codec the jpeg2000 codec to read.
* @param numcomps Size of the comps_indices array.
* @param comps_indices Array of numcomps values representing the indices
* of the components to decode (relative to the
* codestream, starting at 0)
* @param apply_color_transforms Whether multi-component transform at codestream level
* or JP2 channel transformations should be applied.
* Currently this parameter should be set to OPJ_FALSE.
* Setting it to OPJ_TRUE will result in an error.
*
* @return OPJ_TRUE in case of success.
*/
OPJ_API OPJ_BOOL OPJ_CALLCONV opj_set_decoded_components(opj_codec_t *p_codec,
OPJ_UINT32 numcomps,
const OPJ_UINT32* comps_indices,
OPJ_BOOL apply_color_transforms);
/**
* Sets the given area to be decoded. This function should be called right after opj_read_header and before any tile header reading.
*
@ -1438,7 +1350,7 @@ OPJ_API OPJ_BOOL OPJ_CALLCONV opj_set_decoded_components(opj_codec_t *p_codec,
* performance improvements when reading an image by chunks.
*
* @param p_codec the jpeg2000 codec.
* @param p_image the decoded image previously set by opj_read_header
* @param p_image the decoded image previously setted by opj_read_header
* @param p_start_x the left position of the rectangle to decode (in image coordinates).
* @param p_end_x the right position of the rectangle to decode (in image coordinates).
* @param p_start_y the up position of the rectangle to decode (in image coordinates).
@ -1467,7 +1379,7 @@ OPJ_API OPJ_BOOL OPJ_CALLCONV opj_decode(opj_codec_t *p_decompressor,
* Get the decoded tile from the codec
*
* @param p_codec the jpeg2000 codec.
* @param p_stream input stream
* @param p_stream input streamm
* @param p_image output image
* @param tile_index index of the tile which will be decode
*
@ -1540,8 +1452,6 @@ OPJ_API OPJ_BOOL OPJ_CALLCONV opj_read_tile_header(opj_codec_t *p_codec,
* Reads a tile data. This function is compulsory and allows one to decode tile data. opj_read_tile_header should be called before.
* The user may need to refer to the image got by opj_read_header to understand the size being taken by the tile.
*
* Note: opj_decode_tile_data() should not be used together with opj_set_decoded_components().
*
* @param p_codec the jpeg2000 codec.
* @param p_tile_index the index of the tile being decoded, this should be the value set by opj_read_tile_header.
* @param p_data pointer to a memory block that will hold the decoded data.
@ -1599,39 +1509,6 @@ OPJ_API OPJ_BOOL OPJ_CALLCONV opj_setup_encoder(opj_codec_t *p_codec,
opj_cparameters_t *parameters,
opj_image_t *image);
/**
* Specify extra options for the encoder.
*
* This may be called after opj_setup_encoder() and before opj_start_compress()
*
* This is the way to add new options in a fully ABI compatible way, without
* extending the opj_cparameters_t structure.
*
* Currently supported options are:
* <ul>
* <li>PLT=YES/NO. Defaults to NO. If set to YES, PLT marker segments,
* indicating the length of each packet in the tile-part header, will be
* written. Since 2.4.0</li>
* <li>TLM=YES/NO. Defaults to NO (except for Cinema and IMF profiles).
* If set to YES, TLM marker segments, indicating the length of each
* tile-part part will be written. Since 2.4.0</li>
* <li>GUARD_BITS=value. Number of guard bits in [0,7] range. Default value is 2.
* 1 may be used sometimes (like in SMPTE DCP Bv2.1 Application Profile for 2K images).
* Since 2.5.0</li>
* </ul>
*
* @param p_codec Compressor handle
* @param p_options Compression options. This should be a NULL terminated
* array of strings. Each string is of the form KEY=VALUE.
*
* @return OPJ_TRUE in case of success.
* @since 2.4.0
*/
OPJ_API OPJ_BOOL OPJ_CALLCONV opj_encoder_set_extra_options(
opj_codec_t *p_codec,
const char* const* p_options);
/**
* Start to compress the current image.
* @param p_codec Compressor handle

View File

@ -90,9 +90,6 @@ typedef struct opj_codec_private {
/** Setup decoder function handler */
void (*opj_setup_decoder)(void * p_codec, opj_dparameters_t * p_param);
/** Strict mode function handler */
void (*opj_decoder_set_strict_mode)(void * p_codec, OPJ_BOOL strict);
/** Set decode area function handler */
OPJ_BOOL(*opj_set_decode_area)(void * p_codec,
opj_image_t * p_image,
@ -114,11 +111,6 @@ typedef struct opj_codec_private {
OPJ_UINT32 res_factor,
opj_event_mgr_t * p_manager);
/** Set the decoded components */
OPJ_BOOL(*opj_set_decoded_components)(void * p_codec,
OPJ_UINT32 num_comps,
const OPJ_UINT32* comps_indices,
opj_event_mgr_t * p_manager);
} m_decompression;
/**
@ -151,11 +143,6 @@ typedef struct opj_codec_private {
opj_cparameters_t * p_param,
struct opj_image * p_image,
struct opj_event_mgr * p_manager);
OPJ_BOOL(* opj_encoder_set_extra_options)(void * p_codec,
const char* const* p_options,
struct opj_event_mgr * p_manager);
} m_compression;
} m_codec_data;
/** FIXME DOC*/

View File

@ -38,10 +38,4 @@
*/
#define OPJ_COMMON_CBLK_DATA_EXTRA 2 /**< Margin for a fake FFFF marker */
#define OPJ_COMP_PARAM_DEFAULT_CBLOCKW 64
#define OPJ_COMP_PARAM_DEFAULT_CBLOCKH 64
#define OPJ_COMP_PARAM_DEFAULT_PROG_ORDER OPJ_LRCP
#define OPJ_COMP_PARAM_DEFAULT_NUMRESOLUTION 6
#endif /* OPJ_COMMMON_H */

View File

@ -44,11 +44,7 @@
Standard includes used by the library
==========================================================
*/
#if defined(__amigaos4__)
#include <exec/memory.h>
#else
#include <memory.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <math.h>

View File

@ -170,18 +170,7 @@ Divide an integer and round upwards
static INLINE OPJ_UINT32 opj_uint_ceildiv(OPJ_UINT32 a, OPJ_UINT32 b)
{
assert(b);
return (OPJ_UINT32)(((OPJ_UINT64)a + b - 1) / b);
}
/**
Divide an integer and round upwards
@return Returns a divided by b
*/
static INLINE OPJ_UINT32 opj_uint64_ceildiv_res_uint32(OPJ_UINT64 a,
OPJ_UINT64 b)
{
assert(b);
return (OPJ_UINT32)((a + b - 1) / b);
return (a + b - 1) / b;
}
/**
@ -219,16 +208,6 @@ static INLINE OPJ_INT32 opj_int_floordivpow2(OPJ_INT32 a, OPJ_INT32 b)
{
return a >> b;
}
/**
Divide an integer by a power of 2 and round downwards
@return Returns a divided by 2^b
*/
static INLINE OPJ_UINT32 opj_uint_floordivpow2(OPJ_UINT32 a, OPJ_UINT32 b)
{
return a >> b;
}
/**
Get logarithm of an integer and round downwards
@return Returns log2(a)
@ -287,44 +266,6 @@ static INLINE OPJ_INT32 opj_int_fix_mul_t1(OPJ_INT32 a, OPJ_INT32 b)
return (OPJ_INT32)(temp >> (13 + 11 - T1_NMSEDEC_FRACBITS)) ;
}
/**
Addition two signed integers with a wrap-around behaviour.
Assumes complement-to-two signed integers.
@param a
@param b
@return Returns a + b
*/
static INLINE OPJ_INT32 opj_int_add_no_overflow(OPJ_INT32 a, OPJ_INT32 b)
{
void* pa = &a;
void* pb = &b;
OPJ_UINT32* upa = (OPJ_UINT32*)pa;
OPJ_UINT32* upb = (OPJ_UINT32*)pb;
OPJ_UINT32 ures = *upa + *upb;
void* pures = &ures;
OPJ_INT32* ipres = (OPJ_INT32*)pures;
return *ipres;
}
/**
Subtract two signed integers with a wrap-around behaviour.
Assumes complement-to-two signed integers.
@param a
@param b
@return Returns a - b
*/
static INLINE OPJ_INT32 opj_int_sub_no_overflow(OPJ_INT32 a, OPJ_INT32 b)
{
void* pa = &a;
void* pb = &b;
OPJ_UINT32* upa = (OPJ_UINT32*)pa;
OPJ_UINT32* upb = (OPJ_UINT32*)pb;
OPJ_UINT32 ures = *upa - *upb;
void* pures = &ures;
OPJ_INT32* ipres = (OPJ_INT32*)pures;
return *ipres;
}
/* ----------------------------------------------------------------------- */
/*@}*/

File diff suppressed because it is too large Load Diff

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