mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-10-12 02:09:28 +00:00
added support to view JPEG2000 images commonly used with epassports. The lib use a BSD-2 license compatible with our GPL3+
This commit is contained in:
@@ -49,10 +49,18 @@ client/CMakeFiles/
|
||||
client/deps/**
|
||||
!client/deps/id48/
|
||||
!client/deps/id48/**
|
||||
# vendored openjpeg, sources only. openjpeg.a and obj/ stay ignored
|
||||
!client/deps/openjpeg/
|
||||
!client/deps/openjpeg/*.c
|
||||
!client/deps/openjpeg/*.h
|
||||
!client/deps/openjpeg/Makefile
|
||||
!client/deps/openjpeg/LICENSE
|
||||
!client/deps/openjpeg/README.pm3
|
||||
client/build/
|
||||
client/android/build/
|
||||
CMakeCache.txt
|
||||
*.cmake
|
||||
!client/deps/openjpeg.cmake
|
||||
.cache
|
||||
|
||||
# Coverity
|
||||
|
||||
@@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.
|
||||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||
|
||||
## [unreleased][unreleased]
|
||||
- Changed `hf emrtd info` - now shows EF_DG2 portraits for JPREG2000 via new dependecy lib (@iceman1001)
|
||||
- Changed `hf emrtd info`- now shows portrait, signature and other biometrics at the same time (@iceman1001)
|
||||
- Fixed `pm3_grabbed_output_get` - heap overflow (@jonyen)
|
||||
- Fixed `hf iclass sam` - removed the old implementation (@iceman1001)
|
||||
|
||||
@@ -579,8 +579,12 @@ if ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND OR Qt6_FOUND))
|
||||
set (TARGET_SOURCES
|
||||
${PM3_ROOT}/client/src/proxgui.cpp
|
||||
${PM3_ROOT}/client/src/proxguiqt.cpp
|
||||
${PM3_ROOT}/client/src/imgjp2.c
|
||||
${TARGET_SOURCES})
|
||||
|
||||
# Qt has no JPEG2000 image handler, so we decode EF_DG2 & friends ourselves
|
||||
set(ADDITIONAL_LNK pm3rrg_rdv4_openjpeg ${ADDITIONAL_LNK})
|
||||
|
||||
add_definitions("-DHAVE_GUI")
|
||||
if (Qt6_FOUND)
|
||||
set(ADDITIONAL_DIRS ${Qt6_INCLUDE_DIRS} ${ADDITIONAL_DIRS})
|
||||
|
||||
@@ -123,6 +123,12 @@ REVENGLIBINC = -I$(REVENGLIBPATH)
|
||||
REVENGLIB = $(REVENGLIBPATH)/libreveng.a
|
||||
REVENGLIBLD =
|
||||
|
||||
## OpenJPEG (JPEG2000 decoding for the picture viewer)
|
||||
OPENJPEGLIBPATH = ./deps/openjpeg
|
||||
OPENJPEGLIBINC = -I$(OPENJPEGLIBPATH)
|
||||
OPENJPEGLIB = $(OPENJPEGLIBPATH)/openjpeg.a
|
||||
OPENJPEGLIBLD =
|
||||
|
||||
## Tinycbor
|
||||
TINYCBORLIBPATH = ./deps/tinycbor
|
||||
TINYCBORLIBINC = -I$(TINYCBORLIBPATH)
|
||||
@@ -234,6 +240,11 @@ STATICLIBS += $(REVENGLIB)
|
||||
LDLIBS += $(REVENGLIBLD)
|
||||
PM3INCLUDES += $(REVENGLIBINC)
|
||||
|
||||
## OpenJPEG
|
||||
# vendored, Qt has no JPEG2000 image handler.
|
||||
# Only linked in when the Qt GUI is built, see the "gui" section below
|
||||
PM3INCLUDES += $(OPENJPEGLIBINC)
|
||||
|
||||
## Tinycbor
|
||||
# not distributed as system library
|
||||
STATICLIBS += $(TINYCBORLIB)
|
||||
@@ -946,6 +957,10 @@ endif
|
||||
# gui
|
||||
ifeq ($(QT_FOUND),1)
|
||||
CXXSRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp
|
||||
# Qt has no JPEG2000 image handler, so we decode EF_DG2 & friends ourselves
|
||||
SRCS += imgjp2.c
|
||||
STATICLIBS += $(OPENJPEGLIB)
|
||||
LDLIBS += $(OPENJPEGLIBLD)
|
||||
else
|
||||
CXXSRCS = guidummy.cpp
|
||||
endif
|
||||
@@ -1026,6 +1041,7 @@ ifeq ($(LINENOISE_LOCAL_FOUND), 1)
|
||||
endif
|
||||
$(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) clean
|
||||
$(Q)$(MAKE) --no-print-directory -C $(REVENGLIBPATH) clean
|
||||
$(Q)$(MAKE) --no-print-directory -C $(OPENJPEGLIBPATH) clean
|
||||
$(Q)$(MAKE) --no-print-directory -C $(TINYCBORLIBPATH) clean
|
||||
$(Q)$(MAKE) --no-print-directory -C $(WHEREAMILIBPATH) clean
|
||||
$(Q)$(MAKE) --no-print-directory -C $(MQTTLIBPATH) clean
|
||||
@@ -1116,6 +1132,10 @@ $(REVENGLIB): .FORCE
|
||||
$(info [*] MAKE $@)
|
||||
$(Q)$(MAKE) --no-print-directory -C $(REVENGLIBPATH) all
|
||||
|
||||
$(OPENJPEGLIB): .FORCE
|
||||
$(info [*] MAKE $@)
|
||||
$(Q)$(MAKE) --no-print-directory -C $(OPENJPEGLIBPATH) all
|
||||
|
||||
$(TINYCBORLIB): .FORCE
|
||||
$(info [*] MAKE $@)
|
||||
$(Q)$(MAKE) --no-print-directory -C $(TINYCBORLIBPATH) all
|
||||
|
||||
@@ -25,6 +25,12 @@ endif()
|
||||
if (NOT TARGET pm3rrg_rdv4_mqtt)
|
||||
include(mqtt.cmake)
|
||||
endif()
|
||||
# JPEG2000 is only decoded by the Qt picture viewer, so don't build it for
|
||||
# targets without a GUI (experimental_lib links guidummy.cpp instead).
|
||||
# Condition must match the one guarding proxgui.cpp in client/CMakeLists.txt
|
||||
if ((NOT TARGET pm3rrg_rdv4_openjpeg) AND (NOT SKIPQT EQUAL 1) AND (Qt5_FOUND OR Qt6_FOUND))
|
||||
include(openjpeg.cmake)
|
||||
endif()
|
||||
if (NOT TARGET pm3rrg_rdv4_reveng)
|
||||
include(reveng.cmake)
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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-2014, Antonin Descampe
|
||||
* Copyright (c) 2003-2009, Francois-Olivier Devaux
|
||||
* Copyright (c) 2005, Herve Drolon, FreeImage Team
|
||||
* Copyright (c) 2002-2003, Yannick Verschueren
|
||||
* Copyright (c) 2001-2003, David Janssens
|
||||
* Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France
|
||||
* Copyright (c) 2012, CS Systemes d'Information, France
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
@@ -0,0 +1,32 @@
|
||||
MYSRCPATHS =
|
||||
MYINCLUDES =
|
||||
# Third party code, don't fail the build on upstream's warnings
|
||||
MYCFLAGS = -w -O3
|
||||
MYDEFS =
|
||||
MYSRCS = \
|
||||
bio.c \
|
||||
cio.c \
|
||||
dwt.c \
|
||||
event.c \
|
||||
function_list.c \
|
||||
ht_dec.c \
|
||||
image.c \
|
||||
invert.c \
|
||||
j2k.c \
|
||||
jp2.c \
|
||||
mct.c \
|
||||
mqc.c \
|
||||
openjpeg.c \
|
||||
opj_clock.c \
|
||||
opj_malloc.c \
|
||||
pi.c \
|
||||
sparse_array.c \
|
||||
t1.c \
|
||||
t2.c \
|
||||
tcd.c \
|
||||
tgt.c \
|
||||
thread.c \
|
||||
|
||||
LIB_A = openjpeg.a
|
||||
|
||||
include ../../../Makefile.host
|
||||
@@ -0,0 +1,59 @@
|
||||
openjpeg (openjp2) - vendored for Proxmark3
|
||||
===========================================
|
||||
|
||||
Why
|
||||
---
|
||||
Qt has no JPEG2000 image handler. The old JasPer based `jp2` plugin was
|
||||
dropped from qtimageformats and neither Debian/Ubuntu nor Fedora ship a
|
||||
replacement -- `qt5-image-formats-plugins` and `qt6-image-formats-plugins`
|
||||
contain only ICNS, MNG, TGA, TIFF, WBMP and WEBP.
|
||||
|
||||
Most eMRTD passports store EF_DG2 (the portrait) as JPEG2000, and EF_DG4
|
||||
(iris) uses it as well, so without a decoder of our own `hf emrtd info`
|
||||
could not show the very images people run it for.
|
||||
|
||||
Origin
|
||||
------
|
||||
https://github.com/uclouvain/openjpeg
|
||||
tag v2.5.4
|
||||
license: 2-clause BSD, see LICENSE in this directory
|
||||
|
||||
2-clause BSD is GPL compatible, so it mixes with the Proxmark3 GPLv3
|
||||
codebase. Keep the per file BSD headers intact, they are not ours to
|
||||
relicense.
|
||||
|
||||
Upstream's own notice applies and is repeated here:
|
||||
|
||||
"This software may be subject to other third party and contributor
|
||||
rights, including patent rights, and no such rights are granted under
|
||||
this license."
|
||||
|
||||
What was taken
|
||||
--------------
|
||||
Only the sources listed in upstream's `OPENJPEG_SRCS`
|
||||
(src/lib/openjp2/CMakeLists.txt), which is the openjp2 core library.
|
||||
|
||||
Left out on purpose:
|
||||
- the JPIP index box code (cidx_manager.c, indexbox_manager.h,
|
||||
phix/ppix/thix/tpix_manager.c). It is `#ifdef USE_JPIP` only and we
|
||||
never define that.
|
||||
- the bin/ codec applications, tests, benchmarks and the LUT generators
|
||||
(t1_generate_luts.c, t1_ht_generate_luts.c, bench_dwt.c,
|
||||
test_sparse_array.c). The pre-generated LUT headers are kept.
|
||||
|
||||
Local changes
|
||||
-------------
|
||||
- opj_config.h and opj_config_private.h are hand written replacements
|
||||
for the CMake generated ones. They decide everything from compiler
|
||||
predefines instead of configure time probes, so no CMake config step
|
||||
is needed. On Windows/MinGW no aligned-alloc macro is defined, which
|
||||
makes openjpeg use its own portable fallback.
|
||||
- Makefile added, for the non-CMake build. The CMake side lives in
|
||||
../openjpeg.cmake
|
||||
|
||||
No openjpeg .c or .h file was otherwise modified.
|
||||
|
||||
Updating
|
||||
--------
|
||||
Copy the OPENJPEG_SRCS files from a new upstream tag over this directory,
|
||||
then keep opj_config.h, opj_config_private.h, Makefile and this README.
|
||||
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "opj_includes.h"
|
||||
|
||||
/** @defgroup BIO BIO - Individual bit input-output stream */
|
||||
/*@{*/
|
||||
|
||||
/** @name Local static functions */
|
||||
/*@{*/
|
||||
|
||||
/**
|
||||
Read a bit
|
||||
@param bio BIO handle
|
||||
@return Returns the read bit
|
||||
*/
|
||||
static OPJ_UINT32 opj_bio_getbit(opj_bio_t *bio);
|
||||
/**
|
||||
Write a byte
|
||||
@param bio BIO handle
|
||||
@return Returns OPJ_TRUE if successful, returns OPJ_FALSE otherwise
|
||||
*/
|
||||
static OPJ_BOOL opj_bio_byteout(opj_bio_t *bio);
|
||||
/**
|
||||
Read a byte
|
||||
@param bio BIO handle
|
||||
@return Returns OPJ_TRUE if successful, returns OPJ_FALSE otherwise
|
||||
*/
|
||||
static OPJ_BOOL opj_bio_bytein(opj_bio_t *bio);
|
||||
|
||||
/*@}*/
|
||||
|
||||
/*@}*/
|
||||
|
||||
/*
|
||||
==========================================================
|
||||
local functions
|
||||
==========================================================
|
||||
*/
|
||||
|
||||
static OPJ_BOOL opj_bio_byteout(opj_bio_t *bio)
|
||||
{
|
||||
bio->buf = (bio->buf << 8) & 0xffff;
|
||||
bio->ct = bio->buf == 0xff00 ? 7 : 8;
|
||||
if ((OPJ_SIZE_T)bio->bp >= (OPJ_SIZE_T)bio->end) {
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
*bio->bp++ = (OPJ_BYTE)(bio->buf >> 8);
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
static OPJ_BOOL opj_bio_bytein(opj_bio_t *bio)
|
||||
{
|
||||
bio->buf = (bio->buf << 8) & 0xffff;
|
||||
bio->ct = bio->buf == 0xff00 ? 7 : 8;
|
||||
if ((OPJ_SIZE_T)bio->bp >= (OPJ_SIZE_T)bio->end) {
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
bio->buf |= *bio->bp++;
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
static OPJ_UINT32 opj_bio_getbit(opj_bio_t *bio)
|
||||
{
|
||||
if (bio->ct == 0) {
|
||||
opj_bio_bytein(
|
||||
bio); /* MSD: why not check the return value of this function ? */
|
||||
}
|
||||
bio->ct--;
|
||||
return (bio->buf >> bio->ct) & 1;
|
||||
}
|
||||
|
||||
/*
|
||||
==========================================================
|
||||
Bit Input/Output interface
|
||||
==========================================================
|
||||
*/
|
||||
|
||||
opj_bio_t* opj_bio_create(void)
|
||||
{
|
||||
opj_bio_t *bio = (opj_bio_t*)opj_malloc(sizeof(opj_bio_t));
|
||||
return bio;
|
||||
}
|
||||
|
||||
void opj_bio_destroy(opj_bio_t *bio)
|
||||
{
|
||||
if (bio) {
|
||||
opj_free(bio);
|
||||
}
|
||||
}
|
||||
|
||||
ptrdiff_t opj_bio_numbytes(opj_bio_t *bio)
|
||||
{
|
||||
return (bio->bp - bio->start);
|
||||
}
|
||||
|
||||
void opj_bio_init_enc(opj_bio_t *bio, OPJ_BYTE *bp, OPJ_UINT32 len)
|
||||
{
|
||||
bio->start = bp;
|
||||
bio->end = bp + len;
|
||||
bio->bp = bp;
|
||||
bio->buf = 0;
|
||||
bio->ct = 8;
|
||||
}
|
||||
|
||||
void opj_bio_init_dec(opj_bio_t *bio, OPJ_BYTE *bp, OPJ_UINT32 len)
|
||||
{
|
||||
bio->start = bp;
|
||||
bio->end = bp + len;
|
||||
bio->bp = bp;
|
||||
bio->buf = 0;
|
||||
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;
|
||||
|
||||
assert((n > 0U) && (n <= 32U));
|
||||
for (i = (OPJ_INT32)n - 1; i >= 0; i--) {
|
||||
opj_bio_putbit(bio, (v >> i) & 1);
|
||||
}
|
||||
}
|
||||
|
||||
OPJ_UINT32 opj_bio_read(opj_bio_t *bio, OPJ_UINT32 n)
|
||||
{
|
||||
OPJ_INT32 i;
|
||||
OPJ_UINT32 v;
|
||||
|
||||
assert((n > 0U) /* && (n <= 32U)*/);
|
||||
#ifdef OPJ_UBSAN_BUILD
|
||||
/* This assert fails for some corrupted images which are gracefully rejected */
|
||||
/* Add this assert only for ubsan build. */
|
||||
/* This is the condition for overflow not to occur below which is needed because of OPJ_NOSANITIZE */
|
||||
assert(n <= 32U);
|
||||
#endif
|
||||
v = 0U;
|
||||
for (i = (OPJ_INT32)n - 1; i >= 0; i--) {
|
||||
v |= opj_bio_getbit(bio) <<
|
||||
i; /* can't overflow, opj_bio_getbit returns 0 or 1 */
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
OPJ_BOOL opj_bio_flush(opj_bio_t *bio)
|
||||
{
|
||||
if (! opj_bio_byteout(bio)) {
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
if (bio->ct == 7) {
|
||||
if (! opj_bio_byteout(bio)) {
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
}
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
OPJ_BOOL opj_bio_inalign(opj_bio_t *bio)
|
||||
{
|
||||
if ((bio->buf & 0xff) == 0xff) {
|
||||
if (! opj_bio_bytein(bio)) {
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
}
|
||||
bio->ct = 0;
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* 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 OPJ_BIO_H
|
||||
#define OPJ_BIO_H
|
||||
|
||||
#include <stddef.h> /* ptrdiff_t */
|
||||
|
||||
/**
|
||||
@file bio.h
|
||||
@brief Implementation of an individual bit input-output (BIO)
|
||||
|
||||
The functions in BIO.C have for goal to realize an individual bit input - output.
|
||||
*/
|
||||
|
||||
/** @defgroup BIO BIO - Individual bit input-output stream */
|
||||
/*@{*/
|
||||
|
||||
/**
|
||||
Individual bit input-output stream (BIO)
|
||||
*/
|
||||
typedef struct opj_bio {
|
||||
/** pointer to the start of the buffer */
|
||||
OPJ_BYTE *start;
|
||||
/** pointer to the end of the buffer */
|
||||
OPJ_BYTE *end;
|
||||
/** pointer to the present position in the buffer */
|
||||
OPJ_BYTE *bp;
|
||||
/** temporary place where each byte is read or written */
|
||||
OPJ_UINT32 buf;
|
||||
/** coder : number of bits free to write. decoder : number of bits read */
|
||||
OPJ_UINT32 ct;
|
||||
} opj_bio_t;
|
||||
|
||||
/** @name Exported functions */
|
||||
/*@{*/
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/**
|
||||
Create a new BIO handle
|
||||
@return Returns a new BIO handle if successful, returns NULL otherwise
|
||||
*/
|
||||
opj_bio_t* opj_bio_create(void);
|
||||
/**
|
||||
Destroy a previously created BIO handle
|
||||
@param bio BIO handle to destroy
|
||||
*/
|
||||
void opj_bio_destroy(opj_bio_t *bio);
|
||||
/**
|
||||
Number of bytes written.
|
||||
@param bio BIO handle
|
||||
@return Returns the number of bytes written
|
||||
*/
|
||||
ptrdiff_t opj_bio_numbytes(opj_bio_t *bio);
|
||||
/**
|
||||
Init encoder
|
||||
@param bio BIO handle
|
||||
@param bp Output buffer
|
||||
@param len Output buffer length
|
||||
*/
|
||||
void opj_bio_init_enc(opj_bio_t *bio, OPJ_BYTE *bp, OPJ_UINT32 len);
|
||||
/**
|
||||
Init decoder
|
||||
@param bio BIO handle
|
||||
@param bp Input buffer
|
||||
@param len Input buffer length
|
||||
*/
|
||||
void opj_bio_init_dec(opj_bio_t *bio, OPJ_BYTE *bp, OPJ_UINT32 len);
|
||||
/**
|
||||
Write bits
|
||||
@param bio BIO handle
|
||||
@param v Value of 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
|
||||
@param n Number of bits to read
|
||||
@return Returns the corresponding read number
|
||||
*/
|
||||
OPJ_UINT32 opj_bio_read(opj_bio_t *bio, OPJ_UINT32 n);
|
||||
/**
|
||||
Flush bits
|
||||
@param bio BIO handle
|
||||
@return Returns OPJ_TRUE if successful, returns OPJ_FALSE otherwise
|
||||
*/
|
||||
OPJ_BOOL opj_bio_flush(opj_bio_t *bio);
|
||||
/**
|
||||
Passes the ending bits (coming from flushing)
|
||||
@param bio BIO handle
|
||||
@return Returns OPJ_TRUE if successful, returns OPJ_FALSE otherwise
|
||||
*/
|
||||
OPJ_BOOL opj_bio_inalign(opj_bio_t *bio);
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/*@}*/
|
||||
|
||||
/*@}*/
|
||||
|
||||
#endif /* OPJ_BIO_H */
|
||||
|
||||
@@ -0,0 +1,683 @@
|
||||
/*
|
||||
* 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) 2008, 2011-2012, Centre National d'Etudes Spatiales (CNES), FR
|
||||
* Copyright (c) 2012, CS Systemes d'Information, France
|
||||
* 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 "opj_includes.h"
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
void opj_write_bytes_BE(OPJ_BYTE * p_buffer, OPJ_UINT32 p_value,
|
||||
OPJ_UINT32 p_nb_bytes)
|
||||
{
|
||||
const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + sizeof(
|
||||
OPJ_UINT32) - p_nb_bytes;
|
||||
|
||||
assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
|
||||
|
||||
memcpy(p_buffer, l_data_ptr, p_nb_bytes);
|
||||
}
|
||||
|
||||
void opj_write_bytes_LE(OPJ_BYTE * p_buffer, OPJ_UINT32 p_value,
|
||||
OPJ_UINT32 p_nb_bytes)
|
||||
{
|
||||
const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + p_nb_bytes - 1;
|
||||
OPJ_UINT32 i;
|
||||
|
||||
assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
|
||||
|
||||
for (i = 0; i < p_nb_bytes; ++i) {
|
||||
*(p_buffer++) = *(l_data_ptr--);
|
||||
}
|
||||
}
|
||||
|
||||
void opj_read_bytes_BE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value,
|
||||
OPJ_UINT32 p_nb_bytes)
|
||||
{
|
||||
OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value);
|
||||
|
||||
assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
|
||||
|
||||
*p_value = 0;
|
||||
memcpy(l_data_ptr + sizeof(OPJ_UINT32) - p_nb_bytes, p_buffer, p_nb_bytes);
|
||||
}
|
||||
|
||||
void opj_read_bytes_LE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value,
|
||||
OPJ_UINT32 p_nb_bytes)
|
||||
{
|
||||
OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value) + p_nb_bytes - 1;
|
||||
OPJ_UINT32 i;
|
||||
|
||||
assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
|
||||
|
||||
*p_value = 0;
|
||||
for (i = 0; i < p_nb_bytes; ++i) {
|
||||
*(l_data_ptr--) = *(p_buffer++);
|
||||
}
|
||||
}
|
||||
|
||||
void opj_write_double_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT64 p_value)
|
||||
{
|
||||
const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value);
|
||||
memcpy(p_buffer, l_data_ptr, sizeof(OPJ_FLOAT64));
|
||||
}
|
||||
|
||||
void opj_write_double_LE(OPJ_BYTE * p_buffer, OPJ_FLOAT64 p_value)
|
||||
{
|
||||
const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + sizeof(
|
||||
OPJ_FLOAT64) - 1;
|
||||
OPJ_UINT32 i;
|
||||
for (i = 0; i < sizeof(OPJ_FLOAT64); ++i) {
|
||||
*(p_buffer++) = *(l_data_ptr--);
|
||||
}
|
||||
}
|
||||
|
||||
void opj_read_double_BE(const OPJ_BYTE * p_buffer, OPJ_FLOAT64 * p_value)
|
||||
{
|
||||
OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value);
|
||||
memcpy(l_data_ptr, p_buffer, sizeof(OPJ_FLOAT64));
|
||||
}
|
||||
|
||||
void opj_read_double_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT64 * p_value)
|
||||
{
|
||||
OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value) + sizeof(OPJ_FLOAT64) - 1;
|
||||
OPJ_UINT32 i;
|
||||
for (i = 0; i < sizeof(OPJ_FLOAT64); ++i) {
|
||||
*(l_data_ptr--) = *(p_buffer++);
|
||||
}
|
||||
}
|
||||
|
||||
void opj_write_float_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value)
|
||||
{
|
||||
const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value);
|
||||
memcpy(p_buffer, l_data_ptr, sizeof(OPJ_FLOAT32));
|
||||
}
|
||||
|
||||
void opj_write_float_LE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value)
|
||||
{
|
||||
const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + sizeof(
|
||||
OPJ_FLOAT32) - 1;
|
||||
OPJ_UINT32 i;
|
||||
for (i = 0; i < sizeof(OPJ_FLOAT32); ++i) {
|
||||
*(p_buffer++) = *(l_data_ptr--);
|
||||
}
|
||||
}
|
||||
|
||||
void opj_read_float_BE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value)
|
||||
{
|
||||
OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value);
|
||||
memcpy(l_data_ptr, p_buffer, sizeof(OPJ_FLOAT32));
|
||||
}
|
||||
|
||||
void opj_read_float_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value)
|
||||
{
|
||||
OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value) + sizeof(OPJ_FLOAT32) - 1;
|
||||
OPJ_UINT32 i;
|
||||
for (i = 0; i < sizeof(OPJ_FLOAT32); ++i) {
|
||||
*(l_data_ptr--) = *(p_buffer++);
|
||||
}
|
||||
}
|
||||
|
||||
opj_stream_t* OPJ_CALLCONV opj_stream_create(OPJ_SIZE_T p_buffer_size,
|
||||
OPJ_BOOL l_is_input)
|
||||
{
|
||||
opj_stream_private_t * l_stream = 00;
|
||||
l_stream = (opj_stream_private_t*) opj_calloc(1, sizeof(opj_stream_private_t));
|
||||
if (! l_stream) {
|
||||
return 00;
|
||||
}
|
||||
|
||||
l_stream->m_buffer_size = p_buffer_size;
|
||||
l_stream->m_stored_data = (OPJ_BYTE *) opj_malloc(p_buffer_size);
|
||||
if (! l_stream->m_stored_data) {
|
||||
opj_free(l_stream);
|
||||
return 00;
|
||||
}
|
||||
|
||||
l_stream->m_current_data = l_stream->m_stored_data;
|
||||
|
||||
if (l_is_input) {
|
||||
l_stream->m_status |= OPJ_STREAM_STATUS_INPUT;
|
||||
l_stream->m_opj_skip = opj_stream_read_skip;
|
||||
l_stream->m_opj_seek = opj_stream_read_seek;
|
||||
} else {
|
||||
l_stream->m_status |= OPJ_STREAM_STATUS_OUTPUT;
|
||||
l_stream->m_opj_skip = opj_stream_write_skip;
|
||||
l_stream->m_opj_seek = opj_stream_write_seek;
|
||||
}
|
||||
|
||||
l_stream->m_read_fn = opj_stream_default_read;
|
||||
l_stream->m_write_fn = opj_stream_default_write;
|
||||
l_stream->m_skip_fn = opj_stream_default_skip;
|
||||
l_stream->m_seek_fn = opj_stream_default_seek;
|
||||
|
||||
return (opj_stream_t *) l_stream;
|
||||
}
|
||||
|
||||
opj_stream_t* OPJ_CALLCONV opj_stream_default_create(OPJ_BOOL l_is_input)
|
||||
{
|
||||
return opj_stream_create(OPJ_J2K_STREAM_CHUNK_SIZE, l_is_input);
|
||||
}
|
||||
|
||||
void OPJ_CALLCONV opj_stream_destroy(opj_stream_t* p_stream)
|
||||
{
|
||||
opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
|
||||
|
||||
if (l_stream) {
|
||||
if (l_stream->m_free_user_data_fn) {
|
||||
l_stream->m_free_user_data_fn(l_stream->m_user_data);
|
||||
}
|
||||
opj_free(l_stream->m_stored_data);
|
||||
l_stream->m_stored_data = 00;
|
||||
opj_free(l_stream);
|
||||
}
|
||||
}
|
||||
|
||||
void OPJ_CALLCONV opj_stream_set_read_function(opj_stream_t* p_stream,
|
||||
opj_stream_read_fn p_function)
|
||||
{
|
||||
opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
|
||||
|
||||
if ((!l_stream) || (!(l_stream->m_status & OPJ_STREAM_STATUS_INPUT))) {
|
||||
return;
|
||||
}
|
||||
|
||||
l_stream->m_read_fn = p_function;
|
||||
}
|
||||
|
||||
void OPJ_CALLCONV opj_stream_set_seek_function(opj_stream_t* p_stream,
|
||||
opj_stream_seek_fn p_function)
|
||||
{
|
||||
opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
|
||||
|
||||
if (!l_stream) {
|
||||
return;
|
||||
}
|
||||
l_stream->m_seek_fn = p_function;
|
||||
}
|
||||
|
||||
void OPJ_CALLCONV opj_stream_set_write_function(opj_stream_t* p_stream,
|
||||
opj_stream_write_fn p_function)
|
||||
{
|
||||
opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
|
||||
|
||||
if ((!l_stream) || (!(l_stream->m_status & OPJ_STREAM_STATUS_OUTPUT))) {
|
||||
return;
|
||||
}
|
||||
|
||||
l_stream->m_write_fn = p_function;
|
||||
}
|
||||
|
||||
void OPJ_CALLCONV opj_stream_set_skip_function(opj_stream_t* p_stream,
|
||||
opj_stream_skip_fn p_function)
|
||||
{
|
||||
opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
|
||||
|
||||
if (! l_stream) {
|
||||
return;
|
||||
}
|
||||
|
||||
l_stream->m_skip_fn = p_function;
|
||||
}
|
||||
|
||||
void OPJ_CALLCONV opj_stream_set_user_data(opj_stream_t* p_stream,
|
||||
void * p_data, opj_stream_free_user_data_fn p_function)
|
||||
{
|
||||
opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
|
||||
if (!l_stream) {
|
||||
return;
|
||||
}
|
||||
l_stream->m_user_data = p_data;
|
||||
l_stream->m_free_user_data_fn = p_function;
|
||||
}
|
||||
|
||||
void OPJ_CALLCONV opj_stream_set_user_data_length(opj_stream_t* p_stream,
|
||||
OPJ_UINT64 data_length)
|
||||
{
|
||||
opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
|
||||
if (!l_stream) {
|
||||
return;
|
||||
}
|
||||
l_stream->m_user_data_length = data_length;
|
||||
}
|
||||
|
||||
OPJ_SIZE_T opj_stream_read_data(opj_stream_private_t * p_stream,
|
||||
OPJ_BYTE * p_buffer, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
|
||||
{
|
||||
OPJ_SIZE_T l_read_nb_bytes = 0;
|
||||
if (p_stream->m_bytes_in_buffer >= p_size) {
|
||||
memcpy(p_buffer, p_stream->m_current_data, p_size);
|
||||
p_stream->m_current_data += p_size;
|
||||
p_stream->m_bytes_in_buffer -= p_size;
|
||||
l_read_nb_bytes += p_size;
|
||||
p_stream->m_byte_offset += (OPJ_OFF_T)p_size;
|
||||
return l_read_nb_bytes;
|
||||
}
|
||||
|
||||
/* we are now in the case when the remaining data if not sufficient */
|
||||
if (p_stream->m_status & OPJ_STREAM_STATUS_END) {
|
||||
l_read_nb_bytes += p_stream->m_bytes_in_buffer;
|
||||
memcpy(p_buffer, p_stream->m_current_data, p_stream->m_bytes_in_buffer);
|
||||
p_stream->m_current_data += p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_bytes_in_buffer = 0;
|
||||
return l_read_nb_bytes ? l_read_nb_bytes : (OPJ_SIZE_T) - 1;
|
||||
}
|
||||
|
||||
/* the flag is not set, we copy data and then do an actual read on the stream */
|
||||
if (p_stream->m_bytes_in_buffer) {
|
||||
l_read_nb_bytes += p_stream->m_bytes_in_buffer;
|
||||
memcpy(p_buffer, p_stream->m_current_data, p_stream->m_bytes_in_buffer);
|
||||
p_stream->m_current_data = p_stream->m_stored_data;
|
||||
p_buffer += p_stream->m_bytes_in_buffer;
|
||||
p_size -= p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_bytes_in_buffer = 0;
|
||||
} else {
|
||||
/* case where we are already at the end of the buffer
|
||||
so reset the m_current_data to point to the start of the
|
||||
stored buffer to get ready to read from disk*/
|
||||
p_stream->m_current_data = p_stream->m_stored_data;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
/* we should read less than a chunk -> read a chunk */
|
||||
if (p_size < p_stream->m_buffer_size) {
|
||||
/* we should do an actual read on the media */
|
||||
p_stream->m_bytes_in_buffer = p_stream->m_read_fn(p_stream->m_stored_data,
|
||||
p_stream->m_buffer_size, p_stream->m_user_data);
|
||||
|
||||
if (p_stream->m_bytes_in_buffer == (OPJ_SIZE_T) - 1) {
|
||||
/* end of stream */
|
||||
opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
|
||||
|
||||
p_stream->m_bytes_in_buffer = 0;
|
||||
p_stream->m_status |= OPJ_STREAM_STATUS_END;
|
||||
/* end of stream */
|
||||
return l_read_nb_bytes ? l_read_nb_bytes : (OPJ_SIZE_T) - 1;
|
||||
} else if (p_stream->m_bytes_in_buffer < p_size) {
|
||||
/* not enough data */
|
||||
l_read_nb_bytes += p_stream->m_bytes_in_buffer;
|
||||
memcpy(p_buffer, p_stream->m_current_data, p_stream->m_bytes_in_buffer);
|
||||
p_stream->m_current_data = p_stream->m_stored_data;
|
||||
p_buffer += p_stream->m_bytes_in_buffer;
|
||||
p_size -= p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_bytes_in_buffer = 0;
|
||||
} else {
|
||||
l_read_nb_bytes += p_size;
|
||||
memcpy(p_buffer, p_stream->m_current_data, p_size);
|
||||
p_stream->m_current_data += p_size;
|
||||
p_stream->m_bytes_in_buffer -= p_size;
|
||||
p_stream->m_byte_offset += (OPJ_OFF_T)p_size;
|
||||
return l_read_nb_bytes;
|
||||
}
|
||||
} else {
|
||||
/* direct read on the dest buffer */
|
||||
p_stream->m_bytes_in_buffer = p_stream->m_read_fn(p_buffer, p_size,
|
||||
p_stream->m_user_data);
|
||||
|
||||
if (p_stream->m_bytes_in_buffer == (OPJ_SIZE_T) - 1) {
|
||||
/* end of stream */
|
||||
opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
|
||||
|
||||
p_stream->m_bytes_in_buffer = 0;
|
||||
p_stream->m_status |= OPJ_STREAM_STATUS_END;
|
||||
/* end of stream */
|
||||
return l_read_nb_bytes ? l_read_nb_bytes : (OPJ_SIZE_T) - 1;
|
||||
} else if (p_stream->m_bytes_in_buffer < p_size) {
|
||||
/* not enough data */
|
||||
l_read_nb_bytes += p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_current_data = p_stream->m_stored_data;
|
||||
p_buffer += p_stream->m_bytes_in_buffer;
|
||||
p_size -= p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_bytes_in_buffer = 0;
|
||||
} else {
|
||||
/* we have read the exact size */
|
||||
l_read_nb_bytes += p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_current_data = p_stream->m_stored_data;
|
||||
p_stream->m_bytes_in_buffer = 0;
|
||||
return l_read_nb_bytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OPJ_SIZE_T opj_stream_write_data(opj_stream_private_t * p_stream,
|
||||
const OPJ_BYTE * p_buffer,
|
||||
OPJ_SIZE_T p_size,
|
||||
opj_event_mgr_t * p_event_mgr)
|
||||
{
|
||||
OPJ_SIZE_T l_remaining_bytes = 0;
|
||||
OPJ_SIZE_T l_write_nb_bytes = 0;
|
||||
|
||||
if (p_stream->m_status & OPJ_STREAM_STATUS_ERROR) {
|
||||
return (OPJ_SIZE_T) - 1;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
l_remaining_bytes = p_stream->m_buffer_size - p_stream->m_bytes_in_buffer;
|
||||
|
||||
/* we have more memory than required */
|
||||
if (l_remaining_bytes >= p_size) {
|
||||
memcpy(p_stream->m_current_data, p_buffer, p_size);
|
||||
|
||||
p_stream->m_current_data += p_size;
|
||||
p_stream->m_bytes_in_buffer += p_size;
|
||||
l_write_nb_bytes += p_size;
|
||||
p_stream->m_byte_offset += (OPJ_OFF_T)p_size;
|
||||
|
||||
return l_write_nb_bytes;
|
||||
}
|
||||
|
||||
/* we copy data and then do an actual read on the stream */
|
||||
if (l_remaining_bytes) {
|
||||
l_write_nb_bytes += l_remaining_bytes;
|
||||
|
||||
memcpy(p_stream->m_current_data, p_buffer, l_remaining_bytes);
|
||||
|
||||
p_stream->m_current_data = p_stream->m_stored_data;
|
||||
|
||||
p_buffer += l_remaining_bytes;
|
||||
p_size -= l_remaining_bytes;
|
||||
p_stream->m_bytes_in_buffer += l_remaining_bytes;
|
||||
p_stream->m_byte_offset += (OPJ_OFF_T)l_remaining_bytes;
|
||||
}
|
||||
|
||||
if (! opj_stream_flush(p_stream, p_event_mgr)) {
|
||||
return (OPJ_SIZE_T) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
OPJ_BOOL opj_stream_flush(opj_stream_private_t * p_stream,
|
||||
opj_event_mgr_t * p_event_mgr)
|
||||
{
|
||||
/* the number of bytes written on the media. */
|
||||
OPJ_SIZE_T l_current_write_nb_bytes = 0;
|
||||
|
||||
p_stream->m_current_data = p_stream->m_stored_data;
|
||||
|
||||
while (p_stream->m_bytes_in_buffer) {
|
||||
/* we should do an actual write on the media */
|
||||
l_current_write_nb_bytes = p_stream->m_write_fn(p_stream->m_current_data,
|
||||
p_stream->m_bytes_in_buffer,
|
||||
p_stream->m_user_data);
|
||||
|
||||
if (l_current_write_nb_bytes == (OPJ_SIZE_T) - 1) {
|
||||
p_stream->m_status |= OPJ_STREAM_STATUS_ERROR;
|
||||
opj_event_msg(p_event_mgr, EVT_INFO, "Error on writing stream!\n");
|
||||
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
p_stream->m_current_data += l_current_write_nb_bytes;
|
||||
p_stream->m_bytes_in_buffer -= l_current_write_nb_bytes;
|
||||
}
|
||||
|
||||
p_stream->m_current_data = p_stream->m_stored_data;
|
||||
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
OPJ_OFF_T opj_stream_read_skip(opj_stream_private_t * p_stream,
|
||||
OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
|
||||
{
|
||||
OPJ_OFF_T l_skip_nb_bytes = 0;
|
||||
OPJ_OFF_T l_current_skip_nb_bytes = 0;
|
||||
|
||||
assert(p_size >= 0);
|
||||
|
||||
if (p_stream->m_bytes_in_buffer >= (OPJ_SIZE_T)p_size) {
|
||||
p_stream->m_current_data += p_size;
|
||||
/* it is safe to cast p_size to OPJ_SIZE_T since it is <= m_bytes_in_buffer
|
||||
which is of type OPJ_SIZE_T */
|
||||
p_stream->m_bytes_in_buffer -= (OPJ_SIZE_T)p_size;
|
||||
l_skip_nb_bytes += p_size;
|
||||
p_stream->m_byte_offset += l_skip_nb_bytes;
|
||||
return l_skip_nb_bytes;
|
||||
}
|
||||
|
||||
/* we are now in the case when the remaining data if not sufficient */
|
||||
if (p_stream->m_status & OPJ_STREAM_STATUS_END) {
|
||||
l_skip_nb_bytes += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_current_data += p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_bytes_in_buffer = 0;
|
||||
p_stream->m_byte_offset += l_skip_nb_bytes;
|
||||
return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T) - 1;
|
||||
}
|
||||
|
||||
/* the flag is not set, we copy data and then do an actual skip on the stream */
|
||||
if (p_stream->m_bytes_in_buffer) {
|
||||
l_skip_nb_bytes += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_current_data = p_stream->m_stored_data;
|
||||
p_size -= (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_bytes_in_buffer = 0;
|
||||
}
|
||||
|
||||
while (p_size > 0) {
|
||||
/* Check if we are going beyond the end of file. Most skip_fn do not */
|
||||
/* check that, but we must be careful not to advance m_byte_offset */
|
||||
/* beyond m_user_data_length, otherwise */
|
||||
/* opj_stream_get_number_byte_left() will assert. */
|
||||
if ((OPJ_UINT64)(p_stream->m_byte_offset + l_skip_nb_bytes + p_size) >
|
||||
p_stream->m_user_data_length) {
|
||||
opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
|
||||
|
||||
p_stream->m_byte_offset += l_skip_nb_bytes;
|
||||
l_skip_nb_bytes = (OPJ_OFF_T)(p_stream->m_user_data_length -
|
||||
(OPJ_UINT64)p_stream->m_byte_offset);
|
||||
|
||||
opj_stream_read_seek(p_stream, (OPJ_OFF_T)p_stream->m_user_data_length,
|
||||
p_event_mgr);
|
||||
p_stream->m_status |= OPJ_STREAM_STATUS_END;
|
||||
|
||||
/* end if stream */
|
||||
return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T) - 1;
|
||||
}
|
||||
|
||||
/* we should do an actual skip on the media */
|
||||
l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data);
|
||||
if (l_current_skip_nb_bytes == (OPJ_OFF_T) - 1) {
|
||||
opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
|
||||
|
||||
p_stream->m_status |= OPJ_STREAM_STATUS_END;
|
||||
p_stream->m_byte_offset += l_skip_nb_bytes;
|
||||
/* end if stream */
|
||||
return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T) - 1;
|
||||
}
|
||||
p_size -= l_current_skip_nb_bytes;
|
||||
l_skip_nb_bytes += l_current_skip_nb_bytes;
|
||||
}
|
||||
|
||||
p_stream->m_byte_offset += l_skip_nb_bytes;
|
||||
|
||||
return l_skip_nb_bytes;
|
||||
}
|
||||
|
||||
OPJ_OFF_T opj_stream_write_skip(opj_stream_private_t * p_stream,
|
||||
OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
|
||||
{
|
||||
OPJ_BOOL l_is_written = 0;
|
||||
OPJ_OFF_T l_current_skip_nb_bytes = 0;
|
||||
OPJ_OFF_T l_skip_nb_bytes = 0;
|
||||
|
||||
if (p_stream->m_status & OPJ_STREAM_STATUS_ERROR) {
|
||||
return (OPJ_OFF_T) - 1;
|
||||
}
|
||||
|
||||
/* we should flush data */
|
||||
l_is_written = opj_stream_flush(p_stream, p_event_mgr);
|
||||
if (! l_is_written) {
|
||||
p_stream->m_status |= OPJ_STREAM_STATUS_ERROR;
|
||||
p_stream->m_bytes_in_buffer = 0;
|
||||
return (OPJ_OFF_T) - 1;
|
||||
}
|
||||
/* then skip */
|
||||
|
||||
while (p_size > 0) {
|
||||
/* we should do an actual skip on the media */
|
||||
l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data);
|
||||
|
||||
if (l_current_skip_nb_bytes == (OPJ_OFF_T) - 1) {
|
||||
opj_event_msg(p_event_mgr, EVT_INFO, "Stream error!\n");
|
||||
|
||||
p_stream->m_status |= OPJ_STREAM_STATUS_ERROR;
|
||||
p_stream->m_byte_offset += l_skip_nb_bytes;
|
||||
/* end if stream */
|
||||
return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T) - 1;
|
||||
}
|
||||
p_size -= l_current_skip_nb_bytes;
|
||||
l_skip_nb_bytes += l_current_skip_nb_bytes;
|
||||
}
|
||||
|
||||
p_stream->m_byte_offset += l_skip_nb_bytes;
|
||||
|
||||
return l_skip_nb_bytes;
|
||||
}
|
||||
|
||||
OPJ_OFF_T opj_stream_tell(const opj_stream_private_t * p_stream)
|
||||
{
|
||||
return p_stream->m_byte_offset;
|
||||
}
|
||||
|
||||
OPJ_OFF_T opj_stream_get_number_byte_left(const opj_stream_private_t * p_stream)
|
||||
{
|
||||
assert(p_stream->m_byte_offset >= 0);
|
||||
assert(p_stream->m_user_data_length >= (OPJ_UINT64)p_stream->m_byte_offset);
|
||||
return p_stream->m_user_data_length ?
|
||||
(OPJ_OFF_T)(p_stream->m_user_data_length) - p_stream->m_byte_offset :
|
||||
0;
|
||||
}
|
||||
|
||||
OPJ_OFF_T opj_stream_skip(opj_stream_private_t * p_stream, OPJ_OFF_T p_size,
|
||||
opj_event_mgr_t * p_event_mgr)
|
||||
{
|
||||
assert(p_size >= 0);
|
||||
return p_stream->m_opj_skip(p_stream, p_size, p_event_mgr);
|
||||
}
|
||||
|
||||
OPJ_BOOL opj_stream_read_seek(opj_stream_private_t * p_stream, OPJ_OFF_T p_size,
|
||||
opj_event_mgr_t * p_event_mgr)
|
||||
{
|
||||
OPJ_ARG_NOT_USED(p_event_mgr);
|
||||
p_stream->m_current_data = p_stream->m_stored_data;
|
||||
p_stream->m_bytes_in_buffer = 0;
|
||||
|
||||
if (!(p_stream->m_seek_fn(p_size, p_stream->m_user_data))) {
|
||||
p_stream->m_status |= OPJ_STREAM_STATUS_END;
|
||||
return OPJ_FALSE;
|
||||
} else {
|
||||
/* reset stream status */
|
||||
p_stream->m_status &= (~OPJ_STREAM_STATUS_END);
|
||||
p_stream->m_byte_offset = p_size;
|
||||
|
||||
}
|
||||
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
OPJ_BOOL opj_stream_write_seek(opj_stream_private_t * p_stream,
|
||||
OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
|
||||
{
|
||||
if (! opj_stream_flush(p_stream, p_event_mgr)) {
|
||||
p_stream->m_status |= OPJ_STREAM_STATUS_ERROR;
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
p_stream->m_current_data = p_stream->m_stored_data;
|
||||
p_stream->m_bytes_in_buffer = 0;
|
||||
|
||||
if (! p_stream->m_seek_fn(p_size, p_stream->m_user_data)) {
|
||||
p_stream->m_status |= OPJ_STREAM_STATUS_ERROR;
|
||||
return OPJ_FALSE;
|
||||
} else {
|
||||
p_stream->m_byte_offset = p_size;
|
||||
}
|
||||
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
OPJ_BOOL opj_stream_seek(opj_stream_private_t * p_stream, OPJ_OFF_T p_size,
|
||||
struct opj_event_mgr * p_event_mgr)
|
||||
{
|
||||
assert(p_size >= 0);
|
||||
return p_stream->m_opj_seek(p_stream, p_size, p_event_mgr);
|
||||
}
|
||||
|
||||
OPJ_BOOL opj_stream_has_seek(const opj_stream_private_t * p_stream)
|
||||
{
|
||||
return p_stream->m_seek_fn != opj_stream_default_seek;
|
||||
}
|
||||
|
||||
OPJ_SIZE_T opj_stream_default_read(void * p_buffer, OPJ_SIZE_T p_nb_bytes,
|
||||
void * p_user_data)
|
||||
{
|
||||
OPJ_ARG_NOT_USED(p_buffer);
|
||||
OPJ_ARG_NOT_USED(p_nb_bytes);
|
||||
OPJ_ARG_NOT_USED(p_user_data);
|
||||
return (OPJ_SIZE_T) - 1;
|
||||
}
|
||||
|
||||
OPJ_SIZE_T opj_stream_default_write(void * p_buffer, OPJ_SIZE_T p_nb_bytes,
|
||||
void * p_user_data)
|
||||
{
|
||||
OPJ_ARG_NOT_USED(p_buffer);
|
||||
OPJ_ARG_NOT_USED(p_nb_bytes);
|
||||
OPJ_ARG_NOT_USED(p_user_data);
|
||||
return (OPJ_SIZE_T) - 1;
|
||||
}
|
||||
|
||||
OPJ_OFF_T opj_stream_default_skip(OPJ_OFF_T p_nb_bytes, void * p_user_data)
|
||||
{
|
||||
OPJ_ARG_NOT_USED(p_nb_bytes);
|
||||
OPJ_ARG_NOT_USED(p_user_data);
|
||||
return (OPJ_OFF_T) - 1;
|
||||
}
|
||||
|
||||
OPJ_BOOL opj_stream_default_seek(OPJ_OFF_T p_nb_bytes, void * p_user_data)
|
||||
{
|
||||
OPJ_ARG_NOT_USED(p_nb_bytes);
|
||||
OPJ_ARG_NOT_USED(p_user_data);
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
@@ -0,0 +1,412 @@
|
||||
/*
|
||||
* 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) 2008, 2011-2012, Centre National d'Etudes Spatiales (CNES), FR
|
||||
* Copyright (c) 2012, CS Systemes d'Information, France
|
||||
* 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 OPJ_CIO_H
|
||||
#define OPJ_CIO_H
|
||||
/**
|
||||
@file cio.h
|
||||
@brief Implementation of a byte input-output process (CIO)
|
||||
|
||||
The functions in CIO.C have for goal to realize a byte input / output process.
|
||||
*/
|
||||
|
||||
/** @defgroup CIO CIO - byte input-output stream */
|
||||
/*@{*/
|
||||
|
||||
#include "opj_config_private.h"
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
#if defined(OPJ_BIG_ENDIAN)
|
||||
#define opj_write_bytes opj_write_bytes_BE
|
||||
#define opj_read_bytes opj_read_bytes_BE
|
||||
#define opj_write_double opj_write_double_BE
|
||||
#define opj_read_double opj_read_double_BE
|
||||
#define opj_write_float opj_write_float_BE
|
||||
#define opj_read_float opj_read_float_BE
|
||||
#else
|
||||
#define opj_write_bytes opj_write_bytes_LE
|
||||
#define opj_read_bytes opj_read_bytes_LE
|
||||
#define opj_write_double opj_write_double_LE
|
||||
#define opj_read_double opj_read_double_LE
|
||||
#define opj_write_float opj_write_float_LE
|
||||
#define opj_read_float opj_read_float_LE
|
||||
#endif
|
||||
|
||||
|
||||
#define OPJ_STREAM_STATUS_OUTPUT 0x1U
|
||||
#define OPJ_STREAM_STATUS_INPUT 0x2U
|
||||
#define OPJ_STREAM_STATUS_END 0x4U
|
||||
#define OPJ_STREAM_STATUS_ERROR 0x8U
|
||||
|
||||
/**
|
||||
Byte input-output stream.
|
||||
*/
|
||||
typedef struct opj_stream_private {
|
||||
/**
|
||||
* User data, be it files, ... The actual data depends on the type of the stream.
|
||||
*/
|
||||
void * m_user_data;
|
||||
|
||||
/**
|
||||
* Pointer to function to free m_user_data (NULL at initialization)
|
||||
* when destroying the stream. If pointer is NULL the function is not
|
||||
* called and the m_user_data is not freed (even if non-NULL).
|
||||
*/
|
||||
opj_stream_free_user_data_fn m_free_user_data_fn;
|
||||
|
||||
/**
|
||||
* User data length
|
||||
*/
|
||||
OPJ_UINT64 m_user_data_length;
|
||||
|
||||
/**
|
||||
* Pointer to actual read function (NULL at the initialization of the cio.
|
||||
*/
|
||||
opj_stream_read_fn m_read_fn;
|
||||
|
||||
/**
|
||||
* Pointer to actual write function (NULL at the initialization of the cio.
|
||||
*/
|
||||
opj_stream_write_fn m_write_fn;
|
||||
|
||||
/**
|
||||
* Pointer to actual skip function (NULL at the initialization of the cio.
|
||||
* There is no seek function to prevent from back and forth slow procedures.
|
||||
*/
|
||||
opj_stream_skip_fn m_skip_fn;
|
||||
|
||||
/**
|
||||
* Pointer to actual seek function (if available).
|
||||
*/
|
||||
opj_stream_seek_fn m_seek_fn;
|
||||
|
||||
/**
|
||||
* Actual data stored into the stream if read from. Data is read by chunk of fixed size.
|
||||
* you should never access this data directly.
|
||||
*/
|
||||
OPJ_BYTE * m_stored_data;
|
||||
|
||||
/**
|
||||
* Pointer to the current read data.
|
||||
*/
|
||||
OPJ_BYTE * m_current_data;
|
||||
|
||||
/**
|
||||
* FIXME DOC.
|
||||
*/
|
||||
OPJ_OFF_T(* m_opj_skip)(struct opj_stream_private *, OPJ_OFF_T,
|
||||
struct opj_event_mgr *);
|
||||
|
||||
/**
|
||||
* FIXME DOC.
|
||||
*/
|
||||
OPJ_BOOL(* m_opj_seek)(struct opj_stream_private *, OPJ_OFF_T,
|
||||
struct opj_event_mgr *);
|
||||
|
||||
/**
|
||||
* number of bytes containing in the buffer.
|
||||
*/
|
||||
OPJ_SIZE_T m_bytes_in_buffer;
|
||||
|
||||
/**
|
||||
* The number of bytes read/written from the beginning of the stream
|
||||
*/
|
||||
OPJ_OFF_T m_byte_offset;
|
||||
|
||||
/**
|
||||
* The size of the buffer.
|
||||
*/
|
||||
OPJ_SIZE_T m_buffer_size;
|
||||
|
||||
/**
|
||||
* Flags to tell the status of the stream.
|
||||
* Used with OPJ_STREAM_STATUS_* defines.
|
||||
*/
|
||||
OPJ_UINT32 m_status;
|
||||
|
||||
}
|
||||
opj_stream_private_t;
|
||||
|
||||
/** @name Exported functions (see also openjpeg.h) */
|
||||
/*@{*/
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/**
|
||||
* Write some bytes to the given data buffer, this function is used in Big Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to write data to.
|
||||
* @param p_value the value to write
|
||||
* @param p_nb_bytes the number of bytes to write
|
||||
*/
|
||||
void opj_write_bytes_BE(OPJ_BYTE * p_buffer, OPJ_UINT32 p_value,
|
||||
OPJ_UINT32 p_nb_bytes);
|
||||
|
||||
/**
|
||||
* Reads some bytes from the given data buffer, this function is used in Big Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to read data from.
|
||||
* @param p_value pointer to the value that will store the data.
|
||||
* @param p_nb_bytes the nb bytes to read.
|
||||
* @return the number of bytes read or -1 if an error occurred.
|
||||
*/
|
||||
void opj_read_bytes_BE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value,
|
||||
OPJ_UINT32 p_nb_bytes);
|
||||
|
||||
/**
|
||||
* Write some bytes to the given data buffer, this function is used in Little Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to write data to.
|
||||
* @param p_value the value to write
|
||||
* @param p_nb_bytes the number of bytes to write
|
||||
* @return the number of bytes written or -1 if an error occurred
|
||||
*/
|
||||
void opj_write_bytes_LE(OPJ_BYTE * p_buffer, OPJ_UINT32 p_value,
|
||||
OPJ_UINT32 p_nb_bytes);
|
||||
|
||||
/**
|
||||
* Reads some bytes from the given data buffer, this function is used in Little Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to read data from.
|
||||
* @param p_value pointer to the value that will store the data.
|
||||
* @param p_nb_bytes the nb bytes to read.
|
||||
* @return the number of bytes read or -1 if an error occurred.
|
||||
*/
|
||||
void opj_read_bytes_LE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value,
|
||||
OPJ_UINT32 p_nb_bytes);
|
||||
|
||||
|
||||
/**
|
||||
* Write some bytes to the given data buffer, this function is used in Little Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to write data to.
|
||||
* @param p_value the value to write
|
||||
*/
|
||||
void opj_write_double_LE(OPJ_BYTE * p_buffer, OPJ_FLOAT64 p_value);
|
||||
|
||||
/***
|
||||
* Write some bytes to the given data buffer, this function is used in Big Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to write data to.
|
||||
* @param p_value the value to write
|
||||
*/
|
||||
void opj_write_double_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT64 p_value);
|
||||
|
||||
/**
|
||||
* Reads some bytes from the given data buffer, this function is used in Little Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to read data from.
|
||||
* @param p_value pointer to the value that will store the data.
|
||||
*/
|
||||
void opj_read_double_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT64 * p_value);
|
||||
|
||||
/**
|
||||
* Reads some bytes from the given data buffer, this function is used in Big Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to read data from.
|
||||
* @param p_value pointer to the value that will store the data.
|
||||
*/
|
||||
void opj_read_double_BE(const OPJ_BYTE * p_buffer, OPJ_FLOAT64 * p_value);
|
||||
|
||||
/**
|
||||
* Reads some bytes from the given data buffer, this function is used in Little Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to read data from.
|
||||
* @param p_value pointer to the value that will store the data.
|
||||
*/
|
||||
void opj_read_float_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value);
|
||||
|
||||
/**
|
||||
* Reads some bytes from the given data buffer, this function is used in Big Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to read data from.
|
||||
* @param p_value pointer to the value that will store the data.
|
||||
*/
|
||||
void opj_read_float_BE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value);
|
||||
|
||||
/**
|
||||
* Write some bytes to the given data buffer, this function is used in Little Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to write data to.
|
||||
* @param p_value the value to write
|
||||
*/
|
||||
void opj_write_float_LE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value);
|
||||
|
||||
/***
|
||||
* Write some bytes to the given data buffer, this function is used in Big Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to write data to.
|
||||
* @param p_value the value to write
|
||||
*/
|
||||
void opj_write_float_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value);
|
||||
|
||||
/**
|
||||
* Reads some bytes from the stream.
|
||||
* @param p_stream the stream to read data from.
|
||||
* @param p_buffer pointer to the data buffer that will receive the data.
|
||||
* @param p_size number of bytes to read.
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes read, or -1 if an error occurred or if the stream is at the end.
|
||||
*/
|
||||
OPJ_SIZE_T opj_stream_read_data(opj_stream_private_t * p_stream,
|
||||
OPJ_BYTE * p_buffer, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr);
|
||||
|
||||
/**
|
||||
* Writes some bytes to the stream.
|
||||
* @param p_stream the stream to write data to.
|
||||
* @param p_buffer pointer to the data buffer holds the data to be writtent.
|
||||
* @param p_size number of bytes to write.
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes writtent, or -1 if an error occurred.
|
||||
*/
|
||||
OPJ_SIZE_T opj_stream_write_data(opj_stream_private_t * p_stream,
|
||||
const OPJ_BYTE * p_buffer, OPJ_SIZE_T p_size,
|
||||
struct opj_event_mgr * p_event_mgr);
|
||||
|
||||
/**
|
||||
* Writes the content of the stream buffer to the stream.
|
||||
* @param p_stream the stream to write data to.
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return true if the data could be flushed, false else.
|
||||
*/
|
||||
OPJ_BOOL opj_stream_flush(opj_stream_private_t * p_stream,
|
||||
struct opj_event_mgr * p_event_mgr);
|
||||
|
||||
/**
|
||||
* Skips a number of bytes from the stream.
|
||||
* @param p_stream the stream to skip data from.
|
||||
* @param p_size the number of bytes to skip.
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes skipped, or -1 if an error occurred.
|
||||
*/
|
||||
OPJ_OFF_T opj_stream_skip(opj_stream_private_t * p_stream, OPJ_OFF_T p_size,
|
||||
struct opj_event_mgr * p_event_mgr);
|
||||
|
||||
/**
|
||||
* Tells the byte offset on the stream (similar to ftell).
|
||||
*
|
||||
* @param p_stream the stream to get the information from.
|
||||
*
|
||||
* @return the current position o fthe stream.
|
||||
*/
|
||||
OPJ_OFF_T opj_stream_tell(const opj_stream_private_t * p_stream);
|
||||
|
||||
|
||||
/**
|
||||
* Get the number of bytes left before the end of the stream (similar to cio_numbytesleft).
|
||||
*
|
||||
* @param p_stream the stream to get the information from.
|
||||
*
|
||||
* @return Number of bytes left before the end of the stream.
|
||||
*/
|
||||
OPJ_OFF_T opj_stream_get_number_byte_left(const opj_stream_private_t *
|
||||
p_stream);
|
||||
|
||||
/**
|
||||
* Skips a number of bytes from the stream.
|
||||
* @param p_stream the stream to skip data from.
|
||||
* @param p_size the number of bytes to skip.
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes skipped, or -1 if an error occurred.
|
||||
*/
|
||||
OPJ_OFF_T opj_stream_write_skip(opj_stream_private_t * p_stream,
|
||||
OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr);
|
||||
|
||||
/**
|
||||
* Skips a number of bytes from the stream.
|
||||
* @param p_stream the stream to skip data from.
|
||||
* @param p_size the number of bytes to skip.
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes skipped, or -1 if an error occurred.
|
||||
*/
|
||||
OPJ_OFF_T opj_stream_read_skip(opj_stream_private_t * p_stream,
|
||||
OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr);
|
||||
|
||||
/**
|
||||
* Skips a number of bytes from the stream.
|
||||
* @param p_stream the stream to skip data from.
|
||||
* @param p_size the number of bytes to skip.
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return OPJ_TRUE if success, or OPJ_FALSE if an error occurred.
|
||||
*/
|
||||
OPJ_BOOL opj_stream_read_seek(opj_stream_private_t * p_stream, OPJ_OFF_T p_size,
|
||||
struct opj_event_mgr * p_event_mgr);
|
||||
|
||||
/**
|
||||
* Skips a number of bytes from the stream.
|
||||
* @param p_stream the stream to skip data from.
|
||||
* @param p_size the number of bytes to skip.
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes skipped, or -1 if an error occurred.
|
||||
*/
|
||||
OPJ_BOOL opj_stream_write_seek(opj_stream_private_t * p_stream,
|
||||
OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr);
|
||||
|
||||
/**
|
||||
* Seeks a number of bytes from the stream.
|
||||
* @param p_stream the stream to skip data from.
|
||||
* @param p_size the number of bytes to skip.
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return true if the stream is seekable.
|
||||
*/
|
||||
OPJ_BOOL opj_stream_seek(opj_stream_private_t * p_stream, OPJ_OFF_T p_size,
|
||||
struct opj_event_mgr * p_event_mgr);
|
||||
|
||||
/**
|
||||
* Tells if the given stream is seekable.
|
||||
*/
|
||||
OPJ_BOOL opj_stream_has_seek(const opj_stream_private_t * p_stream);
|
||||
|
||||
/**
|
||||
* FIXME DOC.
|
||||
*/
|
||||
OPJ_SIZE_T opj_stream_default_read(void * p_buffer, OPJ_SIZE_T p_nb_bytes,
|
||||
void * p_user_data);
|
||||
|
||||
/**
|
||||
* FIXME DOC.
|
||||
*/
|
||||
OPJ_SIZE_T opj_stream_default_write(void * p_buffer, OPJ_SIZE_T p_nb_bytes,
|
||||
void * p_user_data);
|
||||
|
||||
/**
|
||||
* FIXME DOC.
|
||||
*/
|
||||
OPJ_OFF_T opj_stream_default_skip(OPJ_OFF_T p_nb_bytes, void * p_user_data);
|
||||
|
||||
/**
|
||||
* FIXME DOC.
|
||||
*/
|
||||
OPJ_BOOL opj_stream_default_seek(OPJ_OFF_T p_nb_bytes, void * p_user_data);
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/*@}*/
|
||||
|
||||
/*@}*/
|
||||
|
||||
|
||||
#endif /* OPJ_CIO_H */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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 OPJ_DWT_H
|
||||
#define OPJ_DWT_H
|
||||
/**
|
||||
@file dwt.h
|
||||
@brief Implementation of a discrete wavelet transform (DWT)
|
||||
|
||||
The functions in DWT.C have for goal to realize forward and inverse discret wavelet
|
||||
transform with filter 5-3 (reversible) and filter 9-7 (irreversible). The functions in
|
||||
DWT.C are used by some function in TCD.C.
|
||||
*/
|
||||
|
||||
/** @defgroup DWT DWT - Implementation of a discrete wavelet transform */
|
||||
/*@{*/
|
||||
|
||||
|
||||
/** @name Exported functions */
|
||||
/*@{*/
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/**
|
||||
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);
|
||||
|
||||
/**
|
||||
Inverse 5-3 wavelet transform in 2-D.
|
||||
Apply a reversible inverse DWT transform to a component of an image.
|
||||
@param p_tcd TCD handle
|
||||
@param tilec Tile component information (current tile)
|
||||
@param numres Number of resolution levels to decode
|
||||
*/
|
||||
OPJ_BOOL opj_dwt_decode(opj_tcd_t *p_tcd,
|
||||
opj_tcd_tilecomp_t* tilec,
|
||||
OPJ_UINT32 numres);
|
||||
|
||||
/**
|
||||
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
|
||||
@param orient Band of the wavelet function
|
||||
@return Returns the norm of the wavelet function
|
||||
*/
|
||||
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);
|
||||
/**
|
||||
Inverse 9-7 wavelet transform in 2-D.
|
||||
Apply an irreversible inverse DWT transform to a component of an image.
|
||||
@param p_tcd TCD handle
|
||||
@param tilec Tile component information (current tile)
|
||||
@param numres Number of resolution levels to decode
|
||||
*/
|
||||
OPJ_BOOL opj_dwt_decode_real(opj_tcd_t *p_tcd,
|
||||
opj_tcd_tilecomp_t* OPJ_RESTRICT tilec,
|
||||
OPJ_UINT32 numres);
|
||||
|
||||
/**
|
||||
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
|
||||
@param orient Band of the wavelet function
|
||||
@return Returns the norm of the 9-7 wavelet
|
||||
*/
|
||||
OPJ_FLOAT64 opj_dwt_getnorm_real(OPJ_UINT32 level, OPJ_UINT32 orient);
|
||||
/**
|
||||
Explicit calculation of the Quantization Stepsizes
|
||||
@param tccp Tile-component coding parameters
|
||||
@param prec Precint analyzed
|
||||
*/
|
||||
void opj_dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, OPJ_UINT32 prec);
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/*@}*/
|
||||
|
||||
/*@}*/
|
||||
|
||||
#endif /* OPJ_DWT_H */
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* 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) 2005, Herve Drolon, FreeImage Team
|
||||
* Copyright (c) 2008, 2011-2012, Centre National d'Etudes Spatiales (CNES), FR
|
||||
* Copyright (c) 2012, CS Systemes d'Information, France
|
||||
* 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 "opj_includes.h"
|
||||
|
||||
/* ==========================================================
|
||||
Utility functions
|
||||
==========================================================*/
|
||||
|
||||
#ifdef OPJ_CODE_NOT_USED
|
||||
#ifndef _WIN32
|
||||
static char*
|
||||
i2a(unsigned i, char *a, unsigned r)
|
||||
{
|
||||
if (i / r > 0) {
|
||||
a = i2a(i / r, a, r);
|
||||
}
|
||||
*a = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i % r];
|
||||
return a + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
Transforms integer i into an ascii string and stores the result in a;
|
||||
string is encoded in the base indicated by r.
|
||||
@param i Number to be converted
|
||||
@param a String result
|
||||
@param r Base of value; must be in the range 2 - 36
|
||||
@return Returns a
|
||||
*/
|
||||
static char *
|
||||
_itoa(int i, char *a, int r)
|
||||
{
|
||||
r = ((r < 2) || (r > 36)) ? 10 : r;
|
||||
if (i < 0) {
|
||||
*a = '-';
|
||||
*i2a(-i, a + 1, r) = 0;
|
||||
} else {
|
||||
*i2a(i, a, r) = 0;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
#endif /* !_WIN32 */
|
||||
#endif
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/**
|
||||
* Default callback function.
|
||||
* Do nothing.
|
||||
*/
|
||||
static void opj_default_callback(const char *msg, void *client_data)
|
||||
{
|
||||
OPJ_ARG_NOT_USED(msg);
|
||||
OPJ_ARG_NOT_USED(client_data);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
OPJ_BOOL opj_event_msg(opj_event_mgr_t* p_event_mgr, OPJ_INT32 event_type,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
#define OPJ_MSG_SIZE 512 /* 512 bytes should be more than enough for a short message */
|
||||
opj_msg_callback msg_handler = 00;
|
||||
void * l_data = 00;
|
||||
|
||||
if (p_event_mgr != 00) {
|
||||
switch (event_type) {
|
||||
case EVT_ERROR:
|
||||
msg_handler = p_event_mgr->error_handler;
|
||||
l_data = p_event_mgr->m_error_data;
|
||||
break;
|
||||
case EVT_WARNING:
|
||||
msg_handler = p_event_mgr->warning_handler;
|
||||
l_data = p_event_mgr->m_warning_data;
|
||||
break;
|
||||
case EVT_INFO:
|
||||
msg_handler = p_event_mgr->info_handler;
|
||||
l_data = p_event_mgr->m_info_data;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (msg_handler == 00) {
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
} else {
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
if ((fmt != 00) && (p_event_mgr != 00)) {
|
||||
va_list arg;
|
||||
char message[OPJ_MSG_SIZE];
|
||||
memset(message, 0, OPJ_MSG_SIZE);
|
||||
/* initialize the optional parameter list */
|
||||
va_start(arg, fmt);
|
||||
/* parse the format string and put the result in 'message' */
|
||||
vsnprintf(message, OPJ_MSG_SIZE, fmt, arg);
|
||||
/* force zero termination for Windows _vsnprintf() of old MSVC */
|
||||
message[OPJ_MSG_SIZE - 1] = '\0';
|
||||
/* deinitialize the optional parameter list */
|
||||
va_end(arg);
|
||||
|
||||
/* output the message to the user program */
|
||||
msg_handler(message, l_data);
|
||||
}
|
||||
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
void opj_set_default_event_handler(opj_event_mgr_t * p_manager)
|
||||
{
|
||||
p_manager->m_error_data = 00;
|
||||
p_manager->m_warning_data = 00;
|
||||
p_manager->m_info_data = 00;
|
||||
p_manager->error_handler = opj_default_callback;
|
||||
p_manager->info_handler = opj_default_callback;
|
||||
p_manager->warning_handler = opj_default_callback;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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) 2005, Herve Drolon, FreeImage Team
|
||||
* Copyright (c) 2008, 2011-2012, Centre National d'Etudes Spatiales (CNES), FR
|
||||
* Copyright (c) 2012, CS Systemes d'Information, France
|
||||
* 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 OPJ_EVENT_H
|
||||
#define OPJ_EVENT_H
|
||||
/**
|
||||
@file event.h
|
||||
@brief Implementation of a event callback system
|
||||
|
||||
The functions in EVENT.C have for goal to send output messages (errors, warnings, debug) to the user.
|
||||
*/
|
||||
/**
|
||||
Message handler object
|
||||
used for
|
||||
<ul>
|
||||
<li>Error messages
|
||||
<li>Warning messages
|
||||
<li>Debugging messages
|
||||
</ul>
|
||||
*/
|
||||
typedef struct opj_event_mgr {
|
||||
/** Data to call the event manager upon */
|
||||
void * m_error_data;
|
||||
/** Data to call the event manager upon */
|
||||
void * m_warning_data;
|
||||
/** Data to call the event manager upon */
|
||||
void * m_info_data;
|
||||
/** Error message callback if available, NULL otherwise */
|
||||
opj_msg_callback error_handler;
|
||||
/** Warning message callback if available, NULL otherwise */
|
||||
opj_msg_callback warning_handler;
|
||||
/** Debug message callback if available, NULL otherwise */
|
||||
opj_msg_callback info_handler;
|
||||
} opj_event_mgr_t;
|
||||
|
||||
|
||||
#define EVT_ERROR 1 /**< Error event type */
|
||||
#define EVT_WARNING 2 /**< Warning event type */
|
||||
#define EVT_INFO 4 /**< Debug event type */
|
||||
|
||||
/** @defgroup EVENT EVENT - Implementation of a event callback system */
|
||||
/*@{*/
|
||||
|
||||
/** @name Exported functions (see also openjpeg.h) */
|
||||
/*@{*/
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Write formatted data to a string and send the string to a user callback.
|
||||
*
|
||||
* @param event_mgr Event handler
|
||||
* @param event_type Event type or callback to use to send the message
|
||||
* @param fmt Format-control string (plus optional arguments)
|
||||
*
|
||||
* @return Returns true if successful, returns false otherwise
|
||||
*/
|
||||
OPJ_BOOL opj_event_msg(opj_event_mgr_t* event_mgr, OPJ_INT32 event_type,
|
||||
const char *fmt, ...);
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Set the event manager with the default callback function for the 3 levels.
|
||||
*/
|
||||
void opj_set_default_event_handler(opj_event_mgr_t * p_manager);
|
||||
|
||||
/*
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC poison printf fprintf
|
||||
#endif
|
||||
*/
|
||||
|
||||
/*@}*/
|
||||
|
||||
/*@}*/
|
||||
|
||||
#endif /* OPJ_EVENT_H */
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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) 2008, Jerome Fimes, Communications & Systemes <[email protected]>
|
||||
* 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 "opj_includes.h"
|
||||
|
||||
/**
|
||||
* Default size of the validation list, if not sufficient, data will be reallocated with a double size.
|
||||
*/
|
||||
#define OPJ_VALIDATION_SIZE 10
|
||||
|
||||
opj_procedure_list_t * opj_procedure_list_create()
|
||||
{
|
||||
/* memory allocation */
|
||||
opj_procedure_list_t * l_validation = (opj_procedure_list_t *) opj_calloc(1,
|
||||
sizeof(opj_procedure_list_t));
|
||||
if (! l_validation) {
|
||||
return 00;
|
||||
}
|
||||
/* initialization */
|
||||
l_validation->m_nb_max_procedures = OPJ_VALIDATION_SIZE;
|
||||
l_validation->m_procedures = (opj_procedure*)opj_calloc(OPJ_VALIDATION_SIZE,
|
||||
sizeof(opj_procedure));
|
||||
if (! l_validation->m_procedures) {
|
||||
opj_free(l_validation);
|
||||
return 00;
|
||||
}
|
||||
return l_validation;
|
||||
}
|
||||
|
||||
void opj_procedure_list_destroy(opj_procedure_list_t * p_list)
|
||||
{
|
||||
if (! p_list) {
|
||||
return;
|
||||
}
|
||||
/* initialization */
|
||||
if (p_list->m_procedures) {
|
||||
opj_free(p_list->m_procedures);
|
||||
}
|
||||
opj_free(p_list);
|
||||
}
|
||||
|
||||
OPJ_BOOL opj_procedure_list_add_procedure(opj_procedure_list_t *
|
||||
p_validation_list, opj_procedure p_procedure, opj_event_mgr_t* p_manager)
|
||||
{
|
||||
|
||||
assert(p_manager != NULL);
|
||||
|
||||
if (p_validation_list->m_nb_max_procedures ==
|
||||
p_validation_list->m_nb_procedures) {
|
||||
opj_procedure * new_procedures;
|
||||
|
||||
p_validation_list->m_nb_max_procedures += OPJ_VALIDATION_SIZE;
|
||||
new_procedures = (opj_procedure*)opj_realloc(
|
||||
p_validation_list->m_procedures,
|
||||
p_validation_list->m_nb_max_procedures * sizeof(opj_procedure));
|
||||
if (! new_procedures) {
|
||||
opj_free(p_validation_list->m_procedures);
|
||||
p_validation_list->m_nb_max_procedures = 0;
|
||||
p_validation_list->m_nb_procedures = 0;
|
||||
opj_event_msg(p_manager, EVT_ERROR,
|
||||
"Not enough memory to add a new validation procedure\n");
|
||||
return OPJ_FALSE;
|
||||
} else {
|
||||
p_validation_list->m_procedures = new_procedures;
|
||||
}
|
||||
}
|
||||
p_validation_list->m_procedures[p_validation_list->m_nb_procedures] =
|
||||
p_procedure;
|
||||
++p_validation_list->m_nb_procedures;
|
||||
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
OPJ_UINT32 opj_procedure_list_get_nb_procedures(opj_procedure_list_t *
|
||||
p_validation_list)
|
||||
{
|
||||
return p_validation_list->m_nb_procedures;
|
||||
}
|
||||
|
||||
opj_procedure* opj_procedure_list_get_first_procedure(opj_procedure_list_t *
|
||||
p_validation_list)
|
||||
{
|
||||
return p_validation_list->m_procedures;
|
||||
}
|
||||
|
||||
void opj_procedure_list_clear(opj_procedure_list_t * p_validation_list)
|
||||
{
|
||||
p_validation_list->m_nb_procedures = 0;
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* 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) 2008, Jerome Fimes, Communications & Systemes <[email protected]>
|
||||
* 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 OPJ_FUNCTION_LIST_H
|
||||
#define OPJ_FUNCTION_LIST_H
|
||||
|
||||
/**
|
||||
* @file function_list.h
|
||||
* @brief Implementation of a list of procedures.
|
||||
|
||||
* The functions in validation.c aims to have access to a list of procedures.
|
||||
*/
|
||||
|
||||
/** @defgroup VAL VAL - validation procedure*/
|
||||
/*@{*/
|
||||
|
||||
/**************************************************************************************************
|
||||
***************************************** FORWARD DECLARATION ************************************
|
||||
**************************************************************************************************/
|
||||
|
||||
/**
|
||||
* declare a function pointer
|
||||
*/
|
||||
typedef void (*opj_procedure)(void);
|
||||
|
||||
/**
|
||||
* A list of procedures.
|
||||
*/
|
||||
typedef struct opj_procedure_list {
|
||||
/**
|
||||
* The number of validation procedures.
|
||||
*/
|
||||
OPJ_UINT32 m_nb_procedures;
|
||||
/**
|
||||
* The number of the array of validation procedures.
|
||||
*/
|
||||
OPJ_UINT32 m_nb_max_procedures;
|
||||
/**
|
||||
* The array of procedures.
|
||||
*/
|
||||
opj_procedure * m_procedures;
|
||||
|
||||
} opj_procedure_list_t;
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Creates a validation list.
|
||||
*
|
||||
* @return the newly created validation list.
|
||||
*/
|
||||
opj_procedure_list_t * opj_procedure_list_create(void);
|
||||
|
||||
/**
|
||||
* Destroys a validation list.
|
||||
*
|
||||
* @param p_list the list to destroy.
|
||||
*/
|
||||
void opj_procedure_list_destroy(opj_procedure_list_t * p_list);
|
||||
|
||||
/**
|
||||
* Adds a new validation procedure.
|
||||
*
|
||||
* @param p_validation_list the list of procedure to modify.
|
||||
* @param p_procedure the procedure to add.
|
||||
* @param p_manager the user event manager.
|
||||
*
|
||||
* @return OPJ_TRUE if the procedure could be added.
|
||||
*/
|
||||
OPJ_BOOL opj_procedure_list_add_procedure(opj_procedure_list_t *
|
||||
p_validation_list, opj_procedure p_procedure, opj_event_mgr_t* p_manager);
|
||||
|
||||
/**
|
||||
* Gets the number of validation procedures.
|
||||
*
|
||||
* @param p_validation_list the list of procedure to modify.
|
||||
*
|
||||
* @return the number of validation procedures.
|
||||
*/
|
||||
OPJ_UINT32 opj_procedure_list_get_nb_procedures(opj_procedure_list_t *
|
||||
p_validation_list);
|
||||
|
||||
/**
|
||||
* Gets the pointer on the first validation procedure. This function is similar to the C++
|
||||
* iterator class to iterate through all the procedures inside the validation list.
|
||||
* the caller does not take ownership of the pointer.
|
||||
*
|
||||
* @param p_validation_list the list of procedure to get the first procedure from.
|
||||
*
|
||||
* @return a pointer to the first procedure.
|
||||
*/
|
||||
opj_procedure* opj_procedure_list_get_first_procedure(opj_procedure_list_t *
|
||||
p_validation_list);
|
||||
|
||||
|
||||
/**
|
||||
* Clears the list of validation procedures.
|
||||
*
|
||||
* @param p_validation_list the list of procedure to clear.
|
||||
*
|
||||
*/
|
||||
void opj_procedure_list_clear(opj_procedure_list_t * p_validation_list);
|
||||
/*@}*/
|
||||
|
||||
#endif /* OPJ_FUNCTION_LIST_H */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
* 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) 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.
|
||||
*/
|
||||
|
||||
#include "opj_includes.h"
|
||||
|
||||
opj_image_t* opj_image_create0(void)
|
||||
{
|
||||
opj_image_t *image = (opj_image_t*)opj_calloc(1, sizeof(opj_image_t));
|
||||
return image;
|
||||
}
|
||||
|
||||
opj_image_t* OPJ_CALLCONV opj_image_create(OPJ_UINT32 numcmpts,
|
||||
opj_image_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc)
|
||||
{
|
||||
OPJ_UINT32 compno;
|
||||
opj_image_t *image = NULL;
|
||||
|
||||
image = (opj_image_t*) opj_calloc(1, sizeof(opj_image_t));
|
||||
if (image) {
|
||||
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));
|
||||
if (!image->comps) {
|
||||
/* TODO replace with event manager, breaks API */
|
||||
/* fprintf(stderr,"Unable to allocate memory for image.\n"); */
|
||||
opj_image_destroy(image);
|
||||
return NULL;
|
||||
}
|
||||
/* create the individual image components */
|
||||
for (compno = 0; compno < numcmpts; compno++) {
|
||||
opj_image_comp_t *comp = &image->comps[compno];
|
||||
comp->dx = cmptparms[compno].dx;
|
||||
comp->dy = cmptparms[compno].dy;
|
||||
comp->w = cmptparms[compno].w;
|
||||
comp->h = cmptparms[compno].h;
|
||||
comp->x0 = cmptparms[compno].x0;
|
||||
comp->y0 = cmptparms[compno].y0;
|
||||
comp->prec = cmptparms[compno].prec;
|
||||
comp->sgnd = cmptparms[compno].sgnd;
|
||||
if (comp->h != 0 &&
|
||||
(OPJ_SIZE_T)comp->w > SIZE_MAX / comp->h / sizeof(OPJ_INT32)) {
|
||||
/* TODO event manager */
|
||||
opj_image_destroy(image);
|
||||
return NULL;
|
||||
}
|
||||
comp->data = (OPJ_INT32*) opj_image_data_alloc(
|
||||
(size_t)comp->w * comp->h * sizeof(OPJ_INT32));
|
||||
if (!comp->data) {
|
||||
/* TODO replace with event manager, breaks API */
|
||||
/* fprintf(stderr,"Unable to allocate memory for image.\n"); */
|
||||
opj_image_destroy(image);
|
||||
return NULL;
|
||||
}
|
||||
memset(comp->data, 0, (size_t)comp->w * comp->h * sizeof(OPJ_INT32));
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
void OPJ_CALLCONV opj_image_destroy(opj_image_t *image)
|
||||
{
|
||||
if (image) {
|
||||
if (image->comps) {
|
||||
OPJ_UINT32 compno;
|
||||
|
||||
/* image components */
|
||||
for (compno = 0; compno < image->numcomps; compno++) {
|
||||
opj_image_comp_t *image_comp = &(image->comps[compno]);
|
||||
if (image_comp->data) {
|
||||
opj_image_data_free(image_comp->data);
|
||||
}
|
||||
}
|
||||
opj_free(image->comps);
|
||||
}
|
||||
|
||||
if (image->icc_profile_buf) {
|
||||
opj_free(image->icc_profile_buf);
|
||||
}
|
||||
|
||||
opj_free(image);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the components characteristics of the image from the coding parameters.
|
||||
*
|
||||
* @param p_image_header the image header to update.
|
||||
* @param p_cp the coding parameters from which to update the image.
|
||||
*/
|
||||
void opj_image_comp_header_update(opj_image_t * p_image_header,
|
||||
const struct opj_cp * p_cp)
|
||||
{
|
||||
OPJ_UINT32 i, l_width, l_height;
|
||||
OPJ_UINT32 l_x0, l_y0, l_x1, l_y1;
|
||||
OPJ_UINT32 l_comp_x0, l_comp_y0, l_comp_x1, l_comp_y1;
|
||||
opj_image_comp_t* l_img_comp = NULL;
|
||||
|
||||
l_x0 = opj_uint_max(p_cp->tx0, p_image_header->x0);
|
||||
l_y0 = opj_uint_max(p_cp->ty0, p_image_header->y0);
|
||||
l_x1 = p_cp->tx0 + (p_cp->tw - 1U) *
|
||||
p_cp->tdx; /* validity of p_cp members used here checked in opj_j2k_read_siz. Can't overflow. */
|
||||
l_y1 = p_cp->ty0 + (p_cp->th - 1U) * p_cp->tdy; /* can't overflow */
|
||||
l_x1 = opj_uint_min(opj_uint_adds(l_x1, p_cp->tdx),
|
||||
p_image_header->x1); /* use add saturated to prevent overflow */
|
||||
l_y1 = opj_uint_min(opj_uint_adds(l_y1, p_cp->tdy),
|
||||
p_image_header->y1); /* use add saturated to prevent overflow */
|
||||
|
||||
l_img_comp = p_image_header->comps;
|
||||
for (i = 0; i < p_image_header->numcomps; ++i) {
|
||||
l_comp_x0 = opj_uint_ceildiv(l_x0, l_img_comp->dx);
|
||||
l_comp_y0 = opj_uint_ceildiv(l_y0, l_img_comp->dy);
|
||||
l_comp_x1 = opj_uint_ceildiv(l_x1, l_img_comp->dx);
|
||||
l_comp_y1 = opj_uint_ceildiv(l_y1, l_img_comp->dy);
|
||||
l_width = opj_uint_ceildivpow2(l_comp_x1 - l_comp_x0, l_img_comp->factor);
|
||||
l_height = opj_uint_ceildivpow2(l_comp_y1 - l_comp_y0, l_img_comp->factor);
|
||||
l_img_comp->w = l_width;
|
||||
l_img_comp->h = l_height;
|
||||
l_img_comp->x0 = l_comp_x0;
|
||||
l_img_comp->y0 = l_comp_y0;
|
||||
++l_img_comp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy only header of image and its component header (no data are copied)
|
||||
* if dest image have data, they will be freed
|
||||
*
|
||||
* @param p_image_src the src image
|
||||
* @param p_image_dest the dest image
|
||||
*
|
||||
*/
|
||||
void opj_copy_image_header(const opj_image_t* p_image_src,
|
||||
opj_image_t* p_image_dest)
|
||||
{
|
||||
OPJ_UINT32 compno;
|
||||
|
||||
/* preconditions */
|
||||
assert(p_image_src != 00);
|
||||
assert(p_image_dest != 00);
|
||||
|
||||
p_image_dest->x0 = p_image_src->x0;
|
||||
p_image_dest->y0 = p_image_src->y0;
|
||||
p_image_dest->x1 = p_image_src->x1;
|
||||
p_image_dest->y1 = p_image_src->y1;
|
||||
|
||||
if (p_image_dest->comps) {
|
||||
for (compno = 0; compno < p_image_dest->numcomps; compno++) {
|
||||
opj_image_comp_t *image_comp = &(p_image_dest->comps[compno]);
|
||||
if (image_comp->data) {
|
||||
opj_image_data_free(image_comp->data);
|
||||
}
|
||||
}
|
||||
opj_free(p_image_dest->comps);
|
||||
p_image_dest->comps = NULL;
|
||||
}
|
||||
|
||||
p_image_dest->numcomps = p_image_src->numcomps;
|
||||
|
||||
p_image_dest->comps = (opj_image_comp_t*) opj_malloc(p_image_dest->numcomps *
|
||||
sizeof(opj_image_comp_t));
|
||||
if (!p_image_dest->comps) {
|
||||
p_image_dest->comps = NULL;
|
||||
p_image_dest->numcomps = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
for (compno = 0; compno < p_image_dest->numcomps; compno++) {
|
||||
memcpy(&(p_image_dest->comps[compno]),
|
||||
&(p_image_src->comps[compno]),
|
||||
sizeof(opj_image_comp_t));
|
||||
p_image_dest->comps[compno].data = NULL;
|
||||
}
|
||||
|
||||
p_image_dest->color_space = p_image_src->color_space;
|
||||
p_image_dest->icc_profile_len = p_image_src->icc_profile_len;
|
||||
|
||||
if (p_image_dest->icc_profile_len) {
|
||||
p_image_dest->icc_profile_buf = (OPJ_BYTE*)opj_malloc(
|
||||
p_image_dest->icc_profile_len);
|
||||
if (!p_image_dest->icc_profile_buf) {
|
||||
p_image_dest->icc_profile_buf = NULL;
|
||||
p_image_dest->icc_profile_len = 0;
|
||||
return;
|
||||
}
|
||||
memcpy(p_image_dest->icc_profile_buf,
|
||||
p_image_src->icc_profile_buf,
|
||||
p_image_src->icc_profile_len);
|
||||
} else {
|
||||
p_image_dest->icc_profile_buf = NULL;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
opj_image_t* OPJ_CALLCONV opj_image_tile_create(OPJ_UINT32 numcmpts,
|
||||
opj_image_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc)
|
||||
{
|
||||
OPJ_UINT32 compno;
|
||||
opj_image_t *image = 00;
|
||||
|
||||
image = (opj_image_t*) opj_calloc(1, sizeof(opj_image_t));
|
||||
if (image) {
|
||||
|
||||
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));
|
||||
if (!image->comps) {
|
||||
opj_image_destroy(image);
|
||||
return 00;
|
||||
}
|
||||
|
||||
/* create the individual image components */
|
||||
for (compno = 0; compno < numcmpts; compno++) {
|
||||
opj_image_comp_t *comp = &image->comps[compno];
|
||||
comp->dx = cmptparms[compno].dx;
|
||||
comp->dy = cmptparms[compno].dy;
|
||||
comp->w = cmptparms[compno].w;
|
||||
comp->h = cmptparms[compno].h;
|
||||
comp->x0 = cmptparms[compno].x0;
|
||||
comp->y0 = cmptparms[compno].y0;
|
||||
comp->prec = cmptparms[compno].prec;
|
||||
comp->sgnd = cmptparms[compno].sgnd;
|
||||
comp->data = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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) 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 OPJ_IMAGE_H
|
||||
#define OPJ_IMAGE_H
|
||||
/**
|
||||
@file image.h
|
||||
@brief Implementation of operations on images (IMAGE)
|
||||
|
||||
The functions in IMAGE.C have for goal to realize operations on images.
|
||||
*/
|
||||
|
||||
struct opj_image;
|
||||
struct opj_cp;
|
||||
|
||||
/** @defgroup IMAGE IMAGE - Implementation of operations on images */
|
||||
/*@{*/
|
||||
|
||||
/**
|
||||
* Create an empty image
|
||||
*
|
||||
* @return returns an empty image if successful, returns NULL otherwise
|
||||
*/
|
||||
opj_image_t* opj_image_create0(void);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Updates the components characteristics of the image from the coding parameters.
|
||||
*
|
||||
* @param p_image_header the image header to update.
|
||||
* @param p_cp the coding parameters from which to update the image.
|
||||
*/
|
||||
void opj_image_comp_header_update(opj_image_t * p_image,
|
||||
const struct opj_cp* p_cp);
|
||||
|
||||
void opj_copy_image_header(const opj_image_t* p_image_src,
|
||||
opj_image_t* p_image_dest);
|
||||
|
||||
/*@}*/
|
||||
|
||||
#endif /* OPJ_IMAGE_H */
|
||||
|
||||
@@ -0,0 +1,295 @@
|
||||
/*
|
||||
* 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) 2008, Jerome Fimes, Communications & Systemes <[email protected]>
|
||||
* 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 "opj_includes.h"
|
||||
|
||||
/**
|
||||
* LUP decomposition
|
||||
*/
|
||||
static OPJ_BOOL opj_lupDecompose(OPJ_FLOAT32 * matrix,
|
||||
OPJ_UINT32 * permutations,
|
||||
OPJ_FLOAT32 * p_swap_area,
|
||||
OPJ_UINT32 nb_compo);
|
||||
/**
|
||||
* LUP solving
|
||||
*/
|
||||
static void opj_lupSolve(OPJ_FLOAT32 * pResult,
|
||||
OPJ_FLOAT32* pMatrix,
|
||||
OPJ_FLOAT32* pVector,
|
||||
OPJ_UINT32* pPermutations,
|
||||
OPJ_UINT32 nb_compo,
|
||||
OPJ_FLOAT32 * p_intermediate_data);
|
||||
|
||||
/**
|
||||
*LUP inversion (call with the result of lupDecompose)
|
||||
*/
|
||||
static void opj_lupInvert(OPJ_FLOAT32 * pSrcMatrix,
|
||||
OPJ_FLOAT32 * pDestMatrix,
|
||||
OPJ_UINT32 nb_compo,
|
||||
OPJ_UINT32 * pPermutations,
|
||||
OPJ_FLOAT32 * p_src_temp,
|
||||
OPJ_FLOAT32 * p_dest_temp,
|
||||
OPJ_FLOAT32 * p_swap_area);
|
||||
|
||||
/*
|
||||
==========================================================
|
||||
Matric inversion interface
|
||||
==========================================================
|
||||
*/
|
||||
/**
|
||||
* Matrix inversion.
|
||||
*/
|
||||
OPJ_BOOL opj_matrix_inversion_f(OPJ_FLOAT32 * pSrcMatrix,
|
||||
OPJ_FLOAT32 * pDestMatrix,
|
||||
OPJ_UINT32 nb_compo)
|
||||
{
|
||||
OPJ_BYTE * l_data = 00;
|
||||
OPJ_UINT32 l_permutation_size = nb_compo * (OPJ_UINT32)sizeof(OPJ_UINT32);
|
||||
OPJ_UINT32 l_swap_size = nb_compo * (OPJ_UINT32)sizeof(OPJ_FLOAT32);
|
||||
OPJ_UINT32 l_total_size = l_permutation_size + 3 * l_swap_size;
|
||||
OPJ_UINT32 * lPermutations = 00;
|
||||
OPJ_FLOAT32 * l_double_data = 00;
|
||||
|
||||
l_data = (OPJ_BYTE *) opj_malloc(l_total_size);
|
||||
if (l_data == 0) {
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
lPermutations = (OPJ_UINT32 *) l_data;
|
||||
l_double_data = (OPJ_FLOAT32 *)(l_data + l_permutation_size);
|
||||
memset(lPermutations, 0, l_permutation_size);
|
||||
|
||||
if (! opj_lupDecompose(pSrcMatrix, lPermutations, l_double_data, nb_compo)) {
|
||||
opj_free(l_data);
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
opj_lupInvert(pSrcMatrix, pDestMatrix, nb_compo, lPermutations, l_double_data,
|
||||
l_double_data + nb_compo, l_double_data + 2 * nb_compo);
|
||||
opj_free(l_data);
|
||||
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==========================================================
|
||||
Local functions
|
||||
==========================================================
|
||||
*/
|
||||
static OPJ_BOOL opj_lupDecompose(OPJ_FLOAT32 * matrix,
|
||||
OPJ_UINT32 * permutations,
|
||||
OPJ_FLOAT32 * p_swap_area,
|
||||
OPJ_UINT32 nb_compo)
|
||||
{
|
||||
OPJ_UINT32 * tmpPermutations = permutations;
|
||||
OPJ_UINT32 * dstPermutations;
|
||||
OPJ_UINT32 k2 = 0, t;
|
||||
OPJ_FLOAT32 temp;
|
||||
OPJ_UINT32 i, j, k;
|
||||
OPJ_FLOAT32 p;
|
||||
OPJ_UINT32 lLastColum = nb_compo - 1;
|
||||
OPJ_UINT32 lSwapSize = nb_compo * (OPJ_UINT32)sizeof(OPJ_FLOAT32);
|
||||
OPJ_FLOAT32 * lTmpMatrix = matrix;
|
||||
OPJ_FLOAT32 * lColumnMatrix, * lDestMatrix;
|
||||
OPJ_UINT32 offset = 1;
|
||||
OPJ_UINT32 lStride = nb_compo - 1;
|
||||
|
||||
/*initialize permutations */
|
||||
for (i = 0; i < nb_compo; ++i) {
|
||||
*tmpPermutations++ = i;
|
||||
}
|
||||
/* now make a pivot with column switch */
|
||||
tmpPermutations = permutations;
|
||||
for (k = 0; k < lLastColum; ++k) {
|
||||
p = 0.0;
|
||||
|
||||
/* take the middle element */
|
||||
lColumnMatrix = lTmpMatrix + k;
|
||||
|
||||
/* make permutation with the biggest value in the column */
|
||||
for (i = k; i < nb_compo; ++i) {
|
||||
temp = ((*lColumnMatrix > 0) ? *lColumnMatrix : -(*lColumnMatrix));
|
||||
if (temp > p) {
|
||||
p = temp;
|
||||
k2 = i;
|
||||
}
|
||||
/* next line */
|
||||
lColumnMatrix += nb_compo;
|
||||
}
|
||||
|
||||
/* a whole rest of 0 -> non singular */
|
||||
if (p == 0.0) {
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
/* should we permute ? */
|
||||
if (k2 != k) {
|
||||
/*exchange of line */
|
||||
/* k2 > k */
|
||||
dstPermutations = tmpPermutations + k2 - k;
|
||||
/* swap indices */
|
||||
t = *tmpPermutations;
|
||||
*tmpPermutations = *dstPermutations;
|
||||
*dstPermutations = t;
|
||||
|
||||
/* and swap entire line. */
|
||||
lColumnMatrix = lTmpMatrix + (k2 - k) * nb_compo;
|
||||
memcpy(p_swap_area, lColumnMatrix, lSwapSize);
|
||||
memcpy(lColumnMatrix, lTmpMatrix, lSwapSize);
|
||||
memcpy(lTmpMatrix, p_swap_area, lSwapSize);
|
||||
}
|
||||
|
||||
/* now update data in the rest of the line and line after */
|
||||
lDestMatrix = lTmpMatrix + k;
|
||||
lColumnMatrix = lDestMatrix + nb_compo;
|
||||
/* take the middle element */
|
||||
temp = *(lDestMatrix++);
|
||||
|
||||
/* now compute up data (i.e. coeff up of the diagonal). */
|
||||
for (i = offset; i < nb_compo; ++i) {
|
||||
/*lColumnMatrix; */
|
||||
/* divide the lower column elements by the diagonal value */
|
||||
|
||||
/* matrix[i][k] /= matrix[k][k]; */
|
||||
/* p = matrix[i][k] */
|
||||
p = *lColumnMatrix / temp;
|
||||
*(lColumnMatrix++) = p;
|
||||
|
||||
for (j = /* k + 1 */ offset; j < nb_compo; ++j) {
|
||||
/* matrix[i][j] -= matrix[i][k] * matrix[k][j]; */
|
||||
*(lColumnMatrix++) -= p * (*(lDestMatrix++));
|
||||
}
|
||||
/* come back to the k+1th element */
|
||||
lDestMatrix -= lStride;
|
||||
/* go to kth element of the next line */
|
||||
lColumnMatrix += k;
|
||||
}
|
||||
|
||||
/* offset is now k+2 */
|
||||
++offset;
|
||||
/* 1 element less for stride */
|
||||
--lStride;
|
||||
/* next line */
|
||||
lTmpMatrix += nb_compo;
|
||||
/* next permutation element */
|
||||
++tmpPermutations;
|
||||
}
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
static void opj_lupSolve(OPJ_FLOAT32 * pResult,
|
||||
OPJ_FLOAT32 * pMatrix,
|
||||
OPJ_FLOAT32 * pVector,
|
||||
OPJ_UINT32* pPermutations,
|
||||
OPJ_UINT32 nb_compo, OPJ_FLOAT32 * p_intermediate_data)
|
||||
{
|
||||
OPJ_INT32 k;
|
||||
OPJ_UINT32 i, j;
|
||||
OPJ_FLOAT32 sum;
|
||||
OPJ_FLOAT32 u;
|
||||
OPJ_UINT32 lStride = nb_compo + 1;
|
||||
OPJ_FLOAT32 * lCurrentPtr;
|
||||
OPJ_FLOAT32 * lIntermediatePtr;
|
||||
OPJ_FLOAT32 * lDestPtr;
|
||||
OPJ_FLOAT32 * lTmpMatrix;
|
||||
OPJ_FLOAT32 * lLineMatrix = pMatrix;
|
||||
OPJ_FLOAT32 * lBeginPtr = pResult + nb_compo - 1;
|
||||
OPJ_FLOAT32 * lGeneratedData;
|
||||
OPJ_UINT32 * lCurrentPermutationPtr = pPermutations;
|
||||
|
||||
|
||||
lIntermediatePtr = p_intermediate_data;
|
||||
lGeneratedData = p_intermediate_data + nb_compo - 1;
|
||||
|
||||
for (i = 0; i < nb_compo; ++i) {
|
||||
sum = 0.0;
|
||||
lCurrentPtr = p_intermediate_data;
|
||||
lTmpMatrix = lLineMatrix;
|
||||
for (j = 1; j <= i; ++j) {
|
||||
/* sum += matrix[i][j-1] * y[j-1]; */
|
||||
sum += (*(lTmpMatrix++)) * (*(lCurrentPtr++));
|
||||
}
|
||||
/*y[i] = pVector[pPermutations[i]] - sum; */
|
||||
*(lIntermediatePtr++) = pVector[*(lCurrentPermutationPtr++)] - sum;
|
||||
lLineMatrix += nb_compo;
|
||||
}
|
||||
|
||||
/* we take the last point of the matrix */
|
||||
lLineMatrix = pMatrix + nb_compo * nb_compo - 1;
|
||||
|
||||
/* and we take after the last point of the destination vector */
|
||||
lDestPtr = pResult + nb_compo;
|
||||
|
||||
|
||||
assert(nb_compo != 0);
|
||||
for (k = (OPJ_INT32)nb_compo - 1; k != -1 ; --k) {
|
||||
sum = 0.0;
|
||||
lTmpMatrix = lLineMatrix;
|
||||
u = *(lTmpMatrix++);
|
||||
lCurrentPtr = lDestPtr--;
|
||||
for (j = (OPJ_UINT32)(k + 1); j < nb_compo; ++j) {
|
||||
/* sum += matrix[k][j] * x[j] */
|
||||
sum += (*(lTmpMatrix++)) * (*(lCurrentPtr++));
|
||||
}
|
||||
/*x[k] = (y[k] - sum) / u; */
|
||||
*(lBeginPtr--) = (*(lGeneratedData--) - sum) / u;
|
||||
lLineMatrix -= lStride;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void opj_lupInvert(OPJ_FLOAT32 * pSrcMatrix,
|
||||
OPJ_FLOAT32 * pDestMatrix,
|
||||
OPJ_UINT32 nb_compo,
|
||||
OPJ_UINT32 * pPermutations,
|
||||
OPJ_FLOAT32 * p_src_temp,
|
||||
OPJ_FLOAT32 * p_dest_temp,
|
||||
OPJ_FLOAT32 * p_swap_area)
|
||||
{
|
||||
OPJ_UINT32 j, i;
|
||||
OPJ_FLOAT32 * lCurrentPtr;
|
||||
OPJ_FLOAT32 * lLineMatrix = pDestMatrix;
|
||||
OPJ_UINT32 lSwapSize = nb_compo * (OPJ_UINT32)sizeof(OPJ_FLOAT32);
|
||||
|
||||
for (j = 0; j < nb_compo; ++j) {
|
||||
lCurrentPtr = lLineMatrix++;
|
||||
memset(p_src_temp, 0, lSwapSize);
|
||||
p_src_temp[j] = 1.0;
|
||||
opj_lupSolve(p_dest_temp, pSrcMatrix, p_src_temp, pPermutations, nb_compo,
|
||||
p_swap_area);
|
||||
|
||||
for (i = 0; i < nb_compo; ++i) {
|
||||
*(lCurrentPtr) = p_dest_temp[i];
|
||||
lCurrentPtr += nb_compo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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) 2008, Jerome Fimes, Communications & Systemes <[email protected]>
|
||||
* 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 OPJ_INVERT_H
|
||||
#define OPJ_INVERT_H
|
||||
/**
|
||||
@file invert.h
|
||||
@brief Implementation of the matrix inversion
|
||||
|
||||
The function in INVERT.H compute a matrix inversion with a LUP method
|
||||
*/
|
||||
|
||||
/** @defgroup INVERT INVERT - Implementation of a matrix inversion */
|
||||
/*@{*/
|
||||
/** @name Exported functions */
|
||||
/*@{*/
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Calculates a n x n double matrix inversion with a LUP method. Data is aligned, rows after rows (or columns after columns).
|
||||
* The function does not take ownership of any memory block, data must be fred by the user.
|
||||
*
|
||||
* @param pSrcMatrix the matrix to invert.
|
||||
* @param pDestMatrix data to store the inverted matrix.
|
||||
* @param nb_compo size of the matrix
|
||||
* @return OPJ_TRUE if the inversion is successful, OPJ_FALSE if the matrix is singular.
|
||||
*/
|
||||
OPJ_BOOL opj_matrix_inversion_f(OPJ_FLOAT32 * pSrcMatrix,
|
||||
OPJ_FLOAT32 * pDestMatrix,
|
||||
OPJ_UINT32 nb_compo);
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/*@}*/
|
||||
|
||||
/*@}*/
|
||||
|
||||
#endif /* OPJ_INVERT_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,954 @@
|
||||
/*
|
||||
* 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
|
||||
* Copyright (c) 2008, Jerome Fimes, Communications & Systemes <[email protected]>
|
||||
* Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France
|
||||
* Copyright (c) 2012, CS Systemes d'Information, France
|
||||
*
|
||||
* 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 OPJ_J2K_H
|
||||
#define OPJ_J2K_H
|
||||
/**
|
||||
@file j2k.h
|
||||
@brief The JPEG-2000 Codestream Reader/Writer (J2K)
|
||||
|
||||
The functions in J2K.C have for goal to read/write the several parts of the codestream: markers and data.
|
||||
*/
|
||||
|
||||
/** @defgroup J2K J2K - JPEG-2000 codestream reader/writer */
|
||||
/*@{*/
|
||||
|
||||
#define J2K_CP_CSTY_PRT 0x01
|
||||
#define J2K_CP_CSTY_SOP 0x02
|
||||
#define J2K_CP_CSTY_EPH 0x04
|
||||
#define J2K_CCP_CSTY_PRT 0x01
|
||||
#define J2K_CCP_CBLKSTY_LAZY 0x01 /**< Selective arithmetic coding bypass */
|
||||
#define J2K_CCP_CBLKSTY_RESET 0x02 /**< Reset context probabilities on coding pass boundaries */
|
||||
#define J2K_CCP_CBLKSTY_TERMALL 0x04 /**< Termination on each coding pass */
|
||||
#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
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
#define J2K_MS_SOC 0xff4f /**< SOC marker value */
|
||||
#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 */
|
||||
#define J2K_MS_POC 0xff5f /**< POC marker value */
|
||||
#define J2K_MS_TLM 0xff55 /**< TLM marker value */
|
||||
#define J2K_MS_PLM 0xff57 /**< PLM marker value */
|
||||
#define J2K_MS_PLT 0xff58 /**< PLT marker value */
|
||||
#define J2K_MS_PPM 0xff60 /**< PPM marker value */
|
||||
#define J2K_MS_PPT 0xff61 /**< PPT marker value */
|
||||
#define J2K_MS_SOP 0xff91 /**< SOP marker value */
|
||||
#define J2K_MS_EPH 0xff92 /**< EPH marker value */
|
||||
#define J2K_MS_CRG 0xff63 /**< CRG marker value */
|
||||
#define J2K_MS_COM 0xff64 /**< COM marker value */
|
||||
#define J2K_MS_CBD 0xff78 /**< CBD marker value */
|
||||
#define J2K_MS_MCC 0xff75 /**< MCC marker value */
|
||||
#define J2K_MS_MCT 0xff74 /**< MCT marker value */
|
||||
#define J2K_MS_MCO 0xff77 /**< MCO marker value */
|
||||
|
||||
#define J2K_MS_UNK 0 /**< UNKNOWN marker value */
|
||||
|
||||
/* UniPG>> */
|
||||
#ifdef USE_JPWL
|
||||
#define J2K_MS_EPC 0xff68 /**< EPC marker value (Part 11: JPEG 2000 for Wireless) */
|
||||
#define J2K_MS_EPB 0xff66 /**< EPB marker value (Part 11: JPEG 2000 for Wireless) */
|
||||
#define J2K_MS_ESD 0xff67 /**< ESD marker value (Part 11: JPEG 2000 for Wireless) */
|
||||
#define J2K_MS_RED 0xff69 /**< RED marker value (Part 11: JPEG 2000 for Wireless) */
|
||||
#endif /* USE_JPWL */
|
||||
#ifdef USE_JPSEC
|
||||
#define J2K_MS_SEC 0xff65 /**< SEC marker value (Part 8: Secure JPEG 2000) */
|
||||
#define J2K_MS_INSEC 0xff94 /**< INSEC marker value (Part 8: Secure JPEG 2000) */
|
||||
#endif /* USE_JPSEC */
|
||||
/* <<UniPG */
|
||||
|
||||
#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
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Values that specify the status of the decoding process when decoding the main header.
|
||||
* These values may be combined with a | operator.
|
||||
* */
|
||||
typedef enum J2K_STATUS {
|
||||
J2K_STATE_NONE = 0x0000, /**< a SOC marker is expected */
|
||||
J2K_STATE_MHSOC = 0x0001, /**< a SOC marker is expected */
|
||||
J2K_STATE_MHSIZ = 0x0002, /**< a SIZ marker is expected */
|
||||
J2K_STATE_MH = 0x0004, /**< the decoding process is in the main header */
|
||||
J2K_STATE_TPHSOT = 0x0008, /**< the decoding process is in a tile part header and expects a SOT marker */
|
||||
J2K_STATE_TPH = 0x0010, /**< the decoding process is in a tile part header */
|
||||
J2K_STATE_MT = 0x0020, /**< the EOC marker has just been read */
|
||||
J2K_STATE_NEOC = 0x0040, /**< the decoding process must not expect a EOC marker because the codestream is truncated */
|
||||
J2K_STATE_DATA = 0x0080, /**< a tile header has been successfully read and codestream is expected */
|
||||
|
||||
J2K_STATE_EOC = 0x0100, /**< the decoding process has encountered the EOC marker */
|
||||
J2K_STATE_ERR = 0x8000 /**< the decoding process has encountered an error (FIXME warning V1 = 0x0080)*/
|
||||
} J2K_STATUS;
|
||||
|
||||
/**
|
||||
* Type of elements storing in the MCT data
|
||||
*/
|
||||
typedef enum MCT_ELEMENT_TYPE {
|
||||
MCT_TYPE_INT16 = 0, /** MCT data is stored as signed shorts*/
|
||||
MCT_TYPE_INT32 = 1, /** MCT data is stored as signed integers*/
|
||||
MCT_TYPE_FLOAT = 2, /** MCT data is stored as floats*/
|
||||
MCT_TYPE_DOUBLE = 3 /** MCT data is stored as doubles*/
|
||||
} J2K_MCT_ELEMENT_TYPE;
|
||||
|
||||
/**
|
||||
* Type of MCT array
|
||||
*/
|
||||
typedef enum MCT_ARRAY_TYPE {
|
||||
MCT_TYPE_DEPENDENCY = 0,
|
||||
MCT_TYPE_DECORRELATION = 1,
|
||||
MCT_TYPE_OFFSET = 2
|
||||
} J2K_MCT_ARRAY_TYPE;
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
T2 encoding mode
|
||||
*/
|
||||
typedef enum T2_MODE {
|
||||
THRESH_CALC = 0, /** Function called in Rate allocation process*/
|
||||
FINAL_PASS = 1 /** Function called in Tier 2 process*/
|
||||
} J2K_T2_MODE;
|
||||
|
||||
/**
|
||||
* Quantization stepsize
|
||||
*/
|
||||
typedef struct opj_stepsize {
|
||||
/** exponent */
|
||||
OPJ_INT32 expn;
|
||||
/** mantissa */
|
||||
OPJ_INT32 mant;
|
||||
} opj_stepsize_t;
|
||||
|
||||
/**
|
||||
Tile-component coding parameters
|
||||
*/
|
||||
typedef struct opj_tccp {
|
||||
/** coding style */
|
||||
OPJ_UINT32 csty;
|
||||
/** number of resolutions */
|
||||
OPJ_UINT32 numresolutions;
|
||||
/** code-blocks width */
|
||||
OPJ_UINT32 cblkw;
|
||||
/** code-blocks height */
|
||||
OPJ_UINT32 cblkh;
|
||||
/** code-block coding style */
|
||||
OPJ_UINT32 cblksty;
|
||||
/** discrete wavelet transform identifier */
|
||||
OPJ_UINT32 qmfbid;
|
||||
/** quantisation style */
|
||||
OPJ_UINT32 qntsty;
|
||||
/** stepsizes used for quantization */
|
||||
opj_stepsize_t stepsizes[OPJ_J2K_MAXBANDS];
|
||||
/** number of guard bits */
|
||||
OPJ_UINT32 numgbits;
|
||||
/** Region Of Interest shift */
|
||||
OPJ_INT32 roishift;
|
||||
/** precinct width */
|
||||
OPJ_UINT32 prcw[OPJ_J2K_MAXRLVLS];
|
||||
/** precinct height */
|
||||
OPJ_UINT32 prch[OPJ_J2K_MAXRLVLS];
|
||||
/** the dc_level_shift **/
|
||||
OPJ_INT32 m_dc_level_shift;
|
||||
}
|
||||
opj_tccp_t;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* FIXME DOC
|
||||
*/
|
||||
typedef struct opj_mct_data {
|
||||
J2K_MCT_ELEMENT_TYPE m_element_type;
|
||||
J2K_MCT_ARRAY_TYPE m_array_type;
|
||||
OPJ_UINT32 m_index;
|
||||
OPJ_BYTE * m_data;
|
||||
OPJ_UINT32 m_data_size;
|
||||
}
|
||||
opj_mct_data_t;
|
||||
|
||||
/**
|
||||
* FIXME DOC
|
||||
*/
|
||||
typedef struct opj_simple_mcc_decorrelation_data {
|
||||
OPJ_UINT32 m_index;
|
||||
OPJ_UINT32 m_nb_comps;
|
||||
opj_mct_data_t * m_decorrelation_array;
|
||||
opj_mct_data_t * m_offset_array;
|
||||
OPJ_BITFIELD m_is_irreversible : 1;
|
||||
}
|
||||
opj_simple_mcc_decorrelation_data_t;
|
||||
|
||||
typedef struct opj_ppx_struct {
|
||||
OPJ_BYTE* m_data; /* m_data == NULL => Zppx not read yet */
|
||||
OPJ_UINT32 m_data_size;
|
||||
} opj_ppx;
|
||||
|
||||
/**
|
||||
Tile coding parameters :
|
||||
this structure is used to store coding/decoding parameters common to all
|
||||
tiles (information like COD, COC in main header)
|
||||
*/
|
||||
typedef struct opj_tcp {
|
||||
/** coding style */
|
||||
OPJ_UINT32 csty;
|
||||
/** progression order */
|
||||
OPJ_PROG_ORDER prg;
|
||||
/** number of layers */
|
||||
OPJ_UINT32 numlayers;
|
||||
OPJ_UINT32 num_layers_to_decode;
|
||||
/** multi-component transform identifier */
|
||||
OPJ_UINT32 mct;
|
||||
/** rates of layers */
|
||||
OPJ_FLOAT32 rates[100];
|
||||
/** number of progression order changes */
|
||||
OPJ_UINT32 numpocs;
|
||||
/** progression order changes */
|
||||
opj_poc_t pocs[J2K_MAX_POCS];
|
||||
|
||||
/** number of ppt markers (reserved size) */
|
||||
OPJ_UINT32 ppt_markers_count;
|
||||
/** ppt markers data (table indexed by Zppt) */
|
||||
opj_ppx* ppt_markers;
|
||||
|
||||
/** packet header store there for future use in t2_decode_packet */
|
||||
OPJ_BYTE *ppt_data;
|
||||
/** used to keep a track of the allocated memory */
|
||||
OPJ_BYTE *ppt_buffer;
|
||||
/** Number of bytes stored inside ppt_data*/
|
||||
OPJ_UINT32 ppt_data_size;
|
||||
/** size of ppt_data*/
|
||||
OPJ_UINT32 ppt_len;
|
||||
/** PSNR values */
|
||||
OPJ_FLOAT32 distoratio[100];
|
||||
/** tile-component coding parameters */
|
||||
opj_tccp_t *tccps;
|
||||
/** current tile part number or -1 if first time into this tile */
|
||||
OPJ_INT32 m_current_tile_part_number;
|
||||
/** number of tile parts for the tile. */
|
||||
OPJ_UINT32 m_nb_tile_parts;
|
||||
/** data for the tile */
|
||||
OPJ_BYTE * m_data;
|
||||
/** size of data */
|
||||
OPJ_UINT32 m_data_size;
|
||||
/** encoding norms */
|
||||
OPJ_FLOAT64 * mct_norms;
|
||||
/** the mct decoding matrix */
|
||||
OPJ_FLOAT32 * m_mct_decoding_matrix;
|
||||
/** the mct coding matrix */
|
||||
OPJ_FLOAT32 * m_mct_coding_matrix;
|
||||
/** mct records */
|
||||
opj_mct_data_t * m_mct_records;
|
||||
/** the number of mct records. */
|
||||
OPJ_UINT32 m_nb_mct_records;
|
||||
/** the max number of mct records. */
|
||||
OPJ_UINT32 m_nb_max_mct_records;
|
||||
/** mcc records */
|
||||
opj_simple_mcc_decorrelation_data_t * m_mcc_records;
|
||||
/** the number of mct records. */
|
||||
OPJ_UINT32 m_nb_mcc_records;
|
||||
/** the max number of mct records. */
|
||||
OPJ_UINT32 m_nb_max_mcc_records;
|
||||
|
||||
|
||||
/***** FLAGS *******/
|
||||
/** If cod == 1 --> there was a COD marker for the present tile */
|
||||
OPJ_BITFIELD cod : 1;
|
||||
/** If ppt == 1 --> there was a PPT marker for the present tile */
|
||||
OPJ_BITFIELD ppt : 1;
|
||||
/** indicates if a POC marker has been used O:NO, 1:YES */
|
||||
OPJ_BITFIELD POC : 1;
|
||||
} 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 {
|
||||
/** Maximum rate for each component. If == 0, component size limitation is not considered */
|
||||
OPJ_UINT32 m_max_comp_size;
|
||||
/** Position of tile part flag in progression order*/
|
||||
OPJ_INT32 m_tp_pos;
|
||||
/** fixed layer */
|
||||
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;
|
||||
/** Enabling Tile part generation*/
|
||||
OPJ_BITFIELD m_tp_on : 1;
|
||||
}
|
||||
opj_encoding_param_t;
|
||||
|
||||
typedef struct opj_decoding_param {
|
||||
/** if != 0, then original dimension divided by 2^(reduce); if == 0 or not used, image is decoded to the full resolution */
|
||||
OPJ_UINT32 m_reduce;
|
||||
/** if != 0, then only the first "layer" layers are decoded; if == 0 or not used, all the quality layers are decoded */
|
||||
OPJ_UINT32 m_layer;
|
||||
}
|
||||
opj_decoding_param_t;
|
||||
|
||||
|
||||
/**
|
||||
* Coding parameters
|
||||
*/
|
||||
typedef struct opj_cp {
|
||||
/** Size of the image in bits*/
|
||||
/*int img_size;*/
|
||||
/** Rsiz*/
|
||||
OPJ_UINT16 rsiz;
|
||||
/** XTOsiz */
|
||||
OPJ_UINT32 tx0; /* MSD see norm */
|
||||
/** YTOsiz */
|
||||
OPJ_UINT32 ty0; /* MSD see norm */
|
||||
/** XTsiz */
|
||||
OPJ_UINT32 tdx;
|
||||
/** YTsiz */
|
||||
OPJ_UINT32 tdy;
|
||||
/** comment */
|
||||
OPJ_CHAR *comment;
|
||||
/** number of tiles in width */
|
||||
OPJ_UINT32 tw;
|
||||
/** number of tiles in height */
|
||||
OPJ_UINT32 th;
|
||||
|
||||
/** number of ppm markers (reserved size) */
|
||||
OPJ_UINT32 ppm_markers_count;
|
||||
/** ppm markers data (table indexed by Zppm) */
|
||||
opj_ppx* ppm_markers;
|
||||
|
||||
/** packet header store there for future use in t2_decode_packet */
|
||||
OPJ_BYTE *ppm_data;
|
||||
/** size of the ppm_data*/
|
||||
OPJ_UINT32 ppm_len;
|
||||
/** size of the ppm_data*/
|
||||
OPJ_UINT32 ppm_data_read;
|
||||
|
||||
OPJ_BYTE *ppm_data_current;
|
||||
|
||||
/** packet header storage original buffer */
|
||||
OPJ_BYTE *ppm_buffer;
|
||||
/** pointer remaining on the first byte of the first header if ppm is used */
|
||||
OPJ_BYTE *ppm_data_first;
|
||||
/** Number of bytes actually stored inside the ppm_data */
|
||||
OPJ_UINT32 ppm_data_size;
|
||||
/** use in case of multiple marker PPM (number of info already store) */
|
||||
OPJ_INT32 ppm_store;
|
||||
/** use in case of multiple marker PPM (case on non-finished previous info) */
|
||||
OPJ_INT32 ppm_previous;
|
||||
|
||||
/** tile coding parameters */
|
||||
opj_tcp_t *tcps;
|
||||
|
||||
union {
|
||||
opj_decoding_param_t m_dec;
|
||||
opj_encoding_param_t m_enc;
|
||||
}
|
||||
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
|
||||
/** enables writing of EPC in MH, thus activating JPWL */
|
||||
OPJ_BOOL epc_on;
|
||||
/** enables writing of EPB, in case of activated JPWL */
|
||||
OPJ_BOOL epb_on;
|
||||
/** enables writing of ESD, in case of activated JPWL */
|
||||
OPJ_BOOL esd_on;
|
||||
/** enables writing of informative techniques of ESD, in case of activated JPWL */
|
||||
OPJ_BOOL info_on;
|
||||
/** enables writing of RED, in case of activated JPWL */
|
||||
OPJ_BOOL red_on;
|
||||
/** error protection method for MH (0,1,16,32,37-128) */
|
||||
int hprot_MH;
|
||||
/** tile number of header protection specification (>=0) */
|
||||
int hprot_TPH_tileno[JPWL_MAX_NO_TILESPECS];
|
||||
/** error protection methods for TPHs (0,1,16,32,37-128) */
|
||||
int hprot_TPH[JPWL_MAX_NO_TILESPECS];
|
||||
/** tile number of packet protection specification (>=0) */
|
||||
int pprot_tileno[JPWL_MAX_NO_PACKSPECS];
|
||||
/** packet number of packet protection specification (>=0) */
|
||||
int pprot_packno[JPWL_MAX_NO_PACKSPECS];
|
||||
/** error protection methods for packets (0,1,16,32,37-128) */
|
||||
int pprot[JPWL_MAX_NO_PACKSPECS];
|
||||
/** enables writing of ESD, (0/2/4 bytes) */
|
||||
int sens_size;
|
||||
/** sensitivity addressing size (0=auto/2/4 bytes) */
|
||||
int sens_addr;
|
||||
/** sensitivity range (0-3) */
|
||||
int sens_range;
|
||||
/** sensitivity method for MH (-1,0-7) */
|
||||
int sens_MH;
|
||||
/** tile number of sensitivity specification (>=0) */
|
||||
int sens_TPH_tileno[JPWL_MAX_NO_TILESPECS];
|
||||
/** sensitivity methods for TPHs (-1,0-7) */
|
||||
int sens_TPH[JPWL_MAX_NO_TILESPECS];
|
||||
/** enables JPWL correction at the decoder */
|
||||
OPJ_BOOL correct;
|
||||
/** expected number of components at the decoder */
|
||||
int exp_comps;
|
||||
/** maximum number of tiles at the decoder */
|
||||
OPJ_UINT32 max_tiles;
|
||||
#endif /* USE_JPWL */
|
||||
|
||||
/******** FLAGS *********/
|
||||
/** if ppm == 1 --> there was a PPM marker*/
|
||||
OPJ_BITFIELD ppm : 1;
|
||||
/** tells if the parameter is a coding or decoding one */
|
||||
OPJ_BITFIELD m_is_decoder : 1;
|
||||
/** whether different bit depth or sign per component is allowed. Decoder only for ow */
|
||||
OPJ_BITFIELD allow_different_bit_depth_sign : 1;
|
||||
/* <<UniPG */
|
||||
} opj_cp_t;
|
||||
|
||||
/** Entry of a TLM marker segment */
|
||||
typedef struct opj_j2k_tlm_tile_part_info {
|
||||
/** Tile index of the tile part. Ttlmi field */
|
||||
OPJ_UINT16 m_tile_index;
|
||||
/** Length in bytes, from the beginning of the SOT marker to the end of
|
||||
* the bit stream data for that tile-part. Ptlmi field */
|
||||
OPJ_UINT32 m_length;
|
||||
} opj_j2k_tlm_tile_part_info_t;
|
||||
|
||||
/** Information got from the concatenation of TLM marker semgnets. */
|
||||
typedef struct opj_j2k_tlm_info {
|
||||
/** Number of entries in m_tile_part_infos. */
|
||||
OPJ_UINT32 m_entries_count;
|
||||
/** Array of m_entries_count values. */
|
||||
opj_j2k_tlm_tile_part_info_t* m_tile_part_infos;
|
||||
|
||||
OPJ_BOOL m_is_invalid;
|
||||
} opj_j2k_tlm_info_t;
|
||||
|
||||
typedef struct opj_j2k_dec {
|
||||
/** locate in which part of the codestream the decoder is (main header, tile header, end) */
|
||||
OPJ_UINT32 m_state;
|
||||
/**
|
||||
* store decoding parameters common to all tiles (information like COD, COC in main header)
|
||||
*/
|
||||
opj_tcp_t *m_default_tcp;
|
||||
OPJ_BYTE *m_header_data;
|
||||
OPJ_UINT32 m_header_data_size;
|
||||
/** to tell the tile part length */
|
||||
OPJ_UINT32 m_sot_length;
|
||||
/** Only tiles index in the correct range will be decoded.*/
|
||||
OPJ_UINT32 m_start_tile_x;
|
||||
OPJ_UINT32 m_start_tile_y;
|
||||
OPJ_UINT32 m_end_tile_x;
|
||||
OPJ_UINT32 m_end_tile_y;
|
||||
|
||||
/** Index of the tile to decode (used in get_tile) */
|
||||
OPJ_INT32 m_tile_ind_to_dec;
|
||||
/** Position of the last SOT marker read */
|
||||
OPJ_OFF_T m_last_sot_read_pos;
|
||||
|
||||
/**
|
||||
* Indicate that the current tile-part is assume as the last tile part of the codestream.
|
||||
* It is useful in the case of PSot is equal to zero. The sot length will be compute in the
|
||||
* 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;
|
||||
|
||||
opj_j2k_tlm_info_t m_tlm;
|
||||
|
||||
/** Below if used when there's TLM information available and we use
|
||||
* opj_set_decoded_area() to a subset of all tiles.
|
||||
*/
|
||||
/* Current index in m_intersecting_tile_parts_offset[] to seek to */
|
||||
OPJ_UINT32 m_idx_intersecting_tile_parts;
|
||||
/* Number of elements of m_intersecting_tile_parts_offset[] */
|
||||
OPJ_UINT32 m_num_intersecting_tile_parts;
|
||||
/* Start offset of contributing tile parts */
|
||||
OPJ_OFF_T* m_intersecting_tile_parts_offset;
|
||||
|
||||
/** to tell that a tile can be decoded. */
|
||||
OPJ_BITFIELD m_can_decode : 1;
|
||||
OPJ_BITFIELD m_discard_tiles : 1;
|
||||
OPJ_BITFIELD m_skip_data : 1;
|
||||
/** TNsot correction : see issue 254 **/
|
||||
OPJ_BITFIELD m_nb_tile_parts_correction_checked : 1;
|
||||
OPJ_BITFIELD m_nb_tile_parts_correction : 1;
|
||||
|
||||
} opj_j2k_dec_t;
|
||||
|
||||
typedef struct opj_j2k_enc {
|
||||
/** Tile part number, regardless of poc, for each new poc, tp is reset to 1*/
|
||||
OPJ_UINT32 m_current_poc_tile_part_number; /* tp_num */
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
OPJ_OFF_T m_tlm_start;
|
||||
/**
|
||||
* Stores the sizes of the tlm.
|
||||
*/
|
||||
OPJ_BYTE * m_tlm_sot_offsets_buffer;
|
||||
/**
|
||||
* The current offset of the tlm buffer.
|
||||
*/
|
||||
OPJ_BYTE * m_tlm_sot_offsets_current;
|
||||
|
||||
/** Total num of tile parts in whole image = num tiles* num tileparts in each tile*/
|
||||
/** used in TLMmarker*/
|
||||
OPJ_UINT32 m_total_tile_parts; /* totnum_tp */
|
||||
|
||||
/* encoded data for a tile */
|
||||
OPJ_BYTE * m_encoded_tile_data;
|
||||
|
||||
/* size of the encoded_data */
|
||||
OPJ_UINT32 m_encoded_tile_size;
|
||||
|
||||
/* encoded data for a tile */
|
||||
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;
|
||||
|
||||
|
||||
|
||||
struct opj_tcd;
|
||||
/**
|
||||
JPEG-2000 codestream reader/writer
|
||||
*/
|
||||
typedef struct opj_j2k {
|
||||
/* J2K codestream is decoded*/
|
||||
OPJ_BOOL m_is_decoder;
|
||||
|
||||
/* FIXME DOC*/
|
||||
union {
|
||||
opj_j2k_dec_t m_decoder;
|
||||
opj_j2k_enc_t m_encoder;
|
||||
}
|
||||
m_specific_param;
|
||||
|
||||
/** pointer to the internal/private encoded / decoded image */
|
||||
opj_image_t* m_private_image;
|
||||
|
||||
/* pointer to the output image (decoded)*/
|
||||
opj_image_t* m_output_image;
|
||||
|
||||
/** Coding parameters */
|
||||
opj_cp_t m_cp;
|
||||
|
||||
/** the list of procedures to exec **/
|
||||
opj_procedure_list_t * m_procedure_list;
|
||||
|
||||
/** the list of validation procedures to follow to make sure the code is valid **/
|
||||
opj_procedure_list_t * m_validation_list;
|
||||
|
||||
/** helper used to write the index file */
|
||||
opj_codestream_index_t *cstr_index;
|
||||
|
||||
/** number of the tile currently concern by coding/decoding */
|
||||
OPJ_UINT32 m_current_tile_number;
|
||||
|
||||
/** the current tile coder/decoder **/
|
||||
struct opj_tcd * m_tcd;
|
||||
|
||||
/** 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 */
|
||||
unsigned int dump_state;
|
||||
}
|
||||
opj_j2k_t;
|
||||
|
||||
|
||||
|
||||
|
||||
/** @name Exported functions */
|
||||
/*@{*/
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
Setup the decoder decoding parameters using user parameters.
|
||||
Decoding parameters are returned in j2k->cp.
|
||||
@param j2k J2K decompressor handle
|
||||
@param parameters decompression parameters
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* Creates a J2K compression structure
|
||||
*
|
||||
* @return Returns a handle to a J2K compressor if successful, returns NULL otherwise
|
||||
*/
|
||||
opj_j2k_t* opj_j2k_create_compress(void);
|
||||
|
||||
|
||||
OPJ_BOOL opj_j2k_setup_encoder(opj_j2k_t *p_j2k,
|
||||
opj_cparameters_t *parameters,
|
||||
opj_image_t *image,
|
||||
opj_event_mgr_t * p_manager);
|
||||
|
||||
/**
|
||||
Converts an enum type progression order to string type
|
||||
*/
|
||||
const char *opj_j2k_convert_progression_order(OPJ_PROG_ORDER prg_order);
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/*@}*/
|
||||
|
||||
/*@}*/
|
||||
|
||||
/**
|
||||
* Ends the decompression procedures and possibiliy add data to be read after the
|
||||
* codestream.
|
||||
*/
|
||||
OPJ_BOOL opj_j2k_end_decompress(opj_j2k_t *j2k,
|
||||
opj_stream_private_t *p_stream,
|
||||
opj_event_mgr_t * p_manager);
|
||||
|
||||
/**
|
||||
* Reads a jpeg2000 codestream header structure.
|
||||
*
|
||||
* @param p_stream the stream to read data from.
|
||||
* @param p_j2k the jpeg2000 codec.
|
||||
* @param p_image FIXME DOC
|
||||
* @param p_manager the user event manager.
|
||||
*
|
||||
* @return true if the box is valid.
|
||||
*/
|
||||
OPJ_BOOL opj_j2k_read_header(opj_stream_private_t *p_stream,
|
||||
opj_j2k_t* p_j2k,
|
||||
opj_image_t** p_image,
|
||||
opj_event_mgr_t* p_manager);
|
||||
|
||||
|
||||
/**
|
||||
* Destroys a jpeg2000 codec.
|
||||
*
|
||||
* @param p_j2k the jpeg20000 structure to destroy.
|
||||
*/
|
||||
void opj_j2k_destroy(opj_j2k_t *p_j2k);
|
||||
|
||||
/**
|
||||
* Destroys a codestream index structure.
|
||||
*
|
||||
* @param p_cstr_ind the codestream index parameter to destroy.
|
||||
*/
|
||||
void j2k_destroy_cstr_index(opj_codestream_index_t *p_cstr_ind);
|
||||
|
||||
/**
|
||||
* Decode tile data.
|
||||
* @param p_j2k the jpeg2000 codec.
|
||||
* @param p_tile_index
|
||||
* @param p_data FIXME DOC
|
||||
* @param p_data_size FIXME DOC
|
||||
* @param p_stream the stream to write data to.
|
||||
* @param p_manager the user event manager.
|
||||
*/
|
||||
OPJ_BOOL opj_j2k_decode_tile(opj_j2k_t * p_j2k,
|
||||
OPJ_UINT32 p_tile_index,
|
||||
OPJ_BYTE * p_data,
|
||||
OPJ_UINT32 p_data_size,
|
||||
opj_stream_private_t *p_stream,
|
||||
opj_event_mgr_t * p_manager);
|
||||
|
||||
/**
|
||||
* Reads a tile header.
|
||||
* @param p_j2k the jpeg2000 codec.
|
||||
* @param p_tile_index FIXME DOC
|
||||
* @param p_data_size FIXME DOC
|
||||
* @param p_tile_x0 FIXME DOC
|
||||
* @param p_tile_y0 FIXME DOC
|
||||
* @param p_tile_x1 FIXME DOC
|
||||
* @param p_tile_y1 FIXME DOC
|
||||
* @param p_nb_comps FIXME DOC
|
||||
* @param p_go_on FIXME DOC
|
||||
* @param p_stream the stream to write data to.
|
||||
* @param p_manager the user event manager.
|
||||
*/
|
||||
OPJ_BOOL opj_j2k_read_tile_header(opj_j2k_t * p_j2k,
|
||||
OPJ_UINT32 * p_tile_index,
|
||||
OPJ_UINT32 * p_data_size,
|
||||
OPJ_INT32 * p_tile_x0,
|
||||
OPJ_INT32 * p_tile_y0,
|
||||
OPJ_INT32 * p_tile_x1,
|
||||
OPJ_INT32 * p_tile_y1,
|
||||
OPJ_UINT32 * p_nb_comps,
|
||||
OPJ_BOOL * p_go_on,
|
||||
opj_stream_private_t *p_stream,
|
||||
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.
|
||||
*
|
||||
* @param p_j2k the jpeg2000 codec.
|
||||
* @param p_image FIXME DOC
|
||||
* @param p_start_x the left position of the rectangle to decode (in image coordinates).
|
||||
* @param p_start_y the up 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_end_y the bottom position of the rectangle to decode (in image coordinates).
|
||||
* @param p_manager the user event manager
|
||||
*
|
||||
* @return true if the area could be set.
|
||||
*/
|
||||
OPJ_BOOL opj_j2k_set_decode_area(opj_j2k_t *p_j2k,
|
||||
opj_image_t* p_image,
|
||||
OPJ_INT32 p_start_x, OPJ_INT32 p_start_y,
|
||||
OPJ_INT32 p_end_x, OPJ_INT32 p_end_y,
|
||||
opj_event_mgr_t * p_manager);
|
||||
|
||||
/**
|
||||
* Creates a J2K decompression structure.
|
||||
*
|
||||
* @return a handle to a J2K decompressor if successful, NULL otherwise.
|
||||
*/
|
||||
opj_j2k_t* opj_j2k_create_decompress(void);
|
||||
|
||||
|
||||
/**
|
||||
* Dump some elements from the J2K decompression structure .
|
||||
*
|
||||
*@param p_j2k the jpeg2000 codec.
|
||||
*@param flag flag to describe what elements are dump.
|
||||
*@param out_stream output stream where dump the elements.
|
||||
*
|
||||
*/
|
||||
void j2k_dump(opj_j2k_t* p_j2k, OPJ_INT32 flag, FILE* out_stream);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Dump an image header structure.
|
||||
*
|
||||
*@param image the image header to dump.
|
||||
*@param dev_dump_flag flag to describe if we are in the case of this function is use outside j2k_dump function
|
||||
*@param out_stream output stream where dump the elements.
|
||||
*/
|
||||
void j2k_dump_image_header(opj_image_t* image, OPJ_BOOL dev_dump_flag,
|
||||
FILE* out_stream);
|
||||
|
||||
/**
|
||||
* Dump a component image header structure.
|
||||
*
|
||||
*@param comp the component image header to dump.
|
||||
*@param dev_dump_flag flag to describe if we are in the case of this function is use outside j2k_dump function
|
||||
*@param out_stream output stream where dump the elements.
|
||||
*/
|
||||
void j2k_dump_image_comp_header(opj_image_comp_t* comp, OPJ_BOOL dev_dump_flag,
|
||||
FILE* out_stream);
|
||||
|
||||
/**
|
||||
* Get the codestream info from a JPEG2000 codec.
|
||||
*
|
||||
*@param p_j2k the component image header to dump.
|
||||
*
|
||||
*@return the codestream information extract from the jpg2000 codec
|
||||
*/
|
||||
opj_codestream_info_v2_t* j2k_get_cstr_info(opj_j2k_t* p_j2k);
|
||||
|
||||
/**
|
||||
* Get the codestream index from a JPEG2000 codec.
|
||||
*
|
||||
*@param p_j2k the component image header to dump.
|
||||
*
|
||||
*@return the codestream index extract from the jpg2000 codec
|
||||
*/
|
||||
opj_codestream_index_t* j2k_get_cstr_index(opj_j2k_t* p_j2k);
|
||||
|
||||
/**
|
||||
* Decode an image from a JPEG-2000 codestream
|
||||
* @param j2k J2K decompressor handle
|
||||
* @param p_stream FIXME DOC
|
||||
* @param p_image FIXME DOC
|
||||
* @param p_manager FIXME DOC
|
||||
* @return FIXME DOC
|
||||
*/
|
||||
OPJ_BOOL opj_j2k_decode(opj_j2k_t *j2k,
|
||||
opj_stream_private_t *p_stream,
|
||||
opj_image_t *p_image,
|
||||
opj_event_mgr_t *p_manager);
|
||||
|
||||
|
||||
OPJ_BOOL opj_j2k_get_tile(opj_j2k_t *p_j2k,
|
||||
opj_stream_private_t *p_stream,
|
||||
opj_image_t* p_image,
|
||||
opj_event_mgr_t * p_manager,
|
||||
OPJ_UINT32 tile_index);
|
||||
|
||||
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.
|
||||
* @param p_j2k the jpeg2000 codec.
|
||||
* @param p_tile_index FIXME DOC
|
||||
* @param p_data FIXME DOC
|
||||
* @param p_data_size FIXME DOC
|
||||
* @param p_stream the stream to write data to.
|
||||
* @param p_manager the user event manager.
|
||||
*/
|
||||
OPJ_BOOL opj_j2k_write_tile(opj_j2k_t * p_j2k,
|
||||
OPJ_UINT32 p_tile_index,
|
||||
OPJ_BYTE * p_data,
|
||||
OPJ_UINT32 p_data_size,
|
||||
opj_stream_private_t *p_stream,
|
||||
opj_event_mgr_t * p_manager);
|
||||
|
||||
/**
|
||||
* Encodes an image into a JPEG-2000 codestream
|
||||
*/
|
||||
OPJ_BOOL opj_j2k_encode(opj_j2k_t * p_j2k,
|
||||
opj_stream_private_t *cio,
|
||||
opj_event_mgr_t * p_manager);
|
||||
|
||||
/**
|
||||
* Starts a compression scheme, i.e. validates the codec parameters, writes the header.
|
||||
*
|
||||
* @param p_j2k the jpeg2000 codec.
|
||||
* @param p_stream the stream object.
|
||||
* @param p_image FIXME DOC
|
||||
* @param p_manager the user event manager.
|
||||
*
|
||||
* @return true if the codec is valid.
|
||||
*/
|
||||
OPJ_BOOL opj_j2k_start_compress(opj_j2k_t *p_j2k,
|
||||
opj_stream_private_t *p_stream,
|
||||
opj_image_t * p_image,
|
||||
opj_event_mgr_t * p_manager);
|
||||
|
||||
/**
|
||||
* Ends the compression procedures and possibiliy add data to be read after the
|
||||
* codestream.
|
||||
*/
|
||||
OPJ_BOOL opj_j2k_end_compress(opj_j2k_t *p_j2k,
|
||||
opj_stream_private_t *cio,
|
||||
opj_event_mgr_t * p_manager);
|
||||
|
||||
OPJ_BOOL opj_j2k_setup_mct_encoding(opj_tcp_t * p_tcp, opj_image_t * p_image);
|
||||
|
||||
|
||||
#endif /* OPJ_J2K_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,521 @@
|
||||
/*
|
||||
* 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) 2002-2003, Yannick Verschueren
|
||||
* Copyright (c) 2005, Herve Drolon, FreeImage Team
|
||||
* Copyright (c) 2008, 2011-2012, Centre National d'Etudes Spatiales (CNES), FR
|
||||
* Copyright (c) 2012, CS Systemes d'Information, France
|
||||
* 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 OPJ_JP2_H
|
||||
#define OPJ_JP2_H
|
||||
/**
|
||||
@file jp2.h
|
||||
@brief The JPEG-2000 file format Reader/Writer (JP2)
|
||||
|
||||
*/
|
||||
|
||||
/** @defgroup JP2 JP2 - JPEG-2000 file format reader/writer */
|
||||
/*@{*/
|
||||
|
||||
/*#define JPIP_JPIP 0x6a706970*/
|
||||
|
||||
#define JP2_JP 0x6a502020 /**< JPEG 2000 signature box */
|
||||
#define JP2_FTYP 0x66747970 /**< File type box */
|
||||
#define JP2_JP2H 0x6a703268 /**< JP2 header box (super-box) */
|
||||
#define JP2_IHDR 0x69686472 /**< Image header box */
|
||||
#define JP2_COLR 0x636f6c72 /**< Colour specification box */
|
||||
#define JP2_JP2C 0x6a703263 /**< Contiguous codestream box */
|
||||
#define JP2_URL 0x75726c20 /**< Data entry URL box */
|
||||
#define JP2_PCLR 0x70636c72 /**< Palette box */
|
||||
#define JP2_CMAP 0x636d6170 /**< Component Mapping box */
|
||||
#define JP2_CDEF 0x63646566 /**< Channel Definition box */
|
||||
#define JP2_DTBL 0x6474626c /**< Data Reference box */
|
||||
#define JP2_BPCC 0x62706363 /**< Bits per component box */
|
||||
#define JP2_JP2 0x6a703220 /**< File type fields */
|
||||
|
||||
/* For the future */
|
||||
/* #define JP2_RES 0x72657320 */ /**< Resolution box (super-box) */
|
||||
/* #define JP2_JP2I 0x6a703269 */ /**< Intellectual property box */
|
||||
/* #define JP2_XML 0x786d6c20 */ /**< XML box */
|
||||
/* #define JP2_UUID 0x75756994 */ /**< UUID box */
|
||||
/* #define JP2_UINF 0x75696e66 */ /**< UUID info box (super-box) */
|
||||
/* #define JP2_ULST 0x756c7374 */ /**< UUID list box */
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
typedef enum {
|
||||
JP2_STATE_NONE = 0x0,
|
||||
JP2_STATE_SIGNATURE = 0x1,
|
||||
JP2_STATE_FILE_TYPE = 0x2,
|
||||
JP2_STATE_HEADER = 0x4,
|
||||
JP2_STATE_CODESTREAM = 0x8,
|
||||
JP2_STATE_END_CODESTREAM = 0x10,
|
||||
JP2_STATE_UNKNOWN = 0x7fffffff /* ISO C restricts enumerator values to range of 'int' */
|
||||
}
|
||||
JP2_STATE;
|
||||
|
||||
typedef enum {
|
||||
JP2_IMG_STATE_NONE = 0x0,
|
||||
JP2_IMG_STATE_UNKNOWN = 0x7fffffff
|
||||
}
|
||||
JP2_IMG_STATE;
|
||||
|
||||
/**
|
||||
Channel description: channel index, type, association
|
||||
*/
|
||||
typedef struct opj_jp2_cdef_info {
|
||||
OPJ_UINT16 cn, typ, asoc;
|
||||
} opj_jp2_cdef_info_t;
|
||||
|
||||
/**
|
||||
Channel descriptions and number of descriptions
|
||||
*/
|
||||
typedef struct opj_jp2_cdef {
|
||||
opj_jp2_cdef_info_t *info;
|
||||
OPJ_UINT16 n;
|
||||
} opj_jp2_cdef_t;
|
||||
|
||||
/**
|
||||
Component mappings: channel index, mapping type, palette index
|
||||
*/
|
||||
typedef struct opj_jp2_cmap_comp {
|
||||
OPJ_UINT16 cmp;
|
||||
OPJ_BYTE mtyp, pcol;
|
||||
} opj_jp2_cmap_comp_t;
|
||||
|
||||
/**
|
||||
Palette data: table entries, palette columns
|
||||
*/
|
||||
typedef struct opj_jp2_pclr {
|
||||
OPJ_UINT32 *entries;
|
||||
OPJ_BYTE *channel_sign;
|
||||
OPJ_BYTE *channel_size;
|
||||
opj_jp2_cmap_comp_t *cmap;
|
||||
OPJ_UINT16 nr_entries;
|
||||
OPJ_BYTE nr_channels;
|
||||
} opj_jp2_pclr_t;
|
||||
|
||||
/**
|
||||
Collector for ICC profile, palette, component mapping, channel description
|
||||
*/
|
||||
typedef struct opj_jp2_color {
|
||||
OPJ_BYTE *icc_profile_buf;
|
||||
OPJ_UINT32 icc_profile_len;
|
||||
|
||||
opj_jp2_cdef_t *jp2_cdef;
|
||||
opj_jp2_pclr_t *jp2_pclr;
|
||||
OPJ_BYTE jp2_has_colr;
|
||||
} opj_jp2_color_t;
|
||||
|
||||
/**
|
||||
JP2 component
|
||||
*/
|
||||
typedef struct opj_jp2_comps {
|
||||
OPJ_UINT32 depth;
|
||||
OPJ_UINT32 sgnd;
|
||||
OPJ_UINT32 bpcc;
|
||||
} opj_jp2_comps_t;
|
||||
|
||||
/**
|
||||
JPEG-2000 file format reader/writer
|
||||
*/
|
||||
typedef struct opj_jp2 {
|
||||
/** handle to the J2K codec */
|
||||
opj_j2k_t *j2k;
|
||||
/** list of validation procedures */
|
||||
struct opj_procedure_list * m_validation_list;
|
||||
/** list of execution procedures */
|
||||
struct opj_procedure_list * m_procedure_list;
|
||||
|
||||
/* width of image */
|
||||
OPJ_UINT32 w;
|
||||
/* height of image */
|
||||
OPJ_UINT32 h;
|
||||
/* number of components in the image */
|
||||
OPJ_UINT32 numcomps;
|
||||
OPJ_UINT32 bpc;
|
||||
OPJ_UINT32 C;
|
||||
OPJ_UINT32 UnkC;
|
||||
OPJ_UINT32 IPR;
|
||||
OPJ_UINT32 meth;
|
||||
OPJ_UINT32 approx;
|
||||
OPJ_UINT32 enumcs;
|
||||
OPJ_UINT32 precedence;
|
||||
OPJ_UINT32 brand;
|
||||
OPJ_UINT32 minversion;
|
||||
OPJ_UINT32 numcl;
|
||||
OPJ_UINT32 *cl;
|
||||
opj_jp2_comps_t *comps;
|
||||
/* FIXME: The following two variables are used to save offset
|
||||
as we write out a JP2 file to disk. This mechanism is not flexible
|
||||
as codec writers will need to extand those fields as new part
|
||||
of the standard are implemented.
|
||||
*/
|
||||
OPJ_OFF_T j2k_codestream_offset;
|
||||
OPJ_OFF_T jpip_iptr_offset;
|
||||
OPJ_BOOL jpip_on;
|
||||
OPJ_UINT32 jp2_state;
|
||||
OPJ_UINT32 jp2_img_state;
|
||||
|
||||
opj_jp2_color_t color;
|
||||
|
||||
OPJ_BOOL ignore_pclr_cmap_cdef;
|
||||
OPJ_BYTE has_jp2h;
|
||||
OPJ_BYTE has_ihdr;
|
||||
}
|
||||
opj_jp2_t;
|
||||
|
||||
/**
|
||||
JP2 Box
|
||||
*/
|
||||
typedef struct opj_jp2_box {
|
||||
OPJ_UINT32 length;
|
||||
OPJ_UINT32 type;
|
||||
OPJ_INT32 init_pos;
|
||||
} opj_jp2_box_t;
|
||||
|
||||
typedef struct opj_jp2_header_handler {
|
||||
/* marker value */
|
||||
OPJ_UINT32 id;
|
||||
/* action linked to the marker */
|
||||
OPJ_BOOL(*handler)(opj_jp2_t *jp2,
|
||||
OPJ_BYTE *p_header_data,
|
||||
OPJ_UINT32 p_header_size,
|
||||
opj_event_mgr_t * p_manager);
|
||||
}
|
||||
opj_jp2_header_handler_t;
|
||||
|
||||
|
||||
typedef struct opj_jp2_img_header_writer_handler {
|
||||
/* action to perform */
|
||||
OPJ_BYTE* (*handler)(opj_jp2_t *jp2, OPJ_UINT32 * p_data_size);
|
||||
/* result of the action : data */
|
||||
OPJ_BYTE* m_data;
|
||||
/* size of data */
|
||||
OPJ_UINT32 m_size;
|
||||
}
|
||||
opj_jp2_img_header_writer_handler_t;
|
||||
|
||||
/** @name Exported functions */
|
||||
/*@{*/
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
Setup the decoder decoding parameters using user parameters.
|
||||
Decoding parameters are returned in jp2->j2k->cp.
|
||||
@param jp2 JP2 decompressor handle
|
||||
@param parameters decompression parameters
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* Decode an image from a JPEG-2000 file stream
|
||||
* @param jp2 JP2 decompressor handle
|
||||
* @param p_stream FIXME DOC
|
||||
* @param p_image FIXME DOC
|
||||
* @param p_manager FIXME DOC
|
||||
*
|
||||
* @return Returns a decoded image if successful, returns NULL otherwise
|
||||
*/
|
||||
OPJ_BOOL opj_jp2_decode(opj_jp2_t *jp2,
|
||||
opj_stream_private_t *p_stream,
|
||||
opj_image_t* p_image,
|
||||
opj_event_mgr_t * p_manager);
|
||||
|
||||
/**
|
||||
* Setup the encoder parameters using the current image and using user parameters.
|
||||
* Coding parameters are returned in jp2->j2k->cp.
|
||||
*
|
||||
* @param jp2 JP2 compressor handle
|
||||
* @param parameters compression parameters
|
||||
* @param image input filled image
|
||||
* @param p_manager FIXME DOC
|
||||
* @return OPJ_TRUE if successful, OPJ_FALSE otherwise
|
||||
*/
|
||||
OPJ_BOOL opj_jp2_setup_encoder(opj_jp2_t *jp2,
|
||||
opj_cparameters_t *parameters,
|
||||
opj_image_t *image,
|
||||
opj_event_mgr_t * p_manager);
|
||||
|
||||
/**
|
||||
Encode an image into a JPEG-2000 file stream
|
||||
@param jp2 JP2 compressor handle
|
||||
@param stream Output buffer stream
|
||||
@param p_manager event manager
|
||||
@return Returns true if successful, returns false otherwise
|
||||
*/
|
||||
OPJ_BOOL opj_jp2_encode(opj_jp2_t *jp2,
|
||||
opj_stream_private_t *stream,
|
||||
opj_event_mgr_t * p_manager);
|
||||
|
||||
|
||||
/**
|
||||
* Starts a compression scheme, i.e. validates the codec parameters, writes the header.
|
||||
*
|
||||
* @param jp2 the jpeg2000 file codec.
|
||||
* @param stream the stream object.
|
||||
* @param p_image FIXME DOC
|
||||
* @param p_manager FIXME DOC
|
||||
*
|
||||
* @return true if the codec is valid.
|
||||
*/
|
||||
OPJ_BOOL opj_jp2_start_compress(opj_jp2_t *jp2,
|
||||
opj_stream_private_t *stream,
|
||||
opj_image_t * p_image,
|
||||
opj_event_mgr_t * p_manager);
|
||||
|
||||
|
||||
/**
|
||||
* Ends the compression procedures and possibiliy add data to be read after the
|
||||
* codestream.
|
||||
*/
|
||||
OPJ_BOOL opj_jp2_end_compress(opj_jp2_t *jp2,
|
||||
opj_stream_private_t *cio,
|
||||
opj_event_mgr_t * p_manager);
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Ends the decompression procedures and possibiliy add data to be read after the
|
||||
* codestream.
|
||||
*/
|
||||
OPJ_BOOL opj_jp2_end_decompress(opj_jp2_t *jp2,
|
||||
opj_stream_private_t *cio,
|
||||
opj_event_mgr_t * p_manager);
|
||||
|
||||
/**
|
||||
* Reads a jpeg2000 file header structure.
|
||||
*
|
||||
* @param p_stream the stream to read data from.
|
||||
* @param jp2 the jpeg2000 file header structure.
|
||||
* @param p_image FIXME DOC
|
||||
* @param p_manager the user event manager.
|
||||
*
|
||||
* @return true if the box is valid.
|
||||
*/
|
||||
OPJ_BOOL opj_jp2_read_header(opj_stream_private_t *p_stream,
|
||||
opj_jp2_t *jp2,
|
||||
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.
|
||||
* @param p_tile_index FIXME DOC
|
||||
* @param p_data_size FIXME DOC
|
||||
* @param p_tile_x0 FIXME DOC
|
||||
* @param p_tile_y0 FIXME DOC
|
||||
* @param p_tile_x1 FIXME DOC
|
||||
* @param p_tile_y1 FIXME DOC
|
||||
* @param p_nb_comps FIXME DOC
|
||||
* @param p_go_on FIXME DOC
|
||||
* @param p_stream the stream to write data to.
|
||||
* @param p_manager the user event manager.
|
||||
*/
|
||||
OPJ_BOOL opj_jp2_read_tile_header(opj_jp2_t * p_jp2,
|
||||
OPJ_UINT32 * p_tile_index,
|
||||
OPJ_UINT32 * p_data_size,
|
||||
OPJ_INT32 * p_tile_x0,
|
||||
OPJ_INT32 * p_tile_y0,
|
||||
OPJ_INT32 * p_tile_x1,
|
||||
OPJ_INT32 * p_tile_y1,
|
||||
OPJ_UINT32 * p_nb_comps,
|
||||
OPJ_BOOL * p_go_on,
|
||||
opj_stream_private_t *p_stream,
|
||||
opj_event_mgr_t * p_manager);
|
||||
|
||||
/**
|
||||
* Writes a tile.
|
||||
*
|
||||
* @param p_jp2 the jpeg2000 codec.
|
||||
* @param p_tile_index FIXME DOC
|
||||
* @param p_data FIXME DOC
|
||||
* @param p_data_size FIXME DOC
|
||||
* @param p_stream the stream to write data to.
|
||||
* @param p_manager the user event manager.
|
||||
*/
|
||||
OPJ_BOOL opj_jp2_write_tile(opj_jp2_t *p_jp2,
|
||||
OPJ_UINT32 p_tile_index,
|
||||
OPJ_BYTE * p_data,
|
||||
OPJ_UINT32 p_data_size,
|
||||
opj_stream_private_t *p_stream,
|
||||
opj_event_mgr_t * p_manager);
|
||||
|
||||
/**
|
||||
* Decode tile data.
|
||||
* @param p_jp2 the jpeg2000 codec.
|
||||
* @param p_tile_index FIXME DOC
|
||||
* @param p_data FIXME DOC
|
||||
* @param p_data_size FIXME DOC
|
||||
* @param p_stream the stream to write data to.
|
||||
* @param p_manager the user event manager.
|
||||
*
|
||||
* @return FIXME DOC
|
||||
*/
|
||||
OPJ_BOOL opj_jp2_decode_tile(opj_jp2_t * p_jp2,
|
||||
OPJ_UINT32 p_tile_index,
|
||||
OPJ_BYTE * p_data,
|
||||
OPJ_UINT32 p_data_size,
|
||||
opj_stream_private_t *p_stream,
|
||||
opj_event_mgr_t * p_manager);
|
||||
|
||||
/**
|
||||
* Creates a jpeg2000 file decompressor.
|
||||
*
|
||||
* @return an empty jpeg2000 file codec.
|
||||
*/
|
||||
opj_jp2_t* opj_jp2_create(OPJ_BOOL p_is_decoder);
|
||||
|
||||
/**
|
||||
Destroy a JP2 decompressor handle
|
||||
@param jp2 JP2 decompressor handle to destroy
|
||||
*/
|
||||
void opj_jp2_destroy(opj_jp2_t *jp2);
|
||||
|
||||
|
||||
/**
|
||||
* Sets the given area to be decoded. This function should be called right after opj_read_header and before any tile header reading.
|
||||
*
|
||||
* @param p_jp2 the jpeg2000 codec.
|
||||
* @param p_image FIXME DOC
|
||||
* @param p_start_x the left position of the rectangle to decode (in image coordinates).
|
||||
* @param p_start_y the up 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_end_y the bottom position of the rectangle to decode (in image coordinates).
|
||||
* @param p_manager the user event manager
|
||||
*
|
||||
* @return true if the area could be set.
|
||||
*/
|
||||
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,
|
||||
OPJ_INT32 p_end_x, OPJ_INT32 p_end_y,
|
||||
opj_event_mgr_t * p_manager);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
OPJ_BOOL opj_jp2_get_tile(opj_jp2_t *p_jp2,
|
||||
opj_stream_private_t *p_stream,
|
||||
opj_image_t* p_image,
|
||||
opj_event_mgr_t * p_manager,
|
||||
OPJ_UINT32 tile_index);
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
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 */
|
||||
/**
|
||||
* Dump some elements from the JP2 decompression structure .
|
||||
*
|
||||
*@param p_jp2 the jp2 codec.
|
||||
*@param flag flag to describe what elements are dump.
|
||||
*@param out_stream output stream where dump the elements.
|
||||
*
|
||||
*/
|
||||
void jp2_dump(opj_jp2_t* p_jp2, OPJ_INT32 flag, FILE* out_stream);
|
||||
|
||||
/**
|
||||
* Get the codestream info from a JPEG2000 codec.
|
||||
*
|
||||
*@param p_jp2 jp2 codec.
|
||||
*
|
||||
*@return the codestream information extract from the jpg2000 codec
|
||||
*/
|
||||
opj_codestream_info_v2_t* jp2_get_cstr_info(opj_jp2_t* p_jp2);
|
||||
|
||||
/**
|
||||
* Get the codestream index from a JPEG2000 codec.
|
||||
*
|
||||
*@param p_jp2 jp2 codec.
|
||||
*
|
||||
*@return the codestream index extract from the jpg2000 codec
|
||||
*/
|
||||
opj_codestream_index_t* jp2_get_cstr_index(opj_jp2_t* p_jp2);
|
||||
|
||||
|
||||
/*@}*/
|
||||
|
||||
/*@}*/
|
||||
|
||||
#endif /* OPJ_JP2_H */
|
||||
|
||||
@@ -0,0 +1,464 @@
|
||||
/*
|
||||
* 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) 2008, 2011-2012, Centre National d'Etudes Spatiales (CNES), FR
|
||||
* Copyright (c) 2012, CS Systemes d'Information, France
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef __SSE__
|
||||
#include <xmmintrin.h>
|
||||
#endif
|
||||
#ifdef __SSE2__
|
||||
#include <emmintrin.h>
|
||||
#endif
|
||||
#ifdef __SSE4_1__
|
||||
#include <smmintrin.h>
|
||||
#endif
|
||||
|
||||
#include "opj_includes.h"
|
||||
|
||||
/* <summary> */
|
||||
/* This table contains the norms of the basis function of the reversible MCT. */
|
||||
/* </summary> */
|
||||
static const OPJ_FLOAT64 opj_mct_norms[3] = { 1.732, .8292, .8292 };
|
||||
|
||||
/* <summary> */
|
||||
/* This table contains the norms of the basis function of the irreversible MCT. */
|
||||
/* </summary> */
|
||||
static const OPJ_FLOAT64 opj_mct_norms_real[3] = { 1.732, 1.805, 1.573 };
|
||||
|
||||
const OPJ_FLOAT64 * opj_mct_get_mct_norms()
|
||||
{
|
||||
return opj_mct_norms;
|
||||
}
|
||||
|
||||
const OPJ_FLOAT64 * opj_mct_get_mct_norms_real()
|
||||
{
|
||||
return opj_mct_norms_real;
|
||||
}
|
||||
|
||||
/* <summary> */
|
||||
/* Forward reversible MCT. */
|
||||
/* </summary> */
|
||||
#ifdef __SSE2__
|
||||
void opj_mct_encode(
|
||||
OPJ_INT32* OPJ_RESTRICT c0,
|
||||
OPJ_INT32* OPJ_RESTRICT c1,
|
||||
OPJ_INT32* OPJ_RESTRICT c2,
|
||||
OPJ_SIZE_T n)
|
||||
{
|
||||
OPJ_SIZE_T i;
|
||||
const OPJ_SIZE_T len = n;
|
||||
/* buffer are aligned on 16 bytes */
|
||||
assert(((size_t)c0 & 0xf) == 0);
|
||||
assert(((size_t)c1 & 0xf) == 0);
|
||||
assert(((size_t)c2 & 0xf) == 0);
|
||||
|
||||
for (i = 0; i < (len & ~3U); i += 4) {
|
||||
__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]));
|
||||
y = _mm_add_epi32(g, g);
|
||||
y = _mm_add_epi32(y, b);
|
||||
y = _mm_add_epi32(y, r);
|
||||
y = _mm_srai_epi32(y, 2);
|
||||
u = _mm_sub_epi32(b, g);
|
||||
v = _mm_sub_epi32(r, g);
|
||||
_mm_store_si128((__m128i *) & (c0[i]), y);
|
||||
_mm_store_si128((__m128i *) & (c1[i]), u);
|
||||
_mm_store_si128((__m128i *) & (c2[i]), v);
|
||||
}
|
||||
|
||||
for (; i < len; ++i) {
|
||||
OPJ_INT32 r = c0[i];
|
||||
OPJ_INT32 g = c1[i];
|
||||
OPJ_INT32 b = c2[i];
|
||||
OPJ_INT32 y = (r + (g * 2) + b) >> 2;
|
||||
OPJ_INT32 u = b - g;
|
||||
OPJ_INT32 v = r - g;
|
||||
c0[i] = y;
|
||||
c1[i] = u;
|
||||
c2[i] = v;
|
||||
}
|
||||
}
|
||||
#else
|
||||
void opj_mct_encode(
|
||||
OPJ_INT32* OPJ_RESTRICT c0,
|
||||
OPJ_INT32* OPJ_RESTRICT c1,
|
||||
OPJ_INT32* OPJ_RESTRICT c2,
|
||||
OPJ_SIZE_T n)
|
||||
{
|
||||
OPJ_SIZE_T i;
|
||||
const OPJ_SIZE_T len = n;
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
OPJ_INT32 r = c0[i];
|
||||
OPJ_INT32 g = c1[i];
|
||||
OPJ_INT32 b = c2[i];
|
||||
OPJ_INT32 y = (r + (g * 2) + b) >> 2;
|
||||
OPJ_INT32 u = b - g;
|
||||
OPJ_INT32 v = r - g;
|
||||
c0[i] = y;
|
||||
c1[i] = u;
|
||||
c2[i] = v;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* <summary> */
|
||||
/* Inverse reversible MCT. */
|
||||
/* </summary> */
|
||||
#ifdef __SSE2__
|
||||
void opj_mct_decode(
|
||||
OPJ_INT32* OPJ_RESTRICT c0,
|
||||
OPJ_INT32* OPJ_RESTRICT c1,
|
||||
OPJ_INT32* OPJ_RESTRICT c2,
|
||||
OPJ_SIZE_T n)
|
||||
{
|
||||
OPJ_SIZE_T i;
|
||||
const OPJ_SIZE_T len = n;
|
||||
|
||||
for (i = 0; i < (len & ~3U); i += 4) {
|
||||
__m128i r, g, b;
|
||||
__m128i y = _mm_load_si128((const __m128i *) & (c0[i]));
|
||||
__m128i u = _mm_load_si128((const __m128i *) & (c1[i]));
|
||||
__m128i v = _mm_load_si128((const __m128i *) & (c2[i]));
|
||||
g = y;
|
||||
g = _mm_sub_epi32(g, _mm_srai_epi32(_mm_add_epi32(u, v), 2));
|
||||
r = _mm_add_epi32(v, g);
|
||||
b = _mm_add_epi32(u, g);
|
||||
_mm_store_si128((__m128i *) & (c0[i]), r);
|
||||
_mm_store_si128((__m128i *) & (c1[i]), g);
|
||||
_mm_store_si128((__m128i *) & (c2[i]), b);
|
||||
}
|
||||
for (; i < len; ++i) {
|
||||
OPJ_INT32 y = c0[i];
|
||||
OPJ_INT32 u = c1[i];
|
||||
OPJ_INT32 v = c2[i];
|
||||
OPJ_INT32 g = y - ((u + v) >> 2);
|
||||
OPJ_INT32 r = v + g;
|
||||
OPJ_INT32 b = u + g;
|
||||
c0[i] = r;
|
||||
c1[i] = g;
|
||||
c2[i] = b;
|
||||
}
|
||||
}
|
||||
#else
|
||||
void opj_mct_decode(
|
||||
OPJ_INT32* OPJ_RESTRICT c0,
|
||||
OPJ_INT32* OPJ_RESTRICT c1,
|
||||
OPJ_INT32* OPJ_RESTRICT c2,
|
||||
OPJ_SIZE_T n)
|
||||
{
|
||||
OPJ_SIZE_T i;
|
||||
for (i = 0; i < n; ++i) {
|
||||
OPJ_INT32 y = c0[i];
|
||||
OPJ_INT32 u = c1[i];
|
||||
OPJ_INT32 v = c2[i];
|
||||
OPJ_INT32 g = y - ((u + v) >> 2);
|
||||
OPJ_INT32 r = v + g;
|
||||
OPJ_INT32 b = u + g;
|
||||
c0[i] = r;
|
||||
c1[i] = g;
|
||||
c2[i] = b;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* <summary> */
|
||||
/* Get norm of basis function of reversible MCT. */
|
||||
/* </summary> */
|
||||
OPJ_FLOAT64 opj_mct_getnorm(OPJ_UINT32 compno)
|
||||
{
|
||||
return opj_mct_norms[compno];
|
||||
}
|
||||
|
||||
/* <summary> */
|
||||
/* Forward irreversible MCT. */
|
||||
/* </summary> */
|
||||
void opj_mct_encode_real(
|
||||
OPJ_FLOAT32* OPJ_RESTRICT c0,
|
||||
OPJ_FLOAT32* OPJ_RESTRICT c1,
|
||||
OPJ_FLOAT32* 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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
c0[i] = y;
|
||||
c1[i] = u;
|
||||
c2[i] = v;
|
||||
}
|
||||
}
|
||||
|
||||
/* <summary> */
|
||||
/* Inverse irreversible MCT. */
|
||||
/* </summary> */
|
||||
void opj_mct_decode_real(
|
||||
OPJ_FLOAT32* OPJ_RESTRICT c0,
|
||||
OPJ_FLOAT32* OPJ_RESTRICT c1,
|
||||
OPJ_FLOAT32* OPJ_RESTRICT c2,
|
||||
OPJ_SIZE_T n)
|
||||
{
|
||||
OPJ_SIZE_T i;
|
||||
#ifdef __SSE__
|
||||
__m128 vrv, vgu, vgv, vbu;
|
||||
vrv = _mm_set1_ps(1.402f);
|
||||
vgu = _mm_set1_ps(0.34413f);
|
||||
vgv = _mm_set1_ps(0.71414f);
|
||||
vbu = _mm_set1_ps(1.772f);
|
||||
for (i = 0; i < (n >> 3); ++i) {
|
||||
__m128 vy, vu, vv;
|
||||
__m128 vr, vg, vb;
|
||||
|
||||
vy = _mm_load_ps(c0);
|
||||
vu = _mm_load_ps(c1);
|
||||
vv = _mm_load_ps(c2);
|
||||
vr = _mm_add_ps(vy, _mm_mul_ps(vv, vrv));
|
||||
vg = _mm_sub_ps(_mm_sub_ps(vy, _mm_mul_ps(vu, vgu)), _mm_mul_ps(vv, vgv));
|
||||
vb = _mm_add_ps(vy, _mm_mul_ps(vu, vbu));
|
||||
_mm_store_ps(c0, vr);
|
||||
_mm_store_ps(c1, vg);
|
||||
_mm_store_ps(c2, vb);
|
||||
c0 += 4;
|
||||
c1 += 4;
|
||||
c2 += 4;
|
||||
|
||||
vy = _mm_load_ps(c0);
|
||||
vu = _mm_load_ps(c1);
|
||||
vv = _mm_load_ps(c2);
|
||||
vr = _mm_add_ps(vy, _mm_mul_ps(vv, vrv));
|
||||
vg = _mm_sub_ps(_mm_sub_ps(vy, _mm_mul_ps(vu, vgu)), _mm_mul_ps(vv, vgv));
|
||||
vb = _mm_add_ps(vy, _mm_mul_ps(vu, vbu));
|
||||
_mm_store_ps(c0, vr);
|
||||
_mm_store_ps(c1, vg);
|
||||
_mm_store_ps(c2, vb);
|
||||
c0 += 4;
|
||||
c1 += 4;
|
||||
c2 += 4;
|
||||
}
|
||||
n &= 7;
|
||||
#endif
|
||||
for (i = 0; i < n; ++i) {
|
||||
OPJ_FLOAT32 y = c0[i];
|
||||
OPJ_FLOAT32 u = c1[i];
|
||||
OPJ_FLOAT32 v = c2[i];
|
||||
OPJ_FLOAT32 r = y + (v * 1.402f);
|
||||
OPJ_FLOAT32 g = y - (u * 0.34413f) - (v * (0.71414f));
|
||||
OPJ_FLOAT32 b = y + (u * 1.772f);
|
||||
c0[i] = r;
|
||||
c1[i] = g;
|
||||
c2[i] = b;
|
||||
}
|
||||
}
|
||||
|
||||
/* <summary> */
|
||||
/* Get norm of basis function of irreversible MCT. */
|
||||
/* </summary> */
|
||||
OPJ_FLOAT64 opj_mct_getnorm_real(OPJ_UINT32 compno)
|
||||
{
|
||||
return opj_mct_norms_real[compno];
|
||||
}
|
||||
|
||||
|
||||
OPJ_BOOL opj_mct_encode_custom(
|
||||
OPJ_BYTE * pCodingdata,
|
||||
OPJ_SIZE_T n,
|
||||
OPJ_BYTE ** pData,
|
||||
OPJ_UINT32 pNbComp,
|
||||
OPJ_UINT32 isSigned)
|
||||
{
|
||||
OPJ_FLOAT32 * lMct = (OPJ_FLOAT32 *) pCodingdata;
|
||||
OPJ_SIZE_T i;
|
||||
OPJ_UINT32 j;
|
||||
OPJ_UINT32 k;
|
||||
OPJ_UINT32 lNbMatCoeff = pNbComp * pNbComp;
|
||||
OPJ_INT32 * lCurrentData = 00;
|
||||
OPJ_INT32 * lCurrentMatrix = 00;
|
||||
OPJ_INT32 ** lData = (OPJ_INT32 **) pData;
|
||||
OPJ_UINT32 lMultiplicator = 1 << 13;
|
||||
OPJ_INT32 * lMctPtr;
|
||||
|
||||
OPJ_ARG_NOT_USED(isSigned);
|
||||
|
||||
lCurrentData = (OPJ_INT32 *) opj_malloc((pNbComp + lNbMatCoeff) * sizeof(
|
||||
OPJ_INT32));
|
||||
if (! lCurrentData) {
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
lCurrentMatrix = lCurrentData + pNbComp;
|
||||
|
||||
for (i = 0; i < lNbMatCoeff; ++i) {
|
||||
lCurrentMatrix[i] = (OPJ_INT32)(*(lMct++) * (OPJ_FLOAT32)lMultiplicator);
|
||||
}
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
lMctPtr = lCurrentMatrix;
|
||||
for (j = 0; j < pNbComp; ++j) {
|
||||
lCurrentData[j] = (*(lData[j]));
|
||||
}
|
||||
|
||||
for (j = 0; j < pNbComp; ++j) {
|
||||
*(lData[j]) = 0;
|
||||
for (k = 0; k < pNbComp; ++k) {
|
||||
*(lData[j]) += opj_int_fix_mul(*lMctPtr, lCurrentData[k]);
|
||||
++lMctPtr;
|
||||
}
|
||||
|
||||
++lData[j];
|
||||
}
|
||||
}
|
||||
|
||||
opj_free(lCurrentData);
|
||||
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
OPJ_BOOL opj_mct_decode_custom(
|
||||
OPJ_BYTE * pDecodingData,
|
||||
OPJ_SIZE_T n,
|
||||
OPJ_BYTE ** pData,
|
||||
OPJ_UINT32 pNbComp,
|
||||
OPJ_UINT32 isSigned)
|
||||
{
|
||||
OPJ_FLOAT32 * lMct;
|
||||
OPJ_SIZE_T i;
|
||||
OPJ_UINT32 j;
|
||||
OPJ_UINT32 k;
|
||||
|
||||
OPJ_FLOAT32 * lCurrentData = 00;
|
||||
OPJ_FLOAT32 * lCurrentResult = 00;
|
||||
OPJ_FLOAT32 ** lData = (OPJ_FLOAT32 **) pData;
|
||||
|
||||
OPJ_ARG_NOT_USED(isSigned);
|
||||
|
||||
lCurrentData = (OPJ_FLOAT32 *) opj_malloc(2 * pNbComp * sizeof(OPJ_FLOAT32));
|
||||
if (! lCurrentData) {
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
lCurrentResult = lCurrentData + pNbComp;
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
lMct = (OPJ_FLOAT32 *) pDecodingData;
|
||||
for (j = 0; j < pNbComp; ++j) {
|
||||
lCurrentData[j] = (OPJ_FLOAT32)(*(lData[j]));
|
||||
}
|
||||
for (j = 0; j < pNbComp; ++j) {
|
||||
lCurrentResult[j] = 0;
|
||||
for (k = 0; k < pNbComp; ++k) {
|
||||
lCurrentResult[j] += *(lMct++) * lCurrentData[k];
|
||||
}
|
||||
*(lData[j]++) = (OPJ_FLOAT32)(lCurrentResult[j]);
|
||||
}
|
||||
}
|
||||
opj_free(lCurrentData);
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
void opj_calculate_norms(OPJ_FLOAT64 * pNorms,
|
||||
OPJ_UINT32 pNbComps,
|
||||
OPJ_FLOAT32 * pMatrix)
|
||||
{
|
||||
OPJ_UINT32 i, j, lIndex;
|
||||
OPJ_FLOAT32 lCurrentValue;
|
||||
OPJ_FLOAT64 * lNorms = (OPJ_FLOAT64 *) pNorms;
|
||||
OPJ_FLOAT32 * lMatrix = (OPJ_FLOAT32 *) pMatrix;
|
||||
|
||||
for (i = 0; i < pNbComps; ++i) {
|
||||
lNorms[i] = 0;
|
||||
lIndex = i;
|
||||
|
||||
for (j = 0; j < pNbComps; ++j) {
|
||||
lCurrentValue = lMatrix[lIndex];
|
||||
lIndex += pNbComps;
|
||||
lNorms[i] += (OPJ_FLOAT64) lCurrentValue * lCurrentValue;
|
||||
}
|
||||
lNorms[i] = sqrt(lNorms[i]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* 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) 2008, 2011-2012, Centre National d'Etudes Spatiales (CNES), FR
|
||||
* Copyright (c) 2012, CS Systemes d'Information, France
|
||||
* 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 OPJ_MCT_H
|
||||
#define OPJ_MCT_H
|
||||
/**
|
||||
@file mct.h
|
||||
@brief Implementation of a multi-component transforms (MCT)
|
||||
|
||||
The functions in MCT.C have for goal to realize reversible and irreversible multicomponent
|
||||
transform. The functions in MCT.C are used by some function in TCD.C.
|
||||
*/
|
||||
|
||||
/** @defgroup MCT MCT - Implementation of a multi-component transform */
|
||||
/*@{*/
|
||||
|
||||
/** @name Exported functions */
|
||||
/*@{*/
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/**
|
||||
Apply a reversible multi-component transform to an image
|
||||
@param c0 Samples for red component
|
||||
@param c1 Samples for green component
|
||||
@param c2 Samples blue component
|
||||
@param n Number of samples for each component
|
||||
*/
|
||||
void opj_mct_encode(OPJ_INT32* OPJ_RESTRICT c0, OPJ_INT32* OPJ_RESTRICT c1,
|
||||
OPJ_INT32* OPJ_RESTRICT c2, OPJ_SIZE_T n);
|
||||
/**
|
||||
Apply a reversible multi-component inverse transform to an image
|
||||
@param c0 Samples for luminance component
|
||||
@param c1 Samples for red chrominance component
|
||||
@param c2 Samples for blue chrominance component
|
||||
@param n Number of samples for each component
|
||||
*/
|
||||
void opj_mct_decode(OPJ_INT32* OPJ_RESTRICT c0, OPJ_INT32* OPJ_RESTRICT c1,
|
||||
OPJ_INT32* OPJ_RESTRICT c2, OPJ_SIZE_T n);
|
||||
/**
|
||||
Get norm of the basis function used for the reversible multi-component transform
|
||||
@param compno Number of the component (0->Y, 1->U, 2->V)
|
||||
@return
|
||||
*/
|
||||
OPJ_FLOAT64 opj_mct_getnorm(OPJ_UINT32 compno);
|
||||
|
||||
/**
|
||||
Apply an irreversible multi-component transform to an image
|
||||
@param c0 Samples for red component
|
||||
@param c1 Samples for green component
|
||||
@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);
|
||||
/**
|
||||
Apply an irreversible multi-component inverse transform to an image
|
||||
@param c0 Samples for luminance component
|
||||
@param c1 Samples for red chrominance component
|
||||
@param c2 Samples for blue chrominance component
|
||||
@param n Number of samples for each component
|
||||
*/
|
||||
void opj_mct_decode_real(OPJ_FLOAT32* OPJ_RESTRICT c0,
|
||||
OPJ_FLOAT32* OPJ_RESTRICT c1, OPJ_FLOAT32* OPJ_RESTRICT c2, OPJ_SIZE_T n);
|
||||
/**
|
||||
Get norm of the basis function used for the irreversible multi-component transform
|
||||
@param compno Number of the component (0->Y, 1->U, 2->V)
|
||||
@return
|
||||
*/
|
||||
OPJ_FLOAT64 opj_mct_getnorm_real(OPJ_UINT32 compno);
|
||||
|
||||
/**
|
||||
FIXME DOC
|
||||
@param p_coding_data MCT data
|
||||
@param n size of components
|
||||
@param p_data components
|
||||
@param p_nb_comp nb of components (i.e. size of p_data)
|
||||
@param is_signed tells if the data is signed
|
||||
@return OPJ_FALSE if function encounter a problem, OPJ_TRUE otherwise
|
||||
*/
|
||||
OPJ_BOOL opj_mct_encode_custom(
|
||||
OPJ_BYTE * p_coding_data,
|
||||
OPJ_SIZE_T n,
|
||||
OPJ_BYTE ** p_data,
|
||||
OPJ_UINT32 p_nb_comp,
|
||||
OPJ_UINT32 is_signed);
|
||||
/**
|
||||
FIXME DOC
|
||||
@param pDecodingData MCT data
|
||||
@param n size of components
|
||||
@param pData components
|
||||
@param pNbComp nb of components (i.e. size of p_data)
|
||||
@param isSigned tells if the data is signed
|
||||
@return OPJ_FALSE if function encounter a problem, OPJ_TRUE otherwise
|
||||
*/
|
||||
OPJ_BOOL opj_mct_decode_custom(
|
||||
OPJ_BYTE * pDecodingData,
|
||||
OPJ_SIZE_T n,
|
||||
OPJ_BYTE ** pData,
|
||||
OPJ_UINT32 pNbComp,
|
||||
OPJ_UINT32 isSigned);
|
||||
/**
|
||||
FIXME DOC
|
||||
@param pNorms MCT data
|
||||
@param p_nb_comps size of components
|
||||
@param pMatrix components
|
||||
@return
|
||||
*/
|
||||
void opj_calculate_norms(OPJ_FLOAT64 * pNorms,
|
||||
OPJ_UINT32 p_nb_comps,
|
||||
OPJ_FLOAT32 * pMatrix);
|
||||
/**
|
||||
FIXME DOC
|
||||
*/
|
||||
const OPJ_FLOAT64 * opj_mct_get_mct_norms(void);
|
||||
/**
|
||||
FIXME DOC
|
||||
*/
|
||||
const OPJ_FLOAT64 * opj_mct_get_mct_norms_real(void);
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/*@}*/
|
||||
|
||||
/*@}*/
|
||||
|
||||
#endif /* OPJ_MCT_H */
|
||||
@@ -0,0 +1,524 @@
|
||||
/*
|
||||
* 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) 2008, Jerome Fimes, Communications & Systemes <[email protected]>
|
||||
* 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 "opj_includes.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
/** @defgroup MQC MQC - Implementation of an MQ-Coder */
|
||||
/*@{*/
|
||||
|
||||
/** @name Local static functions */
|
||||
/*@{*/
|
||||
|
||||
/**
|
||||
Fill mqc->c with 1's for flushing
|
||||
@param mqc MQC handle
|
||||
*/
|
||||
static void opj_mqc_setbits(opj_mqc_t *mqc);
|
||||
/*@}*/
|
||||
|
||||
/*@}*/
|
||||
|
||||
/* <summary> */
|
||||
/* This array defines all the possible states for a context. */
|
||||
/* </summary> */
|
||||
static const opj_mqc_state_t mqc_states[47 * 2] = {
|
||||
{0x5601, 0, &mqc_states[2], &mqc_states[3]},
|
||||
{0x5601, 1, &mqc_states[3], &mqc_states[2]},
|
||||
{0x3401, 0, &mqc_states[4], &mqc_states[12]},
|
||||
{0x3401, 1, &mqc_states[5], &mqc_states[13]},
|
||||
{0x1801, 0, &mqc_states[6], &mqc_states[18]},
|
||||
{0x1801, 1, &mqc_states[7], &mqc_states[19]},
|
||||
{0x0ac1, 0, &mqc_states[8], &mqc_states[24]},
|
||||
{0x0ac1, 1, &mqc_states[9], &mqc_states[25]},
|
||||
{0x0521, 0, &mqc_states[10], &mqc_states[58]},
|
||||
{0x0521, 1, &mqc_states[11], &mqc_states[59]},
|
||||
{0x0221, 0, &mqc_states[76], &mqc_states[66]},
|
||||
{0x0221, 1, &mqc_states[77], &mqc_states[67]},
|
||||
{0x5601, 0, &mqc_states[14], &mqc_states[13]},
|
||||
{0x5601, 1, &mqc_states[15], &mqc_states[12]},
|
||||
{0x5401, 0, &mqc_states[16], &mqc_states[28]},
|
||||
{0x5401, 1, &mqc_states[17], &mqc_states[29]},
|
||||
{0x4801, 0, &mqc_states[18], &mqc_states[28]},
|
||||
{0x4801, 1, &mqc_states[19], &mqc_states[29]},
|
||||
{0x3801, 0, &mqc_states[20], &mqc_states[28]},
|
||||
{0x3801, 1, &mqc_states[21], &mqc_states[29]},
|
||||
{0x3001, 0, &mqc_states[22], &mqc_states[34]},
|
||||
{0x3001, 1, &mqc_states[23], &mqc_states[35]},
|
||||
{0x2401, 0, &mqc_states[24], &mqc_states[36]},
|
||||
{0x2401, 1, &mqc_states[25], &mqc_states[37]},
|
||||
{0x1c01, 0, &mqc_states[26], &mqc_states[40]},
|
||||
{0x1c01, 1, &mqc_states[27], &mqc_states[41]},
|
||||
{0x1601, 0, &mqc_states[58], &mqc_states[42]},
|
||||
{0x1601, 1, &mqc_states[59], &mqc_states[43]},
|
||||
{0x5601, 0, &mqc_states[30], &mqc_states[29]},
|
||||
{0x5601, 1, &mqc_states[31], &mqc_states[28]},
|
||||
{0x5401, 0, &mqc_states[32], &mqc_states[28]},
|
||||
{0x5401, 1, &mqc_states[33], &mqc_states[29]},
|
||||
{0x5101, 0, &mqc_states[34], &mqc_states[30]},
|
||||
{0x5101, 1, &mqc_states[35], &mqc_states[31]},
|
||||
{0x4801, 0, &mqc_states[36], &mqc_states[32]},
|
||||
{0x4801, 1, &mqc_states[37], &mqc_states[33]},
|
||||
{0x3801, 0, &mqc_states[38], &mqc_states[34]},
|
||||
{0x3801, 1, &mqc_states[39], &mqc_states[35]},
|
||||
{0x3401, 0, &mqc_states[40], &mqc_states[36]},
|
||||
{0x3401, 1, &mqc_states[41], &mqc_states[37]},
|
||||
{0x3001, 0, &mqc_states[42], &mqc_states[38]},
|
||||
{0x3001, 1, &mqc_states[43], &mqc_states[39]},
|
||||
{0x2801, 0, &mqc_states[44], &mqc_states[38]},
|
||||
{0x2801, 1, &mqc_states[45], &mqc_states[39]},
|
||||
{0x2401, 0, &mqc_states[46], &mqc_states[40]},
|
||||
{0x2401, 1, &mqc_states[47], &mqc_states[41]},
|
||||
{0x2201, 0, &mqc_states[48], &mqc_states[42]},
|
||||
{0x2201, 1, &mqc_states[49], &mqc_states[43]},
|
||||
{0x1c01, 0, &mqc_states[50], &mqc_states[44]},
|
||||
{0x1c01, 1, &mqc_states[51], &mqc_states[45]},
|
||||
{0x1801, 0, &mqc_states[52], &mqc_states[46]},
|
||||
{0x1801, 1, &mqc_states[53], &mqc_states[47]},
|
||||
{0x1601, 0, &mqc_states[54], &mqc_states[48]},
|
||||
{0x1601, 1, &mqc_states[55], &mqc_states[49]},
|
||||
{0x1401, 0, &mqc_states[56], &mqc_states[50]},
|
||||
{0x1401, 1, &mqc_states[57], &mqc_states[51]},
|
||||
{0x1201, 0, &mqc_states[58], &mqc_states[52]},
|
||||
{0x1201, 1, &mqc_states[59], &mqc_states[53]},
|
||||
{0x1101, 0, &mqc_states[60], &mqc_states[54]},
|
||||
{0x1101, 1, &mqc_states[61], &mqc_states[55]},
|
||||
{0x0ac1, 0, &mqc_states[62], &mqc_states[56]},
|
||||
{0x0ac1, 1, &mqc_states[63], &mqc_states[57]},
|
||||
{0x09c1, 0, &mqc_states[64], &mqc_states[58]},
|
||||
{0x09c1, 1, &mqc_states[65], &mqc_states[59]},
|
||||
{0x08a1, 0, &mqc_states[66], &mqc_states[60]},
|
||||
{0x08a1, 1, &mqc_states[67], &mqc_states[61]},
|
||||
{0x0521, 0, &mqc_states[68], &mqc_states[62]},
|
||||
{0x0521, 1, &mqc_states[69], &mqc_states[63]},
|
||||
{0x0441, 0, &mqc_states[70], &mqc_states[64]},
|
||||
{0x0441, 1, &mqc_states[71], &mqc_states[65]},
|
||||
{0x02a1, 0, &mqc_states[72], &mqc_states[66]},
|
||||
{0x02a1, 1, &mqc_states[73], &mqc_states[67]},
|
||||
{0x0221, 0, &mqc_states[74], &mqc_states[68]},
|
||||
{0x0221, 1, &mqc_states[75], &mqc_states[69]},
|
||||
{0x0141, 0, &mqc_states[76], &mqc_states[70]},
|
||||
{0x0141, 1, &mqc_states[77], &mqc_states[71]},
|
||||
{0x0111, 0, &mqc_states[78], &mqc_states[72]},
|
||||
{0x0111, 1, &mqc_states[79], &mqc_states[73]},
|
||||
{0x0085, 0, &mqc_states[80], &mqc_states[74]},
|
||||
{0x0085, 1, &mqc_states[81], &mqc_states[75]},
|
||||
{0x0049, 0, &mqc_states[82], &mqc_states[76]},
|
||||
{0x0049, 1, &mqc_states[83], &mqc_states[77]},
|
||||
{0x0025, 0, &mqc_states[84], &mqc_states[78]},
|
||||
{0x0025, 1, &mqc_states[85], &mqc_states[79]},
|
||||
{0x0015, 0, &mqc_states[86], &mqc_states[80]},
|
||||
{0x0015, 1, &mqc_states[87], &mqc_states[81]},
|
||||
{0x0009, 0, &mqc_states[88], &mqc_states[82]},
|
||||
{0x0009, 1, &mqc_states[89], &mqc_states[83]},
|
||||
{0x0005, 0, &mqc_states[90], &mqc_states[84]},
|
||||
{0x0005, 1, &mqc_states[91], &mqc_states[85]},
|
||||
{0x0001, 0, &mqc_states[90], &mqc_states[86]},
|
||||
{0x0001, 1, &mqc_states[91], &mqc_states[87]},
|
||||
{0x5601, 0, &mqc_states[92], &mqc_states[92]},
|
||||
{0x5601, 1, &mqc_states[93], &mqc_states[93]},
|
||||
};
|
||||
|
||||
/*
|
||||
==========================================================
|
||||
local functions
|
||||
==========================================================
|
||||
*/
|
||||
|
||||
static void opj_mqc_setbits(opj_mqc_t *mqc)
|
||||
{
|
||||
OPJ_UINT32 tempc = mqc->c + mqc->a;
|
||||
mqc->c |= 0xffff;
|
||||
if (mqc->c >= tempc) {
|
||||
mqc->c -= 0x8000;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==========================================================
|
||||
MQ-Coder interface
|
||||
==========================================================
|
||||
*/
|
||||
|
||||
OPJ_UINT32 opj_mqc_numbytes(opj_mqc_t *mqc)
|
||||
{
|
||||
const ptrdiff_t diff = mqc->bp - mqc->start;
|
||||
#if 0
|
||||
assert(diff <= 0xffffffff && diff >= 0); /* UINT32_MAX */
|
||||
#endif
|
||||
return (OPJ_UINT32)diff;
|
||||
}
|
||||
|
||||
void opj_mqc_init_enc(opj_mqc_t *mqc, OPJ_BYTE *bp)
|
||||
{
|
||||
/* To avoid the curctx pointer to be dangling, but not strictly */
|
||||
/* required as the current context is always set before encoding */
|
||||
opj_mqc_setcurctx(mqc, 0);
|
||||
|
||||
/* As specified in Figure C.10 - Initialization of the encoder */
|
||||
/* (C.2.8 Initialization of the encoder (INITENC)) */
|
||||
mqc->a = 0x8000;
|
||||
mqc->c = 0;
|
||||
/* Yes, we point before the start of the buffer, but this is safe */
|
||||
/* given opj_tcd_code_block_enc_allocate_data() */
|
||||
mqc->bp = bp - 1;
|
||||
mqc->ct = 12;
|
||||
/* At this point we should test *(mqc->bp) against 0xFF, but this is not */
|
||||
/* necessary, as this is only used at the beginning of the code block */
|
||||
/* and our initial fake byte is set at 0 */
|
||||
assert(*(mqc->bp) != 0xff);
|
||||
|
||||
mqc->start = bp;
|
||||
mqc->end_of_byte_stream_counter = 0;
|
||||
}
|
||||
|
||||
|
||||
void opj_mqc_flush(opj_mqc_t *mqc)
|
||||
{
|
||||
/* C.2.9 Termination of coding (FLUSH) */
|
||||
/* Figure C.11 – FLUSH procedure */
|
||||
opj_mqc_setbits(mqc);
|
||||
mqc->c <<= mqc->ct;
|
||||
opj_mqc_byteout(mqc);
|
||||
mqc->c <<= mqc->ct;
|
||||
opj_mqc_byteout(mqc);
|
||||
|
||||
/* It is forbidden that a coding pass ends with 0xff */
|
||||
if (*mqc->bp != 0xff) {
|
||||
/* Advance pointer so that opj_mqc_numbytes() returns a valid value */
|
||||
mqc->bp++;
|
||||
}
|
||||
}
|
||||
|
||||
void opj_mqc_bypass_init_enc(opj_mqc_t *mqc)
|
||||
{
|
||||
/* This function is normally called after at least one opj_mqc_flush() */
|
||||
/* which will have advance mqc->bp by at least 2 bytes beyond its */
|
||||
/* initial position */
|
||||
assert(mqc->bp >= mqc->start);
|
||||
mqc->c = 0;
|
||||
/* in theory we should initialize to 8, but use this special value */
|
||||
/* as a hint that opj_mqc_bypass_enc() has never been called, so */
|
||||
/* as to avoid the 0xff 0x7f elimination trick in opj_mqc_bypass_flush_enc() */
|
||||
/* to trigger when we don't have output any bit during this bypass sequence */
|
||||
/* Any value > 8 will do */
|
||||
mqc->ct = BYPASS_CT_INIT;
|
||||
/* Given that we are called after opj_mqc_flush(), the previous byte */
|
||||
/* cannot be 0xff. */
|
||||
assert(mqc->bp[-1] != 0xff);
|
||||
}
|
||||
|
||||
void opj_mqc_bypass_enc(opj_mqc_t *mqc, OPJ_UINT32 d)
|
||||
{
|
||||
if (mqc->ct == BYPASS_CT_INIT) {
|
||||
mqc->ct = 8;
|
||||
}
|
||||
mqc->ct--;
|
||||
mqc->c = mqc->c + (d << mqc->ct);
|
||||
if (mqc->ct == 0) {
|
||||
*mqc->bp = (OPJ_BYTE)mqc->c;
|
||||
mqc->ct = 8;
|
||||
/* If the previous byte was 0xff, make sure that the next msb is 0 */
|
||||
if (*mqc->bp == 0xff) {
|
||||
mqc->ct = 7;
|
||||
}
|
||||
mqc->bp++;
|
||||
mqc->c = 0;
|
||||
}
|
||||
}
|
||||
|
||||
OPJ_UINT32 opj_mqc_bypass_get_extra_bytes(opj_mqc_t *mqc, OPJ_BOOL erterm)
|
||||
{
|
||||
return (mqc->ct < 7 ||
|
||||
(mqc->ct == 7 && (erterm || mqc->bp[-1] != 0xff))) ? 1 : 0;
|
||||
}
|
||||
|
||||
void opj_mqc_bypass_flush_enc(opj_mqc_t *mqc, OPJ_BOOL erterm)
|
||||
{
|
||||
/* Is there any bit remaining to be flushed ? */
|
||||
/* If the last output byte is 0xff, we can discard it, unless */
|
||||
/* erterm is required (I'm not completely sure why in erterm */
|
||||
/* we must output 0xff 0x2a if the last byte was 0xff instead of */
|
||||
/* discarding it, but Kakadu requires it when decoding */
|
||||
/* in -fussy mode) */
|
||||
if (mqc->ct < 7 || (mqc->ct == 7 && (erterm || mqc->bp[-1] != 0xff))) {
|
||||
OPJ_BYTE bit_value = 0;
|
||||
/* If so, fill the remaining lsbs with an alternating sequence of */
|
||||
/* 0,1,... */
|
||||
/* Note: it seems the standard only requires that for a ERTERM flush */
|
||||
/* and doesn't specify what to do for a regular BYPASS flush */
|
||||
while (mqc->ct > 0) {
|
||||
mqc->ct--;
|
||||
mqc->c += (OPJ_UINT32)(bit_value << mqc->ct);
|
||||
bit_value = (OPJ_BYTE)(1U - bit_value);
|
||||
}
|
||||
*mqc->bp = (OPJ_BYTE)mqc->c;
|
||||
/* Advance pointer so that opj_mqc_numbytes() returns a valid value */
|
||||
mqc->bp++;
|
||||
} else if (mqc->ct == 7 && mqc->bp[-1] == 0xff) {
|
||||
/* Discard last 0xff */
|
||||
assert(!erterm);
|
||||
mqc->bp --;
|
||||
} else if (mqc->ct == 8 && !erterm &&
|
||||
mqc->bp[-1] == 0x7f && mqc->bp[-2] == 0xff) {
|
||||
/* Tiny optimization: discard terminating 0xff 0x7f since it is */
|
||||
/* interpreted as 0xff 0x7f [0xff 0xff] by the decoder, and given */
|
||||
/* the bit stuffing, in fact as 0xff 0xff [0xff ..] */
|
||||
/* Happens once on opj_compress -i ../MAPA.tif -o MAPA.j2k -M 1 */
|
||||
mqc->bp -= 2;
|
||||
}
|
||||
|
||||
assert(mqc->bp[-1] != 0xff);
|
||||
}
|
||||
|
||||
void opj_mqc_reset_enc(opj_mqc_t *mqc)
|
||||
{
|
||||
opj_mqc_resetstates(mqc);
|
||||
opj_mqc_setstate(mqc, T1_CTXNO_UNI, 0, 46);
|
||||
opj_mqc_setstate(mqc, T1_CTXNO_AGG, 0, 3);
|
||||
opj_mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4);
|
||||
}
|
||||
|
||||
#ifdef notdef
|
||||
OPJ_UINT32 opj_mqc_restart_enc(opj_mqc_t *mqc)
|
||||
{
|
||||
OPJ_UINT32 correction = 1;
|
||||
|
||||
/* <flush part> */
|
||||
OPJ_INT32 n = (OPJ_INT32)(27 - 15 - mqc->ct);
|
||||
mqc->c <<= mqc->ct;
|
||||
while (n > 0) {
|
||||
opj_mqc_byteout(mqc);
|
||||
n -= (OPJ_INT32)mqc->ct;
|
||||
mqc->c <<= mqc->ct;
|
||||
}
|
||||
opj_mqc_byteout(mqc);
|
||||
|
||||
return correction;
|
||||
}
|
||||
#endif
|
||||
|
||||
void opj_mqc_restart_init_enc(opj_mqc_t *mqc)
|
||||
{
|
||||
/* <Re-init part> */
|
||||
|
||||
/* As specified in Figure C.10 - Initialization of the encoder */
|
||||
/* (C.2.8 Initialization of the encoder (INITENC)) */
|
||||
mqc->a = 0x8000;
|
||||
mqc->c = 0;
|
||||
mqc->ct = 12;
|
||||
/* This function is normally called after at least one opj_mqc_flush() */
|
||||
/* which will have advance mqc->bp by at least 2 bytes beyond its */
|
||||
/* initial position */
|
||||
mqc->bp --;
|
||||
assert(mqc->bp >= mqc->start - 1);
|
||||
assert(*mqc->bp != 0xff);
|
||||
if (*mqc->bp == 0xff) {
|
||||
mqc->ct = 13;
|
||||
}
|
||||
}
|
||||
|
||||
void opj_mqc_erterm_enc(opj_mqc_t *mqc)
|
||||
{
|
||||
OPJ_INT32 k = (OPJ_INT32)(11 - mqc->ct + 1);
|
||||
|
||||
while (k > 0) {
|
||||
mqc->c <<= mqc->ct;
|
||||
mqc->ct = 0;
|
||||
opj_mqc_byteout(mqc);
|
||||
k -= (OPJ_INT32)mqc->ct;
|
||||
}
|
||||
|
||||
if (*mqc->bp != 0xff) {
|
||||
opj_mqc_byteout(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;
|
||||
opj_mqc_setcurctx(mqc, 18);
|
||||
|
||||
for (i = 1; i < 5; i++) {
|
||||
opj_mqc_encode(mqc, i % 2);
|
||||
}
|
||||
}
|
||||
|
||||
static void opj_mqc_init_dec_common(opj_mqc_t *mqc,
|
||||
OPJ_BYTE *bp,
|
||||
OPJ_UINT32 len,
|
||||
OPJ_UINT32 extra_writable_bytes)
|
||||
{
|
||||
(void)extra_writable_bytes;
|
||||
|
||||
assert(extra_writable_bytes >= OPJ_COMMON_CBLK_DATA_EXTRA);
|
||||
mqc->start = bp;
|
||||
mqc->end = bp + len;
|
||||
/* Insert an artificial 0xFF 0xFF marker at end of the code block */
|
||||
/* data so that the bytein routines stop on it. This saves us comparing */
|
||||
/* the bp and end pointers */
|
||||
/* But before inserting it, backup th bytes we will overwrite */
|
||||
memcpy(mqc->backup, mqc->end, OPJ_COMMON_CBLK_DATA_EXTRA);
|
||||
mqc->end[0] = 0xFF;
|
||||
mqc->end[1] = 0xFF;
|
||||
mqc->bp = bp;
|
||||
}
|
||||
void opj_mqc_init_dec(opj_mqc_t *mqc, OPJ_BYTE *bp, OPJ_UINT32 len,
|
||||
OPJ_UINT32 extra_writable_bytes)
|
||||
{
|
||||
/* Implements ISO 15444-1 C.3.5 Initialization of the decoder (INITDEC) */
|
||||
/* Note: alternate "J.1 - Initialization of the software-conventions */
|
||||
/* decoder" has been tried, but does */
|
||||
/* not bring any improvement. */
|
||||
/* See https://github.com/uclouvain/openjpeg/issues/921 */
|
||||
opj_mqc_init_dec_common(mqc, bp, len, extra_writable_bytes);
|
||||
opj_mqc_setcurctx(mqc, 0);
|
||||
mqc->end_of_byte_stream_counter = 0;
|
||||
if (len == 0) {
|
||||
mqc->c = 0xff << 16;
|
||||
} else {
|
||||
mqc->c = (OPJ_UINT32)(*mqc->bp << 16);
|
||||
}
|
||||
|
||||
opj_mqc_bytein(mqc);
|
||||
mqc->c <<= 7;
|
||||
mqc->ct -= 7;
|
||||
mqc->a = 0x8000;
|
||||
}
|
||||
|
||||
|
||||
void opj_mqc_raw_init_dec(opj_mqc_t *mqc, OPJ_BYTE *bp, OPJ_UINT32 len,
|
||||
OPJ_UINT32 extra_writable_bytes)
|
||||
{
|
||||
opj_mqc_init_dec_common(mqc, bp, len, extra_writable_bytes);
|
||||
mqc->c = 0;
|
||||
mqc->ct = 0;
|
||||
}
|
||||
|
||||
|
||||
void opq_mqc_finish_dec(opj_mqc_t *mqc)
|
||||
{
|
||||
/* Restore the bytes overwritten by opj_mqc_init_dec_common() */
|
||||
memcpy(mqc->end, mqc->backup, OPJ_COMMON_CBLK_DATA_EXTRA);
|
||||
}
|
||||
|
||||
void opj_mqc_resetstates(opj_mqc_t *mqc)
|
||||
{
|
||||
OPJ_UINT32 i;
|
||||
for (i = 0; i < MQC_NUMCTXS; i++) {
|
||||
mqc->ctxs[i] = mqc_states;
|
||||
}
|
||||
}
|
||||
|
||||
void opj_mqc_setstate(opj_mqc_t *mqc, OPJ_UINT32 ctxno, OPJ_UINT32 msb,
|
||||
OPJ_INT32 prob)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
* 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) 2008, Jerome Fimes, Communications & Systemes <[email protected]>
|
||||
* 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 OPJ_MQC_H
|
||||
#define OPJ_MQC_H
|
||||
|
||||
#include "opj_common.h"
|
||||
|
||||
/**
|
||||
@file mqc.h
|
||||
@brief Implementation of an MQ-Coder (MQC)
|
||||
|
||||
The functions in MQC.C have for goal to realize the MQ-coder operations. The functions
|
||||
in MQC.C are used by some function in T1.C.
|
||||
*/
|
||||
|
||||
/** @defgroup MQC MQC - Implementation of an MQ-Coder */
|
||||
/*@{*/
|
||||
|
||||
/**
|
||||
This struct defines the state of a context.
|
||||
*/
|
||||
typedef struct opj_mqc_state {
|
||||
/** the probability of the Least Probable Symbol (0.75->0x8000, 1.5->0xffff) */
|
||||
OPJ_UINT32 qeval;
|
||||
/** the Most Probable Symbol (0 or 1) */
|
||||
OPJ_UINT32 mps;
|
||||
/** next state if the next encoded symbol is the MPS */
|
||||
const struct opj_mqc_state *nmps;
|
||||
/** next state if the next encoded symbol is the LPS */
|
||||
const struct opj_mqc_state *nlps;
|
||||
} opj_mqc_state_t;
|
||||
|
||||
#define MQC_NUMCTXS 19
|
||||
|
||||
/**
|
||||
MQ coder
|
||||
*/
|
||||
typedef struct opj_mqc {
|
||||
/** temporary buffer where bits are coded or decoded */
|
||||
OPJ_UINT32 c;
|
||||
/** only used by MQ decoder */
|
||||
OPJ_UINT32 a;
|
||||
/** number of bits already read or free to write */
|
||||
OPJ_UINT32 ct;
|
||||
/* only used by decoder, to count the number of times a terminating 0xFF >0x8F marker is read */
|
||||
OPJ_UINT32 end_of_byte_stream_counter;
|
||||
/** pointer to the current position in the buffer */
|
||||
OPJ_BYTE *bp;
|
||||
/** pointer to the start of the buffer */
|
||||
OPJ_BYTE *start;
|
||||
/** pointer to the end of the buffer */
|
||||
OPJ_BYTE *end;
|
||||
/** Array of contexts */
|
||||
const opj_mqc_state_t *ctxs[MQC_NUMCTXS];
|
||||
/** Active context */
|
||||
const opj_mqc_state_t **curctx;
|
||||
/* lut_ctxno_zc shifted by (1 << 9) * bandno */
|
||||
const OPJ_BYTE* lut_ctxno_zc_orient;
|
||||
/** Original value of the 2 bytes at end[0] and end[1] */
|
||||
OPJ_BYTE backup[OPJ_COMMON_CBLK_DATA_EXTRA];
|
||||
} opj_mqc_t;
|
||||
|
||||
#define BYPASS_CT_INIT 0xDEADBEEF
|
||||
|
||||
#include "mqc_inl.h"
|
||||
|
||||
/** @name Exported functions */
|
||||
/*@{*/
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
Return the number of bytes written/read since initialisation
|
||||
@param mqc MQC handle
|
||||
@return Returns the number of bytes already encoded
|
||||
*/
|
||||
OPJ_UINT32 opj_mqc_numbytes(opj_mqc_t *mqc);
|
||||
/**
|
||||
Reset the states of all the context of the coder/decoder
|
||||
(each context is set to a state where 0 and 1 are more or less equiprobable)
|
||||
@param mqc MQC handle
|
||||
*/
|
||||
void opj_mqc_resetstates(opj_mqc_t *mqc);
|
||||
/**
|
||||
Set the state of a particular context
|
||||
@param mqc MQC handle
|
||||
@param ctxno Number that identifies the context
|
||||
@param msb The MSB of the new state of the context
|
||||
@param prob Number that identifies the probability of the symbols for the new state of the context
|
||||
*/
|
||||
void opj_mqc_setstate(opj_mqc_t *mqc, OPJ_UINT32 ctxno, OPJ_UINT32 msb,
|
||||
OPJ_INT32 prob);
|
||||
/**
|
||||
Initialize the encoder
|
||||
@param mqc MQC handle
|
||||
@param bp Pointer to the start of the buffer where the bytes will be written
|
||||
*/
|
||||
void opj_mqc_init_enc(opj_mqc_t *mqc, OPJ_BYTE *bp);
|
||||
/**
|
||||
Set the current context used for coding/decoding
|
||||
@param mqc MQC handle
|
||||
@param ctxno Number that identifies the context
|
||||
*/
|
||||
#define opj_mqc_setcurctx(mqc, ctxno) (mqc)->curctx = &(mqc)->ctxs[(OPJ_UINT32)(ctxno)]
|
||||
|
||||
/**
|
||||
Flush the encoder, so that all remaining data is written
|
||||
@param mqc MQC handle
|
||||
*/
|
||||
void opj_mqc_flush(opj_mqc_t *mqc);
|
||||
/**
|
||||
BYPASS mode switch, initialization operation.
|
||||
JPEG 2000 p 505.
|
||||
@param mqc MQC handle
|
||||
*/
|
||||
void opj_mqc_bypass_init_enc(opj_mqc_t *mqc);
|
||||
|
||||
/** Return number of extra bytes to add to opj_mqc_numbytes() for the²
|
||||
size of a non-terminating BYPASS pass
|
||||
@param mqc MQC handle
|
||||
@param erterm 1 if ERTERM is enabled, 0 otherwise
|
||||
*/
|
||||
OPJ_UINT32 opj_mqc_bypass_get_extra_bytes(opj_mqc_t *mqc, OPJ_BOOL erterm);
|
||||
|
||||
/**
|
||||
BYPASS mode switch, coding operation.
|
||||
JPEG 2000 p 505.
|
||||
@param mqc MQC handle
|
||||
@param d The symbol to be encoded (0 or 1)
|
||||
*/
|
||||
void opj_mqc_bypass_enc(opj_mqc_t *mqc, OPJ_UINT32 d);
|
||||
/**
|
||||
BYPASS mode switch, flush operation
|
||||
@param mqc MQC handle
|
||||
@param erterm 1 if ERTERM is enabled, 0 otherwise
|
||||
*/
|
||||
void opj_mqc_bypass_flush_enc(opj_mqc_t *mqc, OPJ_BOOL erterm);
|
||||
/**
|
||||
RESET mode switch
|
||||
@param mqc MQC handle
|
||||
*/
|
||||
void opj_mqc_reset_enc(opj_mqc_t *mqc);
|
||||
|
||||
#ifdef notdef
|
||||
/**
|
||||
RESTART mode switch (TERMALL)
|
||||
@param mqc MQC handle
|
||||
@return Returns 1 (always)
|
||||
*/
|
||||
OPJ_UINT32 opj_mqc_restart_enc(opj_mqc_t *mqc);
|
||||
#endif
|
||||
|
||||
/**
|
||||
RESTART mode switch (TERMALL) reinitialisation
|
||||
@param mqc MQC handle
|
||||
*/
|
||||
void opj_mqc_restart_init_enc(opj_mqc_t *mqc);
|
||||
/**
|
||||
ERTERM mode switch (PTERM)
|
||||
@param mqc MQC handle
|
||||
*/
|
||||
void opj_mqc_erterm_enc(opj_mqc_t *mqc);
|
||||
/**
|
||||
SEGMARK mode switch (SEGSYM)
|
||||
@param mqc MQC handle
|
||||
*/
|
||||
void opj_mqc_segmark_enc(opj_mqc_t *mqc);
|
||||
|
||||
/**
|
||||
Initialize the decoder for MQ decoding.
|
||||
|
||||
opj_mqc_finish_dec() must be absolutely called after finishing the decoding
|
||||
passes, so as to restore the bytes temporarily overwritten.
|
||||
|
||||
@param mqc MQC handle
|
||||
@param bp Pointer to the start of the buffer from which the bytes will be read
|
||||
Note that OPJ_COMMON_CBLK_DATA_EXTRA bytes at the end of the buffer
|
||||
will be temporarily overwritten with an artificial 0xFF 0xFF marker.
|
||||
(they will be backuped in the mqc structure to be restored later)
|
||||
So bp must be at least len + OPJ_COMMON_CBLK_DATA_EXTRA large, and
|
||||
writable.
|
||||
@param len Length of the input buffer
|
||||
@param extra_writable_bytes Indicate how many bytes after len are writable.
|
||||
This is to indicate your consent that bp must be
|
||||
large enough.
|
||||
*/
|
||||
void opj_mqc_init_dec(opj_mqc_t *mqc, OPJ_BYTE *bp, OPJ_UINT32 len,
|
||||
OPJ_UINT32 extra_writable_bytes);
|
||||
|
||||
/**
|
||||
Initialize the decoder for RAW decoding.
|
||||
|
||||
opj_mqc_finish_dec() must be absolutely called after finishing the decoding
|
||||
passes, so as to restore the bytes temporarily overwritten.
|
||||
|
||||
@param mqc MQC handle
|
||||
@param bp Pointer to the start of the buffer from which the bytes will be read
|
||||
Note that OPJ_COMMON_CBLK_DATA_EXTRA bytes at the end of the buffer
|
||||
will be temporarily overwritten with an artificial 0xFF 0xFF marker.
|
||||
(they will be backuped in the mqc structure to be restored later)
|
||||
So bp must be at least len + OPJ_COMMON_CBLK_DATA_EXTRA large, and
|
||||
writable.
|
||||
@param len Length of the input buffer
|
||||
@param extra_writable_bytes Indicate how many bytes after len are writable.
|
||||
This is to indicate your consent that bp must be
|
||||
large enough.
|
||||
*/
|
||||
void opj_mqc_raw_init_dec(opj_mqc_t *mqc, OPJ_BYTE *bp, OPJ_UINT32 len,
|
||||
OPJ_UINT32 extra_writable_bytes);
|
||||
|
||||
|
||||
/**
|
||||
Terminate RAW/MQC decoding
|
||||
|
||||
This restores the bytes temporarily overwritten by opj_mqc_init_dec()/
|
||||
opj_mqc_raw_init_dec()
|
||||
|
||||
@param mqc MQC handle
|
||||
*/
|
||||
void opq_mqc_finish_dec(opj_mqc_t *mqc);
|
||||
|
||||
/**
|
||||
Decode a symbol
|
||||
@param mqc MQC handle
|
||||
@return Returns the decoded symbol (0 or 1)
|
||||
*/
|
||||
/*static INLINE OPJ_UINT32 opj_mqc_decode(opj_mqc_t * const mqc);*/
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/*@}*/
|
||||
|
||||
/*@}*/
|
||||
|
||||
#endif /* OPJ_MQC_H */
|
||||
@@ -0,0 +1,282 @@
|
||||
/*
|
||||
* 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) 2008, Jerome Fimes, Communications & Systemes <[email protected]>
|
||||
* 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 OPJ_MQC_INL_H
|
||||
#define OPJ_MQC_INL_H
|
||||
|
||||
/* For internal use of opj_mqc_decode_macro() */
|
||||
#define opj_mqc_mpsexchange_macro(d, curctx, a) \
|
||||
{ \
|
||||
if (a < (*curctx)->qeval) { \
|
||||
d = !((*curctx)->mps); \
|
||||
*curctx = (*curctx)->nlps; \
|
||||
} else { \
|
||||
d = (*curctx)->mps; \
|
||||
*curctx = (*curctx)->nmps; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* For internal use of opj_mqc_decode_macro() */
|
||||
#define opj_mqc_lpsexchange_macro(d, curctx, a) \
|
||||
{ \
|
||||
if (a < (*curctx)->qeval) { \
|
||||
a = (*curctx)->qeval; \
|
||||
d = (*curctx)->mps; \
|
||||
*curctx = (*curctx)->nmps; \
|
||||
} else { \
|
||||
a = (*curctx)->qeval; \
|
||||
d = !((*curctx)->mps); \
|
||||
*curctx = (*curctx)->nlps; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Decode a symbol using raw-decoder. Cfr p.506 TAUBMAN
|
||||
@param mqc MQC handle
|
||||
@return Returns the decoded symbol (0 or 1)
|
||||
*/
|
||||
static INLINE OPJ_UINT32 opj_mqc_raw_decode(opj_mqc_t *mqc)
|
||||
{
|
||||
OPJ_UINT32 d;
|
||||
if (mqc->ct == 0) {
|
||||
/* Given opj_mqc_raw_init_dec() we know that at some point we will */
|
||||
/* have a 0xFF 0xFF artificial marker */
|
||||
if (mqc->c == 0xff) {
|
||||
if (*mqc->bp > 0x8f) {
|
||||
mqc->c = 0xff;
|
||||
mqc->ct = 8;
|
||||
} else {
|
||||
mqc->c = *mqc->bp;
|
||||
mqc->bp ++;
|
||||
mqc->ct = 7;
|
||||
}
|
||||
} else {
|
||||
mqc->c = *mqc->bp;
|
||||
mqc->bp ++;
|
||||
mqc->ct = 8;
|
||||
}
|
||||
}
|
||||
mqc->ct--;
|
||||
d = ((OPJ_UINT32)mqc->c >> mqc->ct) & 0x01U;
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
#define opj_mqc_bytein_macro(mqc, c, ct) \
|
||||
{ \
|
||||
OPJ_UINT32 l_c; \
|
||||
/* Given opj_mqc_init_dec() we know that at some point we will */ \
|
||||
/* have a 0xFF 0xFF artificial marker */ \
|
||||
l_c = *(mqc->bp + 1); \
|
||||
if (*mqc->bp == 0xff) { \
|
||||
if (l_c > 0x8f) { \
|
||||
c += 0xff00; \
|
||||
ct = 8; \
|
||||
mqc->end_of_byte_stream_counter ++; \
|
||||
} else { \
|
||||
mqc->bp++; \
|
||||
c += l_c << 9; \
|
||||
ct = 7; \
|
||||
} \
|
||||
} else { \
|
||||
mqc->bp++; \
|
||||
c += l_c << 8; \
|
||||
ct = 8; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* For internal use of opj_mqc_decode_macro() */
|
||||
#define opj_mqc_renormd_macro(mqc, a, c, ct) \
|
||||
{ \
|
||||
do { \
|
||||
if (ct == 0) { \
|
||||
opj_mqc_bytein_macro(mqc, c, ct); \
|
||||
} \
|
||||
a <<= 1; \
|
||||
c <<= 1; \
|
||||
ct--; \
|
||||
} while (a < 0x8000); \
|
||||
}
|
||||
|
||||
#define opj_mqc_decode_macro(d, mqc, curctx, a, c, ct) \
|
||||
{ \
|
||||
/* Implements ISO 15444-1 C.3.2 Decoding a decision (DECODE) */ \
|
||||
/* Note: alternate "J.2 - Decoding an MPS or an LPS in the */ \
|
||||
/* software-conventions decoder" has been tried, but does not bring any */ \
|
||||
/* improvement. See https://github.com/uclouvain/openjpeg/issues/921 */ \
|
||||
a -= (*curctx)->qeval; \
|
||||
if ((c >> 16) < (*curctx)->qeval) { \
|
||||
opj_mqc_lpsexchange_macro(d, curctx, a); \
|
||||
opj_mqc_renormd_macro(mqc, a, c, ct); \
|
||||
} else { \
|
||||
c -= (*curctx)->qeval << 16; \
|
||||
if ((a & 0x8000) == 0) { \
|
||||
opj_mqc_mpsexchange_macro(d, curctx, a); \
|
||||
opj_mqc_renormd_macro(mqc, a, c, ct); \
|
||||
} else { \
|
||||
d = (*curctx)->mps; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define DOWNLOAD_MQC_VARIABLES(mqc, curctx, a, c, 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) \
|
||||
mqc->curctx = curctx; \
|
||||
mqc->c = c; \
|
||||
mqc->a = a; \
|
||||
mqc->ct = ct;
|
||||
|
||||
/**
|
||||
Input a byte
|
||||
@param mqc MQC handle
|
||||
*/
|
||||
static INLINE void opj_mqc_bytein(opj_mqc_t *const mqc)
|
||||
{
|
||||
opj_mqc_bytein_macro(mqc, mqc->c, mqc->ct);
|
||||
}
|
||||
|
||||
/**
|
||||
Renormalize mqc->a and mqc->c while decoding
|
||||
@param mqc MQC handle
|
||||
*/
|
||||
#define opj_mqc_renormd(mqc) \
|
||||
opj_mqc_renormd_macro(mqc, mqc->a, mqc->c, mqc->ct)
|
||||
|
||||
/**
|
||||
Decode a symbol
|
||||
@param d OPJ_UINT32 value where to store the decoded symbol
|
||||
@param mqc MQC handle
|
||||
@return Returns the decoded symbol (0 or 1) in d
|
||||
*/
|
||||
#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 */
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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) 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.
|
||||
*/
|
||||
|
||||
#include "opj_includes.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/times.h>
|
||||
#endif /* _WIN32 */
|
||||
|
||||
OPJ_FLOAT64 opj_clock(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
/* _WIN32: use QueryPerformance (very accurate) */
|
||||
LARGE_INTEGER freq, t ;
|
||||
/* freq is the clock speed of the CPU */
|
||||
QueryPerformanceFrequency(&freq) ;
|
||||
/* cout << "freq = " << ((double) freq.QuadPart) << endl; */
|
||||
/* t is the high resolution performance counter (see MSDN) */
|
||||
QueryPerformanceCounter(& t) ;
|
||||
return ((OPJ_FLOAT64) t.QuadPart / (OPJ_FLOAT64) freq.QuadPart) ;
|
||||
#else
|
||||
/* Unix or Linux: use resource usage */
|
||||
struct rusage t;
|
||||
OPJ_FLOAT64 procTime;
|
||||
/* (1) Get the rusage data structure at this moment (man getrusage) */
|
||||
getrusage(0, &t);
|
||||
/* (2) What is the elapsed time ? - CPU time = User time + System time */
|
||||
/* (2a) Get the seconds */
|
||||
procTime = (OPJ_FLOAT64)(t.ru_utime.tv_sec + t.ru_stime.tv_sec);
|
||||
/* (2b) More precisely! Get the microseconds part ! */
|
||||
return (procTime + (OPJ_FLOAT64)(t.ru_utime.tv_usec + t.ru_stime.tv_usec) *
|
||||
1e-6) ;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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) 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 OPJ_CLOCK_H
|
||||
#define OPJ_CLOCK_H
|
||||
/**
|
||||
@file opj_clock.h
|
||||
@brief Internal function for timing
|
||||
|
||||
The functions in OPJ_CLOCK.C are internal utilities mainly used for timing.
|
||||
*/
|
||||
|
||||
/** @defgroup MISC MISC - Miscellaneous internal functions */
|
||||
/*@{*/
|
||||
|
||||
/** @name Exported functions */
|
||||
/*@{*/
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
Difference in successive opj_clock() calls tells you the elapsed time
|
||||
@return Returns time in seconds
|
||||
*/
|
||||
OPJ_FLOAT64 opj_clock(void);
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/*@}*/
|
||||
|
||||
/*@}*/
|
||||
|
||||
#endif /* OPJ_CLOCK_H */
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* 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
|
||||
* 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 OPJ_CODEC_H
|
||||
#define OPJ_CODEC_H
|
||||
/**
|
||||
@file opj_codec.h
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Main codec handler used for compression or decompression.
|
||||
*/
|
||||
typedef struct opj_codec_private {
|
||||
/** FIXME DOC */
|
||||
union {
|
||||
/**
|
||||
* Decompression handler.
|
||||
*/
|
||||
struct opj_decompression {
|
||||
/** Main header reading function handler */
|
||||
OPJ_BOOL(*opj_read_header)(struct opj_stream_private * cio,
|
||||
void * p_codec,
|
||||
opj_image_t **p_image,
|
||||
struct opj_event_mgr * p_manager);
|
||||
|
||||
/** Decoding function */
|
||||
OPJ_BOOL(*opj_decode)(void * p_codec,
|
||||
struct opj_stream_private * p_cio,
|
||||
opj_image_t * p_image,
|
||||
struct opj_event_mgr * p_manager);
|
||||
|
||||
/** FIXME DOC */
|
||||
OPJ_BOOL(*opj_read_tile_header)(void * p_codec,
|
||||
OPJ_UINT32 * p_tile_index,
|
||||
OPJ_UINT32 * p_data_size,
|
||||
OPJ_INT32 * p_tile_x0,
|
||||
OPJ_INT32 * p_tile_y0,
|
||||
OPJ_INT32 * p_tile_x1,
|
||||
OPJ_INT32 * p_tile_y1,
|
||||
OPJ_UINT32 * p_nb_comps,
|
||||
OPJ_BOOL * p_should_go_on,
|
||||
struct opj_stream_private * p_cio,
|
||||
struct opj_event_mgr * p_manager);
|
||||
|
||||
/** FIXME DOC */
|
||||
OPJ_BOOL(*opj_decode_tile_data)(void * p_codec,
|
||||
OPJ_UINT32 p_tile_index,
|
||||
OPJ_BYTE * p_data,
|
||||
OPJ_UINT32 p_data_size,
|
||||
struct opj_stream_private * p_cio,
|
||||
struct opj_event_mgr * p_manager);
|
||||
|
||||
/** Reading function used after codestream if necessary */
|
||||
OPJ_BOOL(* opj_end_decompress)(void *p_codec,
|
||||
struct opj_stream_private * cio,
|
||||
struct opj_event_mgr * p_manager);
|
||||
|
||||
/** Codec destroy function handler */
|
||||
void (*opj_destroy)(void * p_codec);
|
||||
|
||||
/** 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,
|
||||
OPJ_INT32 p_start_x,
|
||||
OPJ_INT32 p_end_x,
|
||||
OPJ_INT32 p_start_y,
|
||||
OPJ_INT32 p_end_y,
|
||||
struct opj_event_mgr * p_manager);
|
||||
|
||||
/** Get tile function */
|
||||
OPJ_BOOL(*opj_get_decoded_tile)(void *p_codec,
|
||||
opj_stream_private_t * p_cio,
|
||||
opj_image_t *p_image,
|
||||
struct opj_event_mgr * p_manager,
|
||||
OPJ_UINT32 tile_index);
|
||||
|
||||
/** Set the decoded resolution factor */
|
||||
OPJ_BOOL(*opj_set_decoded_resolution_factor)(void * p_codec,
|
||||
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;
|
||||
|
||||
/**
|
||||
* Compression handler. FIXME DOC
|
||||
*/
|
||||
struct opj_compression {
|
||||
OPJ_BOOL(* opj_start_compress)(void *p_codec,
|
||||
struct opj_stream_private * cio,
|
||||
struct opj_image * p_image,
|
||||
struct opj_event_mgr * p_manager);
|
||||
|
||||
OPJ_BOOL(* opj_encode)(void * p_codec,
|
||||
struct opj_stream_private *p_cio,
|
||||
struct opj_event_mgr * p_manager);
|
||||
|
||||
OPJ_BOOL(* opj_write_tile)(void * p_codec,
|
||||
OPJ_UINT32 p_tile_index,
|
||||
OPJ_BYTE * p_data,
|
||||
OPJ_UINT32 p_data_size,
|
||||
struct opj_stream_private * p_cio,
|
||||
struct opj_event_mgr * p_manager);
|
||||
|
||||
OPJ_BOOL(* opj_end_compress)(void * p_codec,
|
||||
struct opj_stream_private * p_cio,
|
||||
struct opj_event_mgr * p_manager);
|
||||
|
||||
void (* opj_destroy)(void * p_codec);
|
||||
|
||||
OPJ_BOOL(* opj_setup_encoder)(void * p_codec,
|
||||
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*/
|
||||
void * m_codec;
|
||||
/** Event handler */
|
||||
opj_event_mgr_t m_event_mgr;
|
||||
/** Flag to indicate if the codec is used to decode or encode*/
|
||||
OPJ_BOOL is_decompressor;
|
||||
void (*opj_dump_codec)(void * p_codec, OPJ_INT32 info_flag,
|
||||
FILE* output_stream);
|
||||
opj_codestream_info_v2_t* (*opj_get_codec_info)(void* p_codec);
|
||||
opj_codestream_index_t* (*opj_get_codec_index)(void* p_codec);
|
||||
|
||||
/** Set number of threads */
|
||||
OPJ_BOOL(*opj_set_threads)(void * p_codec, OPJ_UINT32 num_threads);
|
||||
}
|
||||
opj_codec_private_t;
|
||||
|
||||
|
||||
#endif /* OPJ_CODEC_H */
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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) 2017, IntoPIX SA <[email protected]>
|
||||
* 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 OPJ_COMMON_H
|
||||
#define OPJ_COMMON_H
|
||||
|
||||
/*
|
||||
==========================================================
|
||||
Common constants shared among several modules
|
||||
==========================================================
|
||||
*/
|
||||
#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_COMMON_H */
|
||||
@@ -0,0 +1,13 @@
|
||||
#ifndef OPJ_CONFIG_H_INCLUDED
|
||||
#define OPJ_CONFIG_H_INCLUDED
|
||||
|
||||
/*
|
||||
* Hand written replacement for the CMake generated opj_config.h
|
||||
* Proxmark3 vendors only the openjp2 decoder, see README.pm3
|
||||
*/
|
||||
|
||||
#define OPJ_VERSION_MAJOR 2
|
||||
#define OPJ_VERSION_MINOR 5
|
||||
#define OPJ_VERSION_BUILD 4
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,44 @@
|
||||
#ifndef OPJ_CONFIG_PRIVATE_H_INCLUDED
|
||||
#define OPJ_CONFIG_PRIVATE_H_INCLUDED
|
||||
|
||||
/*
|
||||
* Hand written replacement for the CMake generated opj_config_private.h
|
||||
*
|
||||
* Upstream probes the host with CMake try_compile checks. We vendor the
|
||||
* sources instead, so everything is decided from compiler predefines here.
|
||||
* This file is included before any system header, see opj_includes.h
|
||||
*/
|
||||
|
||||
#define OPJ_PACKAGE_VERSION "2.5.4"
|
||||
|
||||
/*
|
||||
* Aligned allocation.
|
||||
*
|
||||
* On POSIX we take posix_memalign, it is declared by <stdlib.h> and openjpeg
|
||||
* prefers it over memalign anyway.
|
||||
*
|
||||
* On Windows / MinGW we deliberately define nothing. openjpeg then falls back
|
||||
* to its own portable aligned malloc, which avoids having to reason about
|
||||
* whether _aligned_malloc is visible in a given mingw-w64 / msvcrt combination.
|
||||
* We decode a handful of passport images, the alloc path is not hot.
|
||||
*/
|
||||
#if !defined(_WIN32)
|
||||
# define OPJ_HAVE_POSIX_MEMALIGN
|
||||
# define OPJ_HAVE_FSEEKO
|
||||
#endif
|
||||
|
||||
#if !defined(_POSIX_C_SOURCE)
|
||||
# if defined(OPJ_HAVE_FSEEKO) || defined(OPJ_HAVE_POSIX_MEMALIGN)
|
||||
/* Get declarations of fseeko, ftello, posix_memalign. */
|
||||
# define _POSIX_C_SOURCE 200112L
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Byte order, taken from the compiler rather than from a TRY_RUN */
|
||||
#if defined(__BIG_ENDIAN__)
|
||||
# define OPJ_BIG_ENDIAN
|
||||
#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
|
||||
# define OPJ_BIG_ENDIAN
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,266 @@
|
||||
/*
|
||||
* 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) 2005, Herve Drolon, FreeImage Team
|
||||
* Copyright (c) 2008, 2011-2012, Centre National d'Etudes Spatiales (CNES), FR
|
||||
* Copyright (c) 2012, CS Systemes d'Information, France
|
||||
* 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 OPJ_INCLUDES_H
|
||||
#define OPJ_INCLUDES_H
|
||||
|
||||
/*
|
||||
* This must be included before any system headers,
|
||||
* since they can react to macro defined there
|
||||
*/
|
||||
#include "opj_config_private.h"
|
||||
|
||||
/*
|
||||
==========================================================
|
||||
Standard includes used by the library
|
||||
==========================================================
|
||||
*/
|
||||
#include <memory.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
/*
|
||||
Use fseeko() and ftello() if they are available since they use
|
||||
'off_t' rather than 'long'. It is wrong to use fseeko() and
|
||||
ftello() only on systems with special LFS support since some systems
|
||||
(e.g. FreeBSD) support a 64-bit off_t by default.
|
||||
*/
|
||||
#if defined(OPJ_HAVE_FSEEKO) && !defined(fseek)
|
||||
# define fseek fseeko
|
||||
# define ftell ftello
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(WIN32) && !defined(Windows95) && !defined(__BORLANDC__) && \
|
||||
!(defined(_MSC_VER) && _MSC_VER < 1400) && \
|
||||
!(defined(__MINGW32__) && __MSVCRT_VERSION__ < 0x800)
|
||||
/*
|
||||
Windows '95 and Borland C do not support _lseeki64
|
||||
Visual Studio does not support _fseeki64 and _ftelli64 until the 2005 release.
|
||||
Without these interfaces, files over 2GB in size are not supported for Windows.
|
||||
*/
|
||||
# define OPJ_FSEEK(stream,offset,whence) _fseeki64(stream,/* __int64 */ offset,whence)
|
||||
# define OPJ_FSTAT(fildes,stat_buff) _fstati64(fildes,/* struct _stati64 */ stat_buff)
|
||||
# define OPJ_FTELL(stream) /* __int64 */ _ftelli64(stream)
|
||||
# define OPJ_STAT_STRUCT_T struct _stati64
|
||||
# define OPJ_STAT(path,stat_buff) _stati64(path,/* struct _stati64 */ stat_buff)
|
||||
#else
|
||||
# define OPJ_FSEEK(stream,offset,whence) fseek(stream,offset,whence)
|
||||
# define OPJ_FSTAT(fildes,stat_buff) fstat(fildes,stat_buff)
|
||||
# define OPJ_FTELL(stream) ftell(stream)
|
||||
# define OPJ_STAT_STRUCT_T struct stat
|
||||
# define OPJ_STAT(path,stat_buff) stat(path,stat_buff)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
==========================================================
|
||||
OpenJPEG interface
|
||||
==========================================================
|
||||
*/
|
||||
#include "openjpeg.h"
|
||||
|
||||
/*
|
||||
==========================================================
|
||||
OpenJPEG modules
|
||||
==========================================================
|
||||
*/
|
||||
|
||||
/* Are restricted pointers available? (C99) */
|
||||
#if (__STDC_VERSION__ >= 199901L)
|
||||
#define OPJ_RESTRICT restrict
|
||||
#else
|
||||
/* Not a C99 compiler */
|
||||
#if defined(__GNUC__)
|
||||
#define OPJ_RESTRICT __restrict__
|
||||
|
||||
/*
|
||||
vc14 (2015) outputs wrong results.
|
||||
Need to check OPJ_RESTRICT usage (or a bug in vc14)
|
||||
#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||
#define OPJ_RESTRICT __restrict
|
||||
*/
|
||||
#else
|
||||
#define OPJ_RESTRICT /* restrict */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __has_attribute
|
||||
#if __has_attribute(no_sanitize)
|
||||
#define OPJ_NOSANITIZE(kind) __attribute__((no_sanitize(kind)))
|
||||
#endif
|
||||
#endif
|
||||
#ifndef OPJ_NOSANITIZE
|
||||
#define OPJ_NOSANITIZE(kind)
|
||||
#endif
|
||||
|
||||
|
||||
/* MSVC before 2013 and Borland C do not have lrintf */
|
||||
#if defined(_MSC_VER)
|
||||
#include <intrin.h>
|
||||
static INLINE long opj_lrintf(float f)
|
||||
{
|
||||
#ifdef _M_X64
|
||||
return _mm_cvt_ss2si(_mm_load_ss(&f));
|
||||
|
||||
/* commented out line breaks many tests */
|
||||
/* return (long)((f>0.0f) ? (f + 0.5f):(f -0.5f)); */
|
||||
#elif defined(_M_IX86)
|
||||
int i;
|
||||
_asm{
|
||||
fld f
|
||||
fistp i
|
||||
};
|
||||
|
||||
return i;
|
||||
#else
|
||||
return (long)((f>0.0f) ? (f + 0.5f) : (f - 0.5f));
|
||||
#endif
|
||||
}
|
||||
#elif defined(__BORLANDC__)
|
||||
static INLINE long opj_lrintf(float f)
|
||||
{
|
||||
#ifdef _M_X64
|
||||
return (long)((f > 0.0f) ? (f + 0.5f) : (f - 0.5f));
|
||||
#else
|
||||
int i;
|
||||
|
||||
_asm {
|
||||
fld f
|
||||
fistp i
|
||||
};
|
||||
|
||||
return i;
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
static INLINE long opj_lrintf(float f)
|
||||
{
|
||||
return lrintf(f);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1400)
|
||||
#define vsnprintf _vsnprintf
|
||||
#endif
|
||||
|
||||
/* MSVC x86 is really bad at doing int64 = int32 * int32 on its own. Use intrinsic. */
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__INTEL_COMPILER) && defined(_M_IX86)
|
||||
# include <intrin.h>
|
||||
# pragma intrinsic(__emul)
|
||||
#endif
|
||||
|
||||
/* Apparently Visual Studio doesn't define __SSE__ / __SSE2__ macros */
|
||||
#if defined(_M_X64)
|
||||
/* Intel 64bit support SSE and SSE2 */
|
||||
# ifndef __SSE__
|
||||
# define __SSE__ 1
|
||||
# endif
|
||||
# ifndef __SSE2__
|
||||
# define __SSE2__ 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* For x86, test the value of the _M_IX86_FP macro. */
|
||||
/* See https://msdn.microsoft.com/en-us/library/b0084kay.aspx */
|
||||
#if defined(_M_IX86_FP)
|
||||
# if _M_IX86_FP >= 1
|
||||
# ifndef __SSE__
|
||||
# define __SSE__ 1
|
||||
# endif
|
||||
# endif
|
||||
# if _M_IX86_FP >= 2
|
||||
# ifndef __SSE2__
|
||||
# define __SSE2__ 1
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Type to use for bit-fields in internal headers */
|
||||
typedef unsigned int OPJ_BITFIELD;
|
||||
|
||||
#define OPJ_UNUSED(x) (void)x
|
||||
|
||||
#include "opj_clock.h"
|
||||
#include "opj_malloc.h"
|
||||
#include "event.h"
|
||||
#include "function_list.h"
|
||||
#include "bio.h"
|
||||
#include "cio.h"
|
||||
|
||||
#include "thread.h"
|
||||
#include "tls_keys.h"
|
||||
|
||||
#include "image.h"
|
||||
#include "invert.h"
|
||||
#include "j2k.h"
|
||||
#include "jp2.h"
|
||||
|
||||
#include "mqc.h"
|
||||
#include "bio.h"
|
||||
|
||||
#include "pi.h"
|
||||
#include "tgt.h"
|
||||
#include "tcd.h"
|
||||
#include "t1.h"
|
||||
#include "dwt.h"
|
||||
#include "t2.h"
|
||||
#include "mct.h"
|
||||
#include "opj_intmath.h"
|
||||
#include "sparse_array.h"
|
||||
|
||||
#ifdef USE_JPIP
|
||||
#include "cidx_manager.h"
|
||||
#include "indexbox_manager.h"
|
||||
#endif
|
||||
|
||||
/* JPWL>> */
|
||||
#ifdef USE_JPWL
|
||||
#include "openjpwl/jpwl.h"
|
||||
#endif /* USE_JPWL */
|
||||
/* <<JPWL */
|
||||
|
||||
/* V2 */
|
||||
#include "opj_codec.h"
|
||||
|
||||
|
||||
#endif /* OPJ_INCLUDES_H */
|
||||
@@ -0,0 +1,333 @@
|
||||
/*
|
||||
* 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 OPJ_INTMATH_H
|
||||
#define OPJ_INTMATH_H
|
||||
/**
|
||||
@file opj_intmath.h
|
||||
@brief Implementation of operations on integers (INT)
|
||||
|
||||
The functions in OPJ_INTMATH.H have for goal to realize operations on integers.
|
||||
*/
|
||||
|
||||
/** @defgroup OPJ_INTMATH OPJ_INTMATH - Implementation of operations on integers */
|
||||
/*@{*/
|
||||
|
||||
/** @name Exported functions (see also openjpeg.h) */
|
||||
/*@{*/
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/**
|
||||
Get the minimum of two integers
|
||||
@return Returns a if a < b else b
|
||||
*/
|
||||
static INLINE OPJ_INT32 opj_int_min(OPJ_INT32 a, OPJ_INT32 b)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
/**
|
||||
Get the minimum of two integers
|
||||
@return Returns a if a < b else b
|
||||
*/
|
||||
static INLINE OPJ_UINT32 opj_uint_min(OPJ_UINT32 a, OPJ_UINT32 b)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
/**
|
||||
Get the maximum of two integers
|
||||
@return Returns a if a > b else b
|
||||
*/
|
||||
static INLINE OPJ_INT32 opj_int_max(OPJ_INT32 a, OPJ_INT32 b)
|
||||
{
|
||||
return (a > b) ? a : b;
|
||||
}
|
||||
|
||||
/**
|
||||
Get the maximum of two integers
|
||||
@return Returns a if a > b else b
|
||||
*/
|
||||
static INLINE OPJ_UINT32 opj_uint_max(OPJ_UINT32 a, OPJ_UINT32 b)
|
||||
{
|
||||
return (a > b) ? a : b;
|
||||
}
|
||||
|
||||
/**
|
||||
Get the saturated sum of two unsigned integers
|
||||
@return Returns saturated sum of a+b
|
||||
*/
|
||||
static INLINE OPJ_UINT32 opj_uint_adds(OPJ_UINT32 a, OPJ_UINT32 b)
|
||||
{
|
||||
OPJ_UINT64 sum = (OPJ_UINT64)a + (OPJ_UINT64)b;
|
||||
return (OPJ_UINT32)(-(OPJ_INT32)(sum >> 32)) | (OPJ_UINT32)sum;
|
||||
}
|
||||
|
||||
/**
|
||||
Get the saturated difference of two unsigned integers
|
||||
@return Returns saturated sum of a-b
|
||||
*/
|
||||
static INLINE OPJ_UINT32 opj_uint_subs(OPJ_UINT32 a, OPJ_UINT32 b)
|
||||
{
|
||||
return (a >= b) ? a - b : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Clamp an integer inside an interval
|
||||
@return
|
||||
<ul>
|
||||
<li>Returns a if (min < a < max)
|
||||
<li>Returns max if (a > max)
|
||||
<li>Returns min if (a < min)
|
||||
</ul>
|
||||
*/
|
||||
static INLINE OPJ_INT32 opj_int_clamp(OPJ_INT32 a, OPJ_INT32 min,
|
||||
OPJ_INT32 max)
|
||||
{
|
||||
if (a < min) {
|
||||
return min;
|
||||
}
|
||||
if (a > max) {
|
||||
return max;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
Clamp an integer inside an interval
|
||||
@return
|
||||
<ul>
|
||||
<li>Returns a if (min < a < max)
|
||||
<li>Returns max if (a > max)
|
||||
<li>Returns min if (a < min)
|
||||
</ul>
|
||||
*/
|
||||
static INLINE OPJ_INT64 opj_int64_clamp(OPJ_INT64 a, OPJ_INT64 min,
|
||||
OPJ_INT64 max)
|
||||
{
|
||||
if (a < min) {
|
||||
return min;
|
||||
}
|
||||
if (a > max) {
|
||||
return max;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
@return Get absolute value of integer
|
||||
*/
|
||||
static INLINE OPJ_INT32 opj_int_abs(OPJ_INT32 a)
|
||||
{
|
||||
return a < 0 ? -a : a;
|
||||
}
|
||||
/**
|
||||
Divide an integer and round upwards
|
||||
@return Returns a divided by b
|
||||
*/
|
||||
static INLINE OPJ_INT32 opj_int_ceildiv(OPJ_INT32 a, OPJ_INT32 b)
|
||||
{
|
||||
assert(b);
|
||||
return (OPJ_INT32)(((OPJ_INT64)a + b - 1) / b);
|
||||
}
|
||||
|
||||
/**
|
||||
Divide an integer and round upwards
|
||||
@return Returns a divided by b
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
Divide an integer by a power of 2 and round upwards
|
||||
@return Returns a divided by 2^b
|
||||
*/
|
||||
static INLINE OPJ_INT32 opj_int_ceildivpow2(OPJ_INT32 a, OPJ_INT32 b)
|
||||
{
|
||||
return (OPJ_INT32)((a + ((OPJ_INT64)1 << b) - 1) >> b);
|
||||
}
|
||||
|
||||
/**
|
||||
Divide a 64bits integer by a power of 2 and round upwards
|
||||
@return Returns a divided by 2^b
|
||||
*/
|
||||
static INLINE OPJ_INT32 opj_int64_ceildivpow2(OPJ_INT64 a, OPJ_INT32 b)
|
||||
{
|
||||
return (OPJ_INT32)((a + ((OPJ_INT64)1 << b) - 1) >> b);
|
||||
}
|
||||
|
||||
/**
|
||||
Divide an integer by a power of 2 and round upwards
|
||||
@return Returns a divided by 2^b
|
||||
*/
|
||||
static INLINE OPJ_UINT32 opj_uint_ceildivpow2(OPJ_UINT32 a, OPJ_UINT32 b)
|
||||
{
|
||||
return (OPJ_UINT32)((a + ((OPJ_UINT64)1U << b) - 1U) >> b);
|
||||
}
|
||||
|
||||
/**
|
||||
Divide an integer by a power of 2 and round downwards
|
||||
@return Returns a divided by 2^b
|
||||
*/
|
||||
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)
|
||||
*/
|
||||
static INLINE OPJ_INT32 opj_int_floorlog2(OPJ_INT32 a)
|
||||
{
|
||||
OPJ_INT32 l;
|
||||
for (l = 0; a > 1; l++) {
|
||||
a >>= 1;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
/**
|
||||
Get logarithm of an integer and round downwards
|
||||
@return Returns log2(a)
|
||||
*/
|
||||
static INLINE OPJ_UINT32 opj_uint_floorlog2(OPJ_UINT32 a)
|
||||
{
|
||||
OPJ_UINT32 l;
|
||||
for (l = 0; a > 1; ++l) {
|
||||
a >>= 1;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
/**
|
||||
Multiply two fixed-precision rational numbers.
|
||||
@param a
|
||||
@param b
|
||||
@return Returns a * b
|
||||
*/
|
||||
static INLINE OPJ_INT32 opj_int_fix_mul(OPJ_INT32 a, OPJ_INT32 b)
|
||||
{
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__INTEL_COMPILER) && defined(_M_IX86)
|
||||
OPJ_INT64 temp = __emul(a, b);
|
||||
#else
|
||||
OPJ_INT64 temp = (OPJ_INT64) a * (OPJ_INT64) b ;
|
||||
#endif
|
||||
temp += 4096;
|
||||
assert((temp >> 13) <= (OPJ_INT64)0x7FFFFFFF);
|
||||
assert((temp >> 13) >= (-(OPJ_INT64)0x7FFFFFFF - (OPJ_INT64)1));
|
||||
return (OPJ_INT32)(temp >> 13);
|
||||
}
|
||||
|
||||
static INLINE OPJ_INT32 opj_int_fix_mul_t1(OPJ_INT32 a, OPJ_INT32 b)
|
||||
{
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__INTEL_COMPILER) && defined(_M_IX86)
|
||||
OPJ_INT64 temp = __emul(a, b);
|
||||
#else
|
||||
OPJ_INT64 temp = (OPJ_INT64) a * (OPJ_INT64) b ;
|
||||
#endif
|
||||
temp += 4096;
|
||||
assert((temp >> (13 + 11 - T1_NMSEDEC_FRACBITS)) <= (OPJ_INT64)0x7FFFFFFF);
|
||||
assert((temp >> (13 + 11 - T1_NMSEDEC_FRACBITS)) >= (-(OPJ_INT64)0x7FFFFFFF -
|
||||
(OPJ_INT64)1));
|
||||
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;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/*@}*/
|
||||
|
||||
/*@}*/
|
||||
|
||||
#endif /* OPJ_INTMATH_H */
|
||||
@@ -0,0 +1,249 @@
|
||||
/*
|
||||
* 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) 2015, Mathieu Malaterre <[email protected]>
|
||||
* Copyright (c) 2015, Matthieu Darbois
|
||||
* 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.
|
||||
*/
|
||||
#define OPJ_SKIP_POISON
|
||||
#include "opj_includes.h"
|
||||
|
||||
#if defined(OPJ_HAVE_MALLOC_H) && defined(OPJ_HAVE_MEMALIGN)
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
# define SIZE_MAX ((size_t) -1)
|
||||
#endif
|
||||
|
||||
static INLINE void *opj_aligned_alloc_n(size_t alignment, size_t size)
|
||||
{
|
||||
void* ptr;
|
||||
|
||||
/* alignment shall be power of 2 */
|
||||
assert((alignment != 0U) && ((alignment & (alignment - 1U)) == 0U));
|
||||
/* alignment shall be at least sizeof(void*) */
|
||||
assert(alignment >= sizeof(void*));
|
||||
|
||||
if (size == 0U) { /* prevent implementation defined behavior of realloc */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(OPJ_HAVE_POSIX_MEMALIGN)
|
||||
/* aligned_alloc requires c11, restrict to posix_memalign for now. Quote:
|
||||
* This function was introduced in POSIX 1003.1d. Although this function is
|
||||
* superseded by aligned_alloc, it is more portable to older POSIX systems
|
||||
* that do not support ISO C11. */
|
||||
if (posix_memalign(&ptr, alignment, size)) {
|
||||
ptr = NULL;
|
||||
}
|
||||
/* older linux */
|
||||
#elif defined(OPJ_HAVE_MEMALIGN)
|
||||
ptr = memalign(alignment, size);
|
||||
/* _MSC_VER */
|
||||
#elif defined(OPJ_HAVE__ALIGNED_MALLOC)
|
||||
ptr = _aligned_malloc(size, alignment);
|
||||
#else
|
||||
/*
|
||||
* Generic aligned malloc implementation.
|
||||
* Uses size_t offset for the integer manipulation of the pointer,
|
||||
* as uintptr_t is not available in C89 to do
|
||||
* bitwise operations on the pointer itself.
|
||||
*/
|
||||
alignment--;
|
||||
{
|
||||
size_t offset;
|
||||
OPJ_UINT8 *mem;
|
||||
|
||||
/* Room for padding and extra pointer stored in front of allocated area */
|
||||
size_t overhead = alignment + sizeof(void *);
|
||||
|
||||
/* let's be extra careful */
|
||||
assert(alignment <= (SIZE_MAX - sizeof(void *)));
|
||||
|
||||
/* Avoid integer overflow */
|
||||
if (size > (SIZE_MAX - overhead)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mem = (OPJ_UINT8*)malloc(size + overhead);
|
||||
if (mem == NULL) {
|
||||
return mem;
|
||||
}
|
||||
/* offset = ((alignment + 1U) - ((size_t)(mem + sizeof(void*)) & alignment)) & alignment; */
|
||||
/* Use the fact that alignment + 1U is a power of 2 */
|
||||
offset = ((alignment ^ ((size_t)(mem + sizeof(void*)) & alignment)) + 1U) &
|
||||
alignment;
|
||||
ptr = (void *)(mem + sizeof(void*) + offset);
|
||||
((void**) ptr)[-1] = mem;
|
||||
}
|
||||
#endif
|
||||
return ptr;
|
||||
}
|
||||
static INLINE void *opj_aligned_realloc_n(void *ptr, size_t alignment,
|
||||
size_t new_size)
|
||||
{
|
||||
void *r_ptr;
|
||||
|
||||
/* alignment shall be power of 2 */
|
||||
assert((alignment != 0U) && ((alignment & (alignment - 1U)) == 0U));
|
||||
/* alignment shall be at least sizeof(void*) */
|
||||
assert(alignment >= sizeof(void*));
|
||||
|
||||
if (new_size == 0U) { /* prevent implementation defined behavior of realloc */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* no portable aligned realloc */
|
||||
#if defined(OPJ_HAVE_POSIX_MEMALIGN) || defined(OPJ_HAVE_MEMALIGN)
|
||||
/* glibc doc states one can mix aligned malloc with realloc */
|
||||
r_ptr = realloc(ptr, new_size); /* fast path */
|
||||
/* we simply use `size_t` to cast, since we are only interest in binary AND
|
||||
* operator */
|
||||
if (((size_t)r_ptr & (alignment - 1U)) != 0U) {
|
||||
/* this is non-trivial to implement a portable aligned realloc, so use a
|
||||
* simple approach where we do not need a function that return the size of an
|
||||
* allocated array (eg. _msize on Windows, malloc_size on MacOS,
|
||||
* malloc_usable_size on systems with glibc) */
|
||||
void *a_ptr = opj_aligned_alloc_n(alignment, new_size);
|
||||
if (a_ptr != NULL) {
|
||||
memcpy(a_ptr, r_ptr, new_size);
|
||||
}
|
||||
free(r_ptr);
|
||||
r_ptr = a_ptr;
|
||||
}
|
||||
/* _MSC_VER */
|
||||
#elif defined(OPJ_HAVE__ALIGNED_MALLOC)
|
||||
r_ptr = _aligned_realloc(ptr, new_size, alignment);
|
||||
#else
|
||||
if (ptr == NULL) {
|
||||
return opj_aligned_alloc_n(alignment, new_size);
|
||||
}
|
||||
alignment--;
|
||||
{
|
||||
void *oldmem;
|
||||
OPJ_UINT8 *newmem;
|
||||
size_t overhead = alignment + sizeof(void *);
|
||||
|
||||
/* let's be extra careful */
|
||||
assert(alignment <= (SIZE_MAX - sizeof(void *)));
|
||||
|
||||
/* Avoid integer overflow */
|
||||
if (new_size > SIZE_MAX - overhead) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
oldmem = ((void**) ptr)[-1];
|
||||
newmem = (OPJ_UINT8*)realloc(oldmem, new_size + overhead);
|
||||
if (newmem == NULL) {
|
||||
return newmem;
|
||||
}
|
||||
|
||||
if (newmem == oldmem) {
|
||||
r_ptr = ptr;
|
||||
} else {
|
||||
size_t old_offset;
|
||||
size_t new_offset;
|
||||
|
||||
/* realloc created a new copy, realign the copied memory block */
|
||||
old_offset = (size_t)((OPJ_UINT8*)ptr - (OPJ_UINT8*)oldmem);
|
||||
|
||||
/* offset = ((alignment + 1U) - ((size_t)(mem + sizeof(void*)) & alignment)) & alignment; */
|
||||
/* Use the fact that alignment + 1U is a power of 2 */
|
||||
new_offset = ((alignment ^ ((size_t)(newmem + sizeof(void*)) & alignment)) +
|
||||
1U) & alignment;
|
||||
new_offset += sizeof(void*);
|
||||
r_ptr = (void *)(newmem + new_offset);
|
||||
|
||||
if (new_offset != old_offset) {
|
||||
memmove(newmem + new_offset, newmem + old_offset, new_size);
|
||||
}
|
||||
((void**) r_ptr)[-1] = newmem;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return r_ptr;
|
||||
}
|
||||
void * opj_malloc(size_t size)
|
||||
{
|
||||
if (size == 0U) { /* prevent implementation defined behavior of realloc */
|
||||
return NULL;
|
||||
}
|
||||
return malloc(size);
|
||||
}
|
||||
void * opj_calloc(size_t num, size_t size)
|
||||
{
|
||||
if (num == 0 || size == 0) {
|
||||
/* prevent implementation defined behavior of realloc */
|
||||
return NULL;
|
||||
}
|
||||
return calloc(num, size);
|
||||
}
|
||||
|
||||
void *opj_aligned_malloc(size_t size)
|
||||
{
|
||||
return opj_aligned_alloc_n(16U, size);
|
||||
}
|
||||
void * opj_aligned_realloc(void *ptr, size_t size)
|
||||
{
|
||||
return opj_aligned_realloc_n(ptr, 16U, size);
|
||||
}
|
||||
|
||||
void *opj_aligned_32_malloc(size_t size)
|
||||
{
|
||||
return opj_aligned_alloc_n(32U, size);
|
||||
}
|
||||
void * opj_aligned_32_realloc(void *ptr, size_t size)
|
||||
{
|
||||
return opj_aligned_realloc_n(ptr, 32U, size);
|
||||
}
|
||||
|
||||
void opj_aligned_free(void* ptr)
|
||||
{
|
||||
#if defined(OPJ_HAVE_POSIX_MEMALIGN) || defined(OPJ_HAVE_MEMALIGN)
|
||||
free(ptr);
|
||||
#elif defined(OPJ_HAVE__ALIGNED_MALLOC)
|
||||
_aligned_free(ptr);
|
||||
#else
|
||||
/* Generic implementation has malloced pointer stored in front of used area */
|
||||
if (ptr != NULL) {
|
||||
free(((void**) ptr)[-1]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void * opj_realloc(void *ptr, size_t new_size)
|
||||
{
|
||||
if (new_size == 0U) { /* prevent implementation defined behavior of realloc */
|
||||
return NULL;
|
||||
}
|
||||
return realloc(ptr, new_size);
|
||||
}
|
||||
void opj_free(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* 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) 2005, Herve Drolon, FreeImage Team
|
||||
* Copyright (c) 2007, Callum Lerwick <[email protected]>
|
||||
* 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 OPJ_MALLOC_H
|
||||
#define OPJ_MALLOC_H
|
||||
|
||||
#include <stddef.h>
|
||||
/**
|
||||
@file opj_malloc.h
|
||||
@brief Internal functions
|
||||
|
||||
The functions in opj_malloc.h are internal utilities used for memory management.
|
||||
*/
|
||||
|
||||
/** @defgroup MISC MISC - Miscellaneous internal functions */
|
||||
/*@{*/
|
||||
|
||||
/** @name Exported functions */
|
||||
/*@{*/
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
Allocate an uninitialized memory block
|
||||
@param size Bytes to allocate
|
||||
@return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available
|
||||
*/
|
||||
void * opj_malloc(size_t size);
|
||||
|
||||
/**
|
||||
Allocate a memory block with elements initialized to 0
|
||||
@param numOfElements Blocks to allocate
|
||||
@param sizeOfElements Bytes per block to allocate
|
||||
@return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available
|
||||
*/
|
||||
void * opj_calloc(size_t numOfElements, size_t sizeOfElements);
|
||||
|
||||
/**
|
||||
Allocate memory aligned to a 16 byte boundary
|
||||
@param size Bytes to allocate
|
||||
@return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available
|
||||
*/
|
||||
void * opj_aligned_malloc(size_t size);
|
||||
void * opj_aligned_realloc(void *ptr, size_t size);
|
||||
void opj_aligned_free(void* ptr);
|
||||
|
||||
/**
|
||||
Allocate memory aligned to a 32 byte boundary
|
||||
@param size Bytes to allocate
|
||||
@return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available
|
||||
*/
|
||||
void * opj_aligned_32_malloc(size_t size);
|
||||
void * opj_aligned_32_realloc(void *ptr, size_t size);
|
||||
|
||||
/**
|
||||
Reallocate memory blocks.
|
||||
@param m Pointer to previously allocated memory block
|
||||
@param s New size in bytes
|
||||
@return Returns a void pointer to the reallocated (and possibly moved) memory block
|
||||
*/
|
||||
void * opj_realloc(void * m, size_t s);
|
||||
|
||||
/**
|
||||
Deallocates or frees a memory block.
|
||||
@param m Previously allocated memory block to be freed
|
||||
*/
|
||||
void opj_free(void * m);
|
||||
|
||||
#if defined(__GNUC__) && !defined(OPJ_SKIP_POISON)
|
||||
#pragma GCC poison malloc calloc realloc free
|
||||
#endif
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/*@}*/
|
||||
|
||||
/*@}*/
|
||||
|
||||
#endif /* OPJ_MALLOC_H */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* 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 OPJ_PI_H
|
||||
#define OPJ_PI_H
|
||||
/**
|
||||
@file pi.h
|
||||
@brief Implementation of a packet iterator (PI)
|
||||
|
||||
The functions in PI.C have for goal to realize a packet iterator that permits to get the next
|
||||
packet following the progression order and change of it. The functions in PI.C are used
|
||||
by some function in T2.C.
|
||||
*/
|
||||
|
||||
/** @defgroup PI PI - Implementation of a packet iterator */
|
||||
/*@{*/
|
||||
|
||||
/**
|
||||
FIXME DOC
|
||||
*/
|
||||
typedef struct opj_pi_resolution {
|
||||
OPJ_UINT32 pdx, pdy;
|
||||
OPJ_UINT32 pw, ph;
|
||||
} opj_pi_resolution_t;
|
||||
|
||||
/**
|
||||
FIXME DOC
|
||||
*/
|
||||
typedef struct opj_pi_comp {
|
||||
OPJ_UINT32 dx, dy;
|
||||
/** number of resolution levels */
|
||||
OPJ_UINT32 numresolutions;
|
||||
opj_pi_resolution_t *resolutions;
|
||||
} opj_pi_comp_t;
|
||||
|
||||
/**
|
||||
Packet iterator
|
||||
*/
|
||||
typedef struct opj_pi_iterator {
|
||||
/** Enabling Tile part generation*/
|
||||
OPJ_BYTE tp_on;
|
||||
/** precise if the packet has been already used (useful for progression order change) */
|
||||
OPJ_INT16 *include;
|
||||
/** Number of elements in include array */
|
||||
OPJ_UINT32 include_size;
|
||||
/** layer step used to localize the packet in the include vector */
|
||||
OPJ_UINT32 step_l;
|
||||
/** resolution step used to localize the packet in the include vector */
|
||||
OPJ_UINT32 step_r;
|
||||
/** component step used to localize the packet in the include vector */
|
||||
OPJ_UINT32 step_c;
|
||||
/** precinct step used to localize the packet in the include vector */
|
||||
OPJ_UINT32 step_p;
|
||||
/** component that identify the packet */
|
||||
OPJ_UINT32 compno;
|
||||
/** resolution that identify the packet */
|
||||
OPJ_UINT32 resno;
|
||||
/** precinct that identify the packet */
|
||||
OPJ_UINT32 precno;
|
||||
/** layer that identify the packet */
|
||||
OPJ_UINT32 layno;
|
||||
/** 0 if the first packet */
|
||||
OPJ_BOOL first;
|
||||
/** progression order change information */
|
||||
opj_poc_t poc;
|
||||
/** number of components in the image */
|
||||
OPJ_UINT32 numcomps;
|
||||
/** Components*/
|
||||
opj_pi_comp_t *comps;
|
||||
/** FIXME DOC*/
|
||||
OPJ_UINT32 tx0, ty0, tx1, ty1;
|
||||
/** FIXME DOC*/
|
||||
OPJ_UINT32 x, y;
|
||||
/** FIXME DOC*/
|
||||
OPJ_UINT32 dx, dy;
|
||||
/** event manager */
|
||||
opj_event_mgr_t* manager;
|
||||
} opj_pi_iterator_t;
|
||||
|
||||
/** @name Exported functions */
|
||||
/*@{*/
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/**
|
||||
* Creates a packet iterator for encoding.
|
||||
*
|
||||
* @param image the image being encoded.
|
||||
* @param cp the coding parameters.
|
||||
* @param tileno index of the tile being encoded.
|
||||
* @param t2_mode the type of pass for generating the packet iterator
|
||||
* @param manager Event manager
|
||||
*
|
||||
* @return a list of packet iterator that points to the first packet of the tile (not true).
|
||||
*/
|
||||
opj_pi_iterator_t *opj_pi_initialise_encode(const opj_image_t *image,
|
||||
opj_cp_t *cp,
|
||||
OPJ_UINT32 tileno,
|
||||
J2K_T2_MODE t2_mode,
|
||||
opj_event_mgr_t* manager);
|
||||
|
||||
/**
|
||||
* Updates the encoding parameters of the codec.
|
||||
*
|
||||
* @param p_image the image being encoded.
|
||||
* @param p_cp the coding parameters.
|
||||
* @param p_tile_no index of the tile being encoded.
|
||||
*/
|
||||
void opj_pi_update_encoding_parameters(const opj_image_t *p_image,
|
||||
opj_cp_t *p_cp,
|
||||
OPJ_UINT32 p_tile_no);
|
||||
|
||||
/**
|
||||
Modify the packet iterator for enabling tile part generation
|
||||
@param pi Handle to the packet iterator generated in pi_initialise_encode
|
||||
@param cp Coding parameters
|
||||
@param tileno Number that identifies the tile for which to list the packets
|
||||
@param pino FIXME DOC
|
||||
@param tpnum Tile part number of the current tile
|
||||
@param tppos The position of the tile part flag in the progression order
|
||||
@param t2_mode FIXME DOC
|
||||
*/
|
||||
void opj_pi_create_encode(opj_pi_iterator_t *pi,
|
||||
opj_cp_t *cp,
|
||||
OPJ_UINT32 tileno,
|
||||
OPJ_UINT32 pino,
|
||||
OPJ_UINT32 tpnum,
|
||||
OPJ_INT32 tppos,
|
||||
J2K_T2_MODE t2_mode);
|
||||
|
||||
/**
|
||||
Create a packet iterator for Decoder
|
||||
@param image Raw image for which the packets will be listed
|
||||
@param cp Coding parameters
|
||||
@param tileno Number that identifies the tile for which to list the packets
|
||||
@param manager Event manager
|
||||
@return Returns a packet iterator that points to the first packet of the tile
|
||||
@see opj_pi_destroy
|
||||
*/
|
||||
opj_pi_iterator_t *opj_pi_create_decode(opj_image_t * image,
|
||||
opj_cp_t * cp,
|
||||
OPJ_UINT32 tileno,
|
||||
opj_event_mgr_t* manager);
|
||||
/**
|
||||
* Destroys a packet iterator array.
|
||||
*
|
||||
* @param p_pi the packet iterator array to destroy.
|
||||
* @param p_nb_elements the number of elements in the array.
|
||||
*/
|
||||
void opj_pi_destroy(opj_pi_iterator_t *p_pi,
|
||||
OPJ_UINT32 p_nb_elements);
|
||||
|
||||
/**
|
||||
Modify the packet iterator to point to the next packet
|
||||
@param pi Packet iterator to modify
|
||||
@return Returns false if pi pointed to the last packet or else returns true
|
||||
*/
|
||||
OPJ_BOOL opj_pi_next(opj_pi_iterator_t * pi);
|
||||
|
||||
/**
|
||||
* Return the number of packets in the tile.
|
||||
* @param image the image being encoded.
|
||||
* @param cp Coding parameters
|
||||
* @param tileno Number that identifies the tile.
|
||||
*/
|
||||
OPJ_UINT32 opj_get_encoding_packet_count(const opj_image_t *p_image,
|
||||
const opj_cp_t *p_cp,
|
||||
OPJ_UINT32 p_tile_no);
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/*@}*/
|
||||
|
||||
/*@}*/
|
||||
|
||||
#endif /* OPJ_PI_H */
|
||||
@@ -0,0 +1,346 @@
|
||||
/*
|
||||
* 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) 2017, IntoPix SA <[email protected]>
|
||||
* 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 "opj_includes.h"
|
||||
|
||||
|
||||
struct opj_sparse_array_int32 {
|
||||
OPJ_UINT32 width;
|
||||
OPJ_UINT32 height;
|
||||
OPJ_UINT32 block_width;
|
||||
OPJ_UINT32 block_height;
|
||||
OPJ_UINT32 block_count_hor;
|
||||
OPJ_UINT32 block_count_ver;
|
||||
OPJ_INT32** data_blocks;
|
||||
};
|
||||
|
||||
opj_sparse_array_int32_t* opj_sparse_array_int32_create(OPJ_UINT32 width,
|
||||
OPJ_UINT32 height,
|
||||
OPJ_UINT32 block_width,
|
||||
OPJ_UINT32 block_height)
|
||||
{
|
||||
opj_sparse_array_int32_t* sa;
|
||||
|
||||
if (width == 0 || height == 0 || block_width == 0 || block_height == 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (block_width > ((OPJ_UINT32)~0U) / block_height / sizeof(OPJ_INT32)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sa = (opj_sparse_array_int32_t*) opj_calloc(1,
|
||||
sizeof(opj_sparse_array_int32_t));
|
||||
sa->width = width;
|
||||
sa->height = height;
|
||||
sa->block_width = block_width;
|
||||
sa->block_height = block_height;
|
||||
sa->block_count_hor = opj_uint_ceildiv(width, block_width);
|
||||
sa->block_count_ver = opj_uint_ceildiv(height, block_height);
|
||||
if (sa->block_count_hor > ((OPJ_UINT32)~0U) / sa->block_count_ver) {
|
||||
opj_free(sa);
|
||||
return NULL;
|
||||
}
|
||||
sa->data_blocks = (OPJ_INT32**) opj_calloc(sizeof(OPJ_INT32*),
|
||||
(size_t) sa->block_count_hor * sa->block_count_ver);
|
||||
if (sa->data_blocks == NULL) {
|
||||
opj_free(sa);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return sa;
|
||||
}
|
||||
|
||||
void opj_sparse_array_int32_free(opj_sparse_array_int32_t* sa)
|
||||
{
|
||||
if (sa) {
|
||||
OPJ_UINT32 i;
|
||||
for (i = 0; i < sa->block_count_hor * sa->block_count_ver; i++) {
|
||||
if (sa->data_blocks[i]) {
|
||||
opj_free(sa->data_blocks[i]);
|
||||
}
|
||||
}
|
||||
opj_free(sa->data_blocks);
|
||||
opj_free(sa);
|
||||
}
|
||||
}
|
||||
|
||||
OPJ_BOOL opj_sparse_array_is_region_valid(const opj_sparse_array_int32_t* sa,
|
||||
OPJ_UINT32 x0,
|
||||
OPJ_UINT32 y0,
|
||||
OPJ_UINT32 x1,
|
||||
OPJ_UINT32 y1)
|
||||
{
|
||||
return !(x0 >= sa->width || x1 <= x0 || x1 > sa->width ||
|
||||
y0 >= sa->height || y1 <= y0 || y1 > sa->height);
|
||||
}
|
||||
|
||||
static OPJ_BOOL opj_sparse_array_int32_read_or_write(
|
||||
const opj_sparse_array_int32_t* sa,
|
||||
OPJ_UINT32 x0,
|
||||
OPJ_UINT32 y0,
|
||||
OPJ_UINT32 x1,
|
||||
OPJ_UINT32 y1,
|
||||
OPJ_INT32* buf,
|
||||
OPJ_UINT32 buf_col_stride,
|
||||
OPJ_UINT32 buf_line_stride,
|
||||
OPJ_BOOL forgiving,
|
||||
OPJ_BOOL is_read_op)
|
||||
{
|
||||
OPJ_UINT32 y, block_y;
|
||||
OPJ_UINT32 y_incr = 0;
|
||||
const OPJ_UINT32 block_width = sa->block_width;
|
||||
|
||||
if (!opj_sparse_array_is_region_valid(sa, x0, y0, x1, y1)) {
|
||||
return forgiving;
|
||||
}
|
||||
|
||||
block_y = y0 / sa->block_height;
|
||||
for (y = y0; y < y1; block_y ++, y += y_incr) {
|
||||
OPJ_UINT32 x, block_x;
|
||||
OPJ_UINT32 x_incr = 0;
|
||||
OPJ_UINT32 block_y_offset;
|
||||
y_incr = (y == y0) ? sa->block_height - (y0 % sa->block_height) :
|
||||
sa->block_height;
|
||||
block_y_offset = sa->block_height - y_incr;
|
||||
y_incr = opj_uint_min(y_incr, y1 - y);
|
||||
block_x = x0 / block_width;
|
||||
for (x = x0; x < x1; block_x ++, x += x_incr) {
|
||||
OPJ_UINT32 j;
|
||||
OPJ_UINT32 block_x_offset;
|
||||
OPJ_INT32* src_block;
|
||||
x_incr = (x == x0) ? block_width - (x0 % block_width) : block_width;
|
||||
block_x_offset = block_width - x_incr;
|
||||
x_incr = opj_uint_min(x_incr, x1 - x);
|
||||
src_block = sa->data_blocks[block_y * sa->block_count_hor + block_x];
|
||||
if (is_read_op) {
|
||||
if (src_block == NULL) {
|
||||
if (buf_col_stride == 1) {
|
||||
OPJ_INT32* dest_ptr = buf + (y - y0) * (OPJ_SIZE_T)buf_line_stride +
|
||||
(x - x0) * buf_col_stride;
|
||||
for (j = 0; j < y_incr; j++) {
|
||||
memset(dest_ptr, 0, sizeof(OPJ_INT32) * x_incr);
|
||||
dest_ptr += buf_line_stride;
|
||||
}
|
||||
} else {
|
||||
OPJ_INT32* dest_ptr = buf + (y - y0) * (OPJ_SIZE_T)buf_line_stride +
|
||||
(x - x0) * buf_col_stride;
|
||||
for (j = 0; j < y_incr; j++) {
|
||||
OPJ_UINT32 k;
|
||||
for (k = 0; k < x_incr; k++) {
|
||||
dest_ptr[k * buf_col_stride] = 0;
|
||||
}
|
||||
dest_ptr += buf_line_stride;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const OPJ_INT32* OPJ_RESTRICT src_ptr = src_block + block_y_offset *
|
||||
(OPJ_SIZE_T)block_width + block_x_offset;
|
||||
if (buf_col_stride == 1) {
|
||||
OPJ_INT32* OPJ_RESTRICT dest_ptr = buf + (y - y0) * (OPJ_SIZE_T)buf_line_stride
|
||||
+
|
||||
(x - x0) * buf_col_stride;
|
||||
if (x_incr == 4) {
|
||||
/* Same code as general branch, but the compiler */
|
||||
/* can have an efficient memcpy() */
|
||||
(void)(x_incr); /* trick to silent cppcheck duplicateBranch warning */
|
||||
for (j = 0; j < y_incr; j++) {
|
||||
memcpy(dest_ptr, src_ptr, sizeof(OPJ_INT32) * x_incr);
|
||||
dest_ptr += buf_line_stride;
|
||||
src_ptr += block_width;
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < y_incr; j++) {
|
||||
memcpy(dest_ptr, src_ptr, sizeof(OPJ_INT32) * x_incr);
|
||||
dest_ptr += buf_line_stride;
|
||||
src_ptr += block_width;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
OPJ_INT32* OPJ_RESTRICT dest_ptr = buf + (y - y0) * (OPJ_SIZE_T)buf_line_stride
|
||||
+
|
||||
(x - x0) * buf_col_stride;
|
||||
if (x_incr == 1) {
|
||||
for (j = 0; j < y_incr; j++) {
|
||||
*dest_ptr = *src_ptr;
|
||||
dest_ptr += buf_line_stride;
|
||||
src_ptr += block_width;
|
||||
}
|
||||
} else if (y_incr == 1 && buf_col_stride == 2) {
|
||||
OPJ_UINT32 k;
|
||||
for (k = 0; k < (x_incr & ~3U); k += 4) {
|
||||
dest_ptr[k * buf_col_stride] = src_ptr[k];
|
||||
dest_ptr[(k + 1) * buf_col_stride] = src_ptr[k + 1];
|
||||
dest_ptr[(k + 2) * buf_col_stride] = src_ptr[k + 2];
|
||||
dest_ptr[(k + 3) * buf_col_stride] = src_ptr[k + 3];
|
||||
}
|
||||
for (; k < x_incr; k++) {
|
||||
dest_ptr[k * buf_col_stride] = src_ptr[k];
|
||||
}
|
||||
} else if (x_incr >= 8 && buf_col_stride == 8) {
|
||||
for (j = 0; j < y_incr; j++) {
|
||||
OPJ_UINT32 k;
|
||||
for (k = 0; k < (x_incr & ~3U); k += 4) {
|
||||
dest_ptr[k * buf_col_stride] = src_ptr[k];
|
||||
dest_ptr[(k + 1) * buf_col_stride] = src_ptr[k + 1];
|
||||
dest_ptr[(k + 2) * buf_col_stride] = src_ptr[k + 2];
|
||||
dest_ptr[(k + 3) * buf_col_stride] = src_ptr[k + 3];
|
||||
}
|
||||
for (; k < x_incr; k++) {
|
||||
dest_ptr[k * buf_col_stride] = src_ptr[k];
|
||||
}
|
||||
dest_ptr += buf_line_stride;
|
||||
src_ptr += block_width;
|
||||
}
|
||||
} else {
|
||||
/* General case */
|
||||
for (j = 0; j < y_incr; j++) {
|
||||
OPJ_UINT32 k;
|
||||
for (k = 0; k < x_incr; k++) {
|
||||
dest_ptr[k * buf_col_stride] = src_ptr[k];
|
||||
}
|
||||
dest_ptr += buf_line_stride;
|
||||
src_ptr += block_width;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (src_block == NULL) {
|
||||
src_block = (OPJ_INT32*) opj_calloc(1,
|
||||
(size_t) sa->block_width * sa->block_height * sizeof(OPJ_INT32));
|
||||
if (src_block == NULL) {
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
sa->data_blocks[block_y * sa->block_count_hor + block_x] = src_block;
|
||||
}
|
||||
|
||||
if (buf_col_stride == 1) {
|
||||
OPJ_INT32* OPJ_RESTRICT dest_ptr = src_block + block_y_offset *
|
||||
(OPJ_SIZE_T)block_width + block_x_offset;
|
||||
const OPJ_INT32* OPJ_RESTRICT src_ptr = buf + (y - y0) *
|
||||
(OPJ_SIZE_T)buf_line_stride + (x - x0) * buf_col_stride;
|
||||
if (x_incr == 4) {
|
||||
/* Same code as general branch, but the compiler */
|
||||
/* can have an efficient memcpy() */
|
||||
(void)(x_incr); /* trick to silent cppcheck duplicateBranch warning */
|
||||
for (j = 0; j < y_incr; j++) {
|
||||
memcpy(dest_ptr, src_ptr, sizeof(OPJ_INT32) * x_incr);
|
||||
dest_ptr += block_width;
|
||||
src_ptr += buf_line_stride;
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < y_incr; j++) {
|
||||
memcpy(dest_ptr, src_ptr, sizeof(OPJ_INT32) * x_incr);
|
||||
dest_ptr += block_width;
|
||||
src_ptr += buf_line_stride;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
OPJ_INT32* OPJ_RESTRICT dest_ptr = src_block + block_y_offset *
|
||||
(OPJ_SIZE_T)block_width + block_x_offset;
|
||||
const OPJ_INT32* OPJ_RESTRICT src_ptr = buf + (y - y0) *
|
||||
(OPJ_SIZE_T)buf_line_stride + (x - x0) * buf_col_stride;
|
||||
if (x_incr == 1) {
|
||||
for (j = 0; j < y_incr; j++) {
|
||||
*dest_ptr = *src_ptr;
|
||||
src_ptr += buf_line_stride;
|
||||
dest_ptr += block_width;
|
||||
}
|
||||
} else if (x_incr >= 8 && buf_col_stride == 8) {
|
||||
for (j = 0; j < y_incr; j++) {
|
||||
OPJ_UINT32 k;
|
||||
for (k = 0; k < (x_incr & ~3U); k += 4) {
|
||||
dest_ptr[k] = src_ptr[k * buf_col_stride];
|
||||
dest_ptr[k + 1] = src_ptr[(k + 1) * buf_col_stride];
|
||||
dest_ptr[k + 2] = src_ptr[(k + 2) * buf_col_stride];
|
||||
dest_ptr[k + 3] = src_ptr[(k + 3) * buf_col_stride];
|
||||
}
|
||||
for (; k < x_incr; k++) {
|
||||
dest_ptr[k] = src_ptr[k * buf_col_stride];
|
||||
}
|
||||
src_ptr += buf_line_stride;
|
||||
dest_ptr += block_width;
|
||||
}
|
||||
} else {
|
||||
/* General case */
|
||||
for (j = 0; j < y_incr; j++) {
|
||||
OPJ_UINT32 k;
|
||||
for (k = 0; k < x_incr; k++) {
|
||||
dest_ptr[k] = src_ptr[k * buf_col_stride];
|
||||
}
|
||||
src_ptr += buf_line_stride;
|
||||
dest_ptr += block_width;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
OPJ_BOOL opj_sparse_array_int32_read(const opj_sparse_array_int32_t* sa,
|
||||
OPJ_UINT32 x0,
|
||||
OPJ_UINT32 y0,
|
||||
OPJ_UINT32 x1,
|
||||
OPJ_UINT32 y1,
|
||||
OPJ_INT32* dest,
|
||||
OPJ_UINT32 dest_col_stride,
|
||||
OPJ_UINT32 dest_line_stride,
|
||||
OPJ_BOOL forgiving)
|
||||
{
|
||||
return opj_sparse_array_int32_read_or_write(
|
||||
(opj_sparse_array_int32_t*)sa, x0, y0, x1, y1,
|
||||
dest,
|
||||
dest_col_stride,
|
||||
dest_line_stride,
|
||||
forgiving,
|
||||
OPJ_TRUE);
|
||||
}
|
||||
|
||||
OPJ_BOOL opj_sparse_array_int32_write(opj_sparse_array_int32_t* sa,
|
||||
OPJ_UINT32 x0,
|
||||
OPJ_UINT32 y0,
|
||||
OPJ_UINT32 x1,
|
||||
OPJ_UINT32 y1,
|
||||
const OPJ_INT32* src,
|
||||
OPJ_UINT32 src_col_stride,
|
||||
OPJ_UINT32 src_line_stride,
|
||||
OPJ_BOOL forgiving)
|
||||
{
|
||||
return opj_sparse_array_int32_read_or_write(sa, x0, y0, x1, y1,
|
||||
(OPJ_INT32*)src,
|
||||
src_col_stride,
|
||||
src_line_stride,
|
||||
forgiving,
|
||||
OPJ_FALSE);
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* 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) 2017, IntoPix SA <[email protected]>
|
||||
* 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 "opj_includes.h"
|
||||
|
||||
#ifndef OPJ_SPARSE_ARRAY_H
|
||||
#define OPJ_SPARSE_ARRAY_H
|
||||
/**
|
||||
@file sparse_array.h
|
||||
@brief Sparse array management
|
||||
|
||||
The functions in this file manage sparse arrays. Sparse arrays are arrays with
|
||||
potential big dimensions, but with very few samples actually set. Such sparse
|
||||
arrays require allocating a low amount of memory, by just allocating memory
|
||||
for blocks of the array that are set. The minimum memory allocation unit is a
|
||||
a block. There is a trade-off to pick up an appropriate dimension for blocks.
|
||||
If it is too big, and pixels set are far from each other, too much memory will
|
||||
be used. If blocks are too small, the book-keeping costs of blocks will raise.
|
||||
*/
|
||||
|
||||
/** @defgroup SPARSE_ARRAY SPARSE ARRAYS - Sparse arrays */
|
||||
/*@{*/
|
||||
|
||||
/** Opaque type for sparse arrays that contain int32 values */
|
||||
typedef struct opj_sparse_array_int32 opj_sparse_array_int32_t;
|
||||
|
||||
/** Creates a new sparse array.
|
||||
* @param width total width of the array.
|
||||
* @param height total height of the array
|
||||
* @param block_width width of a block.
|
||||
* @param block_height height of a block.
|
||||
* @return a new sparse array instance, or NULL in case of failure.
|
||||
*/
|
||||
opj_sparse_array_int32_t* opj_sparse_array_int32_create(OPJ_UINT32 width,
|
||||
OPJ_UINT32 height,
|
||||
OPJ_UINT32 block_width,
|
||||
OPJ_UINT32 block_height);
|
||||
|
||||
/** Frees a sparse array.
|
||||
* @param sa sparse array instance.
|
||||
*/
|
||||
void opj_sparse_array_int32_free(opj_sparse_array_int32_t* sa);
|
||||
|
||||
/** Returns whether region bounds are valid (non empty and within array bounds)
|
||||
* @param sa sparse array instance.
|
||||
* @param x0 left x coordinate of the region.
|
||||
* @param y0 top x coordinate of the region.
|
||||
* @param x1 right x coordinate (not included) of the region. Must be greater than x0.
|
||||
* @param y1 bottom y coordinate (not included) of the region. Must be greater than y0.
|
||||
* @return OPJ_TRUE or OPJ_FALSE.
|
||||
*/
|
||||
OPJ_BOOL opj_sparse_array_is_region_valid(const opj_sparse_array_int32_t* sa,
|
||||
OPJ_UINT32 x0,
|
||||
OPJ_UINT32 y0,
|
||||
OPJ_UINT32 x1,
|
||||
OPJ_UINT32 y1);
|
||||
|
||||
/** Read the content of a rectangular region of the sparse array into a
|
||||
* user buffer.
|
||||
*
|
||||
* Regions not written with opj_sparse_array_int32_write() are read as 0.
|
||||
*
|
||||
* @param sa sparse array instance.
|
||||
* @param x0 left x coordinate of the region to read in the sparse array.
|
||||
* @param y0 top x coordinate of the region to read in the sparse array.
|
||||
* @param x1 right x coordinate (not included) of the region to read in the sparse array. Must be greater than x0.
|
||||
* @param y1 bottom y coordinate (not included) of the region to read in the sparse array. Must be greater than y0.
|
||||
* @param dest user buffer to fill. Must be at least sizeof(int32) * ( (y1 - y0 - 1) * dest_line_stride + (x1 - x0 - 1) * dest_col_stride + 1) bytes large.
|
||||
* @param dest_col_stride spacing (in elements, not in bytes) in x dimension between consecutive elements of the user buffer.
|
||||
* @param dest_line_stride spacing (in elements, not in bytes) in y dimension between consecutive elements of the user buffer.
|
||||
* @param forgiving if set to TRUE and the region is invalid, OPJ_TRUE will still be returned.
|
||||
* @return OPJ_TRUE in case of success.
|
||||
*/
|
||||
OPJ_BOOL opj_sparse_array_int32_read(const opj_sparse_array_int32_t* sa,
|
||||
OPJ_UINT32 x0,
|
||||
OPJ_UINT32 y0,
|
||||
OPJ_UINT32 x1,
|
||||
OPJ_UINT32 y1,
|
||||
OPJ_INT32* dest,
|
||||
OPJ_UINT32 dest_col_stride,
|
||||
OPJ_UINT32 dest_line_stride,
|
||||
OPJ_BOOL forgiving);
|
||||
|
||||
|
||||
/** Write the content of a rectangular region into the sparse array from a
|
||||
* user buffer.
|
||||
*
|
||||
* Blocks intersecting the region are allocated, if not already done.
|
||||
*
|
||||
* @param sa sparse array instance.
|
||||
* @param x0 left x coordinate of the region to write into the sparse array.
|
||||
* @param y0 top x coordinate of the region to write into the sparse array.
|
||||
* @param x1 right x coordinate (not included) of the region to write into the sparse array. Must be greater than x0.
|
||||
* @param y1 bottom y coordinate (not included) of the region to write into the sparse array. Must be greater than y0.
|
||||
* @param src user buffer to fill. Must be at least sizeof(int32) * ( (y1 - y0 - 1) * src_line_stride + (x1 - x0 - 1) * src_col_stride + 1) bytes large.
|
||||
* @param src_col_stride spacing (in elements, not in bytes) in x dimension between consecutive elements of the user buffer.
|
||||
* @param src_line_stride spacing (in elements, not in bytes) in y dimension between consecutive elements of the user buffer.
|
||||
* @param forgiving if set to TRUE and the region is invalid, OPJ_TRUE will still be returned.
|
||||
* @return OPJ_TRUE in case of success.
|
||||
*/
|
||||
OPJ_BOOL opj_sparse_array_int32_write(opj_sparse_array_int32_t* sa,
|
||||
OPJ_UINT32 x0,
|
||||
OPJ_UINT32 y0,
|
||||
OPJ_UINT32 x1,
|
||||
OPJ_UINT32 y1,
|
||||
const OPJ_INT32* src,
|
||||
OPJ_UINT32 src_col_stride,
|
||||
OPJ_UINT32 src_line_stride,
|
||||
OPJ_BOOL forgiving);
|
||||
|
||||
/*@}*/
|
||||
|
||||
#endif /* OPJ_SPARSE_ARRAY_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
* 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) 2012, Carl Hetherington
|
||||
* Copyright (c) 2017, IntoPIX SA <[email protected]>
|
||||
* 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 OPJ_T1_H
|
||||
#define OPJ_T1_H
|
||||
/**
|
||||
@file t1.h
|
||||
@brief Implementation of the tier-1 coding (coding of code-block coefficients) (T1)
|
||||
|
||||
The functions in T1.C have for goal to realize the tier-1 coding operation. The functions
|
||||
in T1.C are used by some function in TCD.C.
|
||||
*/
|
||||
|
||||
/** @defgroup T1 T1 - Implementation of the tier-1 coding */
|
||||
/*@{*/
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
#define T1_NMSEDEC_BITS 7
|
||||
|
||||
#define T1_NUMCTXS_ZC 9
|
||||
#define T1_NUMCTXS_SC 5
|
||||
#define T1_NUMCTXS_MAG 3
|
||||
#define T1_NUMCTXS_AGG 1
|
||||
#define T1_NUMCTXS_UNI 1
|
||||
|
||||
#define T1_CTXNO_ZC 0
|
||||
#define T1_CTXNO_SC (T1_CTXNO_ZC+T1_NUMCTXS_ZC)
|
||||
#define T1_CTXNO_MAG (T1_CTXNO_SC+T1_NUMCTXS_SC)
|
||||
#define T1_CTXNO_AGG (T1_CTXNO_MAG+T1_NUMCTXS_MAG)
|
||||
#define T1_CTXNO_UNI (T1_CTXNO_AGG+T1_NUMCTXS_AGG)
|
||||
#define T1_NUMCTXS (T1_CTXNO_UNI+T1_NUMCTXS_UNI)
|
||||
|
||||
#define T1_NMSEDEC_FRACBITS (T1_NMSEDEC_BITS-1)
|
||||
|
||||
#define T1_TYPE_MQ 0 /**< Normal coding using entropy coder */
|
||||
#define T1_TYPE_RAW 1 /**< No encoding the information is store under raw format in codestream (mode switch RAW)*/
|
||||
|
||||
/* BEGINNING of flags that apply to opj_flag_t */
|
||||
/** We hold the state of individual data points for the T1 encoder using
|
||||
* a single 32-bit flags word to hold the state of 4 data points. This corresponds
|
||||
* to the 4-point-high columns that the data is processed in.
|
||||
*
|
||||
* These \#defines declare the layout of a 32-bit flags word.
|
||||
*
|
||||
* This is currently done for encoding only.
|
||||
* The values must NOT be changed, otherwise this is going to break a lot of
|
||||
* assumptions.
|
||||
*/
|
||||
|
||||
/* SIGMA: significance state (3 cols x 6 rows)
|
||||
* CHI: state for negative sample value (1 col x 6 rows)
|
||||
* MU: state for visited in refinement pass (1 col x 4 rows)
|
||||
* PI: state for visited in significance pass (1 col * 4 rows)
|
||||
*/
|
||||
|
||||
#define T1_SIGMA_0 (1U << 0)
|
||||
#define T1_SIGMA_1 (1U << 1)
|
||||
#define T1_SIGMA_2 (1U << 2)
|
||||
#define T1_SIGMA_3 (1U << 3)
|
||||
#define T1_SIGMA_4 (1U << 4)
|
||||
#define T1_SIGMA_5 (1U << 5)
|
||||
#define T1_SIGMA_6 (1U << 6)
|
||||
#define T1_SIGMA_7 (1U << 7)
|
||||
#define T1_SIGMA_8 (1U << 8)
|
||||
#define T1_SIGMA_9 (1U << 9)
|
||||
#define T1_SIGMA_10 (1U << 10)
|
||||
#define T1_SIGMA_11 (1U << 11)
|
||||
#define T1_SIGMA_12 (1U << 12)
|
||||
#define T1_SIGMA_13 (1U << 13)
|
||||
#define T1_SIGMA_14 (1U << 14)
|
||||
#define T1_SIGMA_15 (1U << 15)
|
||||
#define T1_SIGMA_16 (1U << 16)
|
||||
#define T1_SIGMA_17 (1U << 17)
|
||||
|
||||
#define T1_CHI_0 (1U << 18)
|
||||
#define T1_CHI_0_I 18
|
||||
#define T1_CHI_1 (1U << 19)
|
||||
#define T1_CHI_1_I 19
|
||||
#define T1_MU_0 (1U << 20)
|
||||
#define T1_PI_0 (1U << 21)
|
||||
#define T1_CHI_2 (1U << 22)
|
||||
#define T1_CHI_2_I 22
|
||||
#define T1_MU_1 (1U << 23)
|
||||
#define T1_PI_1 (1U << 24)
|
||||
#define T1_CHI_3 (1U << 25)
|
||||
#define T1_MU_2 (1U << 26)
|
||||
#define T1_PI_2 (1U << 27)
|
||||
#define T1_CHI_4 (1U << 28)
|
||||
#define T1_MU_3 (1U << 29)
|
||||
#define T1_PI_3 (1U << 30)
|
||||
#define T1_CHI_5 (1U << 31)
|
||||
#define T1_CHI_5_I 31
|
||||
|
||||
/** As an example, the bits T1_SIGMA_3, T1_SIGMA_4 and T1_SIGMA_5
|
||||
* indicate the significance state of the west neighbour of data point zero
|
||||
* of our four, the point itself, and its east neighbour respectively.
|
||||
* Many of the bits are arranged so that given a flags word, you can
|
||||
* look at the values for the data point 0, then shift the flags
|
||||
* word right by 3 bits and look at the same bit positions to see the
|
||||
* values for data point 1.
|
||||
*
|
||||
* The \#defines below help a bit with this; say you have a flags word
|
||||
* f, you can do things like
|
||||
*
|
||||
* (f & T1_SIGMA_THIS)
|
||||
*
|
||||
* to see the significance bit of data point 0, then do
|
||||
*
|
||||
* ((f >> 3) & T1_SIGMA_THIS)
|
||||
*
|
||||
* to see the significance bit of data point 1.
|
||||
*/
|
||||
|
||||
#define T1_SIGMA_NW T1_SIGMA_0
|
||||
#define T1_SIGMA_N T1_SIGMA_1
|
||||
#define T1_SIGMA_NE T1_SIGMA_2
|
||||
#define T1_SIGMA_W T1_SIGMA_3
|
||||
#define T1_SIGMA_THIS T1_SIGMA_4
|
||||
#define T1_SIGMA_E T1_SIGMA_5
|
||||
#define T1_SIGMA_SW T1_SIGMA_6
|
||||
#define T1_SIGMA_S T1_SIGMA_7
|
||||
#define T1_SIGMA_SE T1_SIGMA_8
|
||||
#define T1_SIGMA_NEIGHBOURS (T1_SIGMA_NW | T1_SIGMA_N | T1_SIGMA_NE | T1_SIGMA_W | T1_SIGMA_E | T1_SIGMA_SW | T1_SIGMA_S | T1_SIGMA_SE)
|
||||
|
||||
#define T1_CHI_THIS T1_CHI_1
|
||||
#define T1_CHI_THIS_I T1_CHI_1_I
|
||||
#define T1_MU_THIS T1_MU_0
|
||||
#define T1_PI_THIS T1_PI_0
|
||||
#define T1_CHI_S T1_CHI_2
|
||||
|
||||
#define T1_LUT_SGN_W (1U << 0)
|
||||
#define T1_LUT_SIG_N (1U << 1)
|
||||
#define T1_LUT_SGN_E (1U << 2)
|
||||
#define T1_LUT_SIG_W (1U << 3)
|
||||
#define T1_LUT_SGN_N (1U << 4)
|
||||
#define T1_LUT_SIG_E (1U << 5)
|
||||
#define T1_LUT_SGN_S (1U << 6)
|
||||
#define T1_LUT_SIG_S (1U << 7)
|
||||
/* END of flags that apply to opj_flag_t */
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
/** Flags for 4 consecutive rows of a column */
|
||||
typedef OPJ_UINT32 opj_flag_t;
|
||||
|
||||
/**
|
||||
Tier-1 coding (coding of code-block coefficients)
|
||||
*/
|
||||
typedef struct opj_t1 {
|
||||
|
||||
/** MQC component */
|
||||
opj_mqc_t mqc;
|
||||
|
||||
OPJ_INT32 *data;
|
||||
/** Flags used by decoder and encoder.
|
||||
* Such that flags[1+0] is for state of col=0,row=0..3,
|
||||
flags[1+1] for col=1, row=0..3, flags[1+flags_stride] for col=0,row=4..7, ...
|
||||
This array avoids too much cache trashing when processing by 4 vertical samples
|
||||
as done in the various decoding steps. */
|
||||
opj_flag_t *flags;
|
||||
|
||||
OPJ_UINT32 w;
|
||||
OPJ_UINT32 h;
|
||||
OPJ_UINT32 datasize;
|
||||
OPJ_UINT32 flagssize;
|
||||
OPJ_BOOL encoder;
|
||||
|
||||
/* The 3 variables below are only used by the decoder */
|
||||
/* set to TRUE in multithreaded context */
|
||||
OPJ_BOOL mustuse_cblkdatabuffer;
|
||||
/* Temporary buffer to concatenate all chunks of a codebock */
|
||||
OPJ_BYTE *cblkdatabuffer;
|
||||
/* Maximum size available in cblkdatabuffer */
|
||||
OPJ_UINT32 cblkdatabuffersize;
|
||||
} opj_t1_t;
|
||||
|
||||
/** @name Exported functions */
|
||||
/*@{*/
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
Encode the code-blocks of a tile
|
||||
@param tcd TCD handle
|
||||
@param tile The tile to encode
|
||||
@param tcp Tile coding parameters
|
||||
@param mct_norms FIXME DOC
|
||||
@param mct_numcomps Number of components used for MCT
|
||||
*/
|
||||
OPJ_BOOL opj_t1_encode_cblks(opj_tcd_t* tcd,
|
||||
opj_tcd_tile_t *tile,
|
||||
opj_tcp_t *tcp,
|
||||
const OPJ_FLOAT64 * mct_norms,
|
||||
OPJ_UINT32 mct_numcomps);
|
||||
|
||||
/**
|
||||
Decode the code-blocks of a tile
|
||||
@param tcd TCD handle
|
||||
@param pret Pointer to return value
|
||||
@param tilec The tile to decode
|
||||
@param tccp Tile coding parameters
|
||||
@param p_manager the event manager
|
||||
@param p_manager_mutex mutex for the event manager
|
||||
@param check_pterm whether PTERM correct termination should be checked
|
||||
*/
|
||||
void opj_t1_decode_cblks(opj_tcd_t* tcd,
|
||||
volatile OPJ_BOOL* pret,
|
||||
opj_tcd_tilecomp_t* tilec,
|
||||
opj_tccp_t* tccp,
|
||||
opj_event_mgr_t *p_manager,
|
||||
opj_mutex_t* p_manager_mutex,
|
||||
OPJ_BOOL check_pterm);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new Tier 1 handle
|
||||
* and initializes the look-up tables of the Tier-1 coder/decoder
|
||||
* @return a new T1 handle if successful, returns NULL otherwise
|
||||
*/
|
||||
opj_t1_t* opj_t1_create(OPJ_BOOL isEncoder);
|
||||
|
||||
/**
|
||||
* Destroys a previously created T1 handle
|
||||
*
|
||||
* @param p_t1 Tier 1 handle to destroy
|
||||
*/
|
||||
void opj_t1_destroy(opj_t1_t *p_t1);
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/*@}*/
|
||||
|
||||
/*@}*/
|
||||
|
||||
#endif /* OPJ_T1_H */
|
||||
@@ -0,0 +1,261 @@
|
||||
static const OPJ_UINT16 vlc_tbl0[1024] = {
|
||||
0x0023, 0x00a5, 0x0043, 0x0066, 0x0083, 0xa8ee, 0x0014, 0xd8df,
|
||||
0x0023, 0x10be, 0x0043, 0xf5ff, 0x0083, 0x207e, 0x0055, 0x515f,
|
||||
0x0023, 0x0035, 0x0043, 0x444e, 0x0083, 0xc4ce, 0x0014, 0xcccf,
|
||||
0x0023, 0xe2fe, 0x0043, 0x99ff, 0x0083, 0x0096, 0x00c5, 0x313f,
|
||||
0x0023, 0x00a5, 0x0043, 0x445e, 0x0083, 0xc8ce, 0x0014, 0x11df,
|
||||
0x0023, 0xf4fe, 0x0043, 0xfcff, 0x0083, 0x009e, 0x0055, 0x0077,
|
||||
0x0023, 0x0035, 0x0043, 0xf1ff, 0x0083, 0x88ae, 0x0014, 0x00b7,
|
||||
0x0023, 0xf8fe, 0x0043, 0xe4ef, 0x0083, 0x888e, 0x00c5, 0x111f,
|
||||
0x0023, 0x00a5, 0x0043, 0x0066, 0x0083, 0xa8ee, 0x0014, 0x54df,
|
||||
0x0023, 0x10be, 0x0043, 0x22ef, 0x0083, 0x207e, 0x0055, 0x227f,
|
||||
0x0023, 0x0035, 0x0043, 0x444e, 0x0083, 0xc4ce, 0x0014, 0x11bf,
|
||||
0x0023, 0xe2fe, 0x0043, 0x00f7, 0x0083, 0x0096, 0x00c5, 0x223f,
|
||||
0x0023, 0x00a5, 0x0043, 0x445e, 0x0083, 0xc8ce, 0x0014, 0x00d7,
|
||||
0x0023, 0xf4fe, 0x0043, 0xbaff, 0x0083, 0x009e, 0x0055, 0x006f,
|
||||
0x0023, 0x0035, 0x0043, 0xe6ff, 0x0083, 0x88ae, 0x0014, 0xa2af,
|
||||
0x0023, 0xf8fe, 0x0043, 0x00e7, 0x0083, 0x888e, 0x00c5, 0x222f,
|
||||
0x0002, 0x00c5, 0x0084, 0x207e, 0x0002, 0xc4ce, 0x0024, 0x00f7,
|
||||
0x0002, 0xa2fe, 0x0044, 0x0056, 0x0002, 0x009e, 0x0014, 0x00d7,
|
||||
0x0002, 0x10be, 0x0084, 0x0066, 0x0002, 0x88ae, 0x0024, 0x11df,
|
||||
0x0002, 0xa8ee, 0x0044, 0x0036, 0x0002, 0x888e, 0x0014, 0x111f,
|
||||
0x0002, 0x00c5, 0x0084, 0x006e, 0x0002, 0x88ce, 0x0024, 0x88ff,
|
||||
0x0002, 0xb8fe, 0x0044, 0x444e, 0x0002, 0x0096, 0x0014, 0x00b7,
|
||||
0x0002, 0xe4fe, 0x0084, 0x445e, 0x0002, 0x00a6, 0x0024, 0x00e7,
|
||||
0x0002, 0x54de, 0x0044, 0x222e, 0x0002, 0x003e, 0x0014, 0x0077,
|
||||
0x0002, 0x00c5, 0x0084, 0x207e, 0x0002, 0xc4ce, 0x0024, 0xf1ff,
|
||||
0x0002, 0xa2fe, 0x0044, 0x0056, 0x0002, 0x009e, 0x0014, 0x11bf,
|
||||
0x0002, 0x10be, 0x0084, 0x0066, 0x0002, 0x88ae, 0x0024, 0x22ef,
|
||||
0x0002, 0xa8ee, 0x0044, 0x0036, 0x0002, 0x888e, 0x0014, 0x227f,
|
||||
0x0002, 0x00c5, 0x0084, 0x006e, 0x0002, 0x88ce, 0x0024, 0xe4ef,
|
||||
0x0002, 0xb8fe, 0x0044, 0x444e, 0x0002, 0x0096, 0x0014, 0xa2af,
|
||||
0x0002, 0xe4fe, 0x0084, 0x445e, 0x0002, 0x00a6, 0x0024, 0xd8df,
|
||||
0x0002, 0x54de, 0x0044, 0x222e, 0x0002, 0x003e, 0x0014, 0x515f,
|
||||
0x0002, 0x0055, 0x0084, 0x0066, 0x0002, 0x88de, 0x0024, 0x32ff,
|
||||
0x0002, 0x11fe, 0x0044, 0x444e, 0x0002, 0x00ae, 0x0014, 0x00b7,
|
||||
0x0002, 0x317e, 0x0084, 0x515e, 0x0002, 0x00c6, 0x0024, 0x00d7,
|
||||
0x0002, 0x20ee, 0x0044, 0x111e, 0x0002, 0x009e, 0x0014, 0x0077,
|
||||
0x0002, 0x0055, 0x0084, 0x545e, 0x0002, 0x44ce, 0x0024, 0x00e7,
|
||||
0x0002, 0xf1fe, 0x0044, 0x0036, 0x0002, 0x00a6, 0x0014, 0x555f,
|
||||
0x0002, 0x74fe, 0x0084, 0x113e, 0x0002, 0x20be, 0x0024, 0x747f,
|
||||
0x0002, 0xc4de, 0x0044, 0xf8ff, 0x0002, 0x0096, 0x0014, 0x222f,
|
||||
0x0002, 0x0055, 0x0084, 0x0066, 0x0002, 0x88de, 0x0024, 0x00f7,
|
||||
0x0002, 0x11fe, 0x0044, 0x444e, 0x0002, 0x00ae, 0x0014, 0x888f,
|
||||
0x0002, 0x317e, 0x0084, 0x515e, 0x0002, 0x00c6, 0x0024, 0xc8cf,
|
||||
0x0002, 0x20ee, 0x0044, 0x111e, 0x0002, 0x009e, 0x0014, 0x006f,
|
||||
0x0002, 0x0055, 0x0084, 0x545e, 0x0002, 0x44ce, 0x0024, 0xd1df,
|
||||
0x0002, 0xf1fe, 0x0044, 0x0036, 0x0002, 0x00a6, 0x0014, 0x227f,
|
||||
0x0002, 0x74fe, 0x0084, 0x113e, 0x0002, 0x20be, 0x0024, 0x22bf,
|
||||
0x0002, 0xc4de, 0x0044, 0x22ef, 0x0002, 0x0096, 0x0014, 0x323f,
|
||||
0x0003, 0xd4de, 0xf4fd, 0xfcff, 0x0014, 0x113e, 0x0055, 0x888f,
|
||||
0x0003, 0x32be, 0x0085, 0x00e7, 0x0025, 0x515e, 0xaafe, 0x727f,
|
||||
0x0003, 0x44ce, 0xf8fd, 0x44ef, 0x0014, 0x647e, 0x0045, 0xa2af,
|
||||
0x0003, 0x00a6, 0x555d, 0x99df, 0xf1fd, 0x0036, 0xf5fe, 0x626f,
|
||||
0x0003, 0xd1de, 0xf4fd, 0xe6ff, 0x0014, 0x717e, 0x0055, 0xb1bf,
|
||||
0x0003, 0x88ae, 0x0085, 0xd5df, 0x0025, 0x444e, 0xf2fe, 0x667f,
|
||||
0x0003, 0x00c6, 0xf8fd, 0xe2ef, 0x0014, 0x545e, 0x0045, 0x119f,
|
||||
0x0003, 0x0096, 0x555d, 0xc8cf, 0xf1fd, 0x111e, 0xc8ee, 0x0067,
|
||||
0x0003, 0xd4de, 0xf4fd, 0xf3ff, 0x0014, 0x113e, 0x0055, 0x11bf,
|
||||
0x0003, 0x32be, 0x0085, 0xd8df, 0x0025, 0x515e, 0xaafe, 0x222f,
|
||||
0x0003, 0x44ce, 0xf8fd, 0x00f7, 0x0014, 0x647e, 0x0045, 0x989f,
|
||||
0x0003, 0x00a6, 0x555d, 0x00d7, 0xf1fd, 0x0036, 0xf5fe, 0x446f,
|
||||
0x0003, 0xd1de, 0xf4fd, 0xb9ff, 0x0014, 0x717e, 0x0055, 0x00b7,
|
||||
0x0003, 0x88ae, 0x0085, 0xdcdf, 0x0025, 0x444e, 0xf2fe, 0x0077,
|
||||
0x0003, 0x00c6, 0xf8fd, 0xe4ef, 0x0014, 0x545e, 0x0045, 0x737f,
|
||||
0x0003, 0x0096, 0x555d, 0xb8bf, 0xf1fd, 0x111e, 0xc8ee, 0x323f,
|
||||
0x0002, 0x00a5, 0x0084, 0x407e, 0x0002, 0x10de, 0x0024, 0x11df,
|
||||
0x0002, 0x72fe, 0x0044, 0x0056, 0x0002, 0xa8ae, 0x0014, 0xb2bf,
|
||||
0x0002, 0x0096, 0x0084, 0x0066, 0x0002, 0x00c6, 0x0024, 0x00e7,
|
||||
0x0002, 0xc8ee, 0x0044, 0x222e, 0x0002, 0x888e, 0x0014, 0x0077,
|
||||
0x0002, 0x00a5, 0x0084, 0x006e, 0x0002, 0x88ce, 0x0024, 0x00f7,
|
||||
0x0002, 0x91fe, 0x0044, 0x0036, 0x0002, 0xa2ae, 0x0014, 0xaaaf,
|
||||
0x0002, 0xb8fe, 0x0084, 0x005e, 0x0002, 0x00be, 0x0024, 0xc4cf,
|
||||
0x0002, 0x44ee, 0x0044, 0xf4ff, 0x0002, 0x223e, 0x0014, 0x111f,
|
||||
0x0002, 0x00a5, 0x0084, 0x407e, 0x0002, 0x10de, 0x0024, 0x99ff,
|
||||
0x0002, 0x72fe, 0x0044, 0x0056, 0x0002, 0xa8ae, 0x0014, 0x00b7,
|
||||
0x0002, 0x0096, 0x0084, 0x0066, 0x0002, 0x00c6, 0x0024, 0x00d7,
|
||||
0x0002, 0xc8ee, 0x0044, 0x222e, 0x0002, 0x888e, 0x0014, 0x444f,
|
||||
0x0002, 0x00a5, 0x0084, 0x006e, 0x0002, 0x88ce, 0x0024, 0xe2ef,
|
||||
0x0002, 0x91fe, 0x0044, 0x0036, 0x0002, 0xa2ae, 0x0014, 0x447f,
|
||||
0x0002, 0xb8fe, 0x0084, 0x005e, 0x0002, 0x00be, 0x0024, 0x009f,
|
||||
0x0002, 0x44ee, 0x0044, 0x76ff, 0x0002, 0x223e, 0x0014, 0x313f,
|
||||
0x0003, 0x00c6, 0x0085, 0xd9ff, 0xf2fd, 0x647e, 0xf1fe, 0x99bf,
|
||||
0x0003, 0xa2ae, 0x0025, 0x66ef, 0xf4fd, 0x0056, 0xe2ee, 0x737f,
|
||||
0x0003, 0x98be, 0x0045, 0x00f7, 0xf8fd, 0x0066, 0x76fe, 0x889f,
|
||||
0x0003, 0x888e, 0x0015, 0xd5df, 0x00a5, 0x222e, 0x98de, 0x444f,
|
||||
0x0003, 0xb2be, 0x0085, 0xfcff, 0xf2fd, 0x226e, 0x0096, 0x00b7,
|
||||
0x0003, 0xaaae, 0x0025, 0xd1df, 0xf4fd, 0x0036, 0xd4de, 0x646f,
|
||||
0x0003, 0xa8ae, 0x0045, 0xeaef, 0xf8fd, 0x445e, 0xe8ee, 0x717f,
|
||||
0x0003, 0x323e, 0x0015, 0xc4cf, 0x00a5, 0xfaff, 0x88ce, 0x313f,
|
||||
0x0003, 0x00c6, 0x0085, 0x77ff, 0xf2fd, 0x647e, 0xf1fe, 0xb3bf,
|
||||
0x0003, 0xa2ae, 0x0025, 0x00e7, 0xf4fd, 0x0056, 0xe2ee, 0x0077,
|
||||
0x0003, 0x98be, 0x0045, 0xe4ef, 0xf8fd, 0x0066, 0x76fe, 0x667f,
|
||||
0x0003, 0x888e, 0x0015, 0x00d7, 0x00a5, 0x222e, 0x98de, 0x333f,
|
||||
0x0003, 0xb2be, 0x0085, 0x75ff, 0xf2fd, 0x226e, 0x0096, 0x919f,
|
||||
0x0003, 0xaaae, 0x0025, 0x99df, 0xf4fd, 0x0036, 0xd4de, 0x515f,
|
||||
0x0003, 0xa8ae, 0x0045, 0xecef, 0xf8fd, 0x445e, 0xe8ee, 0x727f,
|
||||
0x0003, 0x323e, 0x0015, 0xb1bf, 0x00a5, 0xf3ff, 0x88ce, 0x111f,
|
||||
0x0003, 0x54de, 0xf2fd, 0x111e, 0x0014, 0x647e, 0xf8fe, 0xcccf,
|
||||
0x0003, 0x91be, 0x0045, 0x22ef, 0x0025, 0x222e, 0xf3fe, 0x888f,
|
||||
0x0003, 0x00c6, 0x0085, 0x00f7, 0x0014, 0x115e, 0xfcfe, 0xa8af,
|
||||
0x0003, 0x00a6, 0x0035, 0xc8df, 0xf1fd, 0x313e, 0x66fe, 0x646f,
|
||||
0x0003, 0xc8ce, 0xf2fd, 0xf5ff, 0x0014, 0x0066, 0xf4fe, 0xbabf,
|
||||
0x0003, 0x22ae, 0x0045, 0x00e7, 0x0025, 0x323e, 0xeafe, 0x737f,
|
||||
0x0003, 0xb2be, 0x0085, 0x55df, 0x0014, 0x0056, 0x717e, 0x119f,
|
||||
0x0003, 0x0096, 0x0035, 0xc4cf, 0xf1fd, 0x333e, 0xe8ee, 0x444f,
|
||||
0x0003, 0x54de, 0xf2fd, 0x111e, 0x0014, 0x647e, 0xf8fe, 0x99bf,
|
||||
0x0003, 0x91be, 0x0045, 0xe2ef, 0x0025, 0x222e, 0xf3fe, 0x667f,
|
||||
0x0003, 0x00c6, 0x0085, 0xe4ef, 0x0014, 0x115e, 0xfcfe, 0x989f,
|
||||
0x0003, 0x00a6, 0x0035, 0x00d7, 0xf1fd, 0x313e, 0x66fe, 0x226f,
|
||||
0x0003, 0xc8ce, 0xf2fd, 0xb9ff, 0x0014, 0x0066, 0xf4fe, 0x00b7,
|
||||
0x0003, 0x22ae, 0x0045, 0xd1df, 0x0025, 0x323e, 0xeafe, 0x0077,
|
||||
0x0003, 0xb2be, 0x0085, 0xecef, 0x0014, 0x0056, 0x717e, 0x727f,
|
||||
0x0003, 0x0096, 0x0035, 0xb8bf, 0xf1fd, 0x333e, 0xe8ee, 0x545f,
|
||||
0xf1fc, 0xd1de, 0xfafd, 0x00d7, 0xf8fc, 0x0016, 0xfffd, 0x747f,
|
||||
0xf4fc, 0x717e, 0xf3fd, 0xb3bf, 0xf2fc, 0xeaef, 0xe8ee, 0x444f,
|
||||
0xf1fc, 0x22ae, 0x0005, 0xb8bf, 0xf8fc, 0x00f7, 0xfcfe, 0x0077,
|
||||
0xf4fc, 0x115e, 0xf5fd, 0x757f, 0xf2fc, 0xd8df, 0xe2ee, 0x333f,
|
||||
0xf1fc, 0xb2be, 0xfafd, 0x88cf, 0xf8fc, 0xfbff, 0xfffd, 0x737f,
|
||||
0xf4fc, 0x006e, 0xf3fd, 0x00b7, 0xf2fc, 0x66ef, 0xf9fe, 0x313f,
|
||||
0xf1fc, 0x009e, 0x0005, 0xbabf, 0xf8fc, 0xfdff, 0xf6fe, 0x0067,
|
||||
0xf4fc, 0x0026, 0xf5fd, 0x888f, 0xf2fc, 0xdcdf, 0xd4de, 0x222f,
|
||||
0xf1fc, 0xd1de, 0xfafd, 0xc4cf, 0xf8fc, 0x0016, 0xfffd, 0x727f,
|
||||
0xf4fc, 0x717e, 0xf3fd, 0x99bf, 0xf2fc, 0xecef, 0xe8ee, 0x0047,
|
||||
0xf1fc, 0x22ae, 0x0005, 0x00a7, 0xf8fc, 0xf7ff, 0xfcfe, 0x0057,
|
||||
0xf4fc, 0x115e, 0xf5fd, 0x0097, 0xf2fc, 0xd5df, 0xe2ee, 0x0037,
|
||||
0xf1fc, 0xb2be, 0xfafd, 0x00c7, 0xf8fc, 0xfeff, 0xfffd, 0x667f,
|
||||
0xf4fc, 0x006e, 0xf3fd, 0xa8af, 0xf2fc, 0x00e7, 0xf9fe, 0x323f,
|
||||
0xf1fc, 0x009e, 0x0005, 0xb1bf, 0xf8fc, 0xe4ef, 0xf6fe, 0x545f,
|
||||
0xf4fc, 0x0026, 0xf5fd, 0x0087, 0xf2fc, 0x99df, 0xd4de, 0x111f
|
||||
};
|
||||
|
||||
static const OPJ_UINT16 vlc_tbl1[1024] = {
|
||||
0x0013, 0x0065, 0x0043, 0x00de, 0x0083, 0x888d, 0x0023, 0x444e,
|
||||
0x0013, 0x00a5, 0x0043, 0x88ae, 0x0083, 0x0035, 0x0023, 0x00d7,
|
||||
0x0013, 0x00c5, 0x0043, 0x009e, 0x0083, 0x0055, 0x0023, 0x222e,
|
||||
0x0013, 0x0095, 0x0043, 0x007e, 0x0083, 0x10fe, 0x0023, 0x0077,
|
||||
0x0013, 0x0065, 0x0043, 0x88ce, 0x0083, 0x888d, 0x0023, 0x111e,
|
||||
0x0013, 0x00a5, 0x0043, 0x005e, 0x0083, 0x0035, 0x0023, 0x00e7,
|
||||
0x0013, 0x00c5, 0x0043, 0x00be, 0x0083, 0x0055, 0x0023, 0x11ff,
|
||||
0x0013, 0x0095, 0x0043, 0x003e, 0x0083, 0x40ee, 0x0023, 0xa2af,
|
||||
0x0013, 0x0065, 0x0043, 0x00de, 0x0083, 0x888d, 0x0023, 0x444e,
|
||||
0x0013, 0x00a5, 0x0043, 0x88ae, 0x0083, 0x0035, 0x0023, 0x44ef,
|
||||
0x0013, 0x00c5, 0x0043, 0x009e, 0x0083, 0x0055, 0x0023, 0x222e,
|
||||
0x0013, 0x0095, 0x0043, 0x007e, 0x0083, 0x10fe, 0x0023, 0x00b7,
|
||||
0x0013, 0x0065, 0x0043, 0x88ce, 0x0083, 0x888d, 0x0023, 0x111e,
|
||||
0x0013, 0x00a5, 0x0043, 0x005e, 0x0083, 0x0035, 0x0023, 0xc4cf,
|
||||
0x0013, 0x00c5, 0x0043, 0x00be, 0x0083, 0x0055, 0x0023, 0x00f7,
|
||||
0x0013, 0x0095, 0x0043, 0x003e, 0x0083, 0x40ee, 0x0023, 0x006f,
|
||||
0x0001, 0x0084, 0x0001, 0x0056, 0x0001, 0x0014, 0x0001, 0x00d7,
|
||||
0x0001, 0x0024, 0x0001, 0x0096, 0x0001, 0x0045, 0x0001, 0x0077,
|
||||
0x0001, 0x0084, 0x0001, 0x00c6, 0x0001, 0x0014, 0x0001, 0x888f,
|
||||
0x0001, 0x0024, 0x0001, 0x00f7, 0x0001, 0x0035, 0x0001, 0x222f,
|
||||
0x0001, 0x0084, 0x0001, 0x40fe, 0x0001, 0x0014, 0x0001, 0x00b7,
|
||||
0x0001, 0x0024, 0x0001, 0x00bf, 0x0001, 0x0045, 0x0001, 0x0067,
|
||||
0x0001, 0x0084, 0x0001, 0x00a6, 0x0001, 0x0014, 0x0001, 0x444f,
|
||||
0x0001, 0x0024, 0x0001, 0x00e7, 0x0001, 0x0035, 0x0001, 0x113f,
|
||||
0x0001, 0x0084, 0x0001, 0x0056, 0x0001, 0x0014, 0x0001, 0x00cf,
|
||||
0x0001, 0x0024, 0x0001, 0x0096, 0x0001, 0x0045, 0x0001, 0x006f,
|
||||
0x0001, 0x0084, 0x0001, 0x00c6, 0x0001, 0x0014, 0x0001, 0x009f,
|
||||
0x0001, 0x0024, 0x0001, 0x00ef, 0x0001, 0x0035, 0x0001, 0x323f,
|
||||
0x0001, 0x0084, 0x0001, 0x40fe, 0x0001, 0x0014, 0x0001, 0x00af,
|
||||
0x0001, 0x0024, 0x0001, 0x44ff, 0x0001, 0x0045, 0x0001, 0x005f,
|
||||
0x0001, 0x0084, 0x0001, 0x00a6, 0x0001, 0x0014, 0x0001, 0x007f,
|
||||
0x0001, 0x0024, 0x0001, 0x00df, 0x0001, 0x0035, 0x0001, 0x111f,
|
||||
0x0001, 0x0024, 0x0001, 0x0056, 0x0001, 0x0085, 0x0001, 0x00bf,
|
||||
0x0001, 0x0014, 0x0001, 0x00f7, 0x0001, 0x00c6, 0x0001, 0x0077,
|
||||
0x0001, 0x0024, 0x0001, 0xf8ff, 0x0001, 0x0045, 0x0001, 0x007f,
|
||||
0x0001, 0x0014, 0x0001, 0x00df, 0x0001, 0x00a6, 0x0001, 0x313f,
|
||||
0x0001, 0x0024, 0x0001, 0x222e, 0x0001, 0x0085, 0x0001, 0x00b7,
|
||||
0x0001, 0x0014, 0x0001, 0x44ef, 0x0001, 0xa2ae, 0x0001, 0x0067,
|
||||
0x0001, 0x0024, 0x0001, 0x51ff, 0x0001, 0x0045, 0x0001, 0x0097,
|
||||
0x0001, 0x0014, 0x0001, 0x00cf, 0x0001, 0x0036, 0x0001, 0x223f,
|
||||
0x0001, 0x0024, 0x0001, 0x0056, 0x0001, 0x0085, 0x0001, 0xb2bf,
|
||||
0x0001, 0x0014, 0x0001, 0x40ef, 0x0001, 0x00c6, 0x0001, 0x006f,
|
||||
0x0001, 0x0024, 0x0001, 0x72ff, 0x0001, 0x0045, 0x0001, 0x009f,
|
||||
0x0001, 0x0014, 0x0001, 0x00d7, 0x0001, 0x00a6, 0x0001, 0x444f,
|
||||
0x0001, 0x0024, 0x0001, 0x222e, 0x0001, 0x0085, 0x0001, 0xa8af,
|
||||
0x0001, 0x0014, 0x0001, 0x00e7, 0x0001, 0xa2ae, 0x0001, 0x005f,
|
||||
0x0001, 0x0024, 0x0001, 0x44ff, 0x0001, 0x0045, 0x0001, 0x888f,
|
||||
0x0001, 0x0014, 0x0001, 0xaaaf, 0x0001, 0x0036, 0x0001, 0x111f,
|
||||
0x0002, 0xf8fe, 0x0024, 0x0056, 0x0002, 0x00b6, 0x0085, 0x66ff,
|
||||
0x0002, 0x00ce, 0x0014, 0x111e, 0x0002, 0x0096, 0x0035, 0xa8af,
|
||||
0x0002, 0x00f6, 0x0024, 0x313e, 0x0002, 0x00a6, 0x0045, 0xb3bf,
|
||||
0x0002, 0xb2be, 0x0014, 0xf5ff, 0x0002, 0x0066, 0x517e, 0x545f,
|
||||
0x0002, 0xf2fe, 0x0024, 0x222e, 0x0002, 0x22ae, 0x0085, 0x44ef,
|
||||
0x0002, 0x00c6, 0x0014, 0xf4ff, 0x0002, 0x0076, 0x0035, 0x447f,
|
||||
0x0002, 0x40de, 0x0024, 0x323e, 0x0002, 0x009e, 0x0045, 0x00d7,
|
||||
0x0002, 0x88be, 0x0014, 0xfaff, 0x0002, 0x115e, 0xf1fe, 0x444f,
|
||||
0x0002, 0xf8fe, 0x0024, 0x0056, 0x0002, 0x00b6, 0x0085, 0xc8ef,
|
||||
0x0002, 0x00ce, 0x0014, 0x111e, 0x0002, 0x0096, 0x0035, 0x888f,
|
||||
0x0002, 0x00f6, 0x0024, 0x313e, 0x0002, 0x00a6, 0x0045, 0x44df,
|
||||
0x0002, 0xb2be, 0x0014, 0xa8ff, 0x0002, 0x0066, 0x517e, 0x006f,
|
||||
0x0002, 0xf2fe, 0x0024, 0x222e, 0x0002, 0x22ae, 0x0085, 0x00e7,
|
||||
0x0002, 0x00c6, 0x0014, 0xe2ef, 0x0002, 0x0076, 0x0035, 0x727f,
|
||||
0x0002, 0x40de, 0x0024, 0x323e, 0x0002, 0x009e, 0x0045, 0xb1bf,
|
||||
0x0002, 0x88be, 0x0014, 0x73ff, 0x0002, 0x115e, 0xf1fe, 0x333f,
|
||||
0x0001, 0x0084, 0x0001, 0x20ee, 0x0001, 0x00c5, 0x0001, 0xc4cf,
|
||||
0x0001, 0x0044, 0x0001, 0x32ff, 0x0001, 0x0015, 0x0001, 0x888f,
|
||||
0x0001, 0x0084, 0x0001, 0x0066, 0x0001, 0x0025, 0x0001, 0x00af,
|
||||
0x0001, 0x0044, 0x0001, 0x22ef, 0x0001, 0x00a6, 0x0001, 0x005f,
|
||||
0x0001, 0x0084, 0x0001, 0x444e, 0x0001, 0x00c5, 0x0001, 0xcccf,
|
||||
0x0001, 0x0044, 0x0001, 0x00f7, 0x0001, 0x0015, 0x0001, 0x006f,
|
||||
0x0001, 0x0084, 0x0001, 0x0056, 0x0001, 0x0025, 0x0001, 0x009f,
|
||||
0x0001, 0x0044, 0x0001, 0x00df, 0x0001, 0x30fe, 0x0001, 0x222f,
|
||||
0x0001, 0x0084, 0x0001, 0x20ee, 0x0001, 0x00c5, 0x0001, 0xc8cf,
|
||||
0x0001, 0x0044, 0x0001, 0x11ff, 0x0001, 0x0015, 0x0001, 0x0077,
|
||||
0x0001, 0x0084, 0x0001, 0x0066, 0x0001, 0x0025, 0x0001, 0x007f,
|
||||
0x0001, 0x0044, 0x0001, 0x00e7, 0x0001, 0x00a6, 0x0001, 0x0037,
|
||||
0x0001, 0x0084, 0x0001, 0x444e, 0x0001, 0x00c5, 0x0001, 0x00b7,
|
||||
0x0001, 0x0044, 0x0001, 0x00bf, 0x0001, 0x0015, 0x0001, 0x003f,
|
||||
0x0001, 0x0084, 0x0001, 0x0056, 0x0001, 0x0025, 0x0001, 0x0097,
|
||||
0x0001, 0x0044, 0x0001, 0x00d7, 0x0001, 0x30fe, 0x0001, 0x111f,
|
||||
0x0002, 0xa8ee, 0x0044, 0x888e, 0x0002, 0x00d6, 0x00c5, 0xf3ff,
|
||||
0x0002, 0xfcfe, 0x0025, 0x003e, 0x0002, 0x00b6, 0x0055, 0xd8df,
|
||||
0x0002, 0xf8fe, 0x0044, 0x0066, 0x0002, 0x207e, 0x0085, 0x99ff,
|
||||
0x0002, 0x00e6, 0x00f5, 0x0036, 0x0002, 0x00a6, 0x0015, 0x009f,
|
||||
0x0002, 0xf2fe, 0x0044, 0x0076, 0x0002, 0x44ce, 0x00c5, 0x76ff,
|
||||
0x0002, 0xf1fe, 0x0025, 0x444e, 0x0002, 0x00ae, 0x0055, 0xc8cf,
|
||||
0x0002, 0xf4fe, 0x0044, 0x445e, 0x0002, 0x10be, 0x0085, 0xe4ef,
|
||||
0x0002, 0x54de, 0x00f5, 0x111e, 0x0002, 0x0096, 0x0015, 0x222f,
|
||||
0x0002, 0xa8ee, 0x0044, 0x888e, 0x0002, 0x00d6, 0x00c5, 0xfaff,
|
||||
0x0002, 0xfcfe, 0x0025, 0x003e, 0x0002, 0x00b6, 0x0055, 0x11bf,
|
||||
0x0002, 0xf8fe, 0x0044, 0x0066, 0x0002, 0x207e, 0x0085, 0x22ef,
|
||||
0x0002, 0x00e6, 0x00f5, 0x0036, 0x0002, 0x00a6, 0x0015, 0x227f,
|
||||
0x0002, 0xf2fe, 0x0044, 0x0076, 0x0002, 0x44ce, 0x00c5, 0xd5ff,
|
||||
0x0002, 0xf1fe, 0x0025, 0x444e, 0x0002, 0x00ae, 0x0055, 0x006f,
|
||||
0x0002, 0xf4fe, 0x0044, 0x445e, 0x0002, 0x10be, 0x0085, 0x11df,
|
||||
0x0002, 0x54de, 0x00f5, 0x111e, 0x0002, 0x0096, 0x0015, 0x515f,
|
||||
0x0003, 0x00f6, 0x0014, 0x111e, 0x0044, 0x888e, 0x00a5, 0xd4df,
|
||||
0x0003, 0xa2ae, 0x0055, 0x76ff, 0x0024, 0x223e, 0x00b6, 0xaaaf,
|
||||
0x0003, 0x00e6, 0x0014, 0xf5ff, 0x0044, 0x0066, 0x0085, 0xcccf,
|
||||
0x0003, 0x009e, 0x00c5, 0x44ef, 0x0024, 0x0036, 0xf8fe, 0x317f,
|
||||
0x0003, 0xe8ee, 0x0014, 0xf1ff, 0x0044, 0x0076, 0x00a5, 0xc4cf,
|
||||
0x0003, 0x227e, 0x0055, 0xd1df, 0x0024, 0x444e, 0xf4fe, 0x515f,
|
||||
0x0003, 0x00d6, 0x0014, 0xe2ef, 0x0044, 0x445e, 0x0085, 0x22bf,
|
||||
0x0003, 0x0096, 0x00c5, 0xc8df, 0x0024, 0x222e, 0xf2fe, 0x226f,
|
||||
0x0003, 0x00f6, 0x0014, 0x111e, 0x0044, 0x888e, 0x00a5, 0xb1bf,
|
||||
0x0003, 0xa2ae, 0x0055, 0x33ff, 0x0024, 0x223e, 0x00b6, 0xa8af,
|
||||
0x0003, 0x00e6, 0x0014, 0xb9ff, 0x0044, 0x0066, 0x0085, 0xa8bf,
|
||||
0x0003, 0x009e, 0x00c5, 0xe4ef, 0x0024, 0x0036, 0xf8fe, 0x646f,
|
||||
0x0003, 0xe8ee, 0x0014, 0xfcff, 0x0044, 0x0076, 0x00a5, 0xc8cf,
|
||||
0x0003, 0x227e, 0x0055, 0xeaef, 0x0024, 0x444e, 0xf4fe, 0x747f,
|
||||
0x0003, 0x00d6, 0x0014, 0xfaff, 0x0044, 0x445e, 0x0085, 0xb2bf,
|
||||
0x0003, 0x0096, 0x00c5, 0x44df, 0x0024, 0x222e, 0xf2fe, 0x313f,
|
||||
0x00f3, 0xfafe, 0xf1fd, 0x0036, 0x0004, 0x32be, 0x0075, 0x11df,
|
||||
0x00f3, 0x54de, 0xf2fd, 0xe4ef, 0x00d5, 0x717e, 0xfcfe, 0x737f,
|
||||
0x00f3, 0xf3fe, 0xf8fd, 0x111e, 0x0004, 0x0096, 0x0055, 0xb1bf,
|
||||
0x00f3, 0x00ce, 0x00b5, 0xd8df, 0xf4fd, 0x0066, 0xb9fe, 0x545f,
|
||||
0x00f3, 0x76fe, 0xf1fd, 0x0026, 0x0004, 0x00a6, 0x0075, 0x009f,
|
||||
0x00f3, 0x00ae, 0xf2fd, 0xf7ff, 0x00d5, 0x0046, 0xf5fe, 0x747f,
|
||||
0x00f3, 0x00e6, 0xf8fd, 0x0016, 0x0004, 0x0086, 0x0055, 0x888f,
|
||||
0x00f3, 0x00c6, 0x00b5, 0xe2ef, 0xf4fd, 0x115e, 0xa8ee, 0x113f,
|
||||
0x00f3, 0xfafe, 0xf1fd, 0x0036, 0x0004, 0x32be, 0x0075, 0xd1df,
|
||||
0x00f3, 0x54de, 0xf2fd, 0xfbff, 0x00d5, 0x717e, 0xfcfe, 0x447f,
|
||||
0x00f3, 0xf3fe, 0xf8fd, 0x111e, 0x0004, 0x0096, 0x0055, 0x727f,
|
||||
0x00f3, 0x00ce, 0x00b5, 0x22ef, 0xf4fd, 0x0066, 0xb9fe, 0x444f,
|
||||
0x00f3, 0x76fe, 0xf1fd, 0x0026, 0x0004, 0x00a6, 0x0075, 0x11bf,
|
||||
0x00f3, 0x00ae, 0xf2fd, 0xffff, 0x00d5, 0x0046, 0xf5fe, 0x323f,
|
||||
0x00f3, 0x00e6, 0xf8fd, 0x0016, 0x0004, 0x0086, 0x0055, 0x006f,
|
||||
0x00f3, 0x00c6, 0x00b5, 0xb8bf, 0xf4fd, 0x115e, 0xa8ee, 0x222f
|
||||
};
|
||||
@@ -0,0 +1,175 @@
|
||||
/* This file was automatically generated by t1_generate_luts.c */
|
||||
|
||||
static const OPJ_BYTE lut_ctxno_zc[2048] = {
|
||||
0, 1, 3, 3, 1, 2, 3, 3, 5, 6, 7, 7, 6, 6, 7, 7, 0, 1, 3, 3, 1, 2, 3, 3, 5, 6, 7, 7, 6, 6, 7, 7,
|
||||
5, 6, 7, 7, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 5, 6, 7, 7, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
1, 2, 3, 3, 2, 2, 3, 3, 6, 6, 7, 7, 6, 6, 7, 7, 1, 2, 3, 3, 2, 2, 3, 3, 6, 6, 7, 7, 6, 6, 7, 7,
|
||||
6, 6, 7, 7, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 7, 7, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
3, 3, 4, 4, 3, 3, 4, 4, 7, 7, 7, 7, 7, 7, 7, 7, 3, 3, 4, 4, 3, 3, 4, 4, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
3, 3, 4, 4, 3, 3, 4, 4, 7, 7, 7, 7, 7, 7, 7, 7, 3, 3, 4, 4, 3, 3, 4, 4, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
1, 2, 3, 3, 2, 2, 3, 3, 6, 6, 7, 7, 6, 6, 7, 7, 1, 2, 3, 3, 2, 2, 3, 3, 6, 6, 7, 7, 6, 6, 7, 7,
|
||||
6, 6, 7, 7, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 7, 7, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
2, 2, 3, 3, 2, 2, 3, 3, 6, 6, 7, 7, 6, 6, 7, 7, 2, 2, 3, 3, 2, 2, 3, 3, 6, 6, 7, 7, 6, 6, 7, 7,
|
||||
6, 6, 7, 7, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 7, 7, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
3, 3, 4, 4, 3, 3, 4, 4, 7, 7, 7, 7, 7, 7, 7, 7, 3, 3, 4, 4, 3, 3, 4, 4, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
3, 3, 4, 4, 3, 3, 4, 4, 7, 7, 7, 7, 7, 7, 7, 7, 3, 3, 4, 4, 3, 3, 4, 4, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
0, 1, 5, 6, 1, 2, 6, 6, 3, 3, 7, 7, 3, 3, 7, 7, 0, 1, 5, 6, 1, 2, 6, 6, 3, 3, 7, 7, 3, 3, 7, 7,
|
||||
3, 3, 7, 7, 3, 3, 7, 7, 4, 4, 7, 7, 4, 4, 7, 7, 3, 3, 7, 7, 3, 3, 7, 7, 4, 4, 7, 7, 4, 4, 7, 7,
|
||||
1, 2, 6, 6, 2, 2, 6, 6, 3, 3, 7, 7, 3, 3, 7, 7, 1, 2, 6, 6, 2, 2, 6, 6, 3, 3, 7, 7, 3, 3, 7, 7,
|
||||
3, 3, 7, 7, 3, 3, 7, 7, 4, 4, 7, 7, 4, 4, 7, 7, 3, 3, 7, 7, 3, 3, 7, 7, 4, 4, 7, 7, 4, 4, 7, 7,
|
||||
5, 6, 8, 8, 6, 6, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8, 5, 6, 8, 8, 6, 6, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8,
|
||||
7, 7, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8,
|
||||
6, 6, 8, 8, 6, 6, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8, 6, 6, 8, 8, 6, 6, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8,
|
||||
7, 7, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8,
|
||||
1, 2, 6, 6, 2, 2, 6, 6, 3, 3, 7, 7, 3, 3, 7, 7, 1, 2, 6, 6, 2, 2, 6, 6, 3, 3, 7, 7, 3, 3, 7, 7,
|
||||
3, 3, 7, 7, 3, 3, 7, 7, 4, 4, 7, 7, 4, 4, 7, 7, 3, 3, 7, 7, 3, 3, 7, 7, 4, 4, 7, 7, 4, 4, 7, 7,
|
||||
2, 2, 6, 6, 2, 2, 6, 6, 3, 3, 7, 7, 3, 3, 7, 7, 2, 2, 6, 6, 2, 2, 6, 6, 3, 3, 7, 7, 3, 3, 7, 7,
|
||||
3, 3, 7, 7, 3, 3, 7, 7, 4, 4, 7, 7, 4, 4, 7, 7, 3, 3, 7, 7, 3, 3, 7, 7, 4, 4, 7, 7, 4, 4, 7, 7,
|
||||
6, 6, 8, 8, 6, 6, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8, 6, 6, 8, 8, 6, 6, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8,
|
||||
7, 7, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8,
|
||||
6, 6, 8, 8, 6, 6, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8, 6, 6, 8, 8, 6, 6, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8,
|
||||
7, 7, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8, 7, 7, 8, 8,
|
||||
0, 1, 3, 3, 1, 2, 3, 3, 5, 6, 7, 7, 6, 6, 7, 7, 0, 1, 3, 3, 1, 2, 3, 3, 5, 6, 7, 7, 6, 6, 7, 7,
|
||||
5, 6, 7, 7, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 5, 6, 7, 7, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
1, 2, 3, 3, 2, 2, 3, 3, 6, 6, 7, 7, 6, 6, 7, 7, 1, 2, 3, 3, 2, 2, 3, 3, 6, 6, 7, 7, 6, 6, 7, 7,
|
||||
6, 6, 7, 7, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 7, 7, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
3, 3, 4, 4, 3, 3, 4, 4, 7, 7, 7, 7, 7, 7, 7, 7, 3, 3, 4, 4, 3, 3, 4, 4, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
3, 3, 4, 4, 3, 3, 4, 4, 7, 7, 7, 7, 7, 7, 7, 7, 3, 3, 4, 4, 3, 3, 4, 4, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
1, 2, 3, 3, 2, 2, 3, 3, 6, 6, 7, 7, 6, 6, 7, 7, 1, 2, 3, 3, 2, 2, 3, 3, 6, 6, 7, 7, 6, 6, 7, 7,
|
||||
6, 6, 7, 7, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 7, 7, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
2, 2, 3, 3, 2, 2, 3, 3, 6, 6, 7, 7, 6, 6, 7, 7, 2, 2, 3, 3, 2, 2, 3, 3, 6, 6, 7, 7, 6, 6, 7, 7,
|
||||
6, 6, 7, 7, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 7, 7, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
3, 3, 4, 4, 3, 3, 4, 4, 7, 7, 7, 7, 7, 7, 7, 7, 3, 3, 4, 4, 3, 3, 4, 4, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
3, 3, 4, 4, 3, 3, 4, 4, 7, 7, 7, 7, 7, 7, 7, 7, 3, 3, 4, 4, 3, 3, 4, 4, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
0, 3, 1, 4, 3, 6, 4, 7, 1, 4, 2, 5, 4, 7, 5, 7, 0, 3, 1, 4, 3, 6, 4, 7, 1, 4, 2, 5, 4, 7, 5, 7,
|
||||
1, 4, 2, 5, 4, 7, 5, 7, 2, 5, 2, 5, 5, 7, 5, 7, 1, 4, 2, 5, 4, 7, 5, 7, 2, 5, 2, 5, 5, 7, 5, 7,
|
||||
3, 6, 4, 7, 6, 8, 7, 8, 4, 7, 5, 7, 7, 8, 7, 8, 3, 6, 4, 7, 6, 8, 7, 8, 4, 7, 5, 7, 7, 8, 7, 8,
|
||||
4, 7, 5, 7, 7, 8, 7, 8, 5, 7, 5, 7, 7, 8, 7, 8, 4, 7, 5, 7, 7, 8, 7, 8, 5, 7, 5, 7, 7, 8, 7, 8,
|
||||
1, 4, 2, 5, 4, 7, 5, 7, 2, 5, 2, 5, 5, 7, 5, 7, 1, 4, 2, 5, 4, 7, 5, 7, 2, 5, 2, 5, 5, 7, 5, 7,
|
||||
2, 5, 2, 5, 5, 7, 5, 7, 2, 5, 2, 5, 5, 7, 5, 7, 2, 5, 2, 5, 5, 7, 5, 7, 2, 5, 2, 5, 5, 7, 5, 7,
|
||||
4, 7, 5, 7, 7, 8, 7, 8, 5, 7, 5, 7, 7, 8, 7, 8, 4, 7, 5, 7, 7, 8, 7, 8, 5, 7, 5, 7, 7, 8, 7, 8,
|
||||
5, 7, 5, 7, 7, 8, 7, 8, 5, 7, 5, 7, 7, 8, 7, 8, 5, 7, 5, 7, 7, 8, 7, 8, 5, 7, 5, 7, 7, 8, 7, 8,
|
||||
3, 6, 4, 7, 6, 8, 7, 8, 4, 7, 5, 7, 7, 8, 7, 8, 3, 6, 4, 7, 6, 8, 7, 8, 4, 7, 5, 7, 7, 8, 7, 8,
|
||||
4, 7, 5, 7, 7, 8, 7, 8, 5, 7, 5, 7, 7, 8, 7, 8, 4, 7, 5, 7, 7, 8, 7, 8, 5, 7, 5, 7, 7, 8, 7, 8,
|
||||
6, 8, 7, 8, 8, 8, 8, 8, 7, 8, 7, 8, 8, 8, 8, 8, 6, 8, 7, 8, 8, 8, 8, 8, 7, 8, 7, 8, 8, 8, 8, 8,
|
||||
7, 8, 7, 8, 8, 8, 8, 8, 7, 8, 7, 8, 8, 8, 8, 8, 7, 8, 7, 8, 8, 8, 8, 8, 7, 8, 7, 8, 8, 8, 8, 8,
|
||||
4, 7, 5, 7, 7, 8, 7, 8, 5, 7, 5, 7, 7, 8, 7, 8, 4, 7, 5, 7, 7, 8, 7, 8, 5, 7, 5, 7, 7, 8, 7, 8,
|
||||
5, 7, 5, 7, 7, 8, 7, 8, 5, 7, 5, 7, 7, 8, 7, 8, 5, 7, 5, 7, 7, 8, 7, 8, 5, 7, 5, 7, 7, 8, 7, 8,
|
||||
7, 8, 7, 8, 8, 8, 8, 8, 7, 8, 7, 8, 8, 8, 8, 8, 7, 8, 7, 8, 8, 8, 8, 8, 7, 8, 7, 8, 8, 8, 8, 8,
|
||||
7, 8, 7, 8, 8, 8, 8, 8, 7, 8, 7, 8, 8, 8, 8, 8, 7, 8, 7, 8, 8, 8, 8, 8, 7, 8, 7, 8, 8, 8, 8, 8
|
||||
};
|
||||
|
||||
static const OPJ_BYTE lut_ctxno_sc[256] = {
|
||||
0x9, 0x9, 0xa, 0xa, 0x9, 0x9, 0xa, 0xa, 0xc, 0xc, 0xd, 0xb, 0xc, 0xc, 0xd, 0xb,
|
||||
0x9, 0x9, 0xa, 0xa, 0x9, 0x9, 0xa, 0xa, 0xc, 0xc, 0xb, 0xd, 0xc, 0xc, 0xb, 0xd,
|
||||
0xc, 0xc, 0xd, 0xd, 0xc, 0xc, 0xb, 0xb, 0xc, 0x9, 0xd, 0xa, 0x9, 0xc, 0xa, 0xb,
|
||||
0xc, 0xc, 0xb, 0xb, 0xc, 0xc, 0xd, 0xd, 0xc, 0x9, 0xb, 0xa, 0x9, 0xc, 0xa, 0xd,
|
||||
0x9, 0x9, 0xa, 0xa, 0x9, 0x9, 0xa, 0xa, 0xc, 0xc, 0xd, 0xb, 0xc, 0xc, 0xd, 0xb,
|
||||
0x9, 0x9, 0xa, 0xa, 0x9, 0x9, 0xa, 0xa, 0xc, 0xc, 0xb, 0xd, 0xc, 0xc, 0xb, 0xd,
|
||||
0xc, 0xc, 0xd, 0xd, 0xc, 0xc, 0xb, 0xb, 0xc, 0x9, 0xd, 0xa, 0x9, 0xc, 0xa, 0xb,
|
||||
0xc, 0xc, 0xb, 0xb, 0xc, 0xc, 0xd, 0xd, 0xc, 0x9, 0xb, 0xa, 0x9, 0xc, 0xa, 0xd,
|
||||
0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xd, 0xb, 0xd, 0xb, 0xd, 0xb, 0xd, 0xb,
|
||||
0xa, 0xa, 0x9, 0x9, 0xa, 0xa, 0x9, 0x9, 0xd, 0xb, 0xc, 0xc, 0xd, 0xb, 0xc, 0xc,
|
||||
0xd, 0xd, 0xd, 0xd, 0xb, 0xb, 0xb, 0xb, 0xd, 0xa, 0xd, 0xa, 0xa, 0xb, 0xa, 0xb,
|
||||
0xd, 0xd, 0xc, 0xc, 0xb, 0xb, 0xc, 0xc, 0xd, 0xa, 0xc, 0x9, 0xa, 0xb, 0x9, 0xc,
|
||||
0xa, 0xa, 0x9, 0x9, 0xa, 0xa, 0x9, 0x9, 0xb, 0xd, 0xc, 0xc, 0xb, 0xd, 0xc, 0xc,
|
||||
0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xb, 0xd, 0xb, 0xd, 0xb, 0xd, 0xb, 0xd,
|
||||
0xb, 0xb, 0xc, 0xc, 0xd, 0xd, 0xc, 0xc, 0xb, 0xa, 0xc, 0x9, 0xa, 0xd, 0x9, 0xc,
|
||||
0xb, 0xb, 0xb, 0xb, 0xd, 0xd, 0xd, 0xd, 0xb, 0xa, 0xb, 0xa, 0xa, 0xd, 0xa, 0xd
|
||||
};
|
||||
|
||||
static const OPJ_BYTE lut_spb[256] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1,
|
||||
0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1,
|
||||
0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1,
|
||||
0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1,
|
||||
1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1,
|
||||
0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1
|
||||
};
|
||||
|
||||
static const OPJ_INT16 lut_nmsedec_sig[1U << T1_NMSEDEC_BITS] = {
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0180, 0x0300, 0x0480, 0x0600, 0x0780, 0x0900, 0x0a80,
|
||||
0x0c00, 0x0d80, 0x0f00, 0x1080, 0x1200, 0x1380, 0x1500, 0x1680,
|
||||
0x1800, 0x1980, 0x1b00, 0x1c80, 0x1e00, 0x1f80, 0x2100, 0x2280,
|
||||
0x2400, 0x2580, 0x2700, 0x2880, 0x2a00, 0x2b80, 0x2d00, 0x2e80,
|
||||
0x3000, 0x3180, 0x3300, 0x3480, 0x3600, 0x3780, 0x3900, 0x3a80,
|
||||
0x3c00, 0x3d80, 0x3f00, 0x4080, 0x4200, 0x4380, 0x4500, 0x4680,
|
||||
0x4800, 0x4980, 0x4b00, 0x4c80, 0x4e00, 0x4f80, 0x5100, 0x5280,
|
||||
0x5400, 0x5580, 0x5700, 0x5880, 0x5a00, 0x5b80, 0x5d00, 0x5e80,
|
||||
0x6000, 0x6180, 0x6300, 0x6480, 0x6600, 0x6780, 0x6900, 0x6a80,
|
||||
0x6c00, 0x6d80, 0x6f00, 0x7080, 0x7200, 0x7380, 0x7500, 0x7680
|
||||
};
|
||||
|
||||
static const OPJ_INT16 lut_nmsedec_sig0[1U << T1_NMSEDEC_BITS] = {
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0080, 0x0080,
|
||||
0x0080, 0x0080, 0x0100, 0x0100, 0x0100, 0x0180, 0x0180, 0x0200,
|
||||
0x0200, 0x0280, 0x0280, 0x0300, 0x0300, 0x0380, 0x0400, 0x0400,
|
||||
0x0480, 0x0500, 0x0580, 0x0580, 0x0600, 0x0680, 0x0700, 0x0780,
|
||||
0x0800, 0x0880, 0x0900, 0x0980, 0x0a00, 0x0a80, 0x0b80, 0x0c00,
|
||||
0x0c80, 0x0d00, 0x0e00, 0x0e80, 0x0f00, 0x1000, 0x1080, 0x1180,
|
||||
0x1200, 0x1300, 0x1380, 0x1480, 0x1500, 0x1600, 0x1700, 0x1780,
|
||||
0x1880, 0x1980, 0x1a80, 0x1b00, 0x1c00, 0x1d00, 0x1e00, 0x1f00,
|
||||
0x2000, 0x2100, 0x2200, 0x2300, 0x2400, 0x2500, 0x2680, 0x2780,
|
||||
0x2880, 0x2980, 0x2b00, 0x2c00, 0x2d00, 0x2e80, 0x2f80, 0x3100,
|
||||
0x3200, 0x3380, 0x3480, 0x3600, 0x3700, 0x3880, 0x3a00, 0x3b00,
|
||||
0x3c80, 0x3e00, 0x3f80, 0x4080, 0x4200, 0x4380, 0x4500, 0x4680,
|
||||
0x4800, 0x4980, 0x4b00, 0x4c80, 0x4e00, 0x4f80, 0x5180, 0x5300,
|
||||
0x5480, 0x5600, 0x5800, 0x5980, 0x5b00, 0x5d00, 0x5e80, 0x6080,
|
||||
0x6200, 0x6400, 0x6580, 0x6780, 0x6900, 0x6b00, 0x6d00, 0x6e80,
|
||||
0x7080, 0x7280, 0x7480, 0x7600, 0x7800, 0x7a00, 0x7c00, 0x7e00
|
||||
};
|
||||
|
||||
static const OPJ_INT16 lut_nmsedec_ref[1U << T1_NMSEDEC_BITS] = {
|
||||
0x1800, 0x1780, 0x1700, 0x1680, 0x1600, 0x1580, 0x1500, 0x1480,
|
||||
0x1400, 0x1380, 0x1300, 0x1280, 0x1200, 0x1180, 0x1100, 0x1080,
|
||||
0x1000, 0x0f80, 0x0f00, 0x0e80, 0x0e00, 0x0d80, 0x0d00, 0x0c80,
|
||||
0x0c00, 0x0b80, 0x0b00, 0x0a80, 0x0a00, 0x0980, 0x0900, 0x0880,
|
||||
0x0800, 0x0780, 0x0700, 0x0680, 0x0600, 0x0580, 0x0500, 0x0480,
|
||||
0x0400, 0x0380, 0x0300, 0x0280, 0x0200, 0x0180, 0x0100, 0x0080,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0080, 0x0100, 0x0180, 0x0200, 0x0280, 0x0300, 0x0380,
|
||||
0x0400, 0x0480, 0x0500, 0x0580, 0x0600, 0x0680, 0x0700, 0x0780,
|
||||
0x0800, 0x0880, 0x0900, 0x0980, 0x0a00, 0x0a80, 0x0b00, 0x0b80,
|
||||
0x0c00, 0x0c80, 0x0d00, 0x0d80, 0x0e00, 0x0e80, 0x0f00, 0x0f80,
|
||||
0x1000, 0x1080, 0x1100, 0x1180, 0x1200, 0x1280, 0x1300, 0x1380,
|
||||
0x1400, 0x1480, 0x1500, 0x1580, 0x1600, 0x1680, 0x1700, 0x1780
|
||||
};
|
||||
|
||||
static const OPJ_INT16 lut_nmsedec_ref0[1U << T1_NMSEDEC_BITS] = {
|
||||
0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00, 0x1b00, 0x1a80, 0x1980,
|
||||
0x1880, 0x1780, 0x1700, 0x1600, 0x1500, 0x1480, 0x1380, 0x1300,
|
||||
0x1200, 0x1180, 0x1080, 0x1000, 0x0f00, 0x0e80, 0x0e00, 0x0d00,
|
||||
0x0c80, 0x0c00, 0x0b80, 0x0a80, 0x0a00, 0x0980, 0x0900, 0x0880,
|
||||
0x0800, 0x0780, 0x0700, 0x0680, 0x0600, 0x0580, 0x0580, 0x0500,
|
||||
0x0480, 0x0400, 0x0400, 0x0380, 0x0300, 0x0300, 0x0280, 0x0280,
|
||||
0x0200, 0x0200, 0x0180, 0x0180, 0x0100, 0x0100, 0x0100, 0x0080,
|
||||
0x0080, 0x0080, 0x0080, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0080, 0x0080,
|
||||
0x0080, 0x0080, 0x0100, 0x0100, 0x0100, 0x0180, 0x0180, 0x0200,
|
||||
0x0200, 0x0280, 0x0280, 0x0300, 0x0300, 0x0380, 0x0400, 0x0400,
|
||||
0x0480, 0x0500, 0x0580, 0x0580, 0x0600, 0x0680, 0x0700, 0x0780,
|
||||
0x0800, 0x0880, 0x0900, 0x0980, 0x0a00, 0x0a80, 0x0b80, 0x0c00,
|
||||
0x0c80, 0x0d00, 0x0e00, 0x0e80, 0x0f00, 0x1000, 0x1080, 0x1180,
|
||||
0x1200, 0x1300, 0x1380, 0x1480, 0x1500, 0x1600, 0x1700, 0x1780,
|
||||
0x1880, 0x1980, 0x1a80, 0x1b00, 0x1c00, 0x1d00, 0x1e00, 0x1f00
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* 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) 2008, 2011-2012, Centre National d'Etudes Spatiales (CNES), FR
|
||||
* Copyright (c) 2012, CS Systemes d'Information, France
|
||||
* Copyright (c) 2017, IntoPIX SA <[email protected]>
|
||||
* 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 OPJ_T2_H
|
||||
#define OPJ_T2_H
|
||||
/**
|
||||
@file t2.h
|
||||
@brief Implementation of a tier-2 coding (packetization of code-block data) (T2)
|
||||
|
||||
*/
|
||||
|
||||
/** @defgroup T2 T2 - Implementation of a tier-2 coding */
|
||||
/*@{*/
|
||||
|
||||
/**
|
||||
Tier-2 coding
|
||||
*/
|
||||
typedef struct opj_t2 {
|
||||
|
||||
/** Encoding: pointer to the src image. Decoding: pointer to the dst image. */
|
||||
opj_image_t *image;
|
||||
/** pointer to the image coding parameters */
|
||||
opj_cp_t *cp;
|
||||
} opj_t2_t;
|
||||
|
||||
/** @name Exported functions */
|
||||
/*@{*/
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
Encode the packets of a tile to a destination buffer
|
||||
@param t2 T2 handle
|
||||
@param tileno number of the tile encoded
|
||||
@param tile the tile for which to write the packets
|
||||
@param maxlayers maximum number of layers
|
||||
@param dest the destination buffer
|
||||
@param p_data_written FIXME DOC
|
||||
@param len the length of the destination buffer
|
||||
@param cstr_info Codestream information structure
|
||||
@param p_marker_info Marker information structure
|
||||
@param tpnum Tile part number of the current tile
|
||||
@param tppos The position of the tile part flag in the progression order
|
||||
@param pino FIXME DOC
|
||||
@param t2_mode If == THRESH_CALC In Threshold calculation ,If == FINAL_PASS Final pass
|
||||
@param p_manager the user event manager
|
||||
*/
|
||||
OPJ_BOOL opj_t2_encode_packets(opj_t2_t* t2,
|
||||
OPJ_UINT32 tileno,
|
||||
opj_tcd_tile_t *tile,
|
||||
OPJ_UINT32 maxlayers,
|
||||
OPJ_BYTE *dest,
|
||||
OPJ_UINT32 * p_data_written,
|
||||
OPJ_UINT32 len,
|
||||
opj_codestream_info_t *cstr_info,
|
||||
opj_tcd_marker_info_t* p_marker_info,
|
||||
OPJ_UINT32 tpnum,
|
||||
OPJ_INT32 tppos,
|
||||
OPJ_UINT32 pino,
|
||||
J2K_T2_MODE t2_mode,
|
||||
opj_event_mgr_t *p_manager);
|
||||
|
||||
/**
|
||||
Decode the packets of a tile from a source buffer
|
||||
@param tcd TCD handle
|
||||
@param t2 T2 handle
|
||||
@param tileno number that identifies the tile for which to decode the packets
|
||||
@param tile tile for which to decode the packets
|
||||
@param src FIXME DOC
|
||||
@param p_data_read the source buffer
|
||||
@param len length of the source buffer
|
||||
@param cstr_info FIXME DOC
|
||||
@param p_manager the user event manager
|
||||
|
||||
@return FIXME DOC
|
||||
*/
|
||||
OPJ_BOOL opj_t2_decode_packets(opj_tcd_t* tcd,
|
||||
opj_t2_t *t2,
|
||||
OPJ_UINT32 tileno,
|
||||
opj_tcd_tile_t *tile,
|
||||
OPJ_BYTE *src,
|
||||
OPJ_UINT32 * p_data_read,
|
||||
OPJ_UINT32 len,
|
||||
opj_codestream_index_t *cstr_info,
|
||||
opj_event_mgr_t *p_manager);
|
||||
|
||||
/**
|
||||
* Creates a Tier 2 handle
|
||||
*
|
||||
* @param p_image Source or destination image
|
||||
* @param p_cp Image coding parameters.
|
||||
* @return a new T2 handle if successful, NULL otherwise.
|
||||
*/
|
||||
opj_t2_t* opj_t2_create(opj_image_t *p_image, opj_cp_t *p_cp);
|
||||
|
||||
/**
|
||||
Destroy a T2 handle
|
||||
@param t2 T2 handle to destroy
|
||||
*/
|
||||
void opj_t2_destroy(opj_t2_t *t2);
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/*@}*/
|
||||
|
||||
/*@}*/
|
||||
|
||||
#endif /* OPJ_T2_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,512 @@
|
||||
/*
|
||||
* 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) 2008, 2011-2012, Centre National d'Etudes Spatiales (CNES), FR
|
||||
* Copyright (c) 2012, CS Systemes d'Information, France
|
||||
* Copyright (c) 2017, IntoPIX SA <[email protected]>
|
||||
* 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 OPJ_TCD_H
|
||||
#define OPJ_TCD_H
|
||||
/**
|
||||
@file tcd.h
|
||||
@brief Implementation of a tile coder/decoder (TCD)
|
||||
|
||||
The functions in TCD.C encode or decode each tile independently from
|
||||
each other. The functions in TCD.C are used by other functions in J2K.C.
|
||||
*/
|
||||
|
||||
/** @defgroup TCD TCD - Implementation of a tile coder/decoder */
|
||||
/*@{*/
|
||||
|
||||
|
||||
/**
|
||||
FIXME DOC
|
||||
*/
|
||||
typedef struct opj_tcd_pass {
|
||||
OPJ_UINT32 rate;
|
||||
OPJ_FLOAT64 distortiondec;
|
||||
OPJ_UINT32 len;
|
||||
OPJ_BITFIELD term : 1;
|
||||
} opj_tcd_pass_t;
|
||||
|
||||
/**
|
||||
FIXME DOC
|
||||
*/
|
||||
typedef struct opj_tcd_layer {
|
||||
OPJ_UINT32 numpasses; /* Number of passes in the layer */
|
||||
OPJ_UINT32 len; /* len of information */
|
||||
OPJ_FLOAT64 disto; /* add for index (Cfr. Marcela) */
|
||||
OPJ_BYTE *data; /* data */
|
||||
} opj_tcd_layer_t;
|
||||
|
||||
/**
|
||||
FIXME DOC
|
||||
*/
|
||||
typedef struct opj_tcd_cblk_enc {
|
||||
OPJ_BYTE* data; /* Data */
|
||||
opj_tcd_layer_t* layers; /* layer information */
|
||||
opj_tcd_pass_t* passes; /* information about the passes */
|
||||
OPJ_INT32 x0, y0, x1,
|
||||
y1; /* dimension of the code-blocks : left upper corner (x0, y0) right low corner (x1,y1) */
|
||||
OPJ_UINT32 numbps;
|
||||
OPJ_UINT32 numlenbits;
|
||||
OPJ_UINT32 data_size; /* Size of allocated data buffer */
|
||||
OPJ_UINT32
|
||||
numpasses; /* number of pass already done for the code-blocks */
|
||||
OPJ_UINT32 numpassesinlayers; /* number of passes in the layer */
|
||||
OPJ_UINT32 totalpasses; /* total number of passes */
|
||||
} opj_tcd_cblk_enc_t;
|
||||
|
||||
|
||||
/** Chunk of codestream data that is part of a code block */
|
||||
typedef struct opj_tcd_seg_data_chunk {
|
||||
/* Point to tilepart buffer. We don't make a copy !
|
||||
So the tilepart buffer must be kept alive
|
||||
as long as we need to decode the codeblocks */
|
||||
OPJ_BYTE * data;
|
||||
OPJ_UINT32 len; /* Usable length of data */
|
||||
} opj_tcd_seg_data_chunk_t;
|
||||
|
||||
/** Segment of a code-block.
|
||||
* A segment represent a number of consecutive coding passes, without termination
|
||||
* of MQC or RAW between them. */
|
||||
typedef struct opj_tcd_seg {
|
||||
OPJ_UINT32 len; /* Size of data related to this segment */
|
||||
/* Number of passes decoded. Including those that we skip */
|
||||
OPJ_UINT32 numpasses;
|
||||
/* Number of passes actually to be decoded. To be used for code-block decoding */
|
||||
OPJ_UINT32 real_num_passes;
|
||||
/* Maximum number of passes for this segment */
|
||||
OPJ_UINT32 maxpasses;
|
||||
/* Number of new passes for current packed. Transitory value */
|
||||
OPJ_UINT32 numnewpasses;
|
||||
/* Codestream length for this segment for current packed. Transitory value */
|
||||
OPJ_UINT32 newlen;
|
||||
} opj_tcd_seg_t;
|
||||
|
||||
/** Code-block for decoding */
|
||||
typedef struct opj_tcd_cblk_dec {
|
||||
opj_tcd_seg_t* segs; /* segments information */
|
||||
opj_tcd_seg_data_chunk_t* chunks; /* Array of chunks */
|
||||
/* position of the code-blocks : left upper corner (x0, y0) right low corner (x1,y1) */
|
||||
OPJ_INT32 x0, y0, x1, y1;
|
||||
/* Mb is The maximum number of bit-planes available for the representation of
|
||||
coefficients in any sub-band, b, as defined in Equation (E-2). See
|
||||
Section B.10.5 of the standard */
|
||||
OPJ_UINT32 Mb; /* currently used only to check if HT decoding is correct */
|
||||
/* numbps is Mb - P as defined in Section B.10.5 of the standard */
|
||||
OPJ_UINT32 numbps;
|
||||
/* number of bits for len, for the current packet. Transitory value */
|
||||
OPJ_UINT32 numlenbits;
|
||||
/* number of pass added to the code-blocks, for the current packet. Transitory value */
|
||||
OPJ_UINT32 numnewpasses;
|
||||
/* number of segments, including those of packet we skip */
|
||||
OPJ_UINT32 numsegs;
|
||||
/* number of segments, to be used for code block decoding */
|
||||
OPJ_UINT32 real_num_segs;
|
||||
OPJ_UINT32 m_current_max_segs; /* allocated number of segs[] items */
|
||||
OPJ_UINT32 numchunks; /* Number of valid chunks items */
|
||||
OPJ_UINT32 numchunksalloc; /* Number of chunks item allocated */
|
||||
/* Decoded code-block. Only used for subtile decoding. Otherwise tilec->data is directly updated */
|
||||
OPJ_INT32* decoded_data;
|
||||
OPJ_BOOL corrupted; /* whether the code block data is corrupted */
|
||||
} opj_tcd_cblk_dec_t;
|
||||
|
||||
/** Precinct structure */
|
||||
typedef struct opj_tcd_precinct {
|
||||
/* dimension of the precinct : left upper corner (x0, y0) right low corner (x1,y1) */
|
||||
OPJ_INT32 x0, y0, x1, y1;
|
||||
OPJ_UINT32 cw, ch; /* number of code-blocks, in width and height */
|
||||
union { /* code-blocks information */
|
||||
opj_tcd_cblk_enc_t* enc;
|
||||
opj_tcd_cblk_dec_t* dec;
|
||||
void* blocks;
|
||||
} cblks;
|
||||
OPJ_UINT32 block_size; /* size taken by cblks (in bytes) */
|
||||
opj_tgt_tree_t *incltree; /* inclusion tree */
|
||||
opj_tgt_tree_t *imsbtree; /* IMSB tree */
|
||||
} opj_tcd_precinct_t;
|
||||
|
||||
/** Sub-band structure */
|
||||
typedef struct opj_tcd_band {
|
||||
/* dimension of the subband : left upper corner (x0, y0) right low corner (x1,y1) */
|
||||
OPJ_INT32 x0, y0, x1, y1;
|
||||
/* band number: for lowest resolution level (0=LL), otherwise (1=HL, 2=LH, 3=HH) */
|
||||
OPJ_UINT32 bandno;
|
||||
/* precinct information */
|
||||
opj_tcd_precinct_t *precincts;
|
||||
/* size of data taken by precincts */
|
||||
OPJ_UINT32 precincts_data_size;
|
||||
OPJ_INT32 numbps;
|
||||
OPJ_FLOAT32 stepsize;
|
||||
} opj_tcd_band_t;
|
||||
|
||||
/** Tile-component resolution structure */
|
||||
typedef struct opj_tcd_resolution {
|
||||
/* dimension of the resolution level : left upper corner (x0, y0) right low corner (x1,y1) */
|
||||
OPJ_INT32 x0, y0, x1, y1;
|
||||
/* number of precincts, in width and height, for this resolution level */
|
||||
OPJ_UINT32 pw, ph;
|
||||
/* number of sub-bands for the resolution level (1 for lowest resolution level, 3 otherwise) */
|
||||
OPJ_UINT32 numbands;
|
||||
/* subband information */
|
||||
opj_tcd_band_t bands[3];
|
||||
|
||||
/* dimension of the resolution limited to window of interest. Only valid if tcd->whole_tile_decoding is set */
|
||||
OPJ_UINT32 win_x0;
|
||||
OPJ_UINT32 win_y0;
|
||||
OPJ_UINT32 win_x1;
|
||||
OPJ_UINT32 win_y1;
|
||||
} opj_tcd_resolution_t;
|
||||
|
||||
/** Tile-component structure */
|
||||
typedef struct opj_tcd_tilecomp {
|
||||
/* dimension of component : left upper corner (x0, y0) right low corner (x1,y1) */
|
||||
OPJ_INT32 x0, y0, x1, y1;
|
||||
/* component number */
|
||||
OPJ_UINT32 compno;
|
||||
/* number of resolutions level */
|
||||
OPJ_UINT32 numresolutions;
|
||||
/* number of resolutions level to decode (at max)*/
|
||||
OPJ_UINT32 minimum_num_resolutions;
|
||||
/* resolutions information */
|
||||
opj_tcd_resolution_t *resolutions;
|
||||
/* size of data for resolutions (in bytes) */
|
||||
OPJ_UINT32 resolutions_size;
|
||||
|
||||
/* data of the component. For decoding, only valid if tcd->whole_tile_decoding is set (so exclusive of data_win member) */
|
||||
OPJ_INT32 *data;
|
||||
/* if true, then need to free after usage, otherwise do not free */
|
||||
OPJ_BOOL ownsData;
|
||||
/* we may either need to allocate this amount of data, or re-use image data and ignore this value */
|
||||
size_t data_size_needed;
|
||||
/* size of the data of the component */
|
||||
size_t data_size;
|
||||
|
||||
/** data of the component limited to window of interest. Only valid for decoding and if tcd->whole_tile_decoding is NOT set (so exclusive of data member) */
|
||||
OPJ_INT32 *data_win;
|
||||
/* dimension of the component limited to window of interest. Only valid for decoding and if tcd->whole_tile_decoding is NOT set */
|
||||
OPJ_UINT32 win_x0;
|
||||
OPJ_UINT32 win_y0;
|
||||
OPJ_UINT32 win_x1;
|
||||
OPJ_UINT32 win_y1;
|
||||
|
||||
/* number of pixels */
|
||||
OPJ_SIZE_T numpix;
|
||||
} opj_tcd_tilecomp_t;
|
||||
|
||||
|
||||
/**
|
||||
FIXME DOC
|
||||
*/
|
||||
typedef struct opj_tcd_tile {
|
||||
/* dimension of the tile : left upper corner (x0, y0) right low corner (x1,y1) */
|
||||
OPJ_INT32 x0, y0, x1, y1;
|
||||
OPJ_UINT32 numcomps; /* number of components in tile */
|
||||
opj_tcd_tilecomp_t *comps; /* Components information */
|
||||
OPJ_SIZE_T numpix; /* number of pixels */
|
||||
OPJ_FLOAT64 distotile; /* distortion of the tile */
|
||||
OPJ_FLOAT64 distolayer[100]; /* distortion per layer */
|
||||
OPJ_UINT32 packno; /* packet number */
|
||||
} opj_tcd_tile_t;
|
||||
|
||||
/**
|
||||
FIXME DOC
|
||||
*/
|
||||
typedef struct opj_tcd_image {
|
||||
opj_tcd_tile_t *tiles; /* Tiles information */
|
||||
}
|
||||
opj_tcd_image_t;
|
||||
|
||||
|
||||
/**
|
||||
Tile coder/decoder
|
||||
*/
|
||||
typedef struct opj_tcd {
|
||||
/** Position of the tilepart flag in Progression order*/
|
||||
OPJ_INT32 tp_pos;
|
||||
/** Tile part number*/
|
||||
OPJ_UINT32 tp_num;
|
||||
/** Current tile part number*/
|
||||
OPJ_UINT32 cur_tp_num;
|
||||
/** Total number of tileparts of the current tile*/
|
||||
OPJ_UINT32 cur_totnum_tp;
|
||||
/** Current Packet iterator number */
|
||||
OPJ_UINT32 cur_pino;
|
||||
/** info on each image tile */
|
||||
opj_tcd_image_t *tcd_image;
|
||||
/** image header */
|
||||
opj_image_t *image;
|
||||
/** coding parameters */
|
||||
opj_cp_t *cp;
|
||||
/** coding/decoding parameters common to all tiles */
|
||||
opj_tcp_t *tcp;
|
||||
/** current encoded/decoded tile */
|
||||
OPJ_UINT32 tcd_tileno;
|
||||
/** tell if the tcd is a decoder. */
|
||||
OPJ_BITFIELD m_is_decoder : 1;
|
||||
/** Thread pool */
|
||||
opj_thread_pool_t* thread_pool;
|
||||
/** Coordinates of the window of interest, in grid reference space */
|
||||
OPJ_UINT32 win_x0;
|
||||
OPJ_UINT32 win_y0;
|
||||
OPJ_UINT32 win_x1;
|
||||
OPJ_UINT32 win_y1;
|
||||
/** Only valid for decoding. Whether the whole tile is decoded, or just the region in win_x0/win_y0/win_x1/win_y1 */
|
||||
OPJ_BOOL whole_tile_decoding;
|
||||
/* Array of size image->numcomps indicating if a component must be decoded. NULL if all components must be decoded */
|
||||
OPJ_BOOL* used_component;
|
||||
} opj_tcd_t;
|
||||
|
||||
/**
|
||||
* Structure to hold information needed to generate some markers.
|
||||
* Used by encoder.
|
||||
*/
|
||||
typedef struct opj_tcd_marker_info {
|
||||
/** In: Whether information to generate PLT markers in needed */
|
||||
OPJ_BOOL need_PLT;
|
||||
|
||||
/** OUT: Number of elements in p_packet_size[] array */
|
||||
OPJ_UINT32 packet_count;
|
||||
|
||||
/** OUT: Array of size packet_count, such that p_packet_size[i] is
|
||||
* the size in bytes of the ith packet */
|
||||
OPJ_UINT32* p_packet_size;
|
||||
} opj_tcd_marker_info_t;
|
||||
|
||||
/** @name Exported functions */
|
||||
/*@{*/
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
Dump the content of a tcd structure
|
||||
*/
|
||||
/*void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_image_t *img);*/ /* TODO MSD should use the new v2 structures */
|
||||
|
||||
/**
|
||||
Create a new TCD handle
|
||||
@param p_is_decoder FIXME DOC
|
||||
@return Returns a new TCD handle if successful returns NULL otherwise
|
||||
*/
|
||||
opj_tcd_t* opj_tcd_create(OPJ_BOOL p_is_decoder);
|
||||
|
||||
/**
|
||||
Destroy a previously created TCD handle
|
||||
@param tcd TCD handle to destroy
|
||||
*/
|
||||
void opj_tcd_destroy(opj_tcd_t *tcd);
|
||||
|
||||
|
||||
/**
|
||||
* Create a new opj_tcd_marker_info_t* structure
|
||||
* @param need_PLT Whether information is needed to generate PLT markers.
|
||||
*/
|
||||
opj_tcd_marker_info_t* opj_tcd_marker_info_create(OPJ_BOOL need_PLT);
|
||||
|
||||
|
||||
/**
|
||||
Destroy a previously created opj_tcd_marker_info_t* structure
|
||||
@param p_tcd_marker_info Structure to destroy
|
||||
*/
|
||||
void opj_tcd_marker_info_destroy(opj_tcd_marker_info_t *p_tcd_marker_info);
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the tile coder and may reuse some memory.
|
||||
* @param p_tcd TCD handle.
|
||||
* @param p_image raw image.
|
||||
* @param p_cp coding parameters.
|
||||
* @param p_tp thread pool
|
||||
*
|
||||
* @return true if the encoding values could be set (false otherwise).
|
||||
*/
|
||||
OPJ_BOOL opj_tcd_init(opj_tcd_t *p_tcd,
|
||||
opj_image_t * p_image,
|
||||
opj_cp_t * p_cp,
|
||||
opj_thread_pool_t* p_tp);
|
||||
|
||||
/**
|
||||
* Allocates memory for decoding a specific tile.
|
||||
*
|
||||
* @param p_tcd the tile decoder.
|
||||
* @param p_tile_no the index of the tile received in sequence. This not necessarily lead to the
|
||||
* tile at index p_tile_no.
|
||||
* @param p_manager the event manager.
|
||||
*
|
||||
* @return true if the remaining data is sufficient.
|
||||
*/
|
||||
OPJ_BOOL opj_tcd_init_decode_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
|
||||
opj_event_mgr_t* p_manager);
|
||||
|
||||
/**
|
||||
* Gets the maximum tile size that will be taken by the tile once decoded.
|
||||
*/
|
||||
OPJ_UINT32 opj_tcd_get_decoded_tile_size(opj_tcd_t *p_tcd,
|
||||
OPJ_BOOL take_into_account_partial_decoding);
|
||||
|
||||
/**
|
||||
* Encodes a tile from the raw image into the given buffer.
|
||||
* @param p_tcd Tile Coder handle
|
||||
* @param p_tile_no Index of the tile to encode.
|
||||
* @param p_dest Destination buffer
|
||||
* @param p_data_written pointer to an int that is incremented by the number of bytes really written on p_dest
|
||||
* @param p_len Maximum length of the destination buffer
|
||||
* @param p_cstr_info Codestream information structure
|
||||
* @param p_marker_info Marker information structure
|
||||
* @param p_manager the user event manager
|
||||
* @return true if the coding is successful.
|
||||
*/
|
||||
OPJ_BOOL opj_tcd_encode_tile(opj_tcd_t *p_tcd,
|
||||
OPJ_UINT32 p_tile_no,
|
||||
OPJ_BYTE *p_dest,
|
||||
OPJ_UINT32 * p_data_written,
|
||||
OPJ_UINT32 p_len,
|
||||
struct opj_codestream_info *p_cstr_info,
|
||||
opj_tcd_marker_info_t* p_marker_info,
|
||||
opj_event_mgr_t *p_manager);
|
||||
|
||||
|
||||
/**
|
||||
Decode a tile from a buffer into a raw image
|
||||
@param tcd TCD handle
|
||||
@param win_x0 Upper left x of region to decode (in grid coordinates)
|
||||
@param win_y0 Upper left y of region to decode (in grid coordinates)
|
||||
@param win_x1 Lower right x of region to decode (in grid coordinates)
|
||||
@param win_y1 Lower right y of region to decode (in grid coordinates)
|
||||
@param numcomps_to_decode Size of the comps_indices array, or 0 if decoding all components.
|
||||
@param comps_indices Array of numcomps values representing the indices
|
||||
of the components to decode (relative to the
|
||||
codestream, starting at 0). Or NULL if decoding all components.
|
||||
@param src Source buffer
|
||||
@param len Length of source buffer
|
||||
@param tileno Number that identifies one of the tiles to be decoded
|
||||
@param cstr_info FIXME DOC
|
||||
@param manager the event manager.
|
||||
*/
|
||||
OPJ_BOOL opj_tcd_decode_tile(opj_tcd_t *tcd,
|
||||
OPJ_UINT32 win_x0,
|
||||
OPJ_UINT32 win_y0,
|
||||
OPJ_UINT32 win_x1,
|
||||
OPJ_UINT32 win_y1,
|
||||
OPJ_UINT32 numcomps_to_decode,
|
||||
const OPJ_UINT32 *comps_indices,
|
||||
OPJ_BYTE *src,
|
||||
OPJ_UINT32 len,
|
||||
OPJ_UINT32 tileno,
|
||||
opj_codestream_index_t *cstr_info,
|
||||
opj_event_mgr_t *manager);
|
||||
|
||||
|
||||
/**
|
||||
* Copies tile data from the system onto the given memory block.
|
||||
*/
|
||||
OPJ_BOOL opj_tcd_update_tile_data(opj_tcd_t *p_tcd,
|
||||
OPJ_BYTE * p_dest,
|
||||
OPJ_UINT32 p_dest_length);
|
||||
|
||||
/**
|
||||
* Get the size in bytes of the input buffer provided before encoded.
|
||||
* This must be the size provided to the p_src_length argument of
|
||||
* opj_tcd_copy_tile_data()
|
||||
*/
|
||||
OPJ_SIZE_T opj_tcd_get_encoder_input_buffer_size(opj_tcd_t *p_tcd);
|
||||
|
||||
/**
|
||||
* Initialize the tile coder and may reuse some memory.
|
||||
*
|
||||
* @param p_tcd TCD handle.
|
||||
* @param p_tile_no current tile index to encode.
|
||||
* @param p_manager the event manager.
|
||||
*
|
||||
* @return true if the encoding values could be set (false otherwise).
|
||||
*/
|
||||
OPJ_BOOL opj_tcd_init_encode_tile(opj_tcd_t *p_tcd,
|
||||
OPJ_UINT32 p_tile_no, opj_event_mgr_t* p_manager);
|
||||
|
||||
/**
|
||||
* Copies tile data from the given memory block onto the system.
|
||||
*
|
||||
* p_src_length must be equal to opj_tcd_get_encoder_input_buffer_size()
|
||||
*/
|
||||
OPJ_BOOL opj_tcd_copy_tile_data(opj_tcd_t *p_tcd,
|
||||
OPJ_BYTE * p_src,
|
||||
OPJ_SIZE_T p_src_length);
|
||||
|
||||
/**
|
||||
* Allocates tile component data
|
||||
*
|
||||
*
|
||||
*/
|
||||
OPJ_BOOL opj_alloc_tile_component_data(opj_tcd_tilecomp_t *l_tilec);
|
||||
|
||||
/** Returns whether a sub-band is empty (i.e. whether it has a null area)
|
||||
* @param band Sub-band handle.
|
||||
* @return OPJ_TRUE whether the sub-band is empty.
|
||||
*/
|
||||
OPJ_BOOL opj_tcd_is_band_empty(opj_tcd_band_t* band);
|
||||
|
||||
/** Reinitialize a segment */
|
||||
void opj_tcd_reinit_segment(opj_tcd_seg_t* seg);
|
||||
|
||||
|
||||
/** Returns whether a sub-band region contributes to the area of interest
|
||||
* tcd->win_x0,tcd->win_y0,tcd->win_x1,tcd->win_y1.
|
||||
*
|
||||
* @param tcd TCD handle.
|
||||
* @param compno Component number
|
||||
* @param resno Resolution number
|
||||
* @param bandno Band number (*not* band index, ie 0, 1, 2 or 3)
|
||||
* @param x0 Upper left x in subband coordinates
|
||||
* @param y0 Upper left y in subband coordinates
|
||||
* @param x1 Lower right x in subband coordinates
|
||||
* @param y1 Lower right y in subband coordinates
|
||||
* @return OPJ_TRUE whether the sub-band region contributes to the area of
|
||||
* interest.
|
||||
*/
|
||||
OPJ_BOOL opj_tcd_is_subband_area_of_interest(opj_tcd_t *tcd,
|
||||
OPJ_UINT32 compno,
|
||||
OPJ_UINT32 resno,
|
||||
OPJ_UINT32 bandno,
|
||||
OPJ_UINT32 x0,
|
||||
OPJ_UINT32 y0,
|
||||
OPJ_UINT32 x1,
|
||||
OPJ_UINT32 y1);
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/*@}*/
|
||||
|
||||
/*@}*/
|
||||
|
||||
#endif /* OPJ_TCD_H */
|
||||
@@ -0,0 +1,344 @@
|
||||
/*
|
||||
* 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) 2008, 2011-2012, Centre National d'Etudes Spatiales (CNES), FR
|
||||
* Copyright (c) 2012, CS Systemes d'Information, France
|
||||
* 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 "opj_includes.h"
|
||||
|
||||
/*
|
||||
==========================================================
|
||||
Tag-tree coder interface
|
||||
==========================================================
|
||||
*/
|
||||
|
||||
opj_tgt_tree_t *opj_tgt_create(OPJ_UINT32 numleafsh, OPJ_UINT32 numleafsv,
|
||||
opj_event_mgr_t *p_manager)
|
||||
{
|
||||
OPJ_INT32 nplh[32];
|
||||
OPJ_INT32 nplv[32];
|
||||
opj_tgt_node_t *node = 00;
|
||||
opj_tgt_node_t *l_parent_node = 00;
|
||||
opj_tgt_node_t *l_parent_node0 = 00;
|
||||
opj_tgt_tree_t *tree = 00;
|
||||
OPJ_UINT32 i;
|
||||
OPJ_INT32 j, k;
|
||||
OPJ_UINT32 numlvls;
|
||||
OPJ_UINT32 n;
|
||||
|
||||
tree = (opj_tgt_tree_t *) opj_calloc(1, sizeof(opj_tgt_tree_t));
|
||||
if (!tree) {
|
||||
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to create Tag-tree\n");
|
||||
return 00;
|
||||
}
|
||||
|
||||
tree->numleafsh = numleafsh;
|
||||
tree->numleafsv = numleafsv;
|
||||
|
||||
numlvls = 0;
|
||||
nplh[0] = (OPJ_INT32)numleafsh;
|
||||
nplv[0] = (OPJ_INT32)numleafsv;
|
||||
tree->numnodes = 0;
|
||||
do {
|
||||
n = (OPJ_UINT32)(nplh[numlvls] * nplv[numlvls]);
|
||||
nplh[numlvls + 1] = (nplh[numlvls] + 1) / 2;
|
||||
nplv[numlvls + 1] = (nplv[numlvls] + 1) / 2;
|
||||
tree->numnodes += n;
|
||||
++numlvls;
|
||||
} while (n > 1);
|
||||
|
||||
/* ADD */
|
||||
if (tree->numnodes == 0) {
|
||||
opj_free(tree);
|
||||
return 00;
|
||||
}
|
||||
|
||||
tree->nodes = (opj_tgt_node_t*) opj_calloc(tree->numnodes,
|
||||
sizeof(opj_tgt_node_t));
|
||||
if (!tree->nodes) {
|
||||
opj_event_msg(p_manager, EVT_ERROR,
|
||||
"Not enough memory to create Tag-tree nodes\n");
|
||||
opj_free(tree);
|
||||
return 00;
|
||||
}
|
||||
tree->nodes_size = tree->numnodes * (OPJ_UINT32)sizeof(opj_tgt_node_t);
|
||||
|
||||
node = tree->nodes;
|
||||
l_parent_node = &tree->nodes[tree->numleafsh * tree->numleafsv];
|
||||
l_parent_node0 = l_parent_node;
|
||||
|
||||
for (i = 0; i < numlvls - 1; ++i) {
|
||||
for (j = 0; j < nplv[i]; ++j) {
|
||||
k = nplh[i];
|
||||
while (--k >= 0) {
|
||||
node->parent = l_parent_node;
|
||||
++node;
|
||||
if (--k >= 0) {
|
||||
node->parent = l_parent_node;
|
||||
++node;
|
||||
}
|
||||
++l_parent_node;
|
||||
}
|
||||
if ((j & 1) || j == nplv[i] - 1) {
|
||||
l_parent_node0 = l_parent_node;
|
||||
} else {
|
||||
l_parent_node = l_parent_node0;
|
||||
l_parent_node0 += nplh[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
node->parent = 0;
|
||||
opj_tgt_reset(tree);
|
||||
return tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reinitialises a tag-tree from an existing one.
|
||||
*
|
||||
* @param p_tree the tree to reinitialize.
|
||||
* @param p_num_leafs_h the width of the array of leafs of the tree
|
||||
* @param p_num_leafs_v the height of the array of leafs of the tree
|
||||
* @return a new tag-tree if successful, NULL otherwise
|
||||
*/
|
||||
opj_tgt_tree_t *opj_tgt_init(opj_tgt_tree_t * p_tree, OPJ_UINT32 p_num_leafs_h,
|
||||
OPJ_UINT32 p_num_leafs_v, opj_event_mgr_t *p_manager)
|
||||
{
|
||||
OPJ_INT32 l_nplh[32];
|
||||
OPJ_INT32 l_nplv[32];
|
||||
opj_tgt_node_t *l_node = 00;
|
||||
opj_tgt_node_t *l_parent_node = 00;
|
||||
opj_tgt_node_t *l_parent_node0 = 00;
|
||||
OPJ_UINT32 i;
|
||||
OPJ_INT32 j, k;
|
||||
OPJ_UINT32 l_num_levels;
|
||||
OPJ_UINT32 n;
|
||||
OPJ_UINT32 l_node_size;
|
||||
|
||||
if (! p_tree) {
|
||||
return 00;
|
||||
}
|
||||
|
||||
if ((p_tree->numleafsh != p_num_leafs_h) ||
|
||||
(p_tree->numleafsv != p_num_leafs_v)) {
|
||||
p_tree->numleafsh = p_num_leafs_h;
|
||||
p_tree->numleafsv = p_num_leafs_v;
|
||||
|
||||
l_num_levels = 0;
|
||||
l_nplh[0] = (OPJ_INT32)p_num_leafs_h;
|
||||
l_nplv[0] = (OPJ_INT32)p_num_leafs_v;
|
||||
p_tree->numnodes = 0;
|
||||
do {
|
||||
n = (OPJ_UINT32)(l_nplh[l_num_levels] * l_nplv[l_num_levels]);
|
||||
l_nplh[l_num_levels + 1] = (l_nplh[l_num_levels] + 1) / 2;
|
||||
l_nplv[l_num_levels + 1] = (l_nplv[l_num_levels] + 1) / 2;
|
||||
p_tree->numnodes += n;
|
||||
++l_num_levels;
|
||||
} while (n > 1);
|
||||
|
||||
/* ADD */
|
||||
if (p_tree->numnodes == 0) {
|
||||
opj_tgt_destroy(p_tree);
|
||||
return 00;
|
||||
}
|
||||
l_node_size = p_tree->numnodes * (OPJ_UINT32)sizeof(opj_tgt_node_t);
|
||||
|
||||
if (l_node_size > p_tree->nodes_size) {
|
||||
opj_tgt_node_t* new_nodes = (opj_tgt_node_t*) opj_realloc(p_tree->nodes,
|
||||
l_node_size);
|
||||
if (! new_nodes) {
|
||||
opj_event_msg(p_manager, EVT_ERROR,
|
||||
"Not enough memory to reinitialize the tag tree\n");
|
||||
opj_tgt_destroy(p_tree);
|
||||
return 00;
|
||||
}
|
||||
p_tree->nodes = new_nodes;
|
||||
memset(((char *) p_tree->nodes) + p_tree->nodes_size, 0,
|
||||
l_node_size - p_tree->nodes_size);
|
||||
p_tree->nodes_size = l_node_size;
|
||||
}
|
||||
l_node = p_tree->nodes;
|
||||
l_parent_node = &p_tree->nodes[p_tree->numleafsh * p_tree->numleafsv];
|
||||
l_parent_node0 = l_parent_node;
|
||||
|
||||
for (i = 0; i < l_num_levels - 1; ++i) {
|
||||
for (j = 0; j < l_nplv[i]; ++j) {
|
||||
k = l_nplh[i];
|
||||
while (--k >= 0) {
|
||||
l_node->parent = l_parent_node;
|
||||
++l_node;
|
||||
if (--k >= 0) {
|
||||
l_node->parent = l_parent_node;
|
||||
++l_node;
|
||||
}
|
||||
++l_parent_node;
|
||||
}
|
||||
if ((j & 1) || j == l_nplv[i] - 1) {
|
||||
l_parent_node0 = l_parent_node;
|
||||
} else {
|
||||
l_parent_node = l_parent_node0;
|
||||
l_parent_node0 += l_nplh[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
l_node->parent = 0;
|
||||
}
|
||||
opj_tgt_reset(p_tree);
|
||||
|
||||
return p_tree;
|
||||
}
|
||||
|
||||
void opj_tgt_destroy(opj_tgt_tree_t *p_tree)
|
||||
{
|
||||
if (! p_tree) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (p_tree->nodes) {
|
||||
opj_free(p_tree->nodes);
|
||||
p_tree->nodes = 00;
|
||||
}
|
||||
opj_free(p_tree);
|
||||
}
|
||||
|
||||
void opj_tgt_reset(opj_tgt_tree_t *p_tree)
|
||||
{
|
||||
OPJ_UINT32 i;
|
||||
opj_tgt_node_t * l_current_node = 00;;
|
||||
|
||||
if (! p_tree) {
|
||||
return;
|
||||
}
|
||||
|
||||
l_current_node = p_tree->nodes;
|
||||
for (i = 0; i < p_tree->numnodes; ++i) {
|
||||
l_current_node->value = 999;
|
||||
l_current_node->low = 0;
|
||||
l_current_node->known = 0;
|
||||
++l_current_node;
|
||||
}
|
||||
}
|
||||
|
||||
void opj_tgt_setvalue(opj_tgt_tree_t *tree, OPJ_UINT32 leafno, OPJ_INT32 value)
|
||||
{
|
||||
opj_tgt_node_t *node;
|
||||
node = &tree->nodes[leafno];
|
||||
while (node && node->value > value) {
|
||||
node->value = value;
|
||||
node = node->parent;
|
||||
}
|
||||
}
|
||||
|
||||
void opj_tgt_encode(opj_bio_t *bio, opj_tgt_tree_t *tree, OPJ_UINT32 leafno,
|
||||
OPJ_INT32 threshold)
|
||||
{
|
||||
opj_tgt_node_t *stk[31];
|
||||
opj_tgt_node_t **stkptr;
|
||||
opj_tgt_node_t *node;
|
||||
OPJ_INT32 low;
|
||||
|
||||
stkptr = stk;
|
||||
node = &tree->nodes[leafno];
|
||||
while (node->parent) {
|
||||
*stkptr++ = node;
|
||||
node = node->parent;
|
||||
}
|
||||
|
||||
low = 0;
|
||||
for (;;) {
|
||||
if (low > node->low) {
|
||||
node->low = low;
|
||||
} else {
|
||||
low = node->low;
|
||||
}
|
||||
|
||||
while (low < threshold) {
|
||||
if (low >= node->value) {
|
||||
if (!node->known) {
|
||||
opj_bio_putbit(bio, 1);
|
||||
node->known = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
opj_bio_putbit(bio, 0);
|
||||
++low;
|
||||
}
|
||||
|
||||
node->low = low;
|
||||
if (stkptr == stk) {
|
||||
break;
|
||||
}
|
||||
node = *--stkptr;
|
||||
}
|
||||
}
|
||||
|
||||
OPJ_UINT32 opj_tgt_decode(opj_bio_t *bio, opj_tgt_tree_t *tree,
|
||||
OPJ_UINT32 leafno, OPJ_INT32 threshold)
|
||||
{
|
||||
opj_tgt_node_t *stk[31];
|
||||
opj_tgt_node_t **stkptr;
|
||||
opj_tgt_node_t *node;
|
||||
OPJ_INT32 low;
|
||||
|
||||
stkptr = stk;
|
||||
node = &tree->nodes[leafno];
|
||||
while (node->parent) {
|
||||
*stkptr++ = node;
|
||||
node = node->parent;
|
||||
}
|
||||
|
||||
low = 0;
|
||||
for (;;) {
|
||||
if (low > node->low) {
|
||||
node->low = low;
|
||||
} else {
|
||||
low = node->low;
|
||||
}
|
||||
while (low < threshold && low < node->value) {
|
||||
if (opj_bio_read(bio, 1)) {
|
||||
node->value = low;
|
||||
} else {
|
||||
++low;
|
||||
}
|
||||
}
|
||||
node->low = low;
|
||||
if (stkptr == stk) {
|
||||
break;
|
||||
}
|
||||
node = *--stkptr;
|
||||
}
|
||||
|
||||
return (node->value < threshold) ? 1 : 0;
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* 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) 2008, Jerome Fimes, Communications & Systemes <[email protected]>
|
||||
* Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France
|
||||
* Copyright (c) 2012, CS Systemes d'Information, France
|
||||
* 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 OPJ_TGT_H
|
||||
#define OPJ_TGT_H
|
||||
/**
|
||||
@file tgt.h
|
||||
@brief Implementation of a tag-tree coder (TGT)
|
||||
|
||||
The functions in TGT.C have for goal to realize a tag-tree coder. The functions in TGT.C
|
||||
are used by some function in T2.C.
|
||||
*/
|
||||
|
||||
/** @defgroup TGT TGT - Implementation of a tag-tree coder */
|
||||
/*@{*/
|
||||
|
||||
/**
|
||||
Tag node
|
||||
*/
|
||||
typedef struct opj_tgt_node {
|
||||
struct opj_tgt_node *parent;
|
||||
OPJ_INT32 value;
|
||||
OPJ_INT32 low;
|
||||
OPJ_UINT32 known;
|
||||
} opj_tgt_node_t;
|
||||
|
||||
/**
|
||||
Tag tree
|
||||
*/
|
||||
typedef struct opj_tgt_tree {
|
||||
OPJ_UINT32 numleafsh;
|
||||
OPJ_UINT32 numleafsv;
|
||||
OPJ_UINT32 numnodes;
|
||||
opj_tgt_node_t *nodes;
|
||||
OPJ_UINT32 nodes_size; /* maximum size taken by nodes */
|
||||
} opj_tgt_tree_t;
|
||||
|
||||
|
||||
/** @name Exported functions */
|
||||
/*@{*/
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/**
|
||||
Create a tag-tree
|
||||
@param numleafsh Width of the array of leafs of the tree
|
||||
@param numleafsv Height of the array of leafs of the tree
|
||||
@param p_manager the event manager
|
||||
@return Returns a new tag-tree if successful, returns NULL otherwise
|
||||
*/
|
||||
opj_tgt_tree_t *opj_tgt_create(OPJ_UINT32 numleafsh, OPJ_UINT32 numleafsv,
|
||||
opj_event_mgr_t *p_manager);
|
||||
|
||||
/**
|
||||
* Reinitialises a tag-tree from an exixting one.
|
||||
*
|
||||
* @param p_tree the tree to reinitialize.
|
||||
* @param p_num_leafs_h the width of the array of leafs of the tree
|
||||
* @param p_num_leafs_v the height of the array of leafs of the tree
|
||||
* @param p_manager the event manager
|
||||
* @return a new tag-tree if successful, NULL otherwise
|
||||
*/
|
||||
opj_tgt_tree_t *opj_tgt_init(opj_tgt_tree_t * p_tree,
|
||||
OPJ_UINT32 p_num_leafs_h,
|
||||
OPJ_UINT32 p_num_leafs_v, opj_event_mgr_t *p_manager);
|
||||
/**
|
||||
Destroy a tag-tree, liberating memory
|
||||
@param tree Tag-tree to destroy
|
||||
*/
|
||||
void opj_tgt_destroy(opj_tgt_tree_t *tree);
|
||||
/**
|
||||
Reset a tag-tree (set all leaves to 0)
|
||||
@param tree Tag-tree to reset
|
||||
*/
|
||||
void opj_tgt_reset(opj_tgt_tree_t *tree);
|
||||
/**
|
||||
Set the value of a leaf of a tag-tree
|
||||
@param tree Tag-tree to modify
|
||||
@param leafno Number that identifies the leaf to modify
|
||||
@param value New value of the leaf
|
||||
*/
|
||||
void opj_tgt_setvalue(opj_tgt_tree_t *tree,
|
||||
OPJ_UINT32 leafno,
|
||||
OPJ_INT32 value);
|
||||
/**
|
||||
Encode the value of a leaf of the tag-tree up to a given threshold
|
||||
@param bio Pointer to a BIO handle
|
||||
@param tree Tag-tree to modify
|
||||
@param leafno Number that identifies the leaf to encode
|
||||
@param threshold Threshold to use when encoding value of the leaf
|
||||
*/
|
||||
void opj_tgt_encode(opj_bio_t *bio,
|
||||
opj_tgt_tree_t *tree,
|
||||
OPJ_UINT32 leafno,
|
||||
OPJ_INT32 threshold);
|
||||
/**
|
||||
Decode the value of a leaf of the tag-tree up to a given threshold
|
||||
@param bio Pointer to a BIO handle
|
||||
@param tree Tag-tree to decode
|
||||
@param leafno Number that identifies the leaf to decode
|
||||
@param threshold Threshold to use when decoding value of the leaf
|
||||
@return Returns 1 if the node's value < threshold, returns 0 otherwise
|
||||
*/
|
||||
OPJ_UINT32 opj_tgt_decode(opj_bio_t *bio,
|
||||
opj_tgt_tree_t *tree,
|
||||
OPJ_UINT32 leafno,
|
||||
OPJ_INT32 threshold);
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/*@}*/
|
||||
|
||||
/*@}*/
|
||||
|
||||
#endif /* OPJ_TGT_H */
|
||||
@@ -0,0 +1,954 @@
|
||||
/*
|
||||
* 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) 2016, Even Rouault
|
||||
* 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 <assert.h>
|
||||
|
||||
#ifdef MUTEX_win32
|
||||
|
||||
/* Some versions of x86_64-w64-mingw32-gc -m32 resolve InterlockedCompareExchange() */
|
||||
/* as __sync_val_compare_and_swap_4 but fails to link it. As this protects against */
|
||||
/* a rather unlikely race, skip it */
|
||||
#if !(defined(__MINGW32__) && defined(__i386__))
|
||||
#define HAVE_INTERLOCKED_COMPARE_EXCHANGE 1
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
|
||||
#include "opj_includes.h"
|
||||
|
||||
OPJ_BOOL OPJ_CALLCONV opj_has_thread_support(void)
|
||||
{
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
int OPJ_CALLCONV opj_get_num_cpus(void)
|
||||
{
|
||||
SYSTEM_INFO info;
|
||||
DWORD dwNum;
|
||||
GetSystemInfo(&info);
|
||||
dwNum = info.dwNumberOfProcessors;
|
||||
if (dwNum < 1) {
|
||||
return 1;
|
||||
}
|
||||
return (int)dwNum;
|
||||
}
|
||||
|
||||
struct opj_mutex_t {
|
||||
CRITICAL_SECTION cs;
|
||||
};
|
||||
|
||||
opj_mutex_t* opj_mutex_create(void)
|
||||
{
|
||||
opj_mutex_t* mutex = (opj_mutex_t*) opj_malloc(sizeof(opj_mutex_t));
|
||||
if (!mutex) {
|
||||
return NULL;
|
||||
}
|
||||
InitializeCriticalSectionAndSpinCount(&(mutex->cs), 4000);
|
||||
return mutex;
|
||||
}
|
||||
|
||||
void opj_mutex_lock(opj_mutex_t* mutex)
|
||||
{
|
||||
EnterCriticalSection(&(mutex->cs));
|
||||
}
|
||||
|
||||
void opj_mutex_unlock(opj_mutex_t* mutex)
|
||||
{
|
||||
LeaveCriticalSection(&(mutex->cs));
|
||||
}
|
||||
|
||||
void opj_mutex_destroy(opj_mutex_t* mutex)
|
||||
{
|
||||
if (!mutex) {
|
||||
return;
|
||||
}
|
||||
DeleteCriticalSection(&(mutex->cs));
|
||||
opj_free(mutex);
|
||||
}
|
||||
|
||||
struct opj_cond_waiter_list_t {
|
||||
HANDLE hEvent;
|
||||
struct opj_cond_waiter_list_t* next;
|
||||
};
|
||||
typedef struct opj_cond_waiter_list_t opj_cond_waiter_list_t;
|
||||
|
||||
struct opj_cond_t {
|
||||
opj_mutex_t *internal_mutex;
|
||||
opj_cond_waiter_list_t *waiter_list;
|
||||
};
|
||||
|
||||
static DWORD TLSKey = 0;
|
||||
static volatile LONG inTLSLockedSection = 0;
|
||||
static volatile int TLSKeyInit = OPJ_FALSE;
|
||||
|
||||
opj_cond_t* opj_cond_create(void)
|
||||
{
|
||||
opj_cond_t* cond = (opj_cond_t*) opj_malloc(sizeof(opj_cond_t));
|
||||
if (!cond) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Make sure that the TLS key is allocated in a thread-safe way */
|
||||
/* We cannot use a global mutex/critical section since its creation itself would not be */
|
||||
/* thread-safe, so use InterlockedCompareExchange trick */
|
||||
while (OPJ_TRUE) {
|
||||
|
||||
#if HAVE_INTERLOCKED_COMPARE_EXCHANGE
|
||||
if (InterlockedCompareExchange(&inTLSLockedSection, 1, 0) == 0)
|
||||
#endif
|
||||
{
|
||||
if (!TLSKeyInit) {
|
||||
TLSKey = TlsAlloc();
|
||||
TLSKeyInit = OPJ_TRUE;
|
||||
}
|
||||
#if HAVE_INTERLOCKED_COMPARE_EXCHANGE
|
||||
InterlockedCompareExchange(&inTLSLockedSection, 0, 1);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (TLSKey == TLS_OUT_OF_INDEXES) {
|
||||
opj_free(cond);
|
||||
return NULL;
|
||||
}
|
||||
cond->internal_mutex = opj_mutex_create();
|
||||
if (cond->internal_mutex == NULL) {
|
||||
opj_free(cond);
|
||||
return NULL;
|
||||
}
|
||||
cond->waiter_list = NULL;
|
||||
return cond;
|
||||
}
|
||||
|
||||
void opj_cond_wait(opj_cond_t* cond, opj_mutex_t* mutex)
|
||||
{
|
||||
opj_cond_waiter_list_t* item;
|
||||
HANDLE hEvent = (HANDLE) TlsGetValue(TLSKey);
|
||||
if (hEvent == NULL) {
|
||||
hEvent = CreateEvent(NULL, /* security attributes */
|
||||
0, /* manual reset = no */
|
||||
0, /* initial state = unsignaled */
|
||||
NULL /* no name */);
|
||||
assert(hEvent);
|
||||
|
||||
TlsSetValue(TLSKey, hEvent);
|
||||
}
|
||||
|
||||
/* Insert the waiter into the waiter list of the condition */
|
||||
opj_mutex_lock(cond->internal_mutex);
|
||||
|
||||
item = (opj_cond_waiter_list_t*)opj_malloc(sizeof(opj_cond_waiter_list_t));
|
||||
assert(item != NULL);
|
||||
|
||||
item->hEvent = hEvent;
|
||||
item->next = cond->waiter_list;
|
||||
|
||||
cond->waiter_list = item;
|
||||
|
||||
opj_mutex_unlock(cond->internal_mutex);
|
||||
|
||||
/* Release the client mutex before waiting for the event being signaled */
|
||||
opj_mutex_unlock(mutex);
|
||||
|
||||
/* Ideally we would check that we do not get WAIT_FAILED but it is hard */
|
||||
/* to report a failure. */
|
||||
WaitForSingleObject(hEvent, INFINITE);
|
||||
|
||||
/* Reacquire the client mutex */
|
||||
opj_mutex_lock(mutex);
|
||||
}
|
||||
|
||||
void opj_cond_signal(opj_cond_t* cond)
|
||||
{
|
||||
opj_cond_waiter_list_t* psIter;
|
||||
|
||||
/* Signal the first registered event, and remove it from the list */
|
||||
opj_mutex_lock(cond->internal_mutex);
|
||||
|
||||
psIter = cond->waiter_list;
|
||||
if (psIter != NULL) {
|
||||
SetEvent(psIter->hEvent);
|
||||
cond->waiter_list = psIter->next;
|
||||
opj_free(psIter);
|
||||
}
|
||||
|
||||
opj_mutex_unlock(cond->internal_mutex);
|
||||
}
|
||||
|
||||
void opj_cond_destroy(opj_cond_t* cond)
|
||||
{
|
||||
if (!cond) {
|
||||
return;
|
||||
}
|
||||
opj_mutex_destroy(cond->internal_mutex);
|
||||
assert(cond->waiter_list == NULL);
|
||||
opj_free(cond);
|
||||
}
|
||||
|
||||
struct opj_thread_t {
|
||||
opj_thread_fn thread_fn;
|
||||
void* user_data;
|
||||
HANDLE hThread;
|
||||
};
|
||||
|
||||
static unsigned int __stdcall opj_thread_callback_adapter(void *info)
|
||||
{
|
||||
opj_thread_t* thread = (opj_thread_t*) info;
|
||||
HANDLE hEvent = NULL;
|
||||
|
||||
thread->thread_fn(thread->user_data);
|
||||
|
||||
/* Free the handle possible allocated by a cond */
|
||||
while (OPJ_TRUE) {
|
||||
/* Make sure TLSKey is not being created just at that moment... */
|
||||
#if HAVE_INTERLOCKED_COMPARE_EXCHANGE
|
||||
if (InterlockedCompareExchange(&inTLSLockedSection, 1, 0) == 0)
|
||||
#endif
|
||||
{
|
||||
if (TLSKeyInit) {
|
||||
hEvent = (HANDLE) TlsGetValue(TLSKey);
|
||||
}
|
||||
#if HAVE_INTERLOCKED_COMPARE_EXCHANGE
|
||||
InterlockedCompareExchange(&inTLSLockedSection, 0, 1);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hEvent) {
|
||||
CloseHandle(hEvent);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
opj_thread_t* opj_thread_create(opj_thread_fn thread_fn, void* user_data)
|
||||
{
|
||||
opj_thread_t* thread;
|
||||
|
||||
assert(thread_fn);
|
||||
|
||||
thread = (opj_thread_t*) opj_malloc(sizeof(opj_thread_t));
|
||||
if (!thread) {
|
||||
return NULL;
|
||||
}
|
||||
thread->thread_fn = thread_fn;
|
||||
thread->user_data = user_data;
|
||||
|
||||
thread->hThread = (HANDLE)_beginthreadex(NULL, 0,
|
||||
opj_thread_callback_adapter, thread, 0, NULL);
|
||||
|
||||
if (thread->hThread == NULL) {
|
||||
opj_free(thread);
|
||||
return NULL;
|
||||
}
|
||||
return thread;
|
||||
}
|
||||
|
||||
void opj_thread_join(opj_thread_t* thread)
|
||||
{
|
||||
WaitForSingleObject(thread->hThread, INFINITE);
|
||||
CloseHandle(thread->hThread);
|
||||
|
||||
opj_free(thread);
|
||||
}
|
||||
|
||||
#elif MUTEX_pthread
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* Moved after all system includes, and in particular pthread.h, so as to */
|
||||
/* avoid poisoning issuing with malloc() use in pthread.h with ulibc (#1013) */
|
||||
#include "opj_includes.h"
|
||||
|
||||
OPJ_BOOL OPJ_CALLCONV opj_has_thread_support(void)
|
||||
{
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
int OPJ_CALLCONV opj_get_num_cpus(void)
|
||||
{
|
||||
#ifdef _SC_NPROCESSORS_ONLN
|
||||
return (int)sysconf(_SC_NPROCESSORS_ONLN);
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
struct opj_mutex_t {
|
||||
pthread_mutex_t mutex;
|
||||
};
|
||||
|
||||
opj_mutex_t* opj_mutex_create(void)
|
||||
{
|
||||
opj_mutex_t* mutex = (opj_mutex_t*) opj_calloc(1U, sizeof(opj_mutex_t));
|
||||
if (mutex != NULL) {
|
||||
if (pthread_mutex_init(&mutex->mutex, NULL) != 0) {
|
||||
opj_free(mutex);
|
||||
mutex = NULL;
|
||||
}
|
||||
}
|
||||
return mutex;
|
||||
}
|
||||
|
||||
void opj_mutex_lock(opj_mutex_t* mutex)
|
||||
{
|
||||
pthread_mutex_lock(&(mutex->mutex));
|
||||
}
|
||||
|
||||
void opj_mutex_unlock(opj_mutex_t* mutex)
|
||||
{
|
||||
pthread_mutex_unlock(&(mutex->mutex));
|
||||
}
|
||||
|
||||
void opj_mutex_destroy(opj_mutex_t* mutex)
|
||||
{
|
||||
if (!mutex) {
|
||||
return;
|
||||
}
|
||||
pthread_mutex_destroy(&(mutex->mutex));
|
||||
opj_free(mutex);
|
||||
}
|
||||
|
||||
struct opj_cond_t {
|
||||
pthread_cond_t cond;
|
||||
};
|
||||
|
||||
opj_cond_t* opj_cond_create(void)
|
||||
{
|
||||
opj_cond_t* cond = (opj_cond_t*) opj_malloc(sizeof(opj_cond_t));
|
||||
if (!cond) {
|
||||
return NULL;
|
||||
}
|
||||
if (pthread_cond_init(&(cond->cond), NULL) != 0) {
|
||||
opj_free(cond);
|
||||
return NULL;
|
||||
}
|
||||
return cond;
|
||||
}
|
||||
|
||||
void opj_cond_wait(opj_cond_t* cond, opj_mutex_t* mutex)
|
||||
{
|
||||
pthread_cond_wait(&(cond->cond), &(mutex->mutex));
|
||||
}
|
||||
|
||||
void opj_cond_signal(opj_cond_t* cond)
|
||||
{
|
||||
int ret = pthread_cond_signal(&(cond->cond));
|
||||
(void)ret;
|
||||
assert(ret == 0);
|
||||
}
|
||||
|
||||
void opj_cond_destroy(opj_cond_t* cond)
|
||||
{
|
||||
if (!cond) {
|
||||
return;
|
||||
}
|
||||
pthread_cond_destroy(&(cond->cond));
|
||||
opj_free(cond);
|
||||
}
|
||||
|
||||
|
||||
struct opj_thread_t {
|
||||
opj_thread_fn thread_fn;
|
||||
void* user_data;
|
||||
pthread_t thread;
|
||||
};
|
||||
|
||||
static void* opj_thread_callback_adapter(void* info)
|
||||
{
|
||||
opj_thread_t* thread = (opj_thread_t*) info;
|
||||
thread->thread_fn(thread->user_data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
opj_thread_t* opj_thread_create(opj_thread_fn thread_fn, void* user_data)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
opj_thread_t* thread;
|
||||
|
||||
assert(thread_fn);
|
||||
|
||||
thread = (opj_thread_t*) opj_malloc(sizeof(opj_thread_t));
|
||||
if (!thread) {
|
||||
return NULL;
|
||||
}
|
||||
thread->thread_fn = thread_fn;
|
||||
thread->user_data = user_data;
|
||||
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
|
||||
if (pthread_create(&(thread->thread), &attr,
|
||||
opj_thread_callback_adapter, (void *) thread) != 0) {
|
||||
opj_free(thread);
|
||||
return NULL;
|
||||
}
|
||||
return thread;
|
||||
}
|
||||
|
||||
void opj_thread_join(opj_thread_t* thread)
|
||||
{
|
||||
void* status;
|
||||
pthread_join(thread->thread, &status);
|
||||
|
||||
opj_free(thread);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Stub implementation */
|
||||
|
||||
#include "opj_includes.h"
|
||||
|
||||
OPJ_BOOL OPJ_CALLCONV opj_has_thread_support(void)
|
||||
{
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
int OPJ_CALLCONV opj_get_num_cpus(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
opj_mutex_t* opj_mutex_create(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void opj_mutex_lock(opj_mutex_t* mutex)
|
||||
{
|
||||
(void) mutex;
|
||||
}
|
||||
|
||||
void opj_mutex_unlock(opj_mutex_t* mutex)
|
||||
{
|
||||
(void) mutex;
|
||||
}
|
||||
|
||||
void opj_mutex_destroy(opj_mutex_t* mutex)
|
||||
{
|
||||
(void) mutex;
|
||||
}
|
||||
|
||||
opj_cond_t* opj_cond_create(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void opj_cond_wait(opj_cond_t* cond, opj_mutex_t* mutex)
|
||||
{
|
||||
(void) cond;
|
||||
(void) mutex;
|
||||
}
|
||||
|
||||
void opj_cond_signal(opj_cond_t* cond)
|
||||
{
|
||||
(void) cond;
|
||||
}
|
||||
|
||||
void opj_cond_destroy(opj_cond_t* cond)
|
||||
{
|
||||
(void) cond;
|
||||
}
|
||||
|
||||
opj_thread_t* opj_thread_create(opj_thread_fn thread_fn, void* user_data)
|
||||
{
|
||||
(void) thread_fn;
|
||||
(void) user_data;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void opj_thread_join(opj_thread_t* thread)
|
||||
{
|
||||
(void) thread;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int key;
|
||||
void* value;
|
||||
opj_tls_free_func opj_free_func;
|
||||
} opj_tls_key_val_t;
|
||||
|
||||
struct opj_tls_t {
|
||||
opj_tls_key_val_t* key_val;
|
||||
int key_val_count;
|
||||
};
|
||||
|
||||
static opj_tls_t* opj_tls_new(void)
|
||||
{
|
||||
return (opj_tls_t*) opj_calloc(1, sizeof(opj_tls_t));
|
||||
}
|
||||
|
||||
static void opj_tls_destroy(opj_tls_t* tls)
|
||||
{
|
||||
int i;
|
||||
if (!tls) {
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < tls->key_val_count; i++) {
|
||||
if (tls->key_val[i].opj_free_func) {
|
||||
tls->key_val[i].opj_free_func(tls->key_val[i].value);
|
||||
}
|
||||
}
|
||||
opj_free(tls->key_val);
|
||||
opj_free(tls);
|
||||
}
|
||||
|
||||
void* opj_tls_get(opj_tls_t* tls, int key)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < tls->key_val_count; i++) {
|
||||
if (tls->key_val[i].key == key) {
|
||||
return tls->key_val[i].value;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
OPJ_BOOL opj_tls_set(opj_tls_t* tls, int key, void* value,
|
||||
opj_tls_free_func opj_free_func)
|
||||
{
|
||||
opj_tls_key_val_t* new_key_val;
|
||||
int i;
|
||||
|
||||
if (tls->key_val_count == INT_MAX) {
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
for (i = 0; i < tls->key_val_count; i++) {
|
||||
if (tls->key_val[i].key == key) {
|
||||
if (tls->key_val[i].opj_free_func) {
|
||||
tls->key_val[i].opj_free_func(tls->key_val[i].value);
|
||||
}
|
||||
tls->key_val[i].value = value;
|
||||
tls->key_val[i].opj_free_func = opj_free_func;
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
}
|
||||
new_key_val = (opj_tls_key_val_t*) opj_realloc(tls->key_val,
|
||||
((size_t)tls->key_val_count + 1U) * sizeof(opj_tls_key_val_t));
|
||||
if (!new_key_val) {
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
tls->key_val = new_key_val;
|
||||
new_key_val[tls->key_val_count].key = key;
|
||||
new_key_val[tls->key_val_count].value = value;
|
||||
new_key_val[tls->key_val_count].opj_free_func = opj_free_func;
|
||||
tls->key_val_count ++;
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
opj_job_fn job_fn;
|
||||
void *user_data;
|
||||
} opj_worker_thread_job_t;
|
||||
|
||||
typedef struct {
|
||||
opj_thread_pool_t *tp;
|
||||
opj_thread_t *thread;
|
||||
int marked_as_waiting;
|
||||
|
||||
opj_mutex_t *mutex;
|
||||
opj_cond_t *cond;
|
||||
} opj_worker_thread_t;
|
||||
|
||||
typedef enum {
|
||||
OPJWTS_OK,
|
||||
OPJWTS_STOP,
|
||||
OPJWTS_ERROR
|
||||
} opj_worker_thread_state;
|
||||
|
||||
struct opj_job_list_t {
|
||||
opj_worker_thread_job_t* job;
|
||||
struct opj_job_list_t* next;
|
||||
};
|
||||
typedef struct opj_job_list_t opj_job_list_t;
|
||||
|
||||
struct opj_worker_thread_list_t {
|
||||
opj_worker_thread_t* worker_thread;
|
||||
struct opj_worker_thread_list_t* next;
|
||||
};
|
||||
typedef struct opj_worker_thread_list_t opj_worker_thread_list_t;
|
||||
|
||||
struct opj_thread_pool_t {
|
||||
opj_worker_thread_t* worker_threads;
|
||||
int worker_threads_count;
|
||||
opj_cond_t* cond;
|
||||
opj_mutex_t* mutex;
|
||||
volatile opj_worker_thread_state state;
|
||||
opj_job_list_t* job_queue;
|
||||
volatile int pending_jobs_count;
|
||||
opj_worker_thread_list_t* waiting_worker_thread_list;
|
||||
int waiting_worker_thread_count;
|
||||
opj_tls_t* tls;
|
||||
int signaling_threshold;
|
||||
};
|
||||
|
||||
static OPJ_BOOL opj_thread_pool_setup(opj_thread_pool_t* tp, int num_threads);
|
||||
static opj_worker_thread_job_t* opj_thread_pool_get_next_job(
|
||||
opj_thread_pool_t* tp,
|
||||
opj_worker_thread_t* worker_thread,
|
||||
OPJ_BOOL signal_job_finished);
|
||||
|
||||
opj_thread_pool_t* opj_thread_pool_create(int num_threads)
|
||||
{
|
||||
opj_thread_pool_t* tp;
|
||||
|
||||
tp = (opj_thread_pool_t*) opj_calloc(1, sizeof(opj_thread_pool_t));
|
||||
if (!tp) {
|
||||
return NULL;
|
||||
}
|
||||
tp->state = OPJWTS_OK;
|
||||
|
||||
if (num_threads <= 0) {
|
||||
tp->tls = opj_tls_new();
|
||||
if (!tp->tls) {
|
||||
opj_free(tp);
|
||||
tp = NULL;
|
||||
}
|
||||
return tp;
|
||||
}
|
||||
|
||||
tp->mutex = opj_mutex_create();
|
||||
if (!tp->mutex) {
|
||||
opj_free(tp);
|
||||
return NULL;
|
||||
}
|
||||
if (!opj_thread_pool_setup(tp, num_threads)) {
|
||||
opj_thread_pool_destroy(tp);
|
||||
return NULL;
|
||||
}
|
||||
return tp;
|
||||
}
|
||||
|
||||
static void opj_worker_thread_function(void* user_data)
|
||||
{
|
||||
opj_worker_thread_t* worker_thread;
|
||||
opj_thread_pool_t* tp;
|
||||
opj_tls_t* tls;
|
||||
OPJ_BOOL job_finished = OPJ_FALSE;
|
||||
|
||||
worker_thread = (opj_worker_thread_t*) user_data;
|
||||
tp = worker_thread->tp;
|
||||
tls = opj_tls_new();
|
||||
|
||||
while (OPJ_TRUE) {
|
||||
opj_worker_thread_job_t* job = opj_thread_pool_get_next_job(tp, worker_thread,
|
||||
job_finished);
|
||||
if (job == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (job->job_fn) {
|
||||
job->job_fn(job->user_data, tls);
|
||||
}
|
||||
opj_free(job);
|
||||
job_finished = OPJ_TRUE;
|
||||
}
|
||||
|
||||
opj_tls_destroy(tls);
|
||||
}
|
||||
|
||||
static OPJ_BOOL opj_thread_pool_setup(opj_thread_pool_t* tp, int num_threads)
|
||||
{
|
||||
int i;
|
||||
OPJ_BOOL bRet = OPJ_TRUE;
|
||||
|
||||
assert(num_threads > 0);
|
||||
|
||||
tp->cond = opj_cond_create();
|
||||
if (tp->cond == NULL) {
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
tp->worker_threads = (opj_worker_thread_t*) opj_calloc((size_t)num_threads,
|
||||
sizeof(opj_worker_thread_t));
|
||||
if (tp->worker_threads == NULL) {
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
tp->worker_threads_count = num_threads;
|
||||
|
||||
for (i = 0; i < num_threads; i++) {
|
||||
tp->worker_threads[i].tp = tp;
|
||||
|
||||
tp->worker_threads[i].mutex = opj_mutex_create();
|
||||
if (tp->worker_threads[i].mutex == NULL) {
|
||||
tp->worker_threads_count = i;
|
||||
bRet = OPJ_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
tp->worker_threads[i].cond = opj_cond_create();
|
||||
if (tp->worker_threads[i].cond == NULL) {
|
||||
opj_mutex_destroy(tp->worker_threads[i].mutex);
|
||||
tp->worker_threads_count = i;
|
||||
bRet = OPJ_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
tp->worker_threads[i].marked_as_waiting = OPJ_FALSE;
|
||||
|
||||
tp->worker_threads[i].thread = opj_thread_create(opj_worker_thread_function,
|
||||
&(tp->worker_threads[i]));
|
||||
if (tp->worker_threads[i].thread == NULL) {
|
||||
opj_mutex_destroy(tp->worker_threads[i].mutex);
|
||||
opj_cond_destroy(tp->worker_threads[i].cond);
|
||||
tp->worker_threads_count = i;
|
||||
bRet = OPJ_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait all threads to be started */
|
||||
/* printf("waiting for all threads to be started\n"); */
|
||||
opj_mutex_lock(tp->mutex);
|
||||
while (tp->waiting_worker_thread_count < tp->worker_threads_count) {
|
||||
opj_cond_wait(tp->cond, tp->mutex);
|
||||
}
|
||||
opj_mutex_unlock(tp->mutex);
|
||||
/* printf("all threads started\n"); */
|
||||
|
||||
if (tp->state == OPJWTS_ERROR) {
|
||||
bRet = OPJ_FALSE;
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
/*
|
||||
void opj_waiting()
|
||||
{
|
||||
printf("waiting!\n");
|
||||
}
|
||||
*/
|
||||
|
||||
static opj_worker_thread_job_t* opj_thread_pool_get_next_job(
|
||||
opj_thread_pool_t* tp,
|
||||
opj_worker_thread_t* worker_thread,
|
||||
OPJ_BOOL signal_job_finished)
|
||||
{
|
||||
while (OPJ_TRUE) {
|
||||
opj_job_list_t* top_job_iter;
|
||||
|
||||
opj_mutex_lock(tp->mutex);
|
||||
|
||||
if (signal_job_finished) {
|
||||
signal_job_finished = OPJ_FALSE;
|
||||
tp->pending_jobs_count --;
|
||||
/*printf("tp=%p, remaining jobs: %d\n", tp, tp->pending_jobs_count);*/
|
||||
if (tp->pending_jobs_count <= tp->signaling_threshold) {
|
||||
opj_cond_signal(tp->cond);
|
||||
}
|
||||
}
|
||||
|
||||
if (tp->state == OPJWTS_STOP) {
|
||||
opj_mutex_unlock(tp->mutex);
|
||||
return NULL;
|
||||
}
|
||||
top_job_iter = tp->job_queue;
|
||||
if (top_job_iter) {
|
||||
opj_worker_thread_job_t* job;
|
||||
tp->job_queue = top_job_iter->next;
|
||||
|
||||
job = top_job_iter->job;
|
||||
opj_mutex_unlock(tp->mutex);
|
||||
opj_free(top_job_iter);
|
||||
return job;
|
||||
}
|
||||
|
||||
/* opj_waiting(); */
|
||||
if (!worker_thread->marked_as_waiting) {
|
||||
opj_worker_thread_list_t* item;
|
||||
|
||||
worker_thread->marked_as_waiting = OPJ_TRUE;
|
||||
tp->waiting_worker_thread_count ++;
|
||||
assert(tp->waiting_worker_thread_count <= tp->worker_threads_count);
|
||||
|
||||
item = (opj_worker_thread_list_t*) opj_malloc(sizeof(opj_worker_thread_list_t));
|
||||
if (item == NULL) {
|
||||
tp->state = OPJWTS_ERROR;
|
||||
opj_cond_signal(tp->cond);
|
||||
|
||||
opj_mutex_unlock(tp->mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
item->worker_thread = worker_thread;
|
||||
item->next = tp->waiting_worker_thread_list;
|
||||
tp->waiting_worker_thread_list = item;
|
||||
}
|
||||
|
||||
/* printf("signaling that worker thread is ready\n"); */
|
||||
opj_cond_signal(tp->cond);
|
||||
|
||||
opj_mutex_lock(worker_thread->mutex);
|
||||
opj_mutex_unlock(tp->mutex);
|
||||
|
||||
/* printf("waiting for job\n"); */
|
||||
opj_cond_wait(worker_thread->cond, worker_thread->mutex);
|
||||
|
||||
opj_mutex_unlock(worker_thread->mutex);
|
||||
/* printf("got job\n"); */
|
||||
}
|
||||
}
|
||||
|
||||
OPJ_BOOL opj_thread_pool_submit_job(opj_thread_pool_t* tp,
|
||||
opj_job_fn job_fn,
|
||||
void* user_data)
|
||||
{
|
||||
opj_worker_thread_job_t* job;
|
||||
opj_job_list_t* item;
|
||||
|
||||
if (tp->mutex == NULL) {
|
||||
job_fn(user_data, tp->tls);
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
job = (opj_worker_thread_job_t*)opj_malloc(sizeof(opj_worker_thread_job_t));
|
||||
if (job == NULL) {
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
job->job_fn = job_fn;
|
||||
job->user_data = user_data;
|
||||
|
||||
item = (opj_job_list_t*) opj_malloc(sizeof(opj_job_list_t));
|
||||
if (item == NULL) {
|
||||
opj_free(job);
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
item->job = job;
|
||||
|
||||
opj_mutex_lock(tp->mutex);
|
||||
|
||||
tp->signaling_threshold = 100 * tp->worker_threads_count;
|
||||
while (tp->pending_jobs_count > tp->signaling_threshold) {
|
||||
/* printf("%d jobs enqueued. Waiting\n", tp->pending_jobs_count); */
|
||||
opj_cond_wait(tp->cond, tp->mutex);
|
||||
/* printf("...%d jobs enqueued.\n", tp->pending_jobs_count); */
|
||||
}
|
||||
|
||||
item->next = tp->job_queue;
|
||||
tp->job_queue = item;
|
||||
tp->pending_jobs_count ++;
|
||||
|
||||
if (tp->waiting_worker_thread_list) {
|
||||
opj_worker_thread_t* worker_thread;
|
||||
opj_worker_thread_list_t* next;
|
||||
opj_worker_thread_list_t* to_opj_free;
|
||||
|
||||
worker_thread = tp->waiting_worker_thread_list->worker_thread;
|
||||
|
||||
assert(worker_thread->marked_as_waiting);
|
||||
worker_thread->marked_as_waiting = OPJ_FALSE;
|
||||
|
||||
next = tp->waiting_worker_thread_list->next;
|
||||
to_opj_free = tp->waiting_worker_thread_list;
|
||||
tp->waiting_worker_thread_list = next;
|
||||
tp->waiting_worker_thread_count --;
|
||||
|
||||
opj_mutex_lock(worker_thread->mutex);
|
||||
opj_mutex_unlock(tp->mutex);
|
||||
opj_cond_signal(worker_thread->cond);
|
||||
opj_mutex_unlock(worker_thread->mutex);
|
||||
|
||||
opj_free(to_opj_free);
|
||||
} else {
|
||||
opj_mutex_unlock(tp->mutex);
|
||||
}
|
||||
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
void opj_thread_pool_wait_completion(opj_thread_pool_t* tp,
|
||||
int max_remaining_jobs)
|
||||
{
|
||||
if (tp->mutex == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (max_remaining_jobs < 0) {
|
||||
max_remaining_jobs = 0;
|
||||
}
|
||||
opj_mutex_lock(tp->mutex);
|
||||
tp->signaling_threshold = max_remaining_jobs;
|
||||
while (tp->pending_jobs_count > max_remaining_jobs) {
|
||||
/*printf("tp=%p, jobs before wait = %d, max_remaining_jobs = %d\n", tp, tp->pending_jobs_count, max_remaining_jobs);*/
|
||||
opj_cond_wait(tp->cond, tp->mutex);
|
||||
/*printf("tp=%p, jobs after wait = %d\n", tp, tp->pending_jobs_count);*/
|
||||
}
|
||||
opj_mutex_unlock(tp->mutex);
|
||||
}
|
||||
|
||||
int opj_thread_pool_get_thread_count(opj_thread_pool_t* tp)
|
||||
{
|
||||
return tp->worker_threads_count;
|
||||
}
|
||||
|
||||
void opj_thread_pool_destroy(opj_thread_pool_t* tp)
|
||||
{
|
||||
if (!tp) {
|
||||
return;
|
||||
}
|
||||
if (tp->cond) {
|
||||
int i;
|
||||
opj_thread_pool_wait_completion(tp, 0);
|
||||
|
||||
opj_mutex_lock(tp->mutex);
|
||||
tp->state = OPJWTS_STOP;
|
||||
opj_mutex_unlock(tp->mutex);
|
||||
|
||||
for (i = 0; i < tp->worker_threads_count; i++) {
|
||||
opj_mutex_lock(tp->worker_threads[i].mutex);
|
||||
opj_cond_signal(tp->worker_threads[i].cond);
|
||||
opj_mutex_unlock(tp->worker_threads[i].mutex);
|
||||
opj_thread_join(tp->worker_threads[i].thread);
|
||||
opj_cond_destroy(tp->worker_threads[i].cond);
|
||||
opj_mutex_destroy(tp->worker_threads[i].mutex);
|
||||
}
|
||||
|
||||
opj_free(tp->worker_threads);
|
||||
|
||||
while (tp->waiting_worker_thread_list != NULL) {
|
||||
opj_worker_thread_list_t* next = tp->waiting_worker_thread_list->next;
|
||||
opj_free(tp->waiting_worker_thread_list);
|
||||
tp->waiting_worker_thread_list = next;
|
||||
}
|
||||
|
||||
opj_cond_destroy(tp->cond);
|
||||
}
|
||||
opj_mutex_destroy(tp->mutex);
|
||||
opj_tls_destroy(tp->tls);
|
||||
opj_free(tp);
|
||||
}
|
||||
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* 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) 2016, Even Rouault
|
||||
* 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 THREAD_H
|
||||
#define THREAD_H
|
||||
|
||||
#include "openjpeg.h"
|
||||
|
||||
/**
|
||||
@file thread.h
|
||||
@brief Thread API
|
||||
|
||||
The functions in thread.c have for goal to manage mutex, conditions, thread
|
||||
creation and thread pools that accept jobs.
|
||||
*/
|
||||
|
||||
/** @defgroup THREAD THREAD - Mutex, conditions, threads and thread pools */
|
||||
/*@{*/
|
||||
|
||||
/** @name Mutex */
|
||||
/*@{*/
|
||||
|
||||
/** Opaque type for a mutex */
|
||||
typedef struct opj_mutex_t opj_mutex_t;
|
||||
|
||||
/** Creates a mutex.
|
||||
* @return the mutex or NULL in case of error (can for example happen if the library
|
||||
* is built without thread support)
|
||||
*/
|
||||
opj_mutex_t* opj_mutex_create(void);
|
||||
|
||||
/** Lock/acquire the mutex.
|
||||
* @param mutex the mutex to acquire.
|
||||
*/
|
||||
void opj_mutex_lock(opj_mutex_t* mutex);
|
||||
|
||||
/** Unlock/release the mutex.
|
||||
* @param mutex the mutex to release.
|
||||
*/
|
||||
void opj_mutex_unlock(opj_mutex_t* mutex);
|
||||
|
||||
/** Destroy a mutex
|
||||
* @param mutex the mutex to destroy.
|
||||
*/
|
||||
void opj_mutex_destroy(opj_mutex_t* mutex);
|
||||
|
||||
/*@}*/
|
||||
|
||||
/** @name Condition */
|
||||
/*@{*/
|
||||
|
||||
/** Opaque type for a condition */
|
||||
typedef struct opj_cond_t opj_cond_t;
|
||||
|
||||
/** Creates a condition.
|
||||
* @return the condition or NULL in case of error (can for example happen if the library
|
||||
* is built without thread support)
|
||||
*/
|
||||
opj_cond_t* opj_cond_create(void);
|
||||
|
||||
/** Wait for the condition to be signaled.
|
||||
* The semantics is the same as the POSIX pthread_cond_wait.
|
||||
* The provided mutex *must* be acquired before calling this function, and
|
||||
* released afterwards.
|
||||
* The mutex will be released by this function while it must wait for the condition
|
||||
* and reacquired afterwards.
|
||||
* In some particular situations, the function might return even if the condition is not signaled
|
||||
* with opj_cond_signal(), hence the need to check with an application level
|
||||
* mechanism.
|
||||
*
|
||||
* Waiting thread :
|
||||
* \code
|
||||
* opj_mutex_lock(mutex);
|
||||
* while( !some_application_level_condition )
|
||||
* {
|
||||
* opj_cond_wait(cond, mutex);
|
||||
* }
|
||||
* opj_mutex_unlock(mutex);
|
||||
* \endcode
|
||||
*
|
||||
* Signaling thread :
|
||||
* \code
|
||||
* opj_mutex_lock(mutex);
|
||||
* some_application_level_condition = TRUE;
|
||||
* opj_cond_signal(cond);
|
||||
* opj_mutex_unlock(mutex);
|
||||
* \endcode
|
||||
*
|
||||
* @param cond the condition to wait.
|
||||
* @param mutex the mutex (in acquired state before calling this function)
|
||||
*/
|
||||
void opj_cond_wait(opj_cond_t* cond, opj_mutex_t* mutex);
|
||||
|
||||
/** Signal waiting threads on a condition.
|
||||
* One of the thread waiting with opj_cond_wait() will be waken up.
|
||||
* It is strongly advised that this call is done with the mutex that is used
|
||||
* by opj_cond_wait(), in a acquired state.
|
||||
* @param cond the condition to signal.
|
||||
*/
|
||||
void opj_cond_signal(opj_cond_t* cond);
|
||||
|
||||
/** Destroy a condition
|
||||
* @param cond the condition to destroy.
|
||||
*/
|
||||
void opj_cond_destroy(opj_cond_t* cond);
|
||||
|
||||
/*@}*/
|
||||
|
||||
/** @name Thread */
|
||||
/*@{*/
|
||||
|
||||
/** Opaque type for a thread handle */
|
||||
typedef struct opj_thread_t opj_thread_t;
|
||||
|
||||
/** User function to execute in a thread
|
||||
* @param user_data user data provided with opj_thread_create()
|
||||
*/
|
||||
typedef void (*opj_thread_fn)(void* user_data);
|
||||
|
||||
/** Creates a new thread.
|
||||
* @param thread_fn Function to run in the new thread.
|
||||
* @param user_data user data provided to the thread function. Might be NULL.
|
||||
* @return a thread handle or NULL in case of failure (can for example happen if the library
|
||||
* is built without thread support)
|
||||
*/
|
||||
opj_thread_t* opj_thread_create(opj_thread_fn thread_fn, void* user_data);
|
||||
|
||||
/** Wait for a thread to be finished and release associated resources to the
|
||||
* thread handle.
|
||||
* @param thread the thread to wait for being finished.
|
||||
*/
|
||||
void opj_thread_join(opj_thread_t* thread);
|
||||
|
||||
/*@}*/
|
||||
|
||||
/** @name Thread local storage */
|
||||
/*@{*/
|
||||
/** Opaque type for a thread local storage */
|
||||
typedef struct opj_tls_t opj_tls_t;
|
||||
|
||||
/** Get a thread local value corresponding to the provided key.
|
||||
* @param tls thread local storage handle
|
||||
* @param key key whose value to retrieve.
|
||||
* @return value associated with the key, or NULL is missing.
|
||||
*/
|
||||
void* opj_tls_get(opj_tls_t* tls, int key);
|
||||
|
||||
/** Type of the function used to free a TLS value */
|
||||
typedef void (*opj_tls_free_func)(void* value);
|
||||
|
||||
/** Set a thread local value corresponding to the provided key.
|
||||
* @param tls thread local storage handle
|
||||
* @param key key whose value to set.
|
||||
* @param value value to set (may be NULL).
|
||||
* @param free_func function to call currently installed value.
|
||||
* @return OPJ_TRUE if successful.
|
||||
*/
|
||||
OPJ_BOOL opj_tls_set(opj_tls_t* tls, int key, void* value,
|
||||
opj_tls_free_func free_func);
|
||||
|
||||
/*@}*/
|
||||
|
||||
/** @name Thread pool */
|
||||
/*@{*/
|
||||
|
||||
/** Opaque type for a thread pool */
|
||||
typedef struct opj_thread_pool_t opj_thread_pool_t;
|
||||
|
||||
/** Create a new thread pool.
|
||||
* num_thread must nominally be >= 1 to create a real thread pool. If num_threads
|
||||
* is negative or null, then a dummy thread pool will be created. All functions
|
||||
* operating on the thread pool will work, but job submission will be run
|
||||
* synchronously in the calling thread.
|
||||
*
|
||||
* @param num_threads the number of threads to allocate for this thread pool.
|
||||
* @return a thread pool handle, or NULL in case of failure (can for example happen if the library
|
||||
* is built without thread support)
|
||||
*/
|
||||
opj_thread_pool_t* opj_thread_pool_create(int num_threads);
|
||||
|
||||
/** User function to execute in a thread
|
||||
* @param user_data user data provided with opj_thread_create()
|
||||
* @param tls handle to thread local storage
|
||||
*/
|
||||
typedef void (*opj_job_fn)(void* user_data, opj_tls_t* tls);
|
||||
|
||||
|
||||
/** Submit a new job to be run by one of the thread in the thread pool.
|
||||
* The job ( thread_fn, user_data ) will be added in the queue of jobs managed
|
||||
* by the thread pool, and run by the first thread that is no longer busy.
|
||||
*
|
||||
* @param tp the thread pool handle.
|
||||
* @param job_fn Function to run. Must not be NULL.
|
||||
* @param user_data User data provided to thread_fn.
|
||||
* @return OPJ_TRUE if the job was successfully submitted.
|
||||
*/
|
||||
OPJ_BOOL opj_thread_pool_submit_job(opj_thread_pool_t* tp, opj_job_fn job_fn,
|
||||
void* user_data);
|
||||
|
||||
/** Wait that no more than max_remaining_jobs jobs are remaining in the queue of
|
||||
* the thread pool. The aim of this function is to avoid submitting too many
|
||||
* jobs while the thread pool cannot cope fast enough with them, which would
|
||||
* result potentially in out-of-memory situations with too many job descriptions
|
||||
* being queued.
|
||||
*
|
||||
* @param tp the thread pool handle
|
||||
* @param max_remaining_jobs maximum number of jobs allowed to be queued without waiting.
|
||||
*/
|
||||
void opj_thread_pool_wait_completion(opj_thread_pool_t* tp,
|
||||
int max_remaining_jobs);
|
||||
|
||||
/** Return the number of threads associated with the thread pool.
|
||||
*
|
||||
* @param tp the thread pool handle.
|
||||
* @return number of threads associated with the thread pool.
|
||||
*/
|
||||
int opj_thread_pool_get_thread_count(opj_thread_pool_t* tp);
|
||||
|
||||
/** Destroy a thread pool.
|
||||
* @param tp the thread pool handle.
|
||||
*/
|
||||
void opj_thread_pool_destroy(opj_thread_pool_t* tp);
|
||||
|
||||
/*@}*/
|
||||
|
||||
/*@}*/
|
||||
|
||||
#endif /* THREAD_H */
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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) 2016, Even Rouault
|
||||
* 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 OPJ_TLS_KEYS_H
|
||||
#define OPJ_TLS_KEYS_H
|
||||
|
||||
#define OPJ_TLS_KEY_T1 0
|
||||
|
||||
#endif /* OPJ_TLS_KEY_H */
|
||||
+15
-2
@@ -1531,8 +1531,21 @@ static int emrtd_print_image(const char *title, uint8_t *data, size_t datalen) {
|
||||
bool found = false;
|
||||
size_t offset = 0;
|
||||
for (offset = 0; offset < datalen - 6; offset++) {
|
||||
if ((data[offset] == 0xFF && memcmp(jpeg_header, data + offset, 4) == 0) ||
|
||||
(data[offset] == 0x00 && memcmp(jpeg2k_header, data + offset, 6) == 0)) {
|
||||
|
||||
if (data[offset] == 0xFF) {
|
||||
// JPEG SOI + any APPn marker, JFIF (FFE0) is the common one but
|
||||
// Exif (FFE1) / raw DQT (FFDB) show up as well
|
||||
if (memcmp(jpeg_header, data + offset, 3) == 0) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
// JPEG2000 raw codestream, no JP2 container
|
||||
if (memcmp(jpeg2k_cs_header, data + offset, 4) == 0) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
} else if (data[offset] == 0x00 && memcmp(jpeg2k_header, data + offset, 6) == 0) {
|
||||
// JPEG2000 in a JP2 container
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
+26
-3
@@ -21,7 +21,8 @@
|
||||
#include <string.h>
|
||||
#include "proxguiqt.h"
|
||||
#include "proxmark3.h"
|
||||
#include "ui.h" // for prints
|
||||
#include "ui.h" // for prints
|
||||
#include "imgjp2.h" // JPEG2000
|
||||
|
||||
static ProxGuiQT *gui = NULL;
|
||||
static WorkerThread *main_loop_thread = NULL;
|
||||
@@ -77,11 +78,33 @@ static void show_no_gui_notice(void) {
|
||||
|
||||
// hook up picture viewer
|
||||
extern "C" void ShowPictureWindow(const char *title, uint8_t *data, int len) {
|
||||
|
||||
if (data == NULL || len <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
QImage img;
|
||||
|
||||
// No support for jpeg2000 in Qt Image since a while...
|
||||
// https://doc.qt.io/qt-5/qtimageformats-index.html
|
||||
QImage img = QImage::fromData(data, len);
|
||||
// and the distros ship no replacement plugin, so decode it ourselves with
|
||||
// the vendored openjpeg. Most eMRTD EF_DG2 portraits are jpeg2000.
|
||||
if (jp2_is_jpeg2000(data, (size_t)len)) {
|
||||
|
||||
int w = 0, h = 0;
|
||||
uint8_t *rgb = jp2_decode_rgb(data, (size_t)len, &w, &h);
|
||||
if (rgb) {
|
||||
// QImage doesn't take ownership of the buffer, copy() detaches it
|
||||
img = QImage(rgb, w, h, w * 3, QImage::Format_RGB888).copy();
|
||||
free(rgb);
|
||||
}
|
||||
|
||||
} else {
|
||||
img = QImage::fromData(data, len);
|
||||
}
|
||||
|
||||
if (img.isNull()) {
|
||||
PrintAndLogEx(WARNING, "Failed to decode image ( %s ), Qt lacks support for this format (jpeg2000?)", (title) ? title : "n/a");
|
||||
PrintAndLogEx(WARNING, "Failed to decode image ( %s )", (title) ? title : "n/a");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user