summaryrefslogtreecommitdiff
path: root/libopenjpeg3d
diff options
context:
space:
mode:
Diffstat (limited to 'libopenjpeg3d')
-rw-r--r--libopenjpeg3d/CMakeLists.txt37
-rw-r--r--libopenjpeg3d/Makefile.am88
-rwxr-xr-xlibopenjpeg3d/bio.c189
-rwxr-xr-xlibopenjpeg3d/bio.h132
-rwxr-xr-xlibopenjpeg3d/cio.c217
-rwxr-xr-xlibopenjpeg3d/cio.h100
-rwxr-xr-xlibopenjpeg3d/dwt.c1016
-rwxr-xr-xlibopenjpeg3d/dwt.h100
-rwxr-xr-xlibopenjpeg3d/event.c181
-rwxr-xr-xlibopenjpeg3d/event.h58
-rwxr-xr-xlibopenjpeg3d/fix.h62
-rwxr-xr-xlibopenjpeg3d/int.h122
-rwxr-xr-xlibopenjpeg3d/jp3d.c2328
-rwxr-xr-xlibopenjpeg3d/jp3d.h518
-rwxr-xr-xlibopenjpeg3d/jp3d_lib.c76
-rwxr-xr-xlibopenjpeg3d/jp3d_lib.h75
-rwxr-xr-xlibopenjpeg3d/mct.c131
-rwxr-xr-xlibopenjpeg3d/mct.h97
-rwxr-xr-xlibopenjpeg3d/mqc.c548
-rwxr-xr-xlibopenjpeg3d/mqc.h201
-rwxr-xr-xlibopenjpeg3d/openjpeg.c207
-rwxr-xr-xlibopenjpeg3d/openjpeg3d.h713
-rwxr-xr-xlibopenjpeg3d/opj_includes.h81
-rwxr-xr-xlibopenjpeg3d/pi.c630
-rwxr-xr-xlibopenjpeg3d/pi.h145
-rwxr-xr-xlibopenjpeg3d/raw.c86
-rwxr-xr-xlibopenjpeg3d/raw.h99
-rwxr-xr-xlibopenjpeg3d/t1.c1181
-rwxr-xr-xlibopenjpeg3d/t1.h173
-rwxr-xr-xlibopenjpeg3d/t1_3d.c1230
-rwxr-xr-xlibopenjpeg3d/t1_3d.h173
-rwxr-xr-xlibopenjpeg3d/t2.c675
-rwxr-xr-xlibopenjpeg3d/t2.h101
-rwxr-xr-xlibopenjpeg3d/tcd.c1738
-rwxr-xr-xlibopenjpeg3d/tcd.h334
-rwxr-xr-xlibopenjpeg3d/tgt.c256
-rwxr-xr-xlibopenjpeg3d/tgt.h124
-rwxr-xr-xlibopenjpeg3d/volume.c89
-rwxr-xr-xlibopenjpeg3d/volume.h43
39 files changed, 14354 insertions, 0 deletions
diff --git a/libopenjpeg3d/CMakeLists.txt b/libopenjpeg3d/CMakeLists.txt
new file mode 100644
index 00000000..85d15b13
--- /dev/null
+++ b/libopenjpeg3d/CMakeLists.txt
@@ -0,0 +1,37 @@
+
+INCLUDE_REGULAR_EXPRESSION("^.*$")
+
+# Defines the source code for the library
+SET(OPENJPEG3D_SRCS
+bio.c cio.c dwt.c event.c jp3d.c jp3d_lib.c mct.c mqc.c openjpeg.c pi.c raw.c t1.c t1_3d.c t2.c tcd.c tgt.c volume.c
+)
+
+# Build the library
+IF(WIN32)
+ IF(BUILD_SHARED_LIBS)
+ ADD_DEFINITIONS(-DOPJ_EXPORTS)
+ ELSE(BUILD_SHARED_LIBS)
+ ADD_DEFINITIONS(-DOPJ_STATIC)
+ ENDIF(BUILD_SHARED_LIBS)
+ENDIF(WIN32)
+ADD_LIBRARY(${OPENJPEG3D_LIBRARY_NAME} ${OPENJPEG3D_SRCS})
+IF(UNIX)
+ TARGET_LINK_LIBRARIES(${OPENJPEG3D_LIBRARY_NAME} m)
+ENDIF(UNIX)
+SET_TARGET_PROPERTIES(${OPENJPEG3D_LIBRARY_NAME} PROPERTIES ${OPENJPEG3D_LIBRARY_PROPERTIES})
+
+# Install library
+INSTALL(TARGETS ${OPENJPEG3D_LIBRARY_NAME}
+ EXPORT OpenJPEG3DTargets
+ DESTINATION ${OPENJPEG3D_INSTALL_LIB_DIR}
+ COMPONENT Libraries
+)
+
+# Install includes files
+INSTALL(FILES openjpeg3d.h
+ DESTINATION ${OPENJPEG3D_INSTALL_INCLUDE_DIR}/${subdir}
+ COMPONENT Headers
+)
+INSTALL(CODE
+ "EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E create_symlink ${subdir}/openjpeg3d.h \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${OPENJPEG3D_INSTALL_INCLUDE_DIR}/openjpeg3d.h)")
+
diff --git a/libopenjpeg3d/Makefile.am b/libopenjpeg3d/Makefile.am
new file mode 100644
index 00000000..ccf72efa
--- /dev/null
+++ b/libopenjpeg3d/Makefile.am
@@ -0,0 +1,88 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+lib_LTLIBRARIES = libopenjp3dvm.la
+
+includesdir = ${includedir}/openjpeg3d-@JP3D_MAJOR_NR@.@JP3D_MINOR_NR@
+includes_HEADERS = openjpeg3d.h
+
+libopenjp3dvm_la_LDFLAGS = -no-undefined -version-info @lt_version_jp3d@
+
+libopenjp3dvm_la_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/jp3d/libjp3dvm \
+-I$(top_builddir)/jp3d/libjp3dvm
+libopenjp3dvm_la_CFLAGS =
+libopenjp3dvm_la_LIBADD = -lm
+libopenjp3dvm_la_SOURCES = \
+bio.c \
+cio.c \
+dwt.c \
+event.c \
+jp3d.c \
+jp3d_lib.c \
+volume.c \
+mct.c \
+mqc.c \
+openjpeg.c \
+pi.c \
+raw.c \
+t1.c \
+t1_3d.c \
+t2.c \
+tcd.c \
+tgt.c \
+bio.h \
+cio.h \
+dwt.h \
+event.h \
+fix.h \
+int.h \
+jp3d.h \
+jp3d_lib.h \
+mct.h \
+mqc.h \
+opj_includes.h \
+pi.h \
+raw.h \
+t1.h \
+t1_3d.h \
+t2.h \
+tcd.h \
+tgt.h \
+volume.h
+
+EXTRA_DIST = \
+CMakeLists.txt
+
+install-data-hook:
+ cd $(DESTDIR)$(includedir) && \
+ rm -f openjpeg3d.h && \
+ $(LN_S) openjpeg3d-@JP3D_MAJOR_NR@.@JP3D_MINOR_NR@/openjpeg3d.h \
+ openjpeg3d.h
+ @echo -e " (LA)\t$(libdir)/libopenjp3dvm.la" >> $(top_builddir)/report.txt
+ @( $(call solist) ) >> $(top_builddir)/report.txt
+ @echo -e " (A)\t$(base)/$(a)" >> $(top_builddir)/report.txt
+ @echo -e " (H)\t$(includedir)/openjpeg3d-$(MAJOR_NR).$(MINOR_NR)/openjpeg3d.h" >> $(top_builddir)/report.txt
+ @echo -e " (LN)\t$(includedir)/openjpeg3d.h" >> $(top_builddir)/report.txt
+
+uninstall-hook:
+ rm -f $(DESTDIR)$(includedir)/openjpeg3d.h
+
+solist = $(foreach f, $(dll) $(so), echo -e ' $(SO_PREFIX)\t$(base)/$(f)' ;)
+get_tok = $(shell grep -E "^$(1)=" $(lib_LTLIBRARIES) | cut -d "'" -f 2)
+base = $(call get_tok,libdir)
+so = $(call get_tok,library_names)
+a = $(call get_tok,old_library)
+
+if HAVE_WIN32
+SO_PREFIX = (DLL)
+dll = $(call get_tok,dlname)
+else
+if HAVE_DARWIN
+SO_PREFIX = (DY)
+dll =
+else
+SO_PREFIX = (SO)
+dll =
+endif
+endif
diff --git a/libopenjpeg3d/bio.c b/libopenjpeg3d/bio.c
new file mode 100755
index 00000000..bc3b1138
--- /dev/null
+++ b/libopenjpeg3d/bio.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * 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 */
+/*@{*/
+
+/**
+Write a bit
+@param bio BIO handle
+@param b Bit to write (0 or 1)
+*/
+static void bio_putbit(opj_bio_t *bio, int b);
+/**
+Read a bit
+@param bio BIO handle
+@return Returns the read bit
+*/
+static int bio_getbit(opj_bio_t *bio);
+/**
+Write a byte
+@param bio BIO handle
+@return Returns 0 if successful, returns 1 otherwise
+*/
+static int bio_byteout(opj_bio_t *bio);
+/**
+Read a byte
+@param bio BIO handle
+@return Returns 0 if successful, returns 1 otherwise
+*/
+static int bio_bytein(opj_bio_t *bio);
+
+/*@}*/
+
+/*@}*/
+
+
+/*
+==========================================================
+ local functions
+==========================================================
+*/
+
+static int bio_byteout(opj_bio_t *bio) {
+ bio->buf = (bio->buf << 8) & 0xffff;
+ bio->ct = bio->buf == 0xff00 ? 7 : 8;
+ if (bio->bp >= bio->end) {
+ return 1;
+ }
+ *bio->bp++ = bio->buf >> 8;
+ return 0;
+}
+
+static int bio_bytein(opj_bio_t *bio) {
+ bio->buf = (bio->buf << 8) & 0xffff;
+ bio->ct = bio->buf == 0xff00 ? 7 : 8;
+ if (bio->bp >= bio->end) {
+ return 1;
+ }
+ bio->buf |= *bio->bp++;
+ return 0;
+}
+
+static void bio_putbit(opj_bio_t *bio, int b) {
+ if (bio->ct == 0) {
+ bio_byteout(bio);
+ }
+ bio->ct--;
+ bio->buf |= b << bio->ct;
+}
+
+/* MOD antonin */
+static int bio_getbit(opj_bio_t *bio) {
+/* DOM */
+ if (bio->ct == 0) {
+ bio_bytein(bio);
+ }
+ bio->ct--;
+ return (bio->buf >> bio->ct) & 1;
+}
+
+/*
+==========================================================
+ Bit Input/Output interface
+==========================================================
+*/
+
+opj_bio_t* bio_create() {
+ opj_bio_t *bio = (opj_bio_t*)opj_malloc(sizeof(opj_bio_t));
+ return bio;
+}
+
+void bio_destroy(opj_bio_t *bio) {
+ if(bio) {
+ opj_free(bio);
+ }
+}
+
+int bio_numbytes(opj_bio_t *bio) {
+ return (bio->bp - bio->start);
+}
+
+void bio_init_enc(opj_bio_t *bio, unsigned char *bp, int len) {
+ bio->start = bp;
+ bio->end = bp + len;
+ bio->bp = bp;
+ bio->buf = 0;
+ bio->ct = 8;
+}
+
+void bio_init_dec(opj_bio_t *bio, unsigned char *bp, int len) {
+ bio->start = bp;
+ bio->end = bp + len;
+ bio->bp = bp;
+ bio->buf = 0;
+ bio->ct = 0;
+}
+
+void bio_write(opj_bio_t *bio, int v, int n) {
+ int i;
+ for (i = n - 1; i >= 0; i--) {
+ bio_putbit(bio, (v >> i) & 1);
+ }
+}
+
+int bio_read(opj_bio_t *bio, int n) {
+ int i, v;
+ v = 0;
+ for (i = n - 1; i >= 0; i--) {
+ v += bio_getbit(bio) << i;
+ }
+ return v;
+}
+
+int bio_flush(opj_bio_t *bio) {
+ bio->ct = 0;
+ if (bio_byteout(bio)) {
+ return 1;
+ }
+ if (bio->ct == 7) {
+ bio->ct = 0;
+ if (bio_byteout(bio)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int bio_inalign(opj_bio_t *bio) {
+ bio->ct = 0;
+ if ((bio->buf & 0xff) == 0xff) {
+ if (bio_bytein(bio)) {
+ return 1;
+ }
+ bio->ct = 0;
+ }
+ return 0;
+}
diff --git a/libopenjpeg3d/bio.h b/libopenjpeg3d/bio.h
new file mode 100755
index 00000000..36bb942b
--- /dev/null
+++ b/libopenjpeg3d/bio.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * 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 __BIO_H
+#define __BIO_H
+/**
+@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 */
+ unsigned char *start;
+/** pointer to the end of the buffer */
+ unsigned char *end;
+/** pointer to the present position in the buffer */
+ unsigned char *bp;
+/** temporary place where each byte is read or written */
+ unsigned int buf;
+/** coder : number of bits free to write. decoder : number of bits read */
+ int ct;
+} opj_bio_t;
+
+/** @name Funciones generales */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+/**
+Create a new BIO handle
+@return Returns a new BIO handle if successful, returns NULL otherwise
+*/
+opj_bio_t* bio_create();
+/**
+Destroy a previously created BIO handle
+@param bio BIO handle to destroy
+*/
+void bio_destroy(opj_bio_t *bio);
+/**
+Number of bytes written.
+@param bio BIO handle
+@return Returns the number of bytes written
+*/
+int bio_numbytes(opj_bio_t *bio);
+/**
+Init encoder
+@param bio BIO handle
+@param bp Output buffer
+@param len Output buffer length
+*/
+void bio_init_enc(opj_bio_t *bio, unsigned char *bp, int len);
+/**
+Init decoder
+@param bio BIO handle
+@param bp Input buffer
+@param len Input buffer length
+*/
+void bio_init_dec(opj_bio_t *bio, unsigned char *bp, int len);
+/**
+Write bits
+@param bio BIO handle
+@param v Value of bits
+@param n Number of bits to write
+*/
+void bio_write(opj_bio_t *bio, int v, int n);
+/**
+Read bits
+@param bio BIO handle
+@param n Number of bits to read
+@return Returns the corresponding read number
+*/
+int bio_read(opj_bio_t *bio, int n);
+/**
+Flush bits
+@param bio BIO handle
+@return Returns 1 if successful, returns 0 otherwise
+*/
+int bio_flush(opj_bio_t *bio);
+/**
+Passes the ending bits (coming from flushing)
+@param bio BIO handle
+@return Returns 1 if successful, returns 0 otherwise
+*/
+int bio_inalign(opj_bio_t *bio);
+/**
+Read a bit
+@param bio BIO handle
+@return Returns the read bit
+*/
+/* MOD antonin */
+//int bio_getbit(opj_bio_t *bio);
+/* DOM */
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+#endif /* __BIO_H */
+
diff --git a/libopenjpeg3d/cio.c b/libopenjpeg3d/cio.c
new file mode 100755
index 00000000..4ac64fd3
--- /dev/null
+++ b/libopenjpeg3d/cio.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * 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_cio_t* OPJ_CALLCONV opj_cio_open(opj_common_ptr cinfo, unsigned char *buffer, int length) {
+ opj_cp_t *cp = NULL;
+ opj_cio_t *cio = (opj_cio_t*)opj_malloc(sizeof(opj_cio_t));
+ if(!cio) return NULL;
+ cio->cinfo = cinfo;
+ if(buffer && length) {
+ /* wrap a user buffer containing the encoded image */
+ cio->openmode = OPJ_STREAM_READ;
+ cio->buffer = buffer;
+ cio->length = length;
+ }
+ else if(!buffer && !length && cinfo) {
+ /* allocate a buffer for the encoded image */
+ cio->openmode = OPJ_STREAM_WRITE;
+ switch(cinfo->codec_format) {
+ case CODEC_J3D:
+ case CODEC_J2K:
+ cp = ((opj_j3d_t*)cinfo->j3d_handle)->cp;
+ break;
+ default:
+ opj_free(cio);
+ return NULL;
+ }
+ cio->length = cp->tdx * cp->tdy * cp->tdz * cp->tw * cp->th * cp->tl * 4;
+ cio->buffer = (unsigned char *)opj_malloc(cio->length);
+ if(!cio->buffer) {
+ opj_free(cio);
+ return NULL;
+ }
+ }
+ else {
+ opj_free(cio);
+ return NULL;
+ }
+
+ /* Initialize byte IO */
+ cio->start = cio->buffer;
+ cio->end = cio->buffer + cio->length;
+ cio->bp = cio->buffer;
+
+ return cio;
+}
+
+void OPJ_CALLCONV opj_cio_close(opj_cio_t *cio) {
+ if(cio) {
+ if(cio->openmode == OPJ_STREAM_WRITE) {
+ /* destroy the allocated buffer */
+ opj_free(cio->buffer);
+ }
+ /* destroy the cio */
+ opj_free(cio);
+ }
+}
+
+
+/* ----------------------------------------------------------------------- */
+
+/*
+ * Get position in byte stream.
+ */
+int OPJ_CALLCONV cio_tell(opj_cio_t *cio) {
+ return cio->bp - cio->start;
+}
+
+/*
+ * Set position in byte stream.
+ *
+ * pos : position, in number of bytes, from the beginning of the stream
+ */
+void OPJ_CALLCONV cio_seek(opj_cio_t *cio, int pos) {
+ cio->bp = cio->start + pos;
+}
+
+/*
+ * Number of bytes left before the end of the stream.
+ */
+int cio_numbytesleft(opj_cio_t *cio) {
+ return cio->end - cio->bp;
+}
+
+/*
+ * Get pointer to the current position in the stream.
+ */
+unsigned char *cio_getbp(opj_cio_t *cio) {
+ return cio->bp;
+}
+
+/*
+ * Write a byte.
+ */
+bool cio_byteout(opj_cio_t *cio, unsigned char v) {
+ if (cio->bp >= cio->end) {
+ opj_event_msg(cio->cinfo, EVT_ERROR, "write error\n");
+ return false;
+ }
+ *cio->bp++ = v;
+ return true;
+}
+
+/*
+ * Read a byte.
+ */
+unsigned char cio_bytein(opj_cio_t *cio) {
+ if (cio->bp >= cio->end) {
+ opj_event_msg(cio->cinfo, EVT_ERROR, "read error\n");
+ return 0;
+ }
+ return *cio->bp++;
+}
+
+/*
+ * Write some bytes.
+ *
+ * v : value to write
+ * n : number of bytes to write
+ */
+unsigned int cio_write(opj_cio_t *cio, unsigned int v, int n) {
+ int i;
+ for (i = n - 1; i >= 0; i--) {
+ if( !cio_byteout(cio, (unsigned char) ((v >> (i << 3)) & 0xff)) )
+ return 0;
+ }
+ return n;
+}
+
+/*
+ * Read some bytes.
+ *
+ * n : number of bytes to read
+ *
+ * return : value of the n bytes read
+ */
+unsigned int cio_read(opj_cio_t *cio, int n) {
+ int i;
+ unsigned int v;
+ v = 0;
+ for (i = n - 1; i >= 0; i--) {
+ v += cio_bytein(cio) << (i << 3);
+ }
+ return v;
+}
+
+/*
+ * Skip some bytes.
+ *
+ * n : number of bytes to skip
+ */
+void cio_skip(opj_cio_t *cio, int n) {
+ cio->bp += n;
+}
+
+/*
+ * Write some bytes.
+ *
+ * v : value to write
+ * n : number of bytes to write
+ */
+int cio_write_int(opj_cio_t *cio, int v, int n) {
+ int i;
+ for (i = n - 1; i >= 0; i--) {
+ if( !cio_byteout(cio, (char) ((v >> (i << 3)) & 0xff)) )
+ return 0;
+ }
+ return n;
+}
+
+/*
+ * Read some bytes.
+ *
+ * n : number of bytes to read
+ *
+ * return : value of the n bytes read
+ */
+int cio_read_int(opj_cio_t *cio, int n) {
+ int i;
+ int v;
+ v = 0;
+ for (i = n - 1; i >= 0; i--) {
+ v += cio_bytein(cio) << (i << 3);
+ }
+ return v;
+}
+
diff --git a/libopenjpeg3d/cio.h b/libopenjpeg3d/cio.h
new file mode 100755
index 00000000..860d0b26
--- /dev/null
+++ b/libopenjpeg3d/cio.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * 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 __CIO_H
+#define __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 */
+/*@{*/
+
+/** @name Funciones generales (see also openjpeg3d.h) */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+/**
+Number of bytes left before the end of the stream
+@param cio CIO handle
+@return Returns the number of bytes before the end of the stream
+*/
+int cio_numbytesleft(opj_cio_t *cio);
+/**
+Get pointer to the current position in the stream
+@param cio CIO handle
+@return Returns a pointer to the current position
+*/
+unsigned char *cio_getbp(opj_cio_t *cio);
+/**
+Write some bytes
+@param cio CIO handle
+@param v Value to write
+@param n Number of bytes to write
+@return Returns the number of bytes written or 0 if an error occured
+*/
+unsigned int cio_write(opj_cio_t *cio, unsigned int v, int n);
+/**
+Read some bytes
+@param cio CIO handle
+@param n Number of bytes to read
+@return Returns the value of the n bytes read
+*/
+unsigned int cio_read(opj_cio_t *cio, int n);
+/**
+Skip some bytes
+@param cio CIO handle
+@param n Number of bytes to skip
+*/
+void cio_skip(opj_cio_t *cio, int n);
+/**
+Write some bytes
+@param cio CIO handle
+@param v Signed integer value to write
+@param n Number of bytes to write
+@return Returns the number of bytes written or 0 if an error occured
+*/
+int cio_write_int(opj_cio_t *cio, int v, int n);
+/**
+Read some bytes
+@param cio CIO handle
+@param n Number of bytes to read
+@return Returns the value of the n bytes read
+*/
+int cio_read_int(opj_cio_t *cio, int n);
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+#endif /* __CIO_H */
+
diff --git a/libopenjpeg3d/dwt.c b/libopenjpeg3d/dwt.c
new file mode 100755
index 00000000..8f30daeb
--- /dev/null
+++ b/libopenjpeg3d/dwt.c
@@ -0,0 +1,1016 @@
+/*
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * Copyrigth (c) 2006, Mónica Díez, LPI-UVA, Spain
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * NOTE:
+ * This is a modified version of the openjpeg dwt.c file.
+ * Average speed improvement compared to the original file (measured on
+ * my own machine, a P4 running at 3.0 GHz):
+ * 5x3 wavelets about 2 times faster
+ * 9x7 wavelets about 3 times faster
+ * for both, encoding and decoding.
+ *
+ * The better performance is caused by doing the 1-dimensional DWT
+ * within a temporary buffer where the data can be accessed sequential
+ * for both directions, horizontal and vertical. The 2d vertical DWT was
+ * the major bottleneck in the former version.
+ *
+ * I have also removed the "Add Patrick" part because it is not longer
+ * needed.
+ *
+ * 6/6/2005
+ * -Ive (aka Reiner Wahler)
+ * mail: ive@lilysoft.com
+ */
+
+#include "opj_includes.h"
+
+/** @defgroup DWT DWT - Implementation of a discrete wavelet transform */
+/*@{*/
+
+/** @name Local static functions */
+/*@{*/
+unsigned int ops;
+/**
+Forward lazy transform (horizontal)
+*/
+static void dwt_deinterleave_h(int *a, int *b, int dn, int sn, int cas);
+/**
+Forward lazy transform (vertical)
+*/
+static void dwt_deinterleave_v(int *a, int *b, int dn, int sn, int x, int cas);
+/**
+Forward lazy transform (axial)
+*/
+static void dwt_deinterleave_z(int *a, int *b, int dn, int sn, int xy, int cas);
+/**
+Inverse lazy transform (horizontal)
+*/
+static void dwt_interleave_h(int *a, int *b, int dn, int sn, int cas);
+/**
+Inverse lazy transform (vertical)
+*/
+static void dwt_interleave_v(int *a, int *b, int dn, int sn, int x, int cas);
+/**
+Inverse lazy transform (axial)
+*/
+static void dwt_interleave_z(int *a, int *b, int dn, int sn, int xy, int cas);
+/**
+Forward 5-3 wavelet tranform in 1-D
+*/
+static void dwt_encode_53(int *a, int dn, int sn, int cas);
+static void dwt_encode_97(int *a, int dn, int sn, int cas);
+/**
+Inverse 5-3 wavelet tranform in 1-D
+*/
+static void dwt_decode_53(int *a, int dn, int sn, int cas);
+static void dwt_decode_97(int *a, int dn, int sn, int cas);
+/**
+Computing of wavelet transform L2 norms for arbitrary transforms
+*/
+static double dwt_calc_wtnorms(int orient, int level[3], int dwtid[3], opj_wtfilt_t *wtfiltx, opj_wtfilt_t *wtfilty, opj_wtfilt_t *wtfiltz);
+/**
+Encoding of quantification stepsize
+*/
+static void dwt_encode_stepsize(int stepsize, int numbps, opj_stepsize_t *bandno_stepsize);
+/*@}*/
+
+/*@}*/
+
+#define S(i) a[(i)*2]
+#define D(i) a[(1+(i)*2)]
+#define S_(i) ((i)<0?S(0):((i)>=sn?S(sn-1):S(i)))
+#define D_(i) ((i)<0?D(0):((i)>=dn?D(dn-1):D(i)))
+/* new */
+#define SS_(i) ((i)<0?S(0):((i)>=dn?S(dn-1):S(i)))
+#define DD_(i) ((i)<0?D(0):((i)>=sn?D(sn-1):D(i)))
+
+/* <summary> */
+/* This table contains the norms of the 5-3 wavelets for different bands. */
+/* </summary> */
+static double dwt_norm[10][10][10][8];
+static int flagnorm[10][10][10][8];
+
+/*static const double dwt_norms[5][8][10] = {
+ {//ResZ=1
+ {1.000, 1.500, 2.750, 5.375, 10.68, 21.34, 42.67, 85.33, 170.7, 341.3},
+ {1.038, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9},
+ {1.038, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9},
+ {.7186, .9218, 1.586, 3.043, 6.019, 12.01, 24.00, 47.97, 95.93}
+ },{//ResZ=2
+ {1.000, 1.8371, 2.750, 5.375, 10.68, 21.34, 42.67, 85.33, 170.7, 341.3},
+ {1.2717, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9},
+ {1.2717, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9},
+ {.8803, .9218, 1.586, 3.043, 6.019, 12.01, 24.00, 47.97, 95.93},
+ {1.2717},
+ {.8803},
+ {.8803},
+ {.6093},
+ },{ //ResZ=3
+ {1.000, 1.8371, 4.5604, 5.375, 10.68, 21.34, 42.67, 85.33, 170.7, 341.3},
+ {1.2717, 2.6403, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9},
+ {1.2717, 2.6403, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9},
+ {.8803, 1.5286, 1.586, 3.043, 6.019, 12.01, 24.00, 47.97, 95.93},
+ {1.2717, 2.6403},
+ {.8803, 1.5286},
+ {.8803, 1.5286},
+ {.6093, 0.8850},
+ },{ //ResZ=4
+ {1.000, 1.8371, 4.5604, 12.4614, 10.68, 21.34, 42.67, 85.33, 170.7, 341.3},
+ {1.2717, 2.6403, 6.7691 , 5.703, 11.33, 22.64, 45.25, 90.48, 180.9},
+ {1.2717, 2.6403, 6.7691 , 5.703, 11.33, 22.64, 45.25, 90.48, 180.9},
+ {.8803, 1.5286, 3.6770 , 3.043, 6.019, 12.01, 24.00, 47.97, 95.93},
+ {1.2717, 2.6403, 6.7691 },
+ {.8803, 1.5286, 3.6770 },
+ {.8803, 1.5286, 3.6770 },
+ {.6093, 0.8850, 1.9974 },
+ },{ //ResZ=5
+ {1.000, 1.8371, 4.5604, 12.4614, 34.9025, 21.34, 42.67, 85.33, 170.7, 341.3},
+ {1.2717, 2.6403, 6.7691 , 18.6304 , 11.33, 22.64, 45.25, 90.48, 180.9},
+ {1.2717, 2.6403, 6.7691 , 18.6304, 11.33, 22.64, 45.25, 90.48, 180.9},
+ {.8803, 1.5286, 3.6770 , 9.9446, 6.019, 12.01, 24.00, 47.97, 95.93},
+ {1.2717, 2.6403, 6.7691, 18.6304},
+ {.8803, 1.5286, 3.6770, 9.9446 },
+ {.8803, 1.5286, 3.6770, 9.9446 },
+ {.6093, 0.8850, 1.9974, 5.3083 },
+ }
+};*/
+
+/* <summary> */
+/* This table contains the norms of the 9-7 wavelets for different bands. */
+/* </summary> */
+/*static const double dwt_norms_real[5][8][10] = {
+ {//ResZ==1
+ {1.000, 1.9659, 4.1224, 8.4167, 16.9356, 33.9249, 67.8772, 135.7680, 271.5430, 543.0894},
+ {1.0113, 1.9968, 4.1834, 8.5341, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196},
+ {1.0113, 1.9968, 4.1834, 8.5341, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196},
+ {0.5202, 0.9672, 2.0793, 4.3005, 8.6867, 17.4188, 34.8608, 69.7332, 139.4722}
+ }, { //ResZ==2
+ {1.000, 2.7564, 4.1224, 8.4167, 16.9356, 33.9249, 67.8772, 135.7680, 271.5430, 543.0894},
+ {1.4179, 1.9968, 4.1834, 8.5341, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196},
+ {1.4179, 1.9968, 4.1834, 8.5341, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196},
+ {0.7294, 0.9672, 2.0793, 4.3005, 8.6867, 17.4188, 34.8608, 69.7332, 139.4722},
+ {1.4179},
+ {0.7294},
+ {0.7294},
+ {0.3752} //HHH
+ },{ //ResZ==3
+ {1.000, 2.7564, 8.3700, 8.4167, 16.9356, 33.9249, 67.8772, 135.7680, 271.5430, 543.0894},
+ {1.4179, 4.0543, 4.1834, 8.5341, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196},
+ {1.4179, 4.0543, 4.1834, 8.5341, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196},
+ {0.7294, 1.9638, 2.0793, 4.3005, 8.6867, 17.4188, 34.8608, 69.7332, 139.4722},
+ {1.4179, 4.0543},
+ {0.7294, 1.9638},
+ {0.7294, 1.9638},
+ {0.3752, 0.9512} //HHH
+ },{ //ResZ==4
+ {1.000, 2.7564, 8.3700, 24.4183, 16.9356, 33.9249, 67.8772, 135.7680, 271.5430, 543.0894},
+ {1.4179, 4.0543, 12.1366, 8.5341, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196},
+ {1.4179, 4.0543, 12.1366, 8.5341, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196},
+ {0.7294, 1.9638, 6.0323, 4.3005, 8.6867, 17.4188, 34.8608, 69.7332, 139.4722},
+ {1.4179, 4.0543, 12.1366},
+ {0.7294, 1.9638, 6.0323},
+ {0.7294, 1.9638, 6.0323},
+ {0.3752, 0.9512, 2.9982} //HHH
+ },{ //ResZ==5
+ {1.000, 2.7564, 8.3700, 24.4183, 69.6947, 33.9249, 67.8772, 135.7680, 271.5430, 543.0894},
+ {1.4179, 4.0543, 12.1366, 35.1203, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196},
+ {1.4179, 4.0543, 12.1366, 35.1203, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196},
+ {0.7294, 1.9638, 6.0323, 17.6977, 8.6867, 17.4188, 34.8608, 69.7332, 139.4722},
+ {1.4179, 4.0543, 12.1366, 35.1203},
+ {0.7294, 1.9638, 6.0323, 17.6977},
+ {0.7294, 1.9638, 6.0323, 17.6977},
+ {0.3752, 0.9512, 2.9982, 8.9182} //HHH
+ }
+};*/
+
+static opj_atk_t atk_info_wt[] = {
+ {0, 1, J3D_ATK_WS, J3D_ATK_IRR, 0, J3D_ATK_WS, 1.230174104, 4, {0}, {0}, {0}, {1,1,1,1}, {-1.586134342059924, -0.052980118572961, 0.882911075530934, 0.443506852043971}},/* WT 9-7 IRR*/
+ {1, 0, J3D_ATK_WS, J3D_ATK_REV, 0, J3D_ATK_WS, 0, 2, {0}, {1,2}, {1,2}, {1,1}, {-1,1}},/* WT 5-3 REV*/
+ {2, 0, J3D_ATK_ARB, J3D_ATK_REV, 0, J3D_ATK_CON, 0, 2, {0,0}, {0,1}, {0,1}, {1,1}, {{-1},{1}}}, /* WT 2-2 REV*/
+ {3, 0, J3D_ATK_ARB, J3D_ATK_REV, 1, J3D_ATK_CON, 0, 3, {0,0,-1}, {0,1,2}, {0,1,2}, {1,1,3}, {{-1},{1},{1,0,-1}}}, /* WT 2-6 REV*/
+ {4, 0, J3D_ATK_ARB, J3D_ATK_REV, 1, J3D_ATK_CON, 0, 3, {0,0,-2}, {0,1,6}, {0,1,32}, {1,1,5}, {{-1},{1},{-3,22,0,-22,3}}}, /* WT 2-10 REV*/
+ {5, 1, J3D_ATK_ARB, J3D_ATK_IRR, 1, J3D_ATK_WS, 1, 7, {0}, {0}, {0}, {1,1,2,1,2,1,3},{{-1},{1.58613434206},{-0.460348209828, 0.460348209828},{0.25},{0.374213867768,-0.374213867768},{-1.33613434206},{0.29306717103,0,-0.29306717103}}}, /* WT 6-10 IRR*/
+ {6, 1, J3D_ATK_ARB, J3D_ATK_IRR, 0, J3D_ATK_WS, 1, 11, {0}, {0}, {0}, {1,1,2,1,2,1,2,1,2,1,5},{{-1},{0,99715069105},{-1.00573127827, 1.00573127827},{-0.27040357631},{2.20509972343, -2.20509972343},{0.08059995736},
+ {-1.62682532350, 1.62682532350},{0.52040357631},{0.60404664250, -0.60404664250},{-0.82775064841},{-0.06615812964, 0.29402137720, 0, -0.29402137720, 0.06615812964}}}, /* WT 10-18 IRR*/
+ {7, 1, J3D_ATK_WS, J3D_ATK_IRR, 0, J3D_ATK_WS, 1, 2, {0}, {0}, {0}, {1,1}, {-0.5, 0.25}}, /* WT 5-3 IRR*/
+ {8, 0, J3D_ATK_WS, J3D_ATK_REV, 0, J3D_ATK_WS, 0, 2, {0}, {4,4}, {8,8}, {2,2}, {{-9,1},{5,-1}}} /* WT 13-7 REV*/
+};
+/*
+==========================================================
+ local functions
+==========================================================
+*/
+
+/* <summary> */
+/* Forward lazy transform (horizontal). */
+/* </summary> */
+static void dwt_deinterleave_h(int *a, int *b, int dn, int sn, int cas) {
+ int i;
+ for (i=0; i<sn; i++) b[i]=a[2*i+cas];
+ for (i=0; i<dn; i++) b[sn+i]=a[(2*i+1-cas)];
+}
+
+/* <summary> */
+/* Forward lazy transform (vertical). */
+/* </summary> */
+static void dwt_deinterleave_v(int *a, int *b, int dn, int sn, int x, int cas) {
+ int i;
+ for (i=0; i<sn; i++) b[i*x]=a[2*i+cas];
+ for (i=0; i<dn; i++) b[(sn+i)*x]=a[(2*i+1-cas)];
+}
+
+/* <summary> */
+/* Forward lazy transform (axial). */
+/* </summary> */
+static void dwt_deinterleave_z(int *a, int *b, int dn, int sn, int xy, int cas) {
+ int i;
+ for (i=0; i<sn; i++) b[i*xy]=a[2*i+cas];
+ for (i=0; i<dn; i++) b[(sn+i)*xy]=a[(2*i+1-cas)];
+}
+
+/* <summary> */
+/* Inverse lazy transform (horizontal). */
+/* </summary> */
+static void dwt_interleave_h(int *a, int *b, int dn, int sn, int cas) {
+ int i;
+ int *ai = NULL;
+ int *bi = NULL;
+ ai = a;
+ bi = b + cas;
+ for (i = 0; i < sn; i++) {
+ *bi = *ai;
+ bi += 2;
+ ai++;
+ }
+ ai = a + sn;
+ bi = b + 1 - cas;
+ for (i = 0; i < dn; i++) {
+ *bi = *ai;
+ bi += 2;
+ ai++;
+ }
+}
+
+/* <summary> */
+/* Inverse lazy transform (vertical). */
+/* </summary> */
+static void dwt_interleave_v(int *a, int *b, int dn, int sn, int x, int cas) {
+ int i;
+ int *ai = NULL;
+ int *bi = NULL;
+ ai = a;
+ bi = b + cas;
+ for (i = 0; i < sn; i++) {
+ *bi = *ai;
+ bi += 2;
+ ai += x;
+ }
+ ai = a + (sn * x);
+ bi = b + 1 - cas;
+ for (i = 0; i < dn; i++) {
+ *bi = *ai;
+ bi += 2;
+ ai += x;
+ }
+}
+
+/* <summary> */
+/* Inverse lazy transform (axial). */
+/* </summary> */
+static void dwt_interleave_z(int *a, int *b, int dn, int sn, int xy, int cas) {
+ int i;
+ int *ai = NULL;
+ int *bi = NULL;
+ ai = a;
+ bi = b + cas;
+ for (i = 0; i < sn; i++) {
+ *bi = *ai;
+ bi += 2;
+ ai += xy;
+ }
+ ai = a + (sn * xy);
+ bi = b + 1 - cas;
+ for (i = 0; i < dn; i++) {
+ *bi = *ai;
+ bi += 2;
+ ai += xy;
+ }
+}
+
+
+/* <summary> */
+/* Forward 5-3 or 9-7 wavelet tranform in 1-D. */
+/* </summary> */
+static void dwt_encode_53(int *a, int dn, int sn, int cas) {
+ int i;
+
+ if (!cas) {
+ if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */
+ //for (i = 0; i < dn; i++) D(i) -= (S_(i) + S_(i + 1)) >> 1;
+ //for (i = 0; i < sn; i++) S(i) += (D_(i - 1) + D_(i) + 2) >> 2;
+ for (i = 0; i < dn; i++){
+ D(i) -= (S_(i) + S_(i + 1)) >> 1;
+ //ops += 2;
+ }
+ for (i = 0; i < sn; i++){
+ S(i) += (D_(i - 1) + D_(i) + 2) >> 2;
+ //ops += 3;
+ }
+ }
+ } else {
+ /*if (!sn && dn == 1)
+ S(0) *= 2;
+ else {
+ for (i = 0; i < dn; i++) S(i) -= (DD_(i) + DD_(i - 1)) >> 1;
+ for (i = 0; i < sn; i++) D(i) += (SS_(i) + SS_(i + 1) + 2) >> 2;
+ }*/
+ if (!sn && dn == 1){
+ S(0) *= 2;
+ //ops++;
+ } else {
+ for (i = 0; i < dn; i++){
+ S(i) -= (DD_(i) + DD_(i - 1)) >> 1;
+ // ops += 2;
+ }
+ for (i = 0; i < sn; i++){
+ D(i) += (SS_(i) + SS_(i + 1) + 2) >> 2;
+ // ops += 3;
+ }
+ }
+ }
+}
+static void dwt_encode_97(int *a, int dn, int sn, int cas) {
+ int i;
+
+ if (!cas) {
+ if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */
+ for (i = 0; i < dn; i++)
+ D(i) -= fix_mul(S_(i) + S_(i + 1), 12993);
+ for (i = 0; i < sn; i++)
+ S(i) -= fix_mul(D_(i - 1) + D_(i), 434);
+ for (i = 0; i < dn; i++)
+ D(i) += fix_mul(S_(i) + S_(i + 1), 7233);
+ for (i = 0; i < sn; i++)
+ S(i) += fix_mul(D_(i - 1) + D_(i), 3633);
+ for (i = 0; i < dn; i++)
+ D(i) = fix_mul(D(i), 5038); /*5038 */
+ for (i = 0; i < sn; i++)
+ S(i) = fix_mul(S(i), 6659); /*6660 */
+ }
+ } else {
+ if ((sn > 0) || (dn > 1)) { /* NEW : CASE ONE ELEMENT */
+ for (i = 0; i < dn; i++)
+ S(i) -= fix_mul(DD_(i) + DD_(i - 1), 12993);
+ for (i = 0; i < sn; i++)
+ D(i) -= fix_mul(SS_(i) + SS_(i + 1), 434);
+ for (i = 0; i < dn; i++)
+ S(i) += fix_mul(DD_(i) + DD_(i - 1), 7233);
+ for (i = 0; i < sn; i++)
+ D(i) += fix_mul(SS_(i) + SS_(i + 1), 3633);
+ for (i = 0; i < dn; i++)
+ S(i) = fix_mul(S(i), 5038); /*5038 */
+ for (i = 0; i < sn; i++)
+ D(i) = fix_mul(D(i), 6659); /*6660 */
+ }
+ }
+}
+/* <summary> */
+/* Inverse 5-3 or 9-7 wavelet tranform in 1-D. */
+/* </summary> */
+static void dwt_decode_53(int *a, int dn, int sn, int cas) {
+ int i;
+ if (!cas) {
+ if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */
+ for (i = 0; i < sn; i++) S(i) -= (D_(i - 1) + D_(i) + 2) >> 2;
+ for (i = 0; i < dn; i++) D(i) += (S_(i) + S_(i + 1)) >> 1;
+ }
+ } else {
+ if (!sn && dn == 1) /* NEW : CASE ONE ELEMENT */
+ S(0) /= 2;
+ else {
+ for (i = 0; i < sn; i++) D(i) -= (SS_(i) + SS_(i + 1) + 2) >> 2;
+ for (i = 0; i < dn; i++) S(i) += (DD_(i) + DD_(i - 1)) >> 1;
+ }
+ }
+}
+static void dwt_decode_97(int *a, int dn, int sn, int cas) {
+ int i;
+
+ if (!cas) {
+ if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */
+ for (i = 0; i < sn; i++)
+ S(i) = fix_mul(S(i), 10078); /* 10076 */
+ for (i = 0; i < dn; i++)
+ D(i) = fix_mul(D(i), 13318); /* 13320 */
+ for (i = 0; i < sn; i++)
+ S(i) -= fix_mul(D_(i - 1) + D_(i), 3633);
+ for (i = 0; i < dn; i++)
+ D(i) -= fix_mul(S_(i) + S_(i + 1), 7233);
+ for (i = 0; i < sn; i++)
+ S(i) += fix_mul(D_(i - 1) + D_(i), 434);
+ for (i = 0; i < dn; i++)
+ D(i) += fix_mul(S_(i) + S_(i + 1), 12994); /* 12993 */
+ }
+ } else {
+ if ((sn > 0) || (dn > 1)) { /* NEW : CASE ONE ELEMENT */
+ for (i = 0; i < sn; i++)
+ D(i) = fix_mul(D(i), 10078); /* 10076 */
+ for (i = 0; i < dn; i++)
+ S(i) = fix_mul(S(i), 13318); /* 13320 */
+ for (i = 0; i < sn; i++)
+ D(i) -= fix_mul(SS_(i) + SS_(i + 1), 3633);
+ for (i = 0; i < dn; i++)
+ S(i) -= fix_mul(DD_(i) + DD_(i - 1), 7233);
+ for (i = 0; i < sn; i++)
+ D(i) += fix_mul(SS_(i) + SS_(i + 1), 434);
+ for (i = 0; i < dn; i++)
+ S(i) += fix_mul(DD_(i) + DD_(i - 1), 12994); /* 12993 */
+ }
+ }
+}
+
+
+/* <summary> */
+/* Get norm of arbitrary wavelet transform. */
+/* </summary> */
+static int upandconv(double *nXPS, double *LPS, int lenXPS, int lenLPS) {
+ /* Perform the convolution of the vectors. */
+ int i,j;
+ double *tmp = (double *)opj_malloc(2*lenXPS * sizeof(double));
+ //Upsample
+ memset(tmp, 0, 2*lenXPS*sizeof(double));
+ for (i = 0; i < lenXPS; i++) {
+ *(tmp + 2*i) = *(nXPS + i);
+ *(nXPS + i) = 0;
+ }
+ //Convolution
+ for (i = 0; i < 2*lenXPS; i++) {
+ for (j = 0; j < lenLPS; j++) {
+ *(nXPS+i+j) = *(nXPS+i+j) + *(tmp + i) * *(LPS + j);
+ //fprintf(stdout,"*(tmp + %d) * *(LPS + %d) = %f * %f \n",i,j,*(tmp + i),*(LPS + j));
+ }
+ }
+ free(tmp);
+ return 2*lenXPS+lenLPS-1;
+}
+
+static double dwt_calc_wtnorms(int orient, int level[3], int dwtid[3], opj_wtfilt_t *wtfiltX, opj_wtfilt_t *wtfiltY, opj_wtfilt_t *wtfiltZ) {
+ int i, lenLPS, lenHPS;
+ double Lx = 0, Ly= 0, Hx= 0, Hy= 0, Lz= 0, Hz= 0;
+ double *nLPSx, *nHPSx,*nLPSy, *nHPSy,*nLPSz, *nHPSz;
+ int levelx, levely, levelz;
+
+ levelx = (orient == 0) ? level[0]-1 : level[0];
+ levely = (orient == 0) ? level[1]-1 : level[1];
+ levelz = (orient == 0) ? level[2]-1 : level[2];
+
+ //X axis
+ lenLPS = wtfiltX->lenLPS;
+ lenHPS = wtfiltX->lenHPS;
+ for (i = 0; i < levelx; i++) {
+ lenLPS *= 2;
+ lenHPS *= 2;
+ lenLPS += wtfiltX->lenLPS - 1;
+ lenHPS += wtfiltX->lenLPS - 1;
+ }
+ nLPSx = (double *)opj_malloc(lenLPS * sizeof(double));
+ nHPSx = (double *)opj_malloc(lenHPS * sizeof(double));
+
+ memcpy(nLPSx, wtfiltX->LPS, wtfiltX->lenLPS * sizeof(double));
+ memcpy(nHPSx, wtfiltX->HPS, wtfiltX->lenHPS * sizeof(double));
+ lenLPS = wtfiltX->lenLPS;
+ lenHPS = wtfiltX->lenHPS;
+ for (i = 0; i < levelx; i++) {
+ lenLPS = upandconv(nLPSx, wtfiltX->LPS, lenLPS, wtfiltX->lenLPS);
+ lenHPS = upandconv(nHPSx, wtfiltX->LPS, lenHPS, wtfiltX->lenLPS);
+ }
+ for (i = 0; i < lenLPS; i++)
+ Lx += nLPSx[i] * nLPSx[i];
+ for (i = 0; i < lenHPS; i++)
+ Hx += nHPSx[i] * nHPSx[i];
+ Lx = sqrt(Lx);
+ Hx = sqrt(Hx);
+ free(nLPSx);
+ free(nHPSx);
+
+ //Y axis
+ if (dwtid[0] != dwtid[1] || level[0] != level[1]){
+ lenLPS = wtfiltY->lenLPS;
+ lenHPS = wtfiltY->lenHPS;
+ for (i = 0; i < levely; i++) {
+ lenLPS *= 2;
+ lenHPS *= 2;
+ lenLPS += wtfiltY->lenLPS - 1;
+ lenHPS += wtfiltY->lenLPS - 1;
+ }
+ nLPSy = (double *)opj_malloc(lenLPS * sizeof(double));
+ nHPSy = (double *)opj_malloc(lenHPS * sizeof(double));
+
+ memcpy(nLPSy, wtfiltY->LPS, wtfiltY->lenLPS * sizeof(double));
+ memcpy(nHPSy, wtfiltY->HPS, wtfiltY->lenHPS * sizeof(double));
+ lenLPS = wtfiltY->lenLPS;
+ lenHPS = wtfiltY->lenHPS;
+ for (i = 0; i < levely; i++) {
+ lenLPS = upandconv(nLPSy, wtfiltY->LPS, lenLPS, wtfiltY->lenLPS);
+ lenHPS = upandconv(nHPSy, wtfiltY->LPS, lenHPS, wtfiltY->lenLPS);
+ }
+ for (i = 0; i < lenLPS; i++)
+ Ly += nLPSy[i] * nLPSy[i];
+ for (i = 0; i < lenHPS; i++)
+ Hy += nHPSy[i] * nHPSy[i];
+ Ly = sqrt(Ly);
+ Hy = sqrt(Hy);
+ free(nLPSy);
+ free(nHPSy);
+ } else {
+ Ly = Lx;
+ Hy = Hx;
+ }
+ //Z axis
+ if (levelz >= 0) {
+ lenLPS = wtfiltZ->lenLPS;
+ lenHPS = wtfiltZ->lenHPS;
+ for (i = 0; i < levelz; i++) {
+ lenLPS *= 2;
+ lenHPS *= 2;
+ lenLPS += wtfiltZ->lenLPS - 1;
+ lenHPS += wtfiltZ->lenLPS - 1;
+ }
+ nLPSz = (double *)opj_malloc(lenLPS * sizeof(double));
+ nHPSz = (double *)opj_malloc(lenHPS * sizeof(double));
+
+ memcpy(nLPSz, wtfiltZ->LPS, wtfiltZ->lenLPS * sizeof(double));
+ memcpy(nHPSz, wtfiltZ->HPS, wtfiltZ->lenHPS * sizeof(double));
+ lenLPS = wtfiltZ->lenLPS;
+ lenHPS = wtfiltZ->lenHPS;
+ for (i = 0; i < levelz; i++) {
+ lenLPS = upandconv(nLPSz, wtfiltZ->LPS, lenLPS, wtfiltZ->lenLPS);
+ lenHPS = upandconv(nHPSz, wtfiltZ->LPS, lenHPS, wtfiltZ->lenLPS);
+ }
+ for (i = 0; i < lenLPS; i++)
+ Lz += nLPSz[i] * nLPSz[i];
+ for (i = 0; i < lenHPS; i++)
+ Hz += nHPSz[i] * nHPSz[i];
+ Lz = sqrt(Lz);
+ Hz = sqrt(Hz);
+ free(nLPSz);
+ free(nHPSz);
+ } else {
+ Lz = 1.0; Hz = 1.0;
+ }
+ switch (orient) {
+ case 0:
+ return Lx * Ly * Lz;
+ case 1:
+ return Lx * Hy * Lz;
+ case 2:
+ return Hx * Ly * Lz;
+ case 3:
+ return Hx * Hy * Lz;
+ case 4:
+ return Lx * Ly * Hz;
+ case 5:
+ return Lx * Hy * Hz;
+ case 6:
+ return Hx * Ly * Hz;
+ case 7:
+ return Hx * Hy * Hz;
+ default:
+ return -1;
+ }
+
+}
+static void dwt_getwtfilters(opj_wtfilt_t *wtfilt, int dwtid) {
+ if (dwtid == 0) { //DWT 9-7
+ wtfilt->lenLPS = 7; wtfilt->lenHPS = 9;
+ wtfilt->LPS = (double *)opj_malloc(wtfilt->lenLPS * sizeof(double));
+ wtfilt->HPS = (double *)opj_malloc(wtfilt->lenHPS * sizeof(double));
+ wtfilt->LPS[0] = -0.091271763114; wtfilt->HPS[0] = 0.026748757411;
+ wtfilt->LPS[1] = -0.057543526228; wtfilt->HPS[1] = 0.016864118443;
+ wtfilt->LPS[2] = 0.591271763114; wtfilt->HPS[2] = -0.078223266529;
+ wtfilt->LPS[3] = 1.115087052457; wtfilt->HPS[3] = -0.266864118443;
+ wtfilt->LPS[4] = 0.591271763114; wtfilt->HPS[4] = 0.602949018236;
+ wtfilt->LPS[5] = -0.057543526228; wtfilt->HPS[5] = -0.266864118443;
+ wtfilt->LPS[6] = -0.091271763114; wtfilt->HPS[6] = -0.078223266529;
+ wtfilt->HPS[7] = 0.016864118443;
+ wtfilt->HPS[8] = 0.026748757411;
+ } else if (dwtid == 1) { //DWT 5-3
+ wtfilt->lenLPS = 3; wtfilt->lenHPS = 5;
+ wtfilt->LPS = (double *)opj_malloc(wtfilt->lenLPS * sizeof(double));
+ wtfilt->HPS = (double *)opj_malloc(wtfilt->lenHPS * sizeof(double));
+ wtfilt->LPS[0] = 0.5; wtfilt->HPS[0] = -0.125;
+ wtfilt->LPS[1] = 1; wtfilt->HPS[1] = -0.25;
+ wtfilt->LPS[2] = 0.5; wtfilt->HPS[2] = 0.75;
+ wtfilt->HPS[3] = -0.25;
+ wtfilt->HPS[4] = -0.125;
+ } else {
+ fprintf(stdout,"[ERROR] Sorry, this wavelet hasn't been implemented so far ... Try another one :-)\n");
+ exit(1);
+ }
+}
+/* <summary> */
+/* Encoding of quantization stepsize for each subband. */
+/* </summary> */
+static void dwt_encode_stepsize(int stepsize, int numbps, opj_stepsize_t *bandno_stepsize) {
+ int p, n;
+ p = int_floorlog2(stepsize) - 13;
+ n = 11 - int_floorlog2(stepsize);
+ bandno_stepsize->mant = (n < 0 ? stepsize >> -n : stepsize << n) & 0x7ff;
+ bandno_stepsize->expn = numbps - p;
+ //if J3D_CCP_QNTSTY_NOQNT --> stepsize = 8192.0 --> p = 0, n = -2 --> mant = 0; expn = (prec+gain)
+ //else --> bandno_stepsize = (1<<(numbps - expn)) + (1<<(numbps - expn - 11)) * Ub
+}
+
+/*
+==========================================================
+ DWT interface
+==========================================================
+*/
+/* <summary> */
+/* Forward 5-3 wavelet tranform in 3-D. */
+/* </summary> */
+void dwt_encode(opj_tcd_tilecomp_t * tilec, int dwtid[3]) {
+ int i, j, k;
+ int x, y, z;
+ int w, h, wh, d;
+ int level,levelx,levely,levelz,diff;
+ int *a = NULL;
+ int *aj = NULL;
+ int *bj = NULL;
+ int *cj = NULL;
+
+ ops = 0;
+
+ memset(flagnorm,0,8000*sizeof(int));
+ w = tilec->x1-tilec->x0;
+ h = tilec->y1-tilec->y0;
+ d = tilec->z1-tilec->z0;
+ wh = w * h;
+ levelx = tilec->numresolution[0]-1;
+ levely = tilec->numresolution[1]-1;
+ levelz = tilec->numresolution[2]-1;
+ level = int_max(levelx,int_max(levely,levelz));
+ diff = tilec->numresolution[0] - tilec->numresolution[2];
+
+ a = tilec->data;
+
+ for (x = 0, y = 0, z = 0; (x < levelx) && (y < levely); x++, y++, z++) {
+ int rw; /* width of the resolution level computed */
+ int rh; /* heigth of the resolution level computed */
+ int rd; /* depth of the resolution level computed */
+ int rw1; /* width of the resolution level once lower than computed one */
+ int rh1; /* height of the resolution level once lower than computed one */
+ int rd1; /* depth of the resolution level once lower than computed one */
+ int cas_col; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */
+ int cas_row; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */
+ int cas_axl; /* 0 = non inversion on axial filtering 1 = inversion between low-pass and high-pass filtering */
+ int dn, sn;
+
+ rw = tilec->resolutions[level - x].x1 - tilec->resolutions[level - x].x0;
+ rh = tilec->resolutions[level - y].y1 - tilec->resolutions[level - y].y0;
+ rd = tilec->resolutions[level - z].z1 - tilec->resolutions[level - z].z0;
+ rw1= tilec->resolutions[level - x - 1].x1 - tilec->resolutions[level - x - 1].x0;
+ rh1= tilec->resolutions[level - y - 1].y1 - tilec->resolutions[level - y - 1].y0;
+ rd1= tilec->resolutions[level - z - 1].z1 - tilec->resolutions[level - z - 1].z0;
+
+ cas_col = tilec->resolutions[level - x].x0 % 2; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */
+ cas_row = tilec->resolutions[level - y].y0 % 2; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */
+ cas_axl = tilec->resolutions[level - z].z0 % 2;
+
+ /*fprintf(stdout," x %d y %d z %d \n",x,y,z);
+ fprintf(stdout," levelx %d levely %d levelz %d \n",levelx,levely,levelz);
+ fprintf(stdout," z1 %d z0 %d\n",tilec->resolutions[level - z].z1,tilec->resolutions[level - z].z0);
+ fprintf(stdout," rw %d rh %d rd %d \n rw1 %d rh1 %d rd1 %d \n",rw,rh,rd,rw1,rh1,rd1);*/
+
+ for (i = 0; i < rd; i++) {
+
+ cj = a + (i * wh);
+
+ //Horizontal
+ sn = rw1;
+ dn = rw - rw1;
+ bj = (int*)opj_malloc(rw * sizeof(int));
+ if (dwtid[0] == 0) {
+ for (j = 0; j < rh; j++) {
+ aj = cj + j * w;
+ for (k = 0; k < rw; k++) bj[k] = aj[k];
+ dwt_encode_97(bj, dn, sn, cas_row);
+ dwt_deinterleave_h(bj, aj, dn, sn, cas_row);
+ }
+ } else if (dwtid[0] == 1) {
+ for (j = 0; j < rh; j++) {
+ aj = cj + j * w;
+ for (k = 0; k < rw; k++) bj[k] = aj[k];
+ dwt_encode_53(bj, dn, sn, cas_row);
+ dwt_deinterleave_h(bj, aj, dn, sn, cas_row);
+ }
+ }
+ opj_free(bj);
+
+ //Vertical
+ sn = rh1;
+ dn = rh - rh1;
+ bj = (int*)opj_malloc(rh * sizeof(int));
+ if (dwtid[1] == 0) { /*DWT 9-7*/
+ for (j = 0; j < rw; j++) {
+ aj = cj + j;
+ for (k = 0; k < rh; k++) bj[k] = aj[k*w];
+ dwt_encode_97(bj, dn, sn, cas_col);
+ dwt_deinterleave_v(bj, aj, dn, sn, w, cas_col);
+ }
+ } else if (dwtid[1] == 1) { /*DWT 5-3*/
+ for (j = 0; j < rw; j++) {
+ aj = cj + j;
+ for (k = 0; k < rh; k++) bj[k] = aj[k*w];
+ dwt_encode_53(bj, dn, sn, cas_col);
+ dwt_deinterleave_v(bj, aj, dn, sn, w, cas_col);
+ }
+ }
+ opj_free(bj);
+ }
+
+ if (z < levelz){
+ //Axial fprintf(stdout,"Axial DWT Transform %d %d %d\n",z,rd,rd1);
+ sn = rd1;
+ dn = rd - rd1;
+ bj = (int*)opj_malloc(rd * sizeof(int));
+ if (dwtid[2] == 0) {
+ for (j = 0; j < (rw*rh); j++) {
+ aj = a + j;
+ for (k = 0; k < rd; k++) bj[k] = aj[k*wh];
+ dwt_encode_97(bj, dn, sn, cas_axl);
+ dwt_deinterleave_z(bj, aj, dn, sn, wh, cas_axl);
+ }
+ } else if (dwtid[2] == 1) {
+ for (j = 0; j < (rw*rh); j++) {
+ aj = a + j;
+ for (k = 0; k < rd; k++) bj[k] = aj[k*wh];
+ dwt_encode_53(bj, dn, sn, cas_axl);
+ dwt_deinterleave_z(bj, aj, dn, sn, wh, cas_axl);
+ }
+ }
+ opj_free(bj);
+ }
+ }
+
+ //fprintf(stdout,"[INFO] Ops: %d \n",ops);
+}
+
+
+/* <summary> */
+/* Inverse 5-3 wavelet tranform in 3-D. */
+/* </summary> */
+void dwt_decode(opj_tcd_tilecomp_t * tilec, int stops[3], int dwtid[3]) {
+ int i, j, k;
+ int x, y, z;
+ int w, h, wh, d;
+ int level, levelx, levely, levelz, diff;
+ int *a = NULL;
+ int *aj = NULL;
+ int *bj = NULL;
+ int *cj = NULL;
+
+ a = tilec->data;
+
+ w = tilec->x1-tilec->x0;
+ h = tilec->y1-tilec->y0;
+ d = tilec->z1-tilec->z0;
+ wh = w * h;
+ levelx = tilec->numresolution[0]-1;
+ levely = tilec->numresolution[1]-1;
+ levelz = tilec->numresolution[2]-1;
+ level = int_max(levelx,int_max(levely,levelz));
+ diff = tilec->numresolution[0] - tilec->numresolution[2];
+
+/* General lifting framework -- DCCS-LIWT */
+ for (x = level - 1, y = level - 1, z = level - 1; (x >= stops[0]) && (y >= stops[1]); x--, y--, z--) {
+ int rw; /* width of the resolution level computed */
+ int rh; /* heigth of the resolution level computed */
+ int rd; /* depth of the resolution level computed */
+ int rw1; /* width of the resolution level once lower than computed one */
+ int rh1; /* height of the resolution level once lower than computed one */
+ int rd1; /* depth of the resolution level once lower than computed one */
+ int cas_col; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */
+ int cas_row; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */
+ int cas_axl; /* 0 = non inversion on axial filtering 1 = inversion between low-pass and high-pass filtering */
+ int dn, sn;
+
+ rw = tilec->resolutions[level - x].x1 - tilec->resolutions[level - x].x0;
+ rh = tilec->resolutions[level - y].y1 - tilec->resolutions[level - y].y0;
+ rd = tilec->resolutions[level - z].z1 - tilec->resolutions[level - z].z0;
+ rw1= tilec->resolutions[level - x - 1].x1 - tilec->resolutions[level - x - 1].x0;
+ rh1= tilec->resolutions[level - y - 1].y1 - tilec->resolutions[level - y - 1].y0;
+ rd1= tilec->resolutions[level - z - 1].z1 - tilec->resolutions[level - z - 1].z0;
+
+ cas_col = tilec->resolutions[level - x].x0 % 2; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */
+ cas_row = tilec->resolutions[level - y].y0 % 2; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */
+ cas_axl = tilec->resolutions[level - z].z0 % 2;
+
+ /*fprintf(stdout," x %d y %d z %d \n",x,y,z);
+ fprintf(stdout," levelx %d levely %d levelz %d \n",levelx,levely,levelz);
+ fprintf(stdout," dwtid[0] %d [1] %d [2] %d \n",dwtid[0],dwtid[1],dwtid[2]);
+ fprintf(stdout," rw %d rh %d rd %d \n rw1 %d rh1 %d rd1 %d \n",rw,rh,rd,rw1,rh1,rd1);
+ fprintf(stdout,"IDWT Transform %d %d %d %d\n",level, z, rd,rd1);*/
+
+ if (z >= stops[2] && rd != rd1) {
+ //fprintf(stdout,"Axial Transform %d %d %d %d\n",levelz, z, rd,rd1);
+ sn = rd1;
+ dn = rd - rd1;
+ bj = (int*)opj_malloc(rd * sizeof(int));
+ if (dwtid[2] == 0) {
+ for (j = 0; j < (rw*rh); j++) {
+ aj = a + j;
+ dwt_interleave_z(aj, bj, dn, sn, wh, cas_axl);
+ dwt_decode_97(bj, dn, sn, cas_axl);
+ for (k = 0; k < rd; k++) aj[k * wh] = bj[k];
+ }
+ } else if (dwtid[2] == 1) {
+ for (j = 0; j < (rw*rh); j++) {
+ aj = a + j;
+ dwt_interleave_z(aj, bj, dn, sn, wh, cas_axl);
+ dwt_decode_53(bj, dn, sn, cas_axl);
+ for (k = 0; k < rd; k++) aj[k * wh] = bj[k];
+ }
+ }
+ opj_free(bj);
+ }
+
+ for (i = 0; i < rd; i++) {
+ //Fetch corresponding slice for doing DWT-2D
+ cj = tilec->data + (i * wh);
+
+ //Vertical
+ sn = rh1;
+ dn = rh - rh1;
+ bj = (int*)opj_malloc(rh * sizeof(int));
+ if (dwtid[1] == 0) {
+ for (j = 0; j < rw; j++) {
+ aj = cj + j;
+ dwt_interleave_v(aj, bj, dn, sn, w, cas_col);
+ dwt_decode_97(bj, dn, sn, cas_col);
+ for (k = 0; k < rh; k++) aj[k * w] = bj[k];
+ }
+ } else if (dwtid[1] == 1) {
+ for (j = 0; j < rw; j++) {
+ aj = cj + j;
+ dwt_interleave_v(aj, bj, dn, sn, w, cas_col);
+ dwt_decode_53(bj, dn, sn, cas_col);
+ for (k = 0; k < rh; k++) aj[k * w] = bj[k];
+ }
+ }
+ opj_free(bj);
+
+ //Horizontal
+ sn = rw1;
+ dn = rw - rw1;
+ bj = (int*)opj_malloc(rw * sizeof(int));
+ if (dwtid[0]==0) {
+ for (j = 0; j < rh; j++) {
+ aj = cj + j*w;
+ dwt_interleave_h(aj, bj, dn, sn, cas_row);
+ dwt_decode_97(bj, dn, sn, cas_row);
+ for (k = 0; k < rw; k++) aj[k] = bj[k];
+ }
+ } else if (dwtid[0]==1) {
+ for (j = 0; j < rh; j++) {
+ aj = cj + j*w;
+ dwt_interleave_h(aj, bj, dn, sn, cas_row);
+ dwt_decode_53(bj, dn, sn, cas_row);
+ for (k = 0; k < rw; k++) aj[k] = bj[k];
+ }
+ }
+ opj_free(bj);
+
+ }
+
+ }
+
+}
+
+
+/* <summary> */
+/* Get gain of wavelet transform. */
+/* </summary> */
+int dwt_getgain(int orient, int reversible) {
+ if (reversible == 1) {
+ if (orient == 0)
+ return 0;
+ else if (orient == 1 || orient == 2 || orient == 4 )
+ return 1;
+ else if (orient == 3 || orient == 5 || orient == 6 )
+ return 2;
+ else
+ return 3;
+ }
+ //else if (reversible == 0){
+ return 0;
+}
+
+/* <summary> */
+/* Get norm of wavelet transform. */
+/* </summary> */
+double dwt_getnorm(int orient, int level[3], int dwtid[3]) {
+ int levelx = level[0];
+ int levely = level[1];
+ int levelz = (level[2] < 0) ? 0 : level[2];
+ double norm;
+
+ if (flagnorm[levelx][levely][levelz][orient] == 1) {
+ norm = dwt_norm[levelx][levely][levelz][orient];
+ //fprintf(stdout,"[INFO] Level: %d %d %d Orient %d Dwt_norm: %f \n",level[0],level[1],level[2],orient,norm);
+ } else {
+ opj_wtfilt_t *wtfiltx =(opj_wtfilt_t *) opj_malloc(sizeof(opj_wtfilt_t));
+ opj_wtfilt_t *wtfilty =(opj_wtfilt_t *) opj_malloc(sizeof(opj_wtfilt_t));
+ opj_wtfilt_t *wtfiltz =(opj_wtfilt_t *) opj_malloc(sizeof(opj_wtfilt_t));
+ //Fetch equivalent filters for each dimension
+ dwt_getwtfilters(wtfiltx, dwtid[0]);
+ dwt_getwtfilters(wtfilty, dwtid[1]);
+ dwt_getwtfilters(wtfiltz, dwtid[2]);
+ //Calculate the corresponding norm
+ norm = dwt_calc_wtnorms(orient, level, dwtid, wtfiltx, wtfilty, wtfiltz);
+ //Save norm in array (no recalculation)
+ dwt_norm[levelx][levely][levelz][orient] = norm;
+ flagnorm[levelx][levely][levelz][orient] = 1;
+ //Free reserved space
+ opj_free(wtfiltx->LPS); opj_free(wtfilty->LPS); opj_free(wtfiltz->LPS);
+ opj_free(wtfiltx->HPS); opj_free(wtfilty->HPS); opj_free(wtfiltz->HPS);
+ opj_free(wtfiltx); opj_free(wtfilty); opj_free(wtfiltz);
+ //fprintf(stdout,"[INFO] Dwtid: %d %d %d Level: %d %d %d Orient %d Norm: %f \n",dwtid[0],dwtid[1],dwtid[2],level[0],level[1],level[2],orient,norm);
+ }
+ return norm;
+}
+/* <summary> */
+/* Calculate explicit stepsizes for DWT. */
+/* </summary> */
+void dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, int prec) {
+ int totnumbands, bandno, diff;
+
+ assert(tccp->numresolution[0] >= tccp->numresolution[2]);
+ diff = tccp->numresolution[0] - tccp->numresolution[2]; /*if RESx=RESy != RESz */
+ totnumbands = (7 * tccp->numresolution[0] - 6) - 4 * diff; /* 3-D */
+
+ for (bandno = 0; bandno < totnumbands; bandno++) {
+ double stepsize;
+ int resno, level[3], orient, gain;
+
+ /* Bandno: 0 - LLL 1 - LHL
+ 2 - HLL 3 - HHL
+ 4 - LLH 5 - LHH
+ 6 - HLH 7 - HHH */
+
+ resno = (bandno == 0) ? 0 : ( (bandno <= 3 * diff) ? ((bandno - 1) / 3 + 1) : ((bandno + 4*diff - 1) / 7 + 1));
+ orient = (bandno == 0) ? 0 : ( (bandno <= 3 * diff) ? ((bandno - 1) % 3 + 1) : ((bandno + 4*diff - 1) % 7 + 1));
+ level[0] = tccp->numresolution[0] - 1 - resno;
+ level[1] = tccp->numresolution[1] - 1 - resno;
+ level[2] = tccp->numresolution[2] - 1 - resno;
+
+ /* Gain: 0 - LLL 1 - LHL
+ 1 - HLL 2 - HHL
+ 1 - LLH 2 - LHH
+ 2 - HLH 3 - HHH */
+ gain = (tccp->reversible == 0) ? 0 : ( (orient == 0) ? 0 :
+ ( ((orient == 1) || (orient == 2) || (orient == 4)) ? 1 :
+ (((orient == 3) || (orient == 5) || (orient == 6)) ? 2 : 3)) );
+
+ if (tccp->qntsty == J3D_CCP_QNTSTY_NOQNT) {
+ stepsize = 1.0;
+ } else {
+ double norm = dwt_getnorm(orient,level,tccp->dwtid); //Fetch norms if irreversible transform (by the moment only I9.7)
+ stepsize = (1 << (gain + 1)) / norm;
+ }
+ //fprintf(stdout,"[INFO] Bandno: %d Orient: %d Level: %d %d %d Stepsize: %f\n",bandno,orient,level[0],level[1],level[2],stepsize);
+ dwt_encode_stepsize((int) floor(stepsize * 8192.0), prec + gain, &tccp->stepsizes[bandno]);
+ }
+}
+
+
+
diff --git a/libopenjpeg3d/dwt.h b/libopenjpeg3d/dwt.h
new file mode 100755
index 00000000..d87f799f
--- /dev/null
+++ b/libopenjpeg3d/dwt.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * Copyrigth (c) 2006, Mónica Díez, LPI-UVA, Spain
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __DWT_H
+#define __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 */
+/*@{*/
+
+/**
+DCCS-LIWT properties
+*/
+
+
+typedef struct opj_wtfilt {
+ double *LPS;
+ int lenLPS;
+ double *HPS;
+ int lenHPS;
+} opj_wtfilt_t;
+/** @name Funciones generales */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+/**
+Forward 5-3 wavelet tranform in 3-D.
+Apply a reversible DWT transform to a component of an volume.
+@param tilec Tile component information (current tile)
+@param dwtid Number of identification of wavelet kernel(s) used in DWT in each direction
+*/
+void dwt_encode(opj_tcd_tilecomp_t * tilec, int dwtid[3]);
+/**
+Inverse 5-3 wavelet tranform in 3-D.
+Apply a reversible inverse DWT transform to a component of an volume.
+@param tilec Tile component information (current tile)
+@param stops Number of decoded resolution levels in each dimension
+@param dwtid Number of identification of wavelet kernel(s) used in DWT in each dimension
+*/
+void dwt_decode(opj_tcd_tilecomp_t * tilec, int stops[3], int dwtid[3]);
+/* ----------------------------------------------------------------------- */
+/**
+Get the gain of a subband for the reversible 3-D DWT.
+@param orient Number that identifies the subband (0->LLL, 1->HLL, 2->LHL, 3->HHL, 4->LLH, 5->HLH, 6->LHH, 7->HHH)
+@param reversible Wavelet transformation type
+@return Returns 0 if orient = 0, returns 1 if orient = 1,2 or 4, returns 2 if orient = 3,5 or 6, returns 3 otherwise
+*/
+int dwt_getgain(int orient, int reversible);
+/**
+Get the norm of a wavelet function of a subband at a specified level for the reversible 5-3 DWT or irreversible 9-7 in 3-D.
+@param orient Band of the wavelet function
+@param level Levels of the wavelet function in X,Y,Z axis
+@param dwtid Wavelet transformation identifier
+@return Returns the norm of the wavelet function
+*/
+double dwt_getnorm(int orient, int level[3], int dwtid[3]);
+/* ----------------------------------------------------------------------- */
+/**
+Calcula el valor del escalón de cuantificación correspondiente a cada subbanda.
+@param tccp Tile component coding parameters
+@param prec Precision of data
+*/
+void dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, int prec);
+/*@}*/
+
+#endif /* __DWT_H */
diff --git a/libopenjpeg3d/event.c b/libopenjpeg3d/event.c
new file mode 100755
index 00000000..e27df654
--- /dev/null
+++ b/libopenjpeg3d/event.c
@@ -0,0 +1,181 @@
+/*
+ * 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"
+
+// ==========================================================
+// Utility functions
+// ==========================================================
+
+#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
+
+/* ----------------------------------------------------------------------- */
+
+opj_event_mgr_t* OPJ_CALLCONV opj_set_event_mgr(opj_common_ptr cinfo, opj_event_mgr_t *event_mgr, void *context) {
+ if(cinfo) {
+ opj_event_mgr_t *previous = cinfo->event_mgr;
+ cinfo->event_mgr = event_mgr;
+ cinfo->client_data = context;
+ return previous;
+ }
+
+ return NULL;
+}
+
+bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...) {
+#define MSG_SIZE 512 /* 512 bytes should be more than enough for a short message */
+ opj_msg_callback msg_handler = NULL;
+
+ opj_event_mgr_t *event_mgr = cinfo->event_mgr;
+ if(event_mgr != NULL) {
+ switch(event_type) {
+ case EVT_ERROR:
+ msg_handler = event_mgr->error_handler;
+ break;
+ case EVT_WARNING:
+ msg_handler = event_mgr->warning_handler;
+ break;
+ case EVT_INFO:
+ msg_handler = event_mgr->info_handler;
+ break;
+ default:
+ break;
+ }
+ if(msg_handler == NULL) {
+ return false;
+ }
+ } else {
+ return false;
+ }
+
+ if ((fmt != NULL) && (event_mgr != NULL)) {
+ va_list arg;
+ int str_length, i, j;
+ char message[MSG_SIZE];
+ memset(message, 0, MSG_SIZE);
+ /* initialize the optional parameter list */
+ va_start(arg, fmt);
+ /* check the length of the format string */
+ str_length = (strlen(fmt) > MSG_SIZE) ? MSG_SIZE : strlen(fmt);
+ /* parse the format string and put the result in 'message' */
+ for (i = 0, j = 0; i < str_length; ++i) {
+ if (fmt[i] == '%') {
+ if (i + 1 < str_length) {
+ switch(tolower(fmt[i + 1])) {
+ case '%' :
+ message[j++] = '%';
+ break;
+ case 'o' : /* octal numbers */
+ {
+ char tmp[16];
+ _itoa(va_arg(arg, int), tmp, 8);
+ strcat(message, tmp);
+ j += strlen(tmp);
+ ++i;
+ break;
+ }
+ case 'i' : /* decimal numbers */
+ case 'd' :
+ {
+ char tmp[16];
+ _itoa(va_arg(arg, int), tmp, 10);
+ strcat(message, tmp);
+ j += strlen(tmp);
+ ++i;
+ break;
+ }
+ case 'x' : /* hexadecimal numbers */
+ {
+ char tmp[16];
+ _itoa(va_arg(arg, int), tmp, 16);
+ strcat(message, tmp);
+ j += strlen(tmp);
+ ++i;
+ break;
+ }
+ case 's' : /* strings */
+ {
+ char *tmp = va_arg(arg, char*);
+ strcat(message, tmp);
+ j += strlen(tmp);
+ ++i;
+ break;
+ }
+ case 'f' : /* floats */
+ {
+ char tmp[16];
+ double value = va_arg(arg, double);
+ sprintf(tmp, "%f", value);
+ strcat(message, tmp);
+ j += strlen(tmp);
+ ++i;
+ break;
+ }
+ };
+ } else {
+ message[j++] = fmt[i];
+ }
+ } else {
+ message[j++] = fmt[i];
+ };
+ }
+ /* deinitialize the optional parameter list */
+ va_end(arg);
+
+ /* output the message to the user program */
+ msg_handler(message, cinfo->client_data);
+ }
+
+ return true;
+}
+
diff --git a/libopenjpeg3d/event.h b/libopenjpeg3d/event.h
new file mode 100755
index 00000000..e01f4684
--- /dev/null
+++ b/libopenjpeg3d/event.h
@@ -0,0 +1,58 @@
+/*
+ * 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 __EVENT_H
+#define __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.
+*/
+
+#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 Funciones generales (see also openjpeg3d.h) */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+/**
+Write formatted data to a string and send the string to a user callback.
+@param cinfo Codec context info
+@param event_type Event type or callback to use to send the message
+@param fmt Format-control string (plus optionnal arguments)
+@return Returns true if successful, returns false otherwise
+*/
+bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...);
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+#endif /* __EVENT_H */
diff --git a/libopenjpeg3d/fix.h b/libopenjpeg3d/fix.h
new file mode 100755
index 00000000..3b5e77ca
--- /dev/null
+++ b/libopenjpeg3d/fix.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * 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 __FIX_H
+#define __FIX_H
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+#define int64 __int64
+#else
+#define int64 long long
+#endif
+
+/**
+@file fix.h
+@brief Implementation of operations of specific multiplication (FIX)
+
+The functions in FIX.H have for goal to realize specific multiplication.
+*/
+
+/** @defgroup FIX FIX - Implementation of operations of specific multiplication */
+/*@{*/
+
+/**
+Multiply two fixed-precision rational numbers.
+@param a
+@param b
+@return Returns a * b
+*/
+static int fix_mul(int a, int b) {
+ int64 temp = (int64) a * (int64) b >> 12;
+ return (int) ((temp >> 1) + (temp & 1)) ;
+}
+
+/*@}*/
+
+#endif /* __FIX_H */
diff --git a/libopenjpeg3d/int.h b/libopenjpeg3d/int.h
new file mode 100755
index 00000000..55be844a
--- /dev/null
+++ b/libopenjpeg3d/int.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * 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 __INT_H
+#define __INT_H
+/**
+@file int.h
+@brief Implementation of operations on integers (INT)
+
+The functions in INT.H have for goal to realize operations on integers.
+*/
+
+/** @defgroup INT INT - Implementation of operations on integers */
+/*@{*/
+
+/** @name Funciones generales (see also openjpeg3d.h) */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+/**
+Get the minimum of two integers
+@return Returns a if a < b else b
+*/
+static int int_min(int a, int b) {
+ return a < b ? a : b;
+}
+/**
+Get the maximum of two integers
+@return Returns a if a > b else b
+*/
+static int int_max(int a, int b) {
+ return (a > b) ? a : b;
+}
+/**
+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 int int_clamp(int a, int min, int max) {
+ if (a < min)
+ return min;
+ if (a > max)
+ return max;
+ return a;
+}
+/**
+@return Get absolute value of integer
+*/
+static int int_abs(int a) {
+ return a < 0 ? -a : a;
+}
+
+static double dbl_abs(double a) {
+ return a < 0 ? -a : a;
+}
+/**
+Divide an integer and round upwards
+@return Returns a divided by b
+*/
+static int int_ceildiv(int a, int b) {
+ return (a + b - 1) / b;
+}
+/**
+Divide an integer by a power of 2 and round upwards
+@return Returns a divided by 2^b
+*/
+static int int_ceildivpow2(int a, int b) {
+ return (a + (1 << b) - 1) >> b;
+}
+/**
+Divide an integer by a power of 2 and round downwards
+@return Returns a divided by 2^b
+*/
+static int int_floordivpow2(int a, int b) {
+ return a >> b;
+}
+/**
+Get logarithm of an integer and round downwards
+@return Returns log2(a)
+*/
+static int int_floorlog2(int a) {
+ int l;
+ for (l = 0; a > 1; l++) {
+ a >>= 1;
+ }
+ return l;
+}
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+#endif
diff --git a/libopenjpeg3d/jp3d.c b/libopenjpeg3d/jp3d.c
new file mode 100755
index 00000000..2fd5d02f
--- /dev/null
+++ b/libopenjpeg3d/jp3d.c
@@ -0,0 +1,2328 @@
+/*
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * Copyright (c) 2006, Mónica Díez García, Image Processing Laboratory, University of Valladolid, Spain
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opj_includes.h"
+
+/** @defgroup J3D J3D - JPEG-2000 PART 10 codestream reader/writer */
+/*@{*/
+
+/** @name Funciones locales */
+/*@{*/
+
+/**
+Write the SOC marker (Start Of Codestream)
+@param j3d J3D handle
+*/
+static void j3d_write_soc(opj_j3d_t *j3d);
+/**
+Read the SOC marker (Start of Codestream)
+@param j3d J3D handle
+*/
+static void j3d_read_soc(opj_j3d_t *j3d);
+/**
+Write the SIZ marker (2D volume and tile size)
+@param j3d J3D handle
+*/
+static void j3d_write_siz(opj_j3d_t *j3d);
+/**
+Read the SIZ marker (2D volume and tile size)
+@param j3d J3D handle
+*/
+static void j3d_read_siz(opj_j3d_t *j3d);
+/**
+Write the ZSI marker (3rd volume and tile size)
+@param j3d J3D handle
+*/
+static void j3d_write_zsi(opj_j3d_t *j3d);
+/**
+Read the ZSI marker (3rd volume and tile size)
+@param j3d J3D handle
+*/
+static void j3d_read_zsi(opj_j3d_t *j3d);
+/**
+Write the COM marker (comment)
+@param j3d J3D handle
+*/
+static void j3d_write_com(opj_j3d_t *j3d);
+/**
+Read the COM marker (comment)
+@param j3d J3D handle
+*/
+static void j3d_read_com(opj_j3d_t *j3d);
+/**
+Write the value concerning the specified component in the marker COD and COC
+@param j3d J3D handle
+@param compno Number of the component concerned by the information written
+*/
+static void j3d_write_cox(opj_j3d_t *j3d, int compno);
+/**
+Read the value concerning the specified component in the marker COD and COC
+@param j3d J3D handle
+@param compno Number of the component concerned by the information read
+*/
+static void j3d_read_cox(opj_j3d_t *j3d, int compno);
+/**
+Write the COD marker (coding style default)
+@param j3d J3D handle
+*/
+static void j3d_write_cod(opj_j3d_t *j3d);
+/**
+Read the COD marker (coding style default)
+@param j3d J3D handle
+*/
+static void j3d_read_cod(opj_j3d_t *j3d);
+/**
+Write the COC marker (coding style component)
+@param j3d J3D handle
+@param compno Number of the component concerned by the information written
+*/
+static void j3d_write_coc(opj_j3d_t *j3d, int compno);
+/**
+Read the COC marker (coding style component)
+@param j3d J3D handle
+*/
+static void j3d_read_coc(opj_j3d_t *j3d);
+/**
+Write the value concerning the specified component in the marker QCD and QCC
+@param j3d J3D handle
+@param compno Number of the component concerned by the information written
+*/
+static void j3d_write_qcx(opj_j3d_t *j3d, int compno);
+/**
+Read the value concerning the specified component in the marker QCD and QCC
+@param j3d J3D handle
+@param compno Number of the component concern by the information read
+@param len Length of the information in the QCX part of the marker QCD/QCC
+*/
+static void j3d_read_qcx(opj_j3d_t *j3d, int compno, int len);
+/**
+Write the QCD marker (quantization default)
+@param j3d J3D handle
+*/
+static void j3d_write_qcd(opj_j3d_t *j3d);
+/**
+Read the QCD marker (quantization default)
+@param j3d J3D handle
+*/
+static void j3d_read_qcd(opj_j3d_t *j3d);
+/**
+Write the QCC marker (quantization component)
+@param j3d J3D handle
+@param compno Number of the component concerned by the information written
+*/
+static void j3d_write_qcc(opj_j3d_t *j3d, int compno);
+/**
+Read the QCC marker (quantization component)
+@param j3d J3D handle
+*/
+static void j3d_read_qcc(opj_j3d_t *j3d);
+/**
+Write the POC marker (progression order change)
+@param j3d J3D handle
+*/
+static void j3d_write_poc(opj_j3d_t *j3d);
+/**
+Read the POC marker (progression order change)
+@param j3d J3D handle
+*/
+static void j3d_read_poc(opj_j3d_t *j3d);
+/**
+Read the CRG marker (component registration)
+@param j3d J3D handle
+*/
+static void j3d_read_crg(opj_j3d_t *j3d);
+/**
+Read the TLM marker (tile-part lengths)
+@param j3d J3D handle
+*/
+static void j3d_read_tlm(opj_j3d_t *j3d);
+/**
+Read the PLM marker (packet length, main header)
+@param j3d J3D handle
+*/
+static void j3d_read_plm(opj_j3d_t *j3d);
+/**
+Read the PLT marker (packet length, tile-part header)
+@param j3d J3D handle
+*/
+static void j3d_read_plt(opj_j3d_t *j3d);
+/**
+Read the PPM marker (packet packet headers, main header)
+@param j3d J3D handle
+*/
+static void j3d_read_ppm(opj_j3d_t *j3d);
+/**
+Read the PPT marker (packet packet headers, tile-part header)
+@param j3d J3D handle
+*/
+static void j3d_read_ppt(opj_j3d_t *j3d);
+/**
+Write the SOT marker (start of tile-part)
+@param j3d J3D handle
+*/
+static void j3d_write_sot(opj_j3d_t *j3d);
+/**
+Read the SOT marker (start of tile-part)
+@param j3d J3D handle
+*/
+static void j3d_read_sot(opj_j3d_t *j3d);
+/**
+Write the SOD marker (start of data)
+@param j3d J3D handle
+@param tile_coder Pointer to a TCD handle
+*/
+static void j3d_write_sod(opj_j3d_t *j3d, void *tile_coder);
+/**
+Read the SOD marker (start of data)
+@param j3d J3D handle
+*/
+static void j3d_read_sod(opj_j3d_t *j3d);
+/**
+Write the RGN marker (region-of-interest)
+@param j3d J3D handle
+@param compno Number of the component concerned by the information written
+@param tileno Number of the tile concerned by the information written
+*/
+static void j3d_write_rgn(opj_j3d_t *j3d, int compno, int tileno);
+/**
+Read the RGN marker (region-of-interest)
+@param j3d J3D handle
+*/
+static void j3d_read_rgn(opj_j3d_t *j3d);
+/**
+Write the EOC marker (end of codestream)
+@param j3d J3D handle
+*/
+static void j3d_write_eoc(opj_j3d_t *j3d);
+/**
+Read the EOC marker (end of codestream)
+@param j3d J3D handle
+*/
+static void j3d_read_eoc(opj_j3d_t *j3d);
+/**
+Read an unknown marker
+@param j3d J3D handle
+*/
+static void j3d_read_unk(opj_j3d_t *j3d);
+/**
+Write the CAP marker (extended capabilities)
+@param j3d J3D handle
+*/
+static void j3d_write_cap(opj_j3d_t *j3d);
+/**
+Read the CAP marker (extended capabilities)
+@param j3d J3D handle
+*/
+static void j3d_read_cap(opj_j3d_t *j3d);
+/**
+Write the DCO marker (Variable DC offset)
+@param j3d J3D handle
+*/
+static void j3d_write_dco(opj_j3d_t *j3d);
+/**
+Read the DCO marker (Variable DC offset)
+@param j3d J3D handle
+*/
+static void j3d_read_dco(opj_j3d_t *j3d);
+/**
+Write the ATK marker (arbitrary transformation kernel)
+@param j3d J3D handle
+*/
+static void j3d_write_atk(opj_j3d_t *j3d);
+/**
+Read the ATK marker (arbitrary transformation kernel)
+@param j3d J3D handle
+*/
+static void j3d_read_atk(opj_j3d_t *j3d);
+/**
+Write the CBD marker (component bit depth definition)
+@param j3d J3D handle
+*/
+static void j3d_write_cbd(opj_j3d_t *j3d);
+/**
+Read the CBD marker (component bit depth definition)
+@param j3d J3D handle
+*/
+static void j3d_read_cbd(opj_j3d_t *j3d);
+/**
+Write the MCT marker (multiple component transfomation definition)
+@param j3d J3D handle
+*/
+static void j3d_write_mct(opj_j3d_t *j3d);
+/**
+Read the MCT marker (multiple component transfomation definition)
+@param j3d J3D handle
+*/
+static void j3d_read_mct(opj_j3d_t *j3d);
+/**
+Write the MCC marker (multiple component transfomation collection)
+@param j3d J3D handle
+*/
+static void j3d_write_mcc(opj_j3d_t *j3d);
+/**
+Read the MCC marker (multiple component transfomation collection)
+@param j3d J3D handle
+*/
+static void j3d_read_mcc(opj_j3d_t *j3d);
+/**
+Write the MCO marker (multiple component transfomation ordering)
+@param j3d J3D handle
+*/
+static void j3d_write_mco(opj_j3d_t *j3d);
+/**
+Read the MCO marker (multiple component transfomation ordering)
+@param j3d J3D handle
+*/
+static void j3d_read_mco(opj_j3d_t *j3d);
+/**
+Write the NLT marker (non-linearity point transformation)
+@param j3d J3D handle
+*/
+static void j3d_write_nlt(opj_j3d_t *j3d);
+/**
+Read the NLT marker (non-linearity point transformation)
+@param j3d J3D handle
+*/
+static void j3d_read_nlt(opj_j3d_t *j3d);
+/*@}*/
+
+/* ----------------------------------------------------------------------- */
+
+void j3d_dump_volume(FILE *fd, opj_volume_t * vol) {
+ int compno;
+ fprintf(fd, "volume {\n");
+ fprintf(fd, " x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d\n", vol->x0, vol->y0, vol->z0,vol->x1, vol->y1, vol->z1);
+ fprintf(fd, " numcomps=%d\n", vol->numcomps);
+ for (compno = 0; compno < vol->numcomps; compno++) {
+ opj_volume_comp_t *comp = &vol->comps[compno];
+ fprintf(fd, " comp %d {\n", compno);
+ fprintf(fd, " dx=%d, dy=%d, dz=%d\n", comp->dx, comp->dy, comp->dz);
+ fprintf(fd, " prec=%d\n", comp->prec);
+ fprintf(fd, " sgnd=%d\n", comp->sgnd);
+ fprintf(fd, " }\n");
+ }
+ fprintf(fd, "}\n");
+}
+
+void j3d_dump_cp(FILE *fd, opj_volume_t * vol, opj_cp_t * cp) {
+ int tileno, compno, layno, bandno, resno, numbands;
+ fprintf(fd, "coding parameters {\n");
+ fprintf(fd, " tx0=%d, ty0=%d, tz0=%d\n", cp->tx0, cp->ty0, cp->tz0);
+ fprintf(fd, " tdx=%d, tdy=%d, tdz=%d\n", cp->tdx, cp->tdy, cp->tdz);
+ fprintf(fd, " tw=%d, th=%d, tl=%d\n", cp->tw, cp->th, cp->tl);
+ fprintf(fd, " transform format: %d\n", cp->transform_format);
+ fprintf(fd, " encoding format: %d\n", cp->encoding_format);
+ for (tileno = 0; tileno < cp->tw * cp->th * cp->tl; tileno++) {
+ opj_tcp_t *tcp = &cp->tcps[tileno];
+ fprintf(fd, " tile %d {\n", tileno);
+ fprintf(fd, " csty=%x\n", tcp->csty);
+ fprintf(fd, " prg=%d\n", tcp->prg);
+ fprintf(fd, " numlayers=%d\n", tcp->numlayers);
+ fprintf(fd, " mct=%d\n", tcp->mct);
+ fprintf(fd, " rates=");
+ for (layno = 0; layno < tcp->numlayers; layno++) {
+ fprintf(fd, "%f ", tcp->rates[layno]);
+ }
+ fprintf(fd, "\n");
+ fprintf(fd, " first=%d\n", tcp->first);
+ for (compno = 0; compno < vol->numcomps; compno++) {
+ opj_tccp_t *tccp = &tcp->tccps[compno];
+ fprintf(fd, " comp %d {\n", compno);
+ fprintf(fd, " csty=%x\n", tccp->csty);
+ fprintf(fd, " numresx=%d, numresy=%d, numresz=%d\n", tccp->numresolution[0], tccp->numresolution[1], tccp->numresolution[2]);
+ fprintf(fd, " cblkw=%d, cblkh=%d, cblkl=%d\n", tccp->cblk[0], tccp->cblk[1], tccp->cblk[2]);
+ fprintf(fd, " cblksty=%x\n", tccp->cblksty);
+ fprintf(fd, " qntsty=%d\n", tccp->qntsty);
+ fprintf(fd, " numgbits=%d\n", tccp->numgbits);
+ fprintf(fd, " roishift=%d\n", tccp->roishift);
+ fprintf(fd, " reversible=%d\n", tccp->reversible);
+ fprintf(fd, " dwtidx=%d dwtidy=%d dwtidz=%d\n", tccp->dwtid[0], tccp->dwtid[1], tccp->dwtid[2]);
+ if (tccp->atk != NULL) {
+ fprintf(fd, " atk.index=%d\n", tccp->atk->index);
+ fprintf(fd, " atk.coeff_typ=%d\n", tccp->atk->coeff_typ);
+ fprintf(fd, " atk.filt_cat=%d\n", tccp->atk->filt_cat);
+ fprintf(fd, " atk.exten=%d\n", tccp->atk->exten);
+ fprintf(fd, " atk.minit=%d\n", tccp->atk->minit);
+ fprintf(fd, " atk.wt_typ=%d\n", tccp->atk->wt_typ);
+ }
+ fprintf(fd, " stepsizes of bands=");
+ numbands = (tccp->qntsty == J3D_CCP_QNTSTY_SIQNT) ? 1 :
+ ( (cp->transform_format == TRF_2D_DWT) ? (tccp->numresolution[0] * 3 - 2) :
+ (tccp->numresolution[0] * 7 - 6) - 4 *(tccp->numresolution[0] - tccp->numresolution[2]) );
+ for (bandno = 0; bandno < numbands; bandno++) {
+ fprintf(fd, "(%d,%d) ", tccp->stepsizes[bandno].mant,tccp->stepsizes[bandno].expn);
+ }
+ fprintf(fd, "\n");
+
+ if (tccp->csty & J3D_CCP_CSTY_PRT) {
+ fprintf(fd, " prcw=");
+ for (resno = 0; resno < tccp->numresolution[0]; resno++) {
+ fprintf(fd, "%d ", tccp->prctsiz[0][resno]);
+ }
+ fprintf(fd, "\n");
+ fprintf(fd, " prch=");
+ for (resno = 0; resno < tccp->numresolution[0]; resno++) {
+ fprintf(fd, "%d ", tccp->prctsiz[1][resno]);
+ }
+ fprintf(fd, "\n");
+ fprintf(fd, " prcl=");
+ for (resno = 0; resno < tccp->numresolution[0]; resno++) {
+ fprintf(fd, "%d ", tccp->prctsiz[2][resno]);
+ }
+ fprintf(fd, "\n");
+ }
+ fprintf(fd, " }\n");
+ }
+ fprintf(fd, " }\n");
+ }
+ fprintf(fd, "}\n");
+}
+
+/* -----------------------------------------------------------------------
+Extended capabilities
+------------------------------------------------------------------------*/
+
+static void j3d_write_cap(opj_j3d_t *j3d){
+ int len,lenp;
+
+ opj_cio_t *cio = j3d->cio;
+ cio_write(cio, J3D_MS_CAP, 2); /* CAP */
+ lenp = cio_tell(cio);
+ cio_skip(cio, 2);
+ cio_write(cio,J3D_CAP_10, 4);
+ len = cio_tell(cio) - lenp;
+ cio_seek(cio, lenp);
+ cio_write(cio, len, 2); /* Lsiz */
+ cio_seek(cio, lenp + len);
+
+}
+static void j3d_read_cap(opj_j3d_t *j3d){
+ int len, Cap;
+ opj_cio_t *cio = j3d->cio;
+ /*cio_read(cio, 2); CAP */
+ len = cio_read(cio, 2);
+ Cap = cio_read(cio, 4);
+}
+static void j3d_write_zsi(opj_j3d_t *j3d) {
+ int i;
+ int lenp, len;
+
+ opj_cio_t *cio = j3d->cio;
+ opj_volume_t *volume = j3d->volume;
+ opj_cp_t *cp = j3d->cp;
+
+ cio_write(cio, J3D_MS_ZSI, 2); /* ZSI */
+ lenp = cio_tell(cio);
+ cio_skip(cio, 2);
+ cio_write(cio, volume->z1, 4); /* Zsiz */
+ cio_write(cio, volume->z0, 4); /* Z0siz */
+ cio_write(cio, cp->tdz, 4); /* ZTsiz */
+ cio_write(cio, cp->tz0, 4); /* ZT0siz */
+ for (i = 0; i < volume->numcomps; i++) {
+ cio_write(cio, volume->comps[i].dz, 1); /* ZRsiz_i */
+ }
+ len = cio_tell(cio) - lenp;
+ cio_seek(cio, lenp);
+ cio_write(cio, len, 2); /* Lsiz */
+ cio_seek(cio, lenp + len);
+}
+
+static void j3d_read_zsi(opj_j3d_t *j3d) {
+ int len, i;
+
+ opj_cio_t *cio = j3d->cio;
+ opj_volume_t *volume = j3d->volume;
+ opj_cp_t *cp = j3d->cp;
+
+ len = cio_read(cio, 2); /* Lsiz */
+ volume->z1 = cio_read(cio, 4); /* Zsiz */
+ volume->z0 = cio_read(cio, 4); /* Z0siz */
+ cp->tdz = cio_read(cio, 4); /* ZTsiz */
+ cp->tz0 = cio_read(cio, 4); /* ZT0siz */
+ for (i = 0; i < volume->numcomps; i++) {
+ volume->comps[i].dz = cio_read(cio, 1); /* ZRsiz_i */
+ }
+
+ //Initialization of volume
+ cp->tw = int_ceildiv(volume->x1 - cp->tx0, cp->tdx);
+ cp->th = int_ceildiv(volume->y1 - cp->ty0, cp->tdy);
+ cp->tl = int_ceildiv(volume->z1 - cp->tz0, cp->tdz);
+ cp->tcps = (opj_tcp_t *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(opj_tcp_t));
+ cp->tileno = (int *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(int));
+ cp->tileno_size = 0;
+
+ for (i = 0; i < cp->tw * cp->th * cp->tl ; i++) {
+ cp->tcps[i].POC = 0;
+ cp->tcps[i].numpocs = 0;
+ cp->tcps[i].first = 1;
+ }
+
+ /* Initialization for PPM marker (Packets header)*/
+ cp->ppm = 0;
+ cp->ppm_data = NULL;
+ cp->ppm_data_first = NULL;
+ cp->ppm_previous = 0;
+ cp->ppm_store = 0;
+
+ j3d->default_tcp->tccps = (opj_tccp_t *) opj_malloc(sizeof(opj_tccp_t) * volume->numcomps);
+ for (i = 0; i < cp->tw * cp->th * cp->tl ; i++) {
+ cp->tcps[i].tccps = (opj_tccp_t *) opj_malloc(sizeof(opj_tccp_t) * volume->numcomps);
+ }
+ j3d->tile_data = (unsigned char **) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(unsigned char *));
+ j3d->tile_len = (int *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(int));
+ j3d->state = J3D_STATE_MH;
+
+}
+static void j3d_write_dco(opj_j3d_t *j3d){
+ int lenp, len, i;
+ int dcotype;
+
+ opj_cio_t *cio = j3d->cio;
+ opj_volume_t *volume = j3d->volume;
+ opj_cp_t *cp = j3d->cp;
+
+ dcotype = 1; /* Offsets are 16bit signed integers Table A21 15444-2 */
+ cio_write(cio, J3D_MS_DCO, 2); /* DCO */
+ lenp = cio_tell(cio);
+ cio_skip(cio, 2);
+ cio_write(cio, dcotype, 1);
+ if (dcotype == 0) {
+ for (i = 0; i < volume->numcomps; i++)
+ cio_write(cio, volume->comps[i].dcoffset, 1); /* SPdco_i */
+ } else if (dcotype == 1) {
+ for (i = 0; i < volume->numcomps; i++){
+ cio_write(cio, volume->comps[i].dcoffset, 1); /* SPdco_i */
+ opj_event_msg(j3d->cinfo, EVT_INFO, "dcotype %d DCO %d \n",dcotype,volume->comps[i].dcoffset);
+ }
+ }
+ len = cio_tell(cio) - lenp;
+ cio_seek(cio, lenp);
+ cio_write(cio, len, 2); /* Ldco */
+ cio_seek(cio, lenp + len);
+
+}
+static void j3d_read_dco(opj_j3d_t *j3d){
+ int len, i;
+ int dcotype;
+
+ opj_cio_t *cio = j3d->cio;
+ opj_volume_t *volume = j3d->volume;
+ opj_cp_t *cp = j3d->cp;
+
+ len = cio_read(cio, 2); /* Lsiz */
+ dcotype = cio_read(cio, 1); //offset 8bit unsigned / 16bit signed integers
+ if (dcotype == 0) {
+ for (i = 0; i < volume->numcomps; i++) {
+ volume->comps[i].dcoffset = cio_read(cio, 1);
+ if (volume->comps[i].dcoffset > 128)
+ volume->comps[i].dcoffset = volume->comps[i].dcoffset - 256;
+ }
+ } else if (dcotype == 1) {
+ for (i = 0; i < volume->numcomps; i++) {
+ volume->comps[i].dcoffset = cio_read(cio, 1);
+ if (volume->comps[i].dcoffset > 128)
+ volume->comps[i].dcoffset = volume->comps[i].dcoffset - 256;
+ }
+ }
+
+}
+static void j3d_write_atk(opj_j3d_t *j3d){
+ int lenp, len, s, k;
+
+ opj_cio_t *cio = j3d->cio;
+ opj_volume_t *volume = j3d->volume;
+ opj_atk_t *atk = j3d->cp->tcps->tccps->atk;
+
+ cio_write(cio, J3D_MS_ATK, 2); /* ATK */
+ lenp = cio_tell(cio);
+ cio_skip(cio, 2);
+ cio_write(cio, atk->index + (atk->coeff_typ << 8) + (atk->filt_cat << 11)
+ + (atk->wt_typ << 12) + (atk->minit << 13) + (atk->exten << 14), 2); /* Satk */
+ if (atk->wt_typ == J3D_ATK_IRR)
+ cio_write(cio,(unsigned int) (atk->Katk * 8192.0), 1 << atk->coeff_typ);
+ cio_write(cio, atk->Natk, 1);
+ for (s = 0; s < atk->Natk; s++){
+ if (atk->filt_cat == J3D_ATK_ARB)
+ cio_write(cio, atk->Oatk[s], 1);
+ if (atk->wt_typ == J3D_ATK_REV){
+ cio_write(cio, atk->Eatk[s], 1);
+ cio_write(cio, atk->Batk[s], 1);
+ }
+ cio_write(cio, atk->LCatk[s], 1);
+ for (k = 0; k < atk->LCatk[s]; k++)
+ cio_write(cio,(unsigned int) (atk->Aatk[s][k] * 8192.0), 1 << atk->coeff_typ);
+ }
+ len = cio_tell(cio) - lenp;
+ cio_seek(cio, lenp);
+ cio_write(cio, len, 2); /* Latk */
+ cio_seek(cio, lenp + len);
+}
+static void j3d_read_atk(opj_j3d_t *j3d){
+ int len, i, Satk, k;
+
+ opj_cio_t *cio = j3d->cio;
+ opj_volume_t *volume = j3d->volume;
+ opj_cp_t *cp = j3d->cp;
+ opj_atk_t *atk = cp->tcps->tccps->atk;
+
+ len = cio_read(cio, 2); /* Latk */
+ Satk = cio_read(cio, 2);
+ atk->index = Satk & 0x00ff;
+ atk->coeff_typ = Satk >> 8 & 0x0007;
+ atk->filt_cat = Satk >> 11 & 0x0001;
+ atk->wt_typ = Satk >> 12 & 0x0001;
+ atk->minit = Satk >> 13 & 0x0001;
+ atk->exten = Satk >> 14 & 0x0001;
+ if (atk->wt_typ == J3D_ATK_IRR)
+ atk->Katk = ((double) cio_read(cio, 1 << atk->coeff_typ) / 8192.0);
+ atk->Natk = cio_read(cio, 1);
+ for (i = 0; i < atk->Natk; i++) {
+ if (atk->filt_cat == J3D_ATK_ARB)
+ atk->Oatk[i] = cio_read(cio, 1);
+ if (atk->wt_typ == J3D_ATK_REV){
+ atk->Eatk[i] = cio_read(cio, 1);
+ atk->Batk[i] = cio_read(cio, 1);
+ }
+ atk->LCatk[i] = cio_read(cio, 1);
+ for (k = 0; k < atk->LCatk[i]; k++)
+ atk->Aatk[i][k] = ((double) cio_read(cio, 1 << atk->coeff_typ) / 8192.0);
+ }
+}
+static void j3d_write_cbd(opj_j3d_t *j3d){
+}
+static void j3d_read_cbd(opj_j3d_t *j3d){
+}
+static void j3d_write_mct(opj_j3d_t *j3d){
+}
+static void j3d_read_mct(opj_j3d_t *j3d){
+}
+static void j3d_write_mcc(opj_j3d_t *j3d){
+}
+static void j3d_read_mcc(opj_j3d_t *j3d){
+}
+static void j3d_write_mco(opj_j3d_t *j3d){
+}
+static void j3d_read_mco(opj_j3d_t *j3d){
+}
+static void j3d_write_nlt(opj_j3d_t *j3d){
+}
+static void j3d_read_nlt(opj_j3d_t *j3d){
+}
+/* -----------------------------------------------------------------------
+15444-1 codestream syntax
+------------------------------------------------------------------------*/
+static void j3d_write_soc(opj_j3d_t *j3d) {
+ opj_cio_t *cio = j3d->cio;
+ cio_write(cio, J3D_MS_SOC, 2);
+}
+
+static void j3d_read_soc(opj_j3d_t *j3d) {
+ j3d->state = J3D_STATE_MHSIZ;
+}
+
+static void j3d_write_siz(opj_j3d_t *j3d) {
+ int i;
+ int lenp, len;
+ int Rsiz;
+
+ opj_cio_t *cio = j3d->cio;
+ opj_volume_t *volume = j3d->volume;
+ opj_cp_t *cp = j3d->cp;
+
+ cio_write(cio, J3D_MS_SIZ, 2); /* SIZ */
+ lenp = cio_tell(cio);
+ cio_skip(cio, 2);
+ //cio_write(cio, 0, 2); /* Rsiz (capabilities of 15444-1 only) */
+ Rsiz = J3D_RSIZ_DCO | J3D_RSIZ_ATK; /** | J3D_RSIZ_MCT | J3D_RSIZ_NONLT (not implemented yet)*/
+ cio_write(cio, Rsiz, 2); /* capabilities of WDv5.2*/
+ cio_write(cio, volume->x1, 4); /* Xsiz */
+ cio_write(cio, volume->y1, 4); /* Ysiz */
+ cio_write(cio, volume->x0, 4); /* X0siz */
+ cio_write(cio, volume->y0, 4); /* Y0siz */
+ cio_write(cio, cp->tdx, 4); /* XTsiz */
+ cio_write(cio, cp->tdy, 4); /* YTsiz */
+ cio_write(cio, cp->tx0, 4); /* XT0siz */
+ cio_write(cio, cp->ty0, 4); /* YT0siz */
+ cio_write(cio, volume->numcomps, 2); /* Csiz */
+ for (i = 0; i < volume->numcomps; i++) {
+ cio_write(cio, volume->comps[i].prec - 1 + (volume->comps[i].sgnd << 7), 1); /* Ssiz_i */
+ cio_write(cio, volume->comps[i].dx, 1); /* XRsiz_i */
+ cio_write(cio, volume->comps[i].dy, 1); /* YRsiz_i */
+ }
+ len = cio_tell(cio) - lenp;
+ cio_seek(cio, lenp);
+ cio_write(cio, len, 2); /* Lsiz */
+ cio_seek(cio, lenp + len);
+}
+
+static void j3d_read_siz(opj_j3d_t *j3d) {
+ int len, i;
+
+ opj_cio_t *cio = j3d->cio;
+ opj_volume_t *volume = j3d->volume;
+ opj_cp_t *cp = j3d->cp;
+
+ len = cio_read(cio, 2); /* Lsiz */
+ cp->rsiz = cio_read(cio, 2); /* Rsiz (capabilities) */
+ volume->x1 = cio_read(cio, 4); /* Xsiz */
+ volume->y1 = cio_read(cio, 4); /* Ysiz */
+ volume->x0 = cio_read(cio, 4); /* X0siz */
+ volume->y0 = cio_read(cio, 4); /* Y0siz */
+ cp->tdx = cio_read(cio, 4); /* XTsiz */
+ cp->tdy = cio_read(cio, 4); /* YTsiz */
+ cp->tx0 = cio_read(cio, 4); /* XT0siz */
+ cp->ty0 = cio_read(cio, 4); /* YT0siz */
+
+ volume->numcomps = cio_read(cio, 2); /* Csiz */
+ volume->comps = (opj_volume_comp_t *) opj_malloc(volume->numcomps * sizeof(opj_volume_comp_t));
+ for (i = 0; i < volume->numcomps; i++) {
+ int tmp, j;
+ tmp = cio_read(cio, 1); /* Ssiz_i */
+ volume->comps[i].prec = (tmp & 0x7f) + 1;
+ volume->comps[i].sgnd = tmp >> 7;
+ volume->comps[i].dx = cio_read(cio, 1); /* XRsiz_i */
+ volume->comps[i].dy = cio_read(cio, 1); /* YRsiz_i */
+ for (j = 0; j < 3; j++) {
+ volume->comps[i].resno_decoded[j] = 0; /* number of resolution decoded */
+ volume->comps[i].factor[j] = 0; /* reducing factor per component */
+ }
+ }
+
+ if (j3d->cinfo->codec_format == CODEC_J2K){
+ volume->z1 = 1;
+ volume->z0 = 0;
+ volume->numslices = 1;
+ cp->tdz = 1;
+ cp->tz0 = 0;
+ for (i = 0; i < volume->numcomps; i++)
+ volume->comps[i].dz = 1;
+
+ //Initialization of volume
+ cp->tw = int_ceildiv(volume->x1 - cp->tx0, cp->tdx);
+ cp->th = int_ceildiv(volume->y1 - cp->ty0, cp->tdy);
+ cp->tl = int_ceildiv(volume->z1 - cp->tz0, cp->tdz);
+ cp->tcps = (opj_tcp_t *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(opj_tcp_t));
+ cp->tileno = (int *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(int));
+ cp->tileno_size = 0;
+
+ for (i = 0; i < cp->tw * cp->th * cp->tl ; i++) {
+ cp->tcps[i].POC = 0;
+ cp->tcps[i].numpocs = 0;
+ cp->tcps[i].first = 1;
+ }
+
+ /* Initialization for PPM marker (Packets header)*/
+ cp->ppm = 0;
+ cp->ppm_data = NULL;
+ cp->ppm_data_first = NULL;
+ cp->ppm_previous = 0;
+ cp->ppm_store = 0;
+
+ j3d->default_tcp->tccps = (opj_tccp_t *) opj_malloc(sizeof(opj_tccp_t) * volume->numcomps);
+ for (i = 0; i < cp->tw * cp->th * cp->tl ; i++) {
+ cp->tcps[i].tccps = (opj_tccp_t *) opj_malloc(sizeof(opj_tccp_t) * volume->numcomps);
+ }
+ j3d->tile_data = (unsigned char **) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(unsigned char *));
+ j3d->tile_len = (int *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(int));
+ j3d->state = J3D_STATE_MH;
+ }
+}
+
+
+
+static void j3d_write_com(opj_j3d_t *j3d) {
+ unsigned int i;
+ int lenp, len;
+
+ opj_cio_t *cio = j3d->cio;
+
+ cio_write(cio, J3D_MS_COM, 2);
+ lenp = cio_tell(cio);
+ cio_skip(cio, 2);
+ //cio_write(cio, 0, 2);
+ cio_write(cio, j3d->cp->transform_format,1);
+ cio_write(cio, j3d->cp->encoding_format,1);
+ //opj_event_msg(j3d->cinfo, EVT_INFO, "TRF %D ENCOD %d\n",j3d->cp->transform_format,j3d->cp->encoding_format);
+ if (j3d->cp->comment != NULL) {
+ char *comment = j3d->cp->comment;
+ for (i = 0; i < strlen(comment); i++) {
+ cio_write(cio, comment[i], 1);
+ }
+ }
+ len = cio_tell(cio) - lenp;
+ cio_seek(cio, lenp);
+ cio_write(cio, len, 2);
+ cio_seek(cio, lenp + len);
+}
+
+static void j3d_read_com(opj_j3d_t *j3d) {
+ int len;
+ opj_cio_t *cio = j3d->cio;
+
+ len = cio_read(cio, 2);
+
+ j3d->cp->transform_format = (OPJ_TRANSFORM) cio_read(cio, 1);
+ j3d->cp->encoding_format = (OPJ_ENTROPY_CODING) cio_read(cio, 1);
+ //opj_event_msg(j3d->cinfo, EVT_INFO, "TRF %D ENCOD %d\n",j3d->cp->transform_format,j3d->cp->encoding_format);
+
+ cio_skip(cio, len - 4); //posible comments
+}
+
+static void j3d_write_cox(opj_j3d_t *j3d, int compno) {
+ int i;
+
+ opj_cp_t *cp = j3d->cp;
+ opj_tcp_t *tcp = &cp->tcps[j3d->curtileno];
+ opj_tccp_t *tccp = &tcp->tccps[compno];
+ opj_cio_t *cio = j3d->cio;
+
+ cio_write(cio, tccp->numresolution[0] - 1, 1); /* SPcox (D) No of decomposition levels in x-axis*/
+ if (j3d->cinfo->codec_format == CODEC_J3D) {
+ cio_write(cio, tccp->numresolution[1] - 1, 1); /* SPcox (E) No of decomposition levels in y-axis*/
+ cio_write(cio, tccp->numresolution[2] - 1, 1); /* SPcox (F) No of decomposition levels in z-axis*/
+ }
+ /* (cblkw - 2) + (cblkh - 2) + (cblkl - 2) <= 18*/
+ cio_write(cio, tccp->cblk[0] - 2, 1); /* SPcox (G) Cblk width entre 10 y 2 (8 y 0)*/
+ cio_write(cio, tccp->cblk[1] - 2, 1); /* SPcox (H) Cblk height*/
+ if (j3d->cinfo->codec_format == CODEC_J3D) {
+ cio_write(cio, tccp->cblk[2] - 2, 1); /* SPcox (I) Cblk depth*/
+ }
+ cio_write(cio, tccp->cblksty, 1); /* SPcox (J) Cblk style*/
+ cio_write(cio, tccp->dwtid[0], 1); /* SPcox (K) WT in x-axis 15444-2 Table A10*/
+ if (j3d->cinfo->codec_format == CODEC_J3D) {
+ cio_write(cio, tccp->dwtid[1], 1); /* SPcox (L) WT in y-axis 15444-2 Table A10*/
+ cio_write(cio, tccp->dwtid[2], 1); /* SPcox (M) WT in z-axis 15444-2 Table A10*/
+ }
+
+ if (tccp->csty & J3D_CCP_CSTY_PRT) {
+ for (i = 0; i < tccp->numresolution[0]; i++) {
+ if (i < tccp->numresolution[2])
+ cio_write(cio, tccp->prctsiz[0][i] + (tccp->prctsiz[1][i] << 4) + (tccp->prctsiz[2][i] << 8), 2); /* SPcox (N_i) Table A9*/
+ else
+ if (j3d->cinfo->codec_format == CODEC_J3D)
+ cio_write(cio, tccp->prctsiz[0][i] + (tccp->prctsiz[1][i] << 4), 2); /* SPcox (N_i) Table A9*/
+ else
+ cio_write(cio, tccp->prctsiz[0][i] + (tccp->prctsiz[1][i] << 4), 1); /* SPcox (N_i) Table A9*/ }
+ }
+}
+
+static void j3d_read_cox(opj_j3d_t *j3d, int compno) {
+ int i;
+
+ opj_cp_t *cp = j3d->cp;
+ opj_tcp_t *tcp = j3d->state == J3D_STATE_TPH ? &cp->tcps[j3d->curtileno] : j3d->default_tcp;
+ opj_tccp_t *tccp = &tcp->tccps[compno];
+ opj_cio_t *cio = j3d->cio;
+
+ tccp->numresolution[0] = cio_read(cio, 1) + 1; /* SPcox (D) No of decomposition levels in x-axis*/
+ if (j3d->cinfo->codec_format == CODEC_J3D) {
+ tccp->numresolution[1] = cio_read(cio, 1) + 1; /* SPcox (E) No of decomposition levels in y-axis*/
+ tccp->numresolution[2] = cio_read(cio, 1) + 1; /* SPcox (F) No of decomposition levels in z-axis*/
+ }else if (j3d->cinfo->codec_format == CODEC_J2K) {
+ tccp->numresolution[1] = tccp->numresolution[0];
+ tccp->numresolution[2] = 1;
+ }
+ /* check the reduce value */
+ cp->reduce[0] = int_min((tccp->numresolution[0])-1, cp->reduce[0]);
+ cp->reduce[1] = int_min((tccp->numresolution[1])-1, cp->reduce[1]);
+ cp->reduce[2] = int_min((tccp->numresolution[2])-1, cp->reduce[2]);
+
+ tccp->cblk[0] = cio_read(cio, 1) + 2; /* SPcox (G) */
+ tccp->cblk[1] = cio_read(cio, 1) + 2; /* SPcox (H) */
+ if (j3d->cinfo->codec_format == CODEC_J3D)
+ tccp->cblk[2] = cio_read(cio, 1) + 2; /* SPcox (I) */
+ else
+ tccp->cblk[2] = tccp->cblk[0];
+
+ tccp->cblksty = cio_read(cio, 1); /* SPcox (J) */
+ tccp->dwtid[0] = cio_read(cio, 1); /* SPcox (K) */
+ if (j3d->cinfo->codec_format == CODEC_J3D) {
+ tccp->dwtid[1] = cio_read(cio, 1); /* SPcox (L) */
+ tccp->dwtid[2] = cio_read(cio, 1); /* SPcox (M) */
+ }else{
+ tccp->dwtid[1] = tccp->dwtid[0]; /* SPcox (L) */
+ tccp->dwtid[2] = tccp->dwtid[0]; /* SPcox (M) */
+ }
+ tccp->reversible = (tccp->dwtid[0]>=1 && tccp->dwtid[1]>=1 && tccp->dwtid[2]>=1); //TODO: only valid for irreversible 9x7 WTs
+ if (tccp->csty & J3D_CP_CSTY_PRT) {
+ for (i = 0; i < tccp->numresolution[0]; i++) {
+ int tmp = cio_read(cio, 2); /* SPcox (N_i) */
+ tccp->prctsiz[0][i] = tmp & 0xf;
+ tccp->prctsiz[1][i] = tmp >> 4;
+ tccp->prctsiz[2][i] = tmp >> 8;
+ }
+ }
+}
+
+static void j3d_write_cod(opj_j3d_t *j3d) {
+ opj_cp_t *cp = NULL;
+ opj_tcp_t *tcp = NULL;
+ int lenp, len;
+
+ opj_cio_t *cio = j3d->cio;
+
+ cio_write(cio, J3D_MS_COD, 2); /* COD */
+
+ lenp = cio_tell(cio);
+ cio_skip(cio, 2);
+
+ cp = j3d->cp;
+ tcp = &cp->tcps[j3d->curtileno];
+
+ /* Scod : Table A-4*/
+ cio_write(cio, tcp->csty, 1); /* Scod : Coding style parameters */
+ /* SGcod : Table A-5*/
+ cio_write(cio, tcp->prg, 1); /* SGcod (A) : Progression order */
+ cio_write(cio, tcp->numlayers, 2); /* SGcod (B) : No of layers */
+ cio_write(cio, tcp->mct, 1); /* SGcod (C) : Multiple component transformation usage */
+ /* SPcod : Table A-6*/
+ j3d_write_cox(j3d, 0);
+ len = cio_tell(cio) - lenp;
+ cio_seek(cio, lenp);
+ cio_write(cio, len, 2); /* Lcod */
+ cio_seek(cio, lenp + len);
+}
+
+static void j3d_read_cod(opj_j3d_t *j3d) {
+ int len, i, pos;
+
+ opj_cio_t *cio = j3d->cio;
+ opj_cp_t *cp = j3d->cp;
+ opj_tcp_t *tcp = j3d->state == J3D_STATE_TPH ? &cp->tcps[j3d->curtileno] : j3d->default_tcp;
+ opj_volume_t *volume = j3d->volume;
+
+ /* Lcod */
+ len = cio_read(cio, 2);
+ /* Scod : Table A-4*/
+ tcp->csty = cio_read(cio, 1);
+ /* SGcod : Table A-5*/
+ tcp->prg = (OPJ_PROG_ORDER)cio_read(cio, 1);
+ tcp->numlayers = cio_read(cio, 2);
+ tcp->mct = cio_read(cio, 1);
+
+ pos = cio_tell(cio);
+ for (i = 0; i < volume->numcomps; i++) {
+ tcp->tccps[i].csty = tcp->csty & J3D_CP_CSTY_PRT;
+ cio_seek(cio, pos);
+ j3d_read_cox(j3d, i);
+ }
+}
+
+static void j3d_write_coc(opj_j3d_t *j3d, int compno) {
+ int lenp, len;
+
+ opj_cp_t *cp = j3d->cp;
+ opj_tcp_t *tcp = &cp->tcps[j3d->curtileno];
+ opj_volume_t *volume = j3d->volume;
+ opj_cio_t *cio = j3d->cio;
+
+ cio_write(cio, J3D_MS_COC, 2); /* COC */
+ lenp = cio_tell(cio);
+ cio_skip(cio, 2);
+ cio_write(cio, compno, volume->numcomps <= 256 ? 1 : 2); /* Ccoc */
+ cio_write(cio, tcp->tccps[compno].csty, 1); /* Scoc */
+
+ j3d_write_cox(j3d, compno);
+
+ len = cio_tell(cio) - lenp;
+ cio_seek(cio, lenp);
+ cio_write(cio, len, 2); /* Lcoc */
+ cio_seek(cio, lenp + len);
+}
+
+static void j3d_read_coc(opj_j3d_t *j3d) {
+ int len, compno;
+
+ opj_cp_t *cp = j3d->cp;
+ opj_tcp_t *tcp = j3d->state == J3D_STATE_TPH ? &cp->tcps[j3d->curtileno] : j3d->default_tcp;
+ opj_volume_t *volume = j3d->volume;
+ opj_cio_t *cio = j3d->cio;
+
+ len = cio_read(cio, 2); /* Lcoc */
+ compno = cio_read(cio, volume->numcomps <= 256 ? 1 : 2); /* Ccoc */
+ tcp->tccps[compno].csty = cio_read(cio, 1); /* Scoc */
+ j3d_read_cox(j3d, compno);
+}
+
+static void j3d_write_qcx(opj_j3d_t *j3d, int compno) {
+ int bandno, numbands;
+ int expn, mant;
+
+ opj_cp_t *cp = j3d->cp;
+ opj_tcp_t *tcp = &cp->tcps[j3d->curtileno];
+ opj_tccp_t *tccp = &tcp->tccps[compno];
+ opj_cio_t *cio = j3d->cio;
+
+ cio_write(cio, tccp->qntsty + (tccp->numgbits << 5), 1); /* Sqcx : Table A28 de 15444-1*/
+
+ if (j3d->cinfo->codec_format == CODEC_J2K)
+ numbands = tccp->qntsty == J3D_CCP_QNTSTY_SIQNT ? 1 : tccp->numresolution[0] * 3 - 2;
+ else if (j3d->cinfo->codec_format == CODEC_J3D) {
+ int diff = tccp->numresolution[0] - tccp->numresolution[2];
+ numbands = (tccp->qntsty == J3D_CCP_QNTSTY_SIQNT) ? 1 : (tccp->numresolution[0] * 7 - 6) - 4 *diff; /* SIQNT vs. SEQNT */
+ }
+
+ for (bandno = 0; bandno < numbands; bandno++) {
+ expn = tccp->stepsizes[bandno].expn;
+ mant = tccp->stepsizes[bandno].mant;
+
+ if (tccp->qntsty == J3D_CCP_QNTSTY_NOQNT) {
+ cio_write(cio, expn << 3, 1); /* SPqcx_i */
+ } else {
+ cio_write(cio, (expn << 11) + mant, 2); /* SPqcx_i */
+ }
+ }
+}
+
+static void j3d_read_qcx(opj_j3d_t *j3d, int compno, int len) {
+ int tmp;
+ int bandno, numbands;
+
+ opj_cp_t *cp = j3d->cp;
+ opj_tcp_t *tcp = j3d->state == J3D_STATE_TPH ? &cp->tcps[j3d->curtileno] : j3d->default_tcp;
+ opj_tccp_t *tccp = &tcp->tccps[compno];
+ opj_cio_t *cio = j3d->cio;
+
+ tmp = cio_read(cio, 1); /* Sqcx */
+ tccp->qntsty = tmp & 0x1f;
+ tccp->numgbits = tmp >> 5;
+
+ /*Numbands = 1 si SIQNT
+ len - 1 si NOQNT
+ (len - 1) / 2 si SEQNT */
+ numbands = tccp->qntsty == J3D_CCP_QNTSTY_SIQNT ? 1 : ((tccp->qntsty == J3D_CCP_QNTSTY_NOQNT) ? len - 1 : (len - 1) / 2);
+
+ for (bandno = 0; bandno < numbands; bandno++) {
+ int expn, mant;
+ if (tccp->qntsty == J3D_CCP_QNTSTY_NOQNT) {
+ expn = cio_read(cio, 1) >> 3; /* SPqcx_i */
+ mant = 0;
+ } else {
+ tmp = cio_read(cio, 2); /* SPqcx_i */
+ expn = tmp >> 11;
+ mant = tmp & 0x7ff;
+ }
+ tccp->stepsizes[bandno].expn = expn;
+ tccp->stepsizes[bandno].mant = mant;
+ }
+
+ /* Add Antonin : if scalar_derived -> compute other stepsizes */
+ if (tccp->qntsty == J3D_CCP_QNTSTY_SIQNT) {
+ for (bandno = 1; bandno < J3D_MAXBANDS; bandno++) {
+ int numbands = (cp->transform_format==TRF_2D_DWT) ? 3 : 7;
+ tccp->stepsizes[bandno].expn = tccp->stepsizes[0].expn - ((bandno - 1) / numbands);
+ tccp->stepsizes[bandno].mant = tccp->stepsizes[0].mant;
+ }
+ }
+ /* ddA */
+}
+
+static void j3d_write_qcd(opj_j3d_t *j3d) {
+ int lenp, len;
+
+ opj_cio_t *cio = j3d->cio;
+
+ cio_write(cio, J3D_MS_QCD, 2); /* QCD */
+ lenp = cio_tell(cio);
+ cio_skip(cio, 2);
+ j3d_write_qcx(j3d, 0); /* Sqcd*/
+ len = cio_tell(cio) - lenp;
+ cio_seek(cio, lenp);
+ cio_write(cio, len, 2); /* Lqcd */
+ cio_seek(cio, lenp + len);
+}
+
+static void j3d_read_qcd(opj_j3d_t *j3d) {
+ int len, i, pos;
+
+ opj_cio_t *cio = j3d->cio;
+ opj_volume_t *volume = j3d->volume;
+
+ len = cio_read(cio, 2); /* Lqcd */
+ pos = cio_tell(cio);
+ for (i = 0; i < volume->numcomps; i++) {
+ cio_seek(cio, pos);
+ j3d_read_qcx(j3d, i, len - 2);
+ }
+}
+
+static void j3d_write_qcc(opj_j3d_t *j3d, int compno) {
+ int lenp, len;
+
+ opj_cio_t *cio = j3d->cio;
+
+ cio_write(cio, J3D_MS_QCC, 2); /* QCC */
+ lenp = cio_tell(cio);
+ cio_skip(cio, 2);
+ cio_write(cio, compno, j3d->volume->numcomps <= 256 ? 1 : 2); /* Cqcc */
+ j3d_write_qcx(j3d, compno);
+ len = cio_tell(cio) - lenp;
+ cio_seek(cio, lenp);
+ cio_write(cio, len, 2); /* Lqcc */
+ cio_seek(cio, lenp + len);
+}
+
+static void j3d_read_qcc(opj_j3d_t *j3d) {
+ int len, compno;
+ int numcomp = j3d->volume->numcomps;
+ opj_cio_t *cio = j3d->cio;
+
+ len = cio_read(cio, 2); /* Lqcc */
+ compno = cio_read(cio, numcomp <= 256 ? 1 : 2); /* Cqcc */
+ j3d_read_qcx(j3d, compno, len - 2 - (numcomp <= 256 ? 1 : 2));
+}
+
+static void j3d_write_poc(opj_j3d_t *j3d) {
+ int len, numpchgs, i;
+
+ int numcomps = j3d->volume->numcomps;
+
+ opj_cp_t *cp = j3d->cp;
+ opj_tcp_t *tcp = &cp->tcps[j3d->curtileno];
+ opj_tccp_t *tccp = &tcp->tccps[0];
+ opj_cio_t *cio = j3d->cio;
+
+ numpchgs = tcp->numpocs;
+ cio_write(cio, J3D_MS_POC, 2); /* POC */
+ len = 2 + (5 + 2 * (numcomps <= 256 ? 1 : 2)) * numpchgs;
+ cio_write(cio, len, 2); /* Lpoc */
+ for (i = 0; i < numpchgs; i++) {
+ opj_poc_t *poc = &tcp->pocs[i];
+ cio_write(cio, poc->resno0, 1); /* RSpoc_i */
+ cio_write(cio, poc->compno0, (numcomps <= 256 ? 1 : 2)); /* CSpoc_i */
+ cio_write(cio, poc->layno1, 2); /* LYEpoc_i */
+ poc->layno1 = int_min(poc->layno1, tcp->numlayers);
+ cio_write(cio, poc->resno1, 1); /* REpoc_i */
+ poc->resno1 = int_min(poc->resno1, tccp->numresolution[0]);
+ cio_write(cio, poc->compno1, (numcomps <= 256 ? 1 : 2)); /* CEpoc_i */
+ poc->compno1 = int_min(poc->compno1, numcomps);
+ cio_write(cio, poc->prg, 1); /* Ppoc_i */
+ }
+}
+
+static void j3d_read_poc(opj_j3d_t *j3d) {
+ int len, numpchgs, i, old_poc;
+
+ int numcomps = j3d->volume->numcomps;
+
+ opj_cp_t *cp = j3d->cp;
+ opj_tcp_t *tcp = j3d->state == J3D_STATE_TPH ? &cp->tcps[j3d->curtileno] : j3d->default_tcp;
+ opj_tccp_t *tccp = &tcp->tccps[0];
+ opj_cio_t *cio = j3d->cio;
+
+ old_poc = tcp->POC ? tcp->numpocs + 1 : 0;
+ tcp->POC = 1;
+ len = cio_read(cio, 2); /* Lpoc */
+ numpchgs = (len - 2) / (5 + 2 * (numcomps <= 256 ? 1 : 2));
+
+ for (i = old_poc; i < numpchgs + old_poc; i++) {
+ opj_poc_t *poc;
+ poc = &tcp->pocs[i];
+ poc->resno0 = cio_read(cio, 1); /* RSpoc_i */
+ poc->compno0 = cio_read(cio, numcomps <= 256 ? 1 : 2); /* CSpoc_i */
+ poc->layno1 = int_min(cio_read(cio, 2), (unsigned int) tcp->numlayers); /* LYEpoc_i */
+ poc->resno1 = int_min(cio_read(cio, 1), (unsigned int) tccp->numresolution[0]); /* REpoc_i */
+ poc->compno1 = int_min(
+ cio_read(cio, numcomps <= 256 ? 1 : 2), (unsigned int) numcomps); /* CEpoc_i */
+ poc->prg = (OPJ_PROG_ORDER)cio_read(cio, 1); /* Ppoc_i */
+ }
+
+ tcp->numpocs = numpchgs + old_poc - 1;
+}
+
+static void j3d_read_crg(opj_j3d_t *j3d) {
+ int len, i, Xcrg_i, Ycrg_i, Zcrg_i;
+
+ opj_cio_t *cio = j3d->cio;
+ int numcomps = j3d->volume->numcomps;
+
+ len = cio_read(cio, 2); /* Lcrg */
+ for (i = 0; i < numcomps; i++) {
+ Xcrg_i = cio_read(cio, 2); /* Xcrg_i */
+ Ycrg_i = cio_read(cio, 2); /* Ycrg_i */
+ Zcrg_i = cio_read(cio, 2); /* Zcrg_i */
+ }
+}
+
+static void j3d_read_tlm(opj_j3d_t *j3d) {
+ int len, Ztlm, Stlm, ST, SP, tile_tlm, i;
+ long int Ttlm_i, Ptlm_i;
+
+ opj_cio_t *cio = j3d->cio;
+
+ len = cio_read(cio, 2); /* Ltlm */
+ Ztlm = cio_read(cio, 1); /* Ztlm */
+ Stlm = cio_read(cio, 1); /* Stlm */
+ ST = ((Stlm >> 4) & 0x01) + ((Stlm >> 4) & 0x02);
+ SP = (Stlm >> 6) & 0x01;
+ tile_tlm = (len - 4) / ((SP + 1) * 2 + ST);
+ for (i = 0; i < tile_tlm; i++) {
+ Ttlm_i = cio_read(cio, ST); /* Ttlm_i */
+ Ptlm_i = cio_read(cio, SP ? 4 : 2); /* Ptlm_i */
+ }
+}
+
+static void j3d_read_plm(opj_j3d_t *j3d) {
+ int len, i, Zplm, Nplm, add, packet_len = 0;
+
+ opj_cio_t *cio = j3d->cio;
+
+ len = cio_read(cio, 2); /* Lplm */
+ Zplm = cio_read(cio, 1); /* Zplm */
+ len -= 3;
+ while (len > 0) {
+ Nplm = cio_read(cio, 4); /* Nplm */
+ len -= 4;
+ for (i = Nplm; i > 0; i--) {
+ add = cio_read(cio, 1);
+ len--;
+ packet_len = (packet_len << 7) + add; /* Iplm_ij */
+ if ((add & 0x80) == 0) {
+ /* New packet */
+ packet_len = 0;
+ }
+ if (len <= 0)
+ break;
+ }
+ }
+}
+
+static void j3d_read_plt(opj_j3d_t *j3d) {
+ int len, i, Zplt, packet_len = 0, add;
+
+ opj_cio_t *cio = j3d->cio;
+
+ len = cio_read(cio, 2); /* Lplt */
+ Zplt = cio_read(cio, 1); /* Zplt */
+ for (i = len - 3; i > 0; i--) {
+ add = cio_read(cio, 1);
+ packet_len = (packet_len << 7) + add; /* Iplt_i */
+ if ((add & 0x80) == 0) {
+ /* New packet */
+ packet_len = 0;
+ }
+ }
+}
+
+static void j3d_read_ppm(opj_j3d_t *j3d) {
+ int len, Z_ppm, i, j;
+ int N_ppm;
+
+ opj_cp_t *cp = j3d->cp;
+ opj_cio_t *cio = j3d->cio;
+
+ len = cio_read(cio, 2);
+ cp->ppm = 1;
+
+ Z_ppm = cio_read(cio, 1); /* Z_ppm */
+ len -= 3;
+ while (len > 0) {
+ if (cp->ppm_previous == 0) {
+ N_ppm = cio_read(cio, 4); /* N_ppm */
+ len -= 4;
+ } else {
+ N_ppm = cp->ppm_previous;
+ }
+ j = cp->ppm_store;
+ if (Z_ppm == 0) { /* First PPM marker */
+ cp->ppm_data = (unsigned char *) opj_malloc(N_ppm * sizeof(unsigned char));
+ cp->ppm_data_first = cp->ppm_data;
+ cp->ppm_len = N_ppm;
+ } else { /* NON-first PPM marker */
+ cp->ppm_data = (unsigned char *) opj_realloc(cp->ppm_data, (N_ppm + cp->ppm_store) * sizeof(unsigned char));
+ cp->ppm_data_first = cp->ppm_data;
+ cp->ppm_len = N_ppm + cp->ppm_store;
+ }
+ for (i = N_ppm; i > 0; i--) { /* Read packet header */
+ cp->ppm_data[j] = cio_read(cio, 1);
+ j++;
+ len--;
+ if (len == 0)
+ break; /* Case of non-finished packet header in present marker but finished in next one */
+ }
+ cp->ppm_previous = i - 1;
+ cp->ppm_store = j;
+ }
+}
+
+static void j3d_read_ppt(opj_j3d_t *j3d) {
+ int len, Z_ppt, i, j = 0;
+
+ opj_cp_t *cp = j3d->cp;
+ opj_tcp_t *tcp = cp->tcps + j3d->curtileno;
+ opj_cio_t *cio = j3d->cio;
+
+ len = cio_read(cio, 2);
+ Z_ppt = cio_read(cio, 1);
+ tcp->ppt = 1;
+ if (Z_ppt == 0) { /* First PPT marker */
+ tcp->ppt_data = (unsigned char *) opj_malloc((len - 3) * sizeof(unsigned char));
+ tcp->ppt_data_first = tcp->ppt_data;
+ tcp->ppt_store = 0;
+ tcp->ppt_len = len - 3;
+ } else { /* NON-first PPT marker */
+ tcp->ppt_data = (unsigned char *) opj_realloc(tcp->ppt_data, (len - 3 + tcp->ppt_store) * sizeof(unsigned char));
+ tcp->ppt_data_first = tcp->ppt_data;
+ tcp->ppt_len = len - 3 + tcp->ppt_store;
+ }
+ j = tcp->ppt_store;
+ for (i = len - 3; i > 0; i--) {
+ tcp->ppt_data[j] = cio_read(cio, 1);
+ j++;
+ }
+ tcp->ppt_store = j;
+}
+
+static void j3d_write_sot(opj_j3d_t *j3d) {
+ int lenp, len;
+
+ opj_cio_t *cio = j3d->cio;
+
+ j3d->sot_start = cio_tell(cio);
+ cio_write(cio, J3D_MS_SOT, 2); /* SOT */
+ lenp = cio_tell(cio);
+ cio_skip(cio, 2); /* Lsot (further) */
+ cio_write(cio, j3d->curtileno, 2); /* Isot */
+ cio_skip(cio, 4); /* Psot (further in j3d_write_sod) */
+ cio_write(cio, 0, 1); /* TPsot */
+ cio_write(cio, 1, 1); /* TNsot (no of tile-parts of this tile in this codestream)*/
+ len = cio_tell(cio) - lenp;
+ cio_seek(cio, lenp);
+ cio_write(cio, len, 2); /* Lsot */
+ cio_seek(cio, lenp + len);
+}
+
+static void j3d_read_sot(opj_j3d_t *j3d) {
+ int len, tileno, totlen, partno, numparts, i;
+ opj_tcp_t *tcp = NULL;
+ char status = 0;
+
+ opj_cp_t *cp = j3d->cp;
+ opj_cio_t *cio = j3d->cio;
+
+ len = cio_read(cio, 2);
+ tileno = cio_read(cio, 2);
+
+ if (cp->tileno_size == 0) {
+ cp->tileno[cp->tileno_size] = tileno;
+ cp->tileno_size++;
+ } else {
+ i = 0;
+ while (i < cp->tileno_size && status == 0) {
+ status = cp->tileno[i] == tileno ? 1 : 0;
+ i++;
+ }
+ if (status == 0) {
+ cp->tileno[cp->tileno_size] = tileno;
+ cp->tileno_size++;
+ }
+ }
+
+ totlen = cio_read(cio, 4);
+ if (!totlen)
+ totlen = cio_numbytesleft(cio) + 8;
+
+ partno = cio_read(cio, 1);
+ numparts = cio_read(cio, 1);
+
+ j3d->curtileno = tileno;
+ j3d->eot = cio_getbp(cio) - 12 + totlen;
+ j3d->state = J3D_STATE_TPH;
+ tcp = &cp->tcps[j3d->curtileno];
+
+ if (tcp->first == 1) {
+
+ /* Initialization PPT */
+ opj_tccp_t *tmp = tcp->tccps;
+ memcpy(tcp, j3d->default_tcp, sizeof(opj_tcp_t));
+ tcp->ppt = 0;
+ tcp->ppt_data = NULL;
+ tcp->ppt_data_first = NULL;
+ tcp->tccps = tmp;
+
+ for (i = 0; i < j3d->volume->numcomps; i++) {
+ tcp->tccps[i] = j3d->default_tcp->tccps[i];
+ }
+ cp->tcps[j3d->curtileno].first = 0;
+ }
+}
+
+static void j3d_write_sod(opj_j3d_t *j3d, void *tile_coder) {
+ int l, layno;
+ int totlen;
+ opj_tcp_t *tcp = NULL;
+ opj_volume_info_t *volume_info = NULL;
+
+ opj_tcd_t *tcd = (opj_tcd_t*)tile_coder; /* cast is needed because of conflicts in header inclusions */
+ opj_cp_t *cp = j3d->cp;
+ opj_cio_t *cio = j3d->cio;
+
+ cio_write(cio, J3D_MS_SOD, 2);
+ if (j3d->curtileno == 0) {
+ j3d->sod_start = cio_tell(cio) + j3d->pos_correction;
+ }
+
+ /* INDEX >> */
+ volume_info = j3d->volume_info;
+ if (volume_info && volume_info->index_on) {
+ volume_info->tile[j3d->curtileno].end_header = cio_tell(cio) + j3d->pos_correction - 1;
+ }
+ /* << INDEX */
+
+ tcp = &cp->tcps[j3d->curtileno];
+ for (layno = 0; layno < tcp->numlayers; layno++) {
+ tcp->rates[layno] -= tcp->rates[layno] ? (j3d->sod_start / (cp->th * cp->tw * cp->tl)) : 0;
+ }
+
+ if(volume_info) {
+ volume_info->num = 0;
+ }
+
+ l = tcd_encode_tile(tcd, j3d->curtileno, cio_getbp(cio), cio_numbytesleft(cio) - 2, volume_info);
+
+ /* Writing Psot in SOT marker */
+ totlen = cio_tell(cio) + l - j3d->sot_start;
+ cio_seek(cio, j3d->sot_start + 6);
+ cio_write(cio, totlen, 4);
+ cio_seek(cio, j3d->sot_start + totlen);
+}
+
+static void j3d_read_sod(opj_j3d_t *j3d) {
+ int len, truncate = 0, i;
+ unsigned char *data = NULL, *data_ptr = NULL;
+
+ opj_cio_t *cio = j3d->cio;
+ int curtileno = j3d->curtileno;
+
+ len = int_min(j3d->eot - cio_getbp(cio), cio_numbytesleft(cio) + 1);
+
+ if (len == cio_numbytesleft(cio) + 1) {
+ truncate = 1; /* Case of a truncate codestream */
+ }
+
+ data = (unsigned char *) opj_malloc((j3d->tile_len[curtileno] + len) * sizeof(unsigned char));
+
+ for (i = 0; i < j3d->tile_len[curtileno]; i++) {
+ data[i] = j3d->tile_data[curtileno][i];
+ }
+
+ data_ptr = data + j3d->tile_len[curtileno];
+ for (i = 0; i < len; i++) {
+ data_ptr[i] = cio_read(cio, 1);
+ }
+
+ j3d->tile_len[curtileno] += len;
+ opj_free(j3d->tile_data[curtileno]);
+ j3d->tile_data[curtileno] = data;
+
+ if (!truncate) {
+ j3d->state = J3D_STATE_TPHSOT;
+ } else {
+ j3d->state = J3D_STATE_NEOC; /* RAJOUTE !! */
+ }
+}
+
+static void j3d_write_rgn(opj_j3d_t *j3d, int compno, int tileno) {
+
+ opj_cp_t *cp = j3d->cp;
+ opj_tcp_t *tcp = &cp->tcps[tileno];
+ opj_cio_t *cio = j3d->cio;
+ int numcomps = j3d->volume->numcomps;
+
+ cio_write(cio, J3D_MS_RGN, 2); /* RGN */
+ cio_write(cio, numcomps <= 256 ? 5 : 6, 2); /* Lrgn */
+ cio_write(cio, compno, numcomps <= 256 ? 1 : 2); /* Crgn */
+ cio_write(cio, 0, 1); /* Srgn */
+ cio_write(cio, tcp->tccps[compno].roishift, 1); /* SPrgn */
+}
+
+static void j3d_read_rgn(opj_j3d_t *j3d) {
+ int len, compno, roisty;
+
+ opj_cp_t *cp = j3d->cp;
+ opj_tcp_t *tcp = j3d->state == J3D_STATE_TPH ? &cp->tcps[j3d->curtileno] : j3d->default_tcp;
+ opj_cio_t *cio = j3d->cio;
+ int numcomps = j3d->volume->numcomps;
+
+ len = cio_read(cio, 2); /* Lrgn */
+ compno = cio_read(cio, numcomps <= 256 ? 1 : 2); /* Crgn */
+ roisty = cio_read(cio, 1); /* Srgn */
+ tcp->tccps[compno].roishift = cio_read(cio, 1); /* SPrgn */
+}
+
+static void j3d_write_eoc(opj_j3d_t *j3d) {
+ opj_cio_t *cio = j3d->cio;
+ /* opj_event_msg(j3d->cinfo, "%.8x: EOC\n", cio_tell(cio) + j3d->pos_correction); */
+ cio_write(cio, J3D_MS_EOC, 2);
+}
+
+static void j3d_read_eoc(opj_j3d_t *j3d) {
+ int i, tileno;
+
+#ifndef NO_PACKETS_DECODING
+ opj_tcd_t *tcd = tcd_create(j3d->cinfo);
+ tcd_malloc_decode(tcd, j3d->volume, j3d->cp);
+ /*j3d_dump_volume(stdout, tcd->volume);
+ j3d_dump_cp(stdout, tcd->volume, tcd->cp);*/
+ for (i = 0; i < j3d->cp->tileno_size; i++) {
+ tileno = j3d->cp->tileno[i];
+ //opj_event_msg(j3d->cinfo, EVT_INFO, "tcd_decode_tile \n");
+ tcd_decode_tile(tcd, j3d->tile_data[tileno], j3d->tile_len[tileno], tileno);
+ opj_free(j3d->tile_data[tileno]);
+ j3d->tile_data[tileno] = NULL;
+ }
+ tcd_free_decode(tcd);
+ tcd_destroy(tcd);
+#else
+ for (i = 0; i < j3d->cp->tileno_size; i++) {
+ tileno = j3d->cp->tileno[i];
+ opj_free(j3d->tile_data[tileno]);
+ j3d->tile_data[tileno] = NULL;
+ }
+#endif
+
+ j3d->state = J3D_STATE_MT;
+}
+
+static void j3d_read_unk(opj_j3d_t *j3d) {
+ opj_event_msg(j3d->cinfo, EVT_WARNING, "Unknown marker\n");
+}
+
+static opj_atk_t atk_info_wt[] = {
+ {0, 1, J3D_ATK_WS, J3D_ATK_IRR, 0, J3D_ATK_WS, 1.230174104, 4, {0}, {0}, {0}, {1,1,1,1}, {-1.586134342059924, -0.052980118572961, 0.882911075530934, 0.443506852043971}},/* WT 9-7 IRR*/
+ {1, 0, J3D_ATK_WS, J3D_ATK_REV, 0, J3D_ATK_WS, 0, 2, {0}, {1,2}, {1,2}, {1,1}, {-1.0,1.0}},/* WT 5-3 REV*/
+ {2, 0, J3D_ATK_ARB, J3D_ATK_REV, 0, J3D_ATK_CON, 0, 2, {0,0}, {0,1}, {0,1}, {1,1}, {{-1.0},{1.0}}}, /* WT 2-2 REV*/
+ {3, 0, J3D_ATK_ARB, J3D_ATK_REV, 1, J3D_ATK_CON, 0, 3, {0,0,-1}, {0,1,2}, {0,1,2}, {1,1,3}, {{-1.0},{1.0},{1.0,0.0,-1.0}}}, /* WT 2-6 REV*/
+ {4, 0, J3D_ATK_ARB, J3D_ATK_REV, 1, J3D_ATK_CON, 0, 3, {0,0,-2}, {0,1,6}, {0,1,32}, {1,1,5}, {{-1},{1},{-3.0,22.0,0.0,-22.0,3.0}}}, /* WT 2-10 REV*/
+ {5, 1, J3D_ATK_ARB, J3D_ATK_IRR, 1, J3D_ATK_WS, 1, 7, {0}, {0}, {0}, {1,1,2,1,2,1,3},{{-1},{1.58613434206},{-0.460348209828, 0.460348209828},{0.25},{0.374213867768,-0.374213867768},{-1.33613434206},{0.29306717103,0,-0.29306717103}}}, /* WT 6-10 IRR*/
+ {6, 1, J3D_ATK_ARB, J3D_ATK_IRR, 0, J3D_ATK_WS, 1, 11, {0}, {0}, {0}, {1,1,2,1,2,1,2,1,2,1,5},{{-1},{0,99715069105},{-1.00573127827, 1.00573127827},{-0.27040357631},{2.20509972343, -2.20509972343},{0.08059995736},
+ {-1.62682532350, 1.62682532350},{0.52040357631},{0.60404664250, -0.60404664250},{-0.82775064841},{-0.06615812964, 0.29402137720, 0, -0.29402137720, 0.06615812964}}}, /* WT 10-18 IRR*/
+ {7, 1, J3D_ATK_WS, J3D_ATK_IRR, 0, J3D_ATK_WS, 1, 2, {0}, {0}, {0}, {1,1}, {-0.5, 0.25}}, /* WT 5-3 IRR*/
+ {8, 0, J3D_ATK_WS, J3D_ATK_REV, 0, J3D_ATK_WS, 0, 2, {0}, {4,4}, {8,8}, {2,2}, {{-9,1},{5,-1}}} /* WT 13-7 REV*/
+};
+
+typedef struct opj_dec_mstabent {
+ /** marker value */
+ int id;
+ /** value of the state when the marker can appear */
+ int states;
+ /** action linked to the marker */
+ void (*handler) (opj_j3d_t *j3d);
+} opj_dec_mstabent_t;
+
+opj_dec_mstabent_t j3d_dec_mstab[] = {
+ {J3D_MS_SOC, J3D_STATE_MHSOC, j3d_read_soc},
+ {J3D_MS_SOT, J3D_STATE_MH | J3D_STATE_TPHSOT, j3d_read_sot},
+ {J3D_MS_SOD, J3D_STATE_TPH, j3d_read_sod},
+ {J3D_MS_EOC, J3D_STATE_TPHSOT, j3d_read_eoc},
+ {J3D_MS_CAP, J3D_STATE_MHSIZ, j3d_read_cap},
+ {J3D_MS_SIZ, J3D_STATE_MHSIZ, j3d_read_siz},
+ {J3D_MS_ZSI, J3D_STATE_MHSIZ, j3d_read_zsi},
+ {J3D_MS_COD, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_cod},
+ {J3D_MS_COC, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_coc},
+ {J3D_MS_RGN, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_rgn},
+ {J3D_MS_QCD, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_qcd},
+ {J3D_MS_QCC, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_qcc},
+ {J3D_MS_POC, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_poc},
+ {J3D_MS_TLM, J3D_STATE_MH, j3d_read_tlm},
+ {J3D_MS_PLM, J3D_STATE_MH, j3d_read_plm},
+ {J3D_MS_PLT, J3D_STATE_TPH, j3d_read_plt},
+ {J3D_MS_PPM, J3D_STATE_MH, j3d_read_ppm},
+ {J3D_MS_PPT, J3D_STATE_TPH, j3d_read_ppt},
+ {J3D_MS_SOP, 0, 0},
+ {J3D_MS_CRG, J3D_STATE_MH, j3d_read_crg},
+ {J3D_MS_COM, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_com},
+ {J3D_MS_DCO, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_dco},
+ {J3D_MS_ATK, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_atk},
+ {0, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_unk}
+ /*, -->must define the j3d_read functions
+ {J3D_MS_CBD, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_cbd},
+ {J3D_MS_MCT, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_mct},
+ {J3D_MS_MCC, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_mcc},
+ {J3D_MS_MCO, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_mco},
+ {J3D_MS_NLT, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_nlt},
+ {J3D_MS_VMS, J3D_STATE_MH, j3d_read_vms},
+ {J3D_MS_DFS, J3D_STATE_MH, j3d_read_dfs},
+ {J3D_MS_ADS, J3D_STATE_MH, j3d_read_ads},
+ {J3D_MS_QPD, J3D_STATE_MH, j3d_read_qpd},
+ {J3D_MS_QPC, J3D_STATE_TPH, j3d_read_qpc}*/
+};
+
+/**
+Read the lookup table containing all the marker, status and action
+@param id Marker value
+*/
+static opj_dec_mstabent_t *j3d_dec_mstab_lookup(int id) {
+ opj_dec_mstabent_t *e;
+ for (e = j3d_dec_mstab; e->id != 0; e++) {
+ if (e->id == id) {
+ break;
+ }
+ }
+ return e;
+}
+
+/* ----------------------------------------------------------------------- */
+/* J3D / JPT decoder interface */
+/* ----------------------------------------------------------------------- */
+
+opj_j3d_t* j3d_create_decompress(opj_common_ptr cinfo) {
+ opj_j3d_t *j3d = (opj_j3d_t*)opj_malloc(sizeof(opj_j3d_t));
+ if(j3d) {
+ j3d->cinfo = cinfo;
+ j3d->default_tcp = (opj_tcp_t*)opj_malloc(sizeof(opj_tcp_t));
+ if(!j3d->default_tcp) {
+ opj_free(j3d);
+ return NULL;
+ }
+ }
+ return j3d;
+}
+
+void j3d_destroy_decompress(opj_j3d_t *j3d) {
+ int i = 0;
+
+ if(j3d->tile_len != NULL) {
+ opj_free(j3d->tile_len);
+ }
+ if(j3d->tile_data != NULL) {
+ opj_free(j3d->tile_data);
+ }
+ if(j3d->default_tcp != NULL) {
+ opj_tcp_t *default_tcp = j3d->default_tcp;
+ if(default_tcp->ppt_data_first != NULL) {
+ opj_free(default_tcp->ppt_data_first);
+ }
+ if(j3d->default_tcp->tccps != NULL) {
+ opj_free(j3d->default_tcp->tccps);
+ }
+ opj_free(j3d->default_tcp);
+ }
+ if(j3d->cp != NULL) {
+ opj_cp_t *cp = j3d->cp;
+ if(cp->tcps != NULL) {
+ for(i = 0; i < cp->tw * cp->th * cp->tl; i++) {
+ if(cp->tcps[i].ppt_data_first != NULL) {
+ opj_free(cp->tcps[i].ppt_data_first);
+ }
+ if(cp->tcps[i].tccps != NULL) {
+ opj_free(cp->tcps[i].tccps);
+ }
+ }
+ opj_free(cp->tcps);
+ }
+ if(cp->ppm_data_first != NULL) {
+ opj_free(cp->ppm_data_first);
+ }
+ if(cp->tileno != NULL) {
+ opj_free(cp->tileno);
+ }
+ if(cp->comment != NULL) {
+ opj_free(cp->comment);
+ }
+
+ opj_free(cp);
+ }
+
+ opj_free(j3d);
+}
+
+void j3d_setup_decoder(opj_j3d_t *j3d, opj_dparameters_t *parameters) {
+ if(j3d && parameters) {
+ /* create and initialize the coding parameters structure */
+ opj_cp_t *cp = (opj_cp_t*)opj_malloc(sizeof(opj_cp_t));
+ cp->reduce[0] = parameters->cp_reduce[0];
+ cp->reduce[1] = parameters->cp_reduce[1];
+ cp->reduce[2] = parameters->cp_reduce[2];
+ cp->layer = parameters->cp_layer;
+ cp->bigendian = parameters->bigendian;
+
+
+ cp->encoding_format = ENCOD_2EB;
+ cp->transform_format = TRF_2D_DWT;
+
+ /* keep a link to cp so that we can destroy it later in j3d_destroy_decompress */
+ j3d->cp = cp;
+ }
+}
+
+opj_volume_t* j3d_decode(opj_j3d_t *j3d, opj_cio_t *cio) {
+ opj_volume_t *volume = NULL;
+
+ opj_common_ptr cinfo = j3d->cinfo;
+
+ j3d->cio = cio;
+
+ /* create an empty volume */
+ volume = (opj_volume_t*)opj_malloc(sizeof(opj_volume_t));
+ j3d->volume = volume;
+
+ j3d->state = J3D_STATE_MHSOC;
+
+ for (;;) {
+ opj_dec_mstabent_t *e;
+ int id = cio_read(cio, 2);
+ if (id >> 8 != 0xff) {
+ opj_volume_destroy(volume);
+ opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
+ return 0;
+ }
+ e = j3d_dec_mstab_lookup(id);
+ //opj_event_msg(cinfo, EVT_INFO, "MARKER %x PREVSTATE %d E->STATE %d\n",e->id,j3d->state,e->states);
+ if (!(j3d->state & e->states)) {
+ opj_volume_destroy(volume);
+ opj_event_msg(cinfo, EVT_ERROR, "%.8x: unexpected marker %x\n", cio_tell(cio) - 2, id);
+ return 0;
+ }
+ if (e->handler) {
+ (*e->handler)(j3d);
+ }
+ //opj_event_msg(cinfo, EVT_INFO, "POSTSTATE %d\n",j3d->state);
+ if (j3d->state == J3D_STATE_MT) {
+ break;
+ }
+ if (j3d->state == J3D_STATE_NEOC) {
+ break;
+ }
+ }
+ if (j3d->state == J3D_STATE_NEOC) {
+ j3d_read_eoc(j3d);
+ }
+
+ if (j3d->state != J3D_STATE_MT) {
+ opj_event_msg(cinfo, EVT_WARNING, "Incomplete bitstream\n");
+ }
+
+ return volume;
+}
+
+/* ----------------------------------------------------------------------- */
+/* J3D encoder interface */
+/* ----------------------------------------------------------------------- */
+
+opj_j3d_t* j3d_create_compress(opj_common_ptr cinfo) {
+ opj_j3d_t *j3d = (opj_j3d_t*)opj_malloc(sizeof(opj_j3d_t));
+ if(j3d) {
+ j3d->cinfo = cinfo;
+ }
+ return j3d;
+}
+
+void j3d_destroy_compress(opj_j3d_t *j3d) {
+ int tileno;
+
+ if(!j3d) return;
+
+ if(j3d->volume_info != NULL) {
+ opj_volume_info_t *volume_info = j3d->volume_info;
+ if (volume_info->index_on && j3d->cp) {
+ opj_cp_t *cp = j3d->cp;
+ for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
+ opj_tile_info_t *tile_info = &volume_info->tile[tileno];
+ opj_free(tile_info->thresh);
+ opj_free(tile_info->packet);
+ }
+ opj_free(volume_info->tile);
+ }
+ opj_free(volume_info);
+ }
+ if(j3d->cp != NULL) {
+ opj_cp_t *cp = j3d->cp;
+
+ if(cp->comment) {
+ opj_free(cp->comment);
+ }
+ if(cp->matrice) {
+ opj_free(cp->matrice);
+ }
+ for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
+ opj_free(cp->tcps[tileno].tccps);
+ }
+ opj_free(cp->tcps);
+ opj_free(cp);
+ }
+
+ opj_free(j3d);
+}
+
+void j3d_setup_encoder(opj_j3d_t *j3d, opj_cparameters_t *parameters, opj_volume_t *volume) {
+ int i, j, tileno, numpocs_tile;
+ opj_cp_t *cp = NULL;
+
+ if(!j3d || !parameters || ! volume) {
+ return;
+ }
+
+ /* create and initialize the coding parameters structure */
+ cp = (opj_cp_t*)opj_malloc(sizeof(opj_cp_t));
+
+ /* keep a link to cp so that we can destroy it later in j3d_destroy_compress */
+ j3d->cp = cp;
+
+ /* set default values for cp */
+ cp->tw = 1;
+ cp->th = 1;
+ cp->tl = 1;
+
+ /* copy user encoding parameters */
+ cp->disto_alloc = parameters->cp_disto_alloc;
+ cp->fixed_alloc = parameters->cp_fixed_alloc;
+ cp->fixed_quality = parameters->cp_fixed_quality;
+
+ /* transform and coding method */
+ cp->transform_format = parameters->transform_format;
+ cp->encoding_format = parameters->encoding_format;
+
+ /* mod fixed_quality */
+ if(parameters->cp_matrice) {
+ size_t array_size = parameters->tcp_numlayers * 3 * parameters->numresolution[0] * sizeof(int);
+ cp->matrice = (int *) opj_malloc(array_size);
+ memcpy(cp->matrice, parameters->cp_matrice, array_size);
+ }
+
+ /* creation of an index file ? */
+ cp->index_on = parameters->index_on;
+ if(cp->index_on) {
+ j3d->volume_info = (opj_volume_info_t*)opj_malloc(sizeof(opj_volume_info_t));
+ }
+
+ /* tiles */
+ cp->tdx = parameters->cp_tdx;
+ cp->tdy = parameters->cp_tdy;
+ cp->tdz = parameters->cp_tdz;
+ /* tile offset */
+ cp->tx0 = parameters->cp_tx0;
+ cp->ty0 = parameters->cp_ty0;
+ cp->tz0 = parameters->cp_tz0;
+ /* comment string */
+ if(parameters->cp_comment) {
+ cp->comment = (char*)opj_malloc(strlen(parameters->cp_comment) + 1);
+ if(cp->comment) {
+ strcpy(cp->comment, parameters->cp_comment);
+ }
+ }
+
+ /*calculate other encoding parameters*/
+ if (parameters->tile_size_on) {
+ cp->tw = int_ceildiv(volume->x1 - cp->tx0, cp->tdx);
+ cp->th = int_ceildiv(volume->y1 - cp->ty0, cp->tdy);
+ cp->tl = int_ceildiv(volume->z1 - cp->tz0, cp->tdz);
+ } else {
+ cp->tdx = volume->x1 - cp->tx0;
+ cp->tdy = volume->y1 - cp->ty0;
+ cp->tdz = volume->z1 - cp->tz0;
+ }
+
+ /* initialize the multiple tiles */
+ /* ---------------------------- */
+ cp->tcps = (opj_tcp_t *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(opj_tcp_t));
+
+ for (tileno = 0; tileno < cp->tw * cp->th * cp->tl; tileno++) {
+ opj_tcp_t *tcp = &cp->tcps[tileno];
+ tcp->numlayers = parameters->tcp_numlayers;
+ for (j = 0; j < tcp->numlayers; j++) {
+ if (cp->fixed_quality) { /* add fixed_quality */
+ tcp->distoratio[j] = parameters->tcp_distoratio[j];
+ } else {
+ tcp->rates[j] = parameters->tcp_rates[j];
+ }
+ }
+ tcp->csty = parameters->csty;
+ tcp->prg = parameters->prog_order;
+ tcp->mct = volume->numcomps == 3 ? 1 : 0;
+
+ numpocs_tile = 0;
+ tcp->POC = 0;
+ if (parameters->numpocs) {
+ /* initialisation of POC */
+ tcp->POC = 1;
+ for (i = 0; i < parameters->numpocs; i++) {
+ if((tileno == parameters->POC[i].tile - 1) || (parameters->POC[i].tile == -1)) {
+ opj_poc_t *tcp_poc = &tcp->pocs[numpocs_tile];
+ tcp_poc->resno0 = parameters->POC[numpocs_tile].resno0;
+ tcp_poc->compno0 = parameters->POC[numpocs_tile].compno0;
+ tcp_poc->layno1 = parameters->POC[numpocs_tile].layno1;
+ tcp_poc->resno1 = parameters->POC[numpocs_tile].resno1;
+ tcp_poc->compno1 = parameters->POC[numpocs_tile].compno1;
+ tcp_poc->prg = parameters->POC[numpocs_tile].prg;
+ tcp_poc->tile = parameters->POC[numpocs_tile].tile;
+ numpocs_tile++;
+ }
+ }
+ }
+ tcp->numpocs = numpocs_tile;
+
+ tcp->tccps = (opj_tccp_t *) opj_malloc(volume->numcomps * sizeof(opj_tccp_t));
+
+ for (i = 0; i < volume->numcomps; i++) {
+ opj_tccp_t *tccp = &tcp->tccps[i];
+ tccp->csty = parameters->csty & J3D_CCP_CSTY_PRT; /* 0 => standard precint || 1 => custom-defined precinct */
+ tccp->numresolution[0] = parameters->numresolution[0];
+ tccp->numresolution[1] = parameters->numresolution[1];
+ tccp->numresolution[2] = parameters->numresolution[2];
+ assert (parameters->cblock_init[0] <= T1_MAXCBLKW);
+ assert (parameters->cblock_init[0] >= T1_MINCBLKW);
+ assert (parameters->cblock_init[1] <= T1_MAXCBLKH);
+ assert (parameters->cblock_init[1] >= T1_MINCBLKH);
+ assert (parameters->cblock_init[2] <= T1_MAXCBLKD);
+ assert (parameters->cblock_init[2] >= T1_MINCBLKD);
+ tccp->cblk[0] = int_floorlog2(parameters->cblock_init[0]);
+ tccp->cblk[1] = int_floorlog2(parameters->cblock_init[1]);
+ tccp->cblk[2] = int_floorlog2(parameters->cblock_init[2]);
+ assert (tccp->cblk[0]+tccp->cblk[1]+tccp->cblk[1] <= T1_MAXWHD);
+ tccp->cblksty = parameters->mode; //Codeblock style --> Table A.19 (default 0)
+
+ /*ATK / transform */
+ tccp->reversible = parameters->irreversible ? 0 : 1; /* 0 => DWT 9-7 || 1 => DWT 5-3 */
+ for (j = 0; j < 3; j++) {
+ tccp->dwtid[j] = parameters->irreversible ? 0 : 1; /* 0 => DWT 9-7 || 1 => DWT 5-3 */
+ }
+
+ /* Quantification: SEQNT (Scalar Expounded, value for each subband) / NOQNT (no quant)*/
+ tccp->qntsty = parameters->irreversible ? J3D_CCP_QNTSTY_SEQNT : J3D_CCP_QNTSTY_NOQNT;
+ tccp->numgbits = 2;
+ if (i == parameters->roi_compno) {
+ tccp->roishift = parameters->roi_shift;
+ } else {
+ tccp->roishift = 0;
+ }
+ /* Custom defined precints */
+ if (parameters->csty & J3D_CCP_CSTY_PRT) {
+ int k;
+ for (k = 0; k < 3; k++) {
+ int p = 0;
+ for (j = tccp->numresolution[k] - 1; j >= 0; j--) {
+ if (p < parameters->res_spec) {/* p < number of precinct size specifications */
+ if (parameters->prct_init[k][p] < 1) {
+ tccp->prctsiz[k][j] = 1;
+ } else {
+ tccp->prctsiz[k][j] = int_floorlog2(parameters->prct_init[k][p]);
+ }
+ } else {
+ int res_spec = parameters->res_spec;
+ int size_prct = parameters->prct_init[k][res_spec - 1] >> (p - (res_spec - 1));
+ if (size_prct < 1) {
+ tccp->prctsiz[k][j] = 1;
+ } else {
+ tccp->prctsiz[k][j] = int_floorlog2(size_prct);
+ }
+ }
+ }
+ p++;
+ }
+ } else {
+ int k;
+ for (k = 0; k < 3; k++) {
+ for (j = 0; j < tccp->numresolution[k]; j++) {
+ tccp->prctsiz[k][j] = 15;
+ }
+ }
+ }
+ //Calcular stepsize for each subband (if NOQNT -->stepsize = 1.0)
+ dwt_calc_explicit_stepsizes(tccp, volume->comps[i].prec);
+ }
+ }
+}
+
+/**
+Create an index file
+@param j3d
+@param cio
+@param volume_info
+@param index Index filename
+@return Returns 1 if successful, returns 0 otherwise
+*/
+static int j3d_create_index(opj_j3d_t *j3d, opj_cio_t *cio, opj_volume_info_t *volume_info, char *index) {
+
+ int tileno, compno, layno, resno, precno, pack_nb, x, y, z;
+ FILE *stream = NULL;
+ double total_disto = 0;
+
+ volume_info->codestream_size = cio_tell(cio) + j3d->pos_correction; /* Correction 14/4/03 suite rmq de Patrick */
+
+ stream = fopen(index, "w");
+ if (!stream) {
+ opj_event_msg(j3d->cinfo, EVT_ERROR, "failed to open %s for writing\n", index);
+ return 0;
+ }
+
+ fprintf(stream, "w %d\t h %d\t l %d\n", volume_info->volume_w, volume_info->volume_h, volume_info->volume_l);
+ fprintf(stream, "TRASNFORM\t%d\n", volume_info->transform_format);
+ fprintf(stream, "ENTROPY CODING\t%d\n", volume_info->encoding_format);
+ fprintf(stream, "PROG\t%d\n", volume_info->prog);
+ fprintf(stream, "TILE\tx %d y %d z %d\n", volume_info->tile_x, volume_info->tile_y, volume_info->tile_z);
+ fprintf(stream, "NOTILE\tx %d y %d z %d\n", volume_info->tw, volume_info->th, volume_info->tl);
+ fprintf(stream, "COMPONENTS\t%d\n", volume_info->comp);
+ fprintf(stream, "LAYER\t%d\n", volume_info->layer);
+ fprintf(stream, "RESOLUTIONS\tx %d y %d z %d\n", volume_info->decomposition[0], volume_info->decomposition[1], volume_info->decomposition[2]);
+
+ fprintf(stream, "Precint sizes for each resolution:\n");
+ for (resno = volume_info->decomposition[0]; resno >= 0; resno--) {
+ fprintf(stream, "Resno %d \t [%d,%d,%d] \n", resno,
+ (1 << volume_info->tile[0].prctsiz[0][resno]), (1 << volume_info->tile[0].prctsiz[0][resno]), (1 << volume_info->tile[0].prctsiz[2][resno])); /* based on tile 0 */
+ }
+ fprintf(stream, "HEADER_END\t%d\n", volume_info->main_head_end);
+ fprintf(stream, "CODESTREAM\t%d\n", volume_info->codestream_size);
+ fprintf(stream, "Num_tile Start_pos End_header End_pos Distotile Nbpix Ratio\n");
+ for (tileno = 0; tileno < (volume_info->tw * volume_info->th * volume_info->tl); tileno++) {
+ fprintf(stream, "%4d\t%9d\t%9d\t%9d\t%9e\t%9d\t%9e\n",
+ volume_info->tile[tileno].num_tile,
+ volume_info->tile[tileno].start_pos,
+ volume_info->tile[tileno].end_header,
+ volume_info->tile[tileno].end_pos,
+ volume_info->tile[tileno].distotile, volume_info->tile[tileno].nbpix,
+ volume_info->tile[tileno].distotile / volume_info->tile[tileno].nbpix);
+ }
+
+ for (tileno = 0; tileno < (volume_info->tw * volume_info->th * volume_info->tl); tileno++) {
+ int start_pos, end_pos;
+ double disto = 0;
+ pack_nb = 0;
+ if (volume_info->prog == LRCP) { /* LRCP */
+ fprintf(stream, "pack_nb tileno layno resno compno precno start_pos end_pos disto\n");
+ for (layno = 0; layno < volume_info->layer; layno++) {
+ for (resno = 0; resno < volume_info->decomposition[0] + 1; resno++) {
+ for (compno = 0; compno < volume_info->comp; compno++) {
+ int prec_max = volume_info->tile[tileno].prctno[0][resno] * volume_info->tile[tileno].prctno[1][resno] * volume_info->tile[tileno].prctno[2][resno];
+ for (precno = 0; precno < prec_max; precno++) {
+ start_pos = volume_info->tile[tileno].packet[pack_nb].start_pos;
+ end_pos = volume_info->tile[tileno].packet[pack_nb].end_pos;
+ disto = volume_info->tile[tileno].packet[pack_nb].disto;
+ fprintf(stream, "%4d %6d %7d %5d %6d %6d %9d %9d %8e\n",pack_nb, tileno, layno, resno, compno, precno, start_pos, end_pos, disto);
+ total_disto += disto;
+ pack_nb++;
+ }
+ }
+ }
+ }
+ } /* LRCP */
+ else if (volume_info->prog == RLCP) { /* RLCP */
+ /*
+ fprintf(stream, "pack_nb tileno resno layno compno precno start_pos end_pos disto");
+ */
+ for (resno = 0; resno < volume_info->decomposition[0] + 1; resno++) {
+ for (layno = 0; layno < volume_info->layer; layno++) {
+ for (compno = 0; compno < volume_info->comp; compno++) {
+ int prec_max = volume_info->tile[tileno].prctno[0][resno] * volume_info->tile[tileno].prctno[1][resno]* volume_info->tile[tileno].prctno[2][resno];
+ for (precno = 0; precno < prec_max; precno++) {
+ start_pos = volume_info->tile[tileno].packet[pack_nb].start_pos;
+ end_pos = volume_info->tile[tileno].packet[pack_nb].end_pos;
+ disto = volume_info->tile[tileno].packet[pack_nb].disto;
+ fprintf(stream, "%4d %6d %5d %7d %6d %6d %9d %9d %8e\n",
+ pack_nb, tileno, resno, layno, compno, precno, start_pos, end_pos, disto);
+ total_disto += disto;
+ pack_nb++;
+ }
+ }
+ }
+ }
+ } /* RLCP */
+ else if (volume_info->prog == RPCL) { /* RPCL */
+ /*
+ fprintf(stream, "\npack_nb tileno resno precno compno layno start_pos end_pos disto\n");
+ */
+ for (resno = 0; resno < volume_info->decomposition[0] + 1; resno++) {
+ /* I suppose components have same XRsiz, YRsiz */
+ //int x0 = volume_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tw * volume_info->tile_x;
+ //int y0 = volume_info->tile_Ox + (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tile_y;
+ int x0 = volume_info->tile_Ox + (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tile_x;
+ int y0 = volume_info->tile_Oy + (int)floor( (float)tileno/(float)volume_info->th ) * volume_info->tile_y;
+ int z0 = volume_info->tile_Ox + (int)floor( (float)tileno/(float)volume_info->tl ) * volume_info->tile_z;
+ int x1 = x0 + volume_info->tile_x;
+ int y1 = y0 + volume_info->tile_y;
+ int z1 = z0 + volume_info->tile_z;
+ for(z = z0; z < z1; z++) {
+ for(y = y0; y < y1; y++) {
+ for(x = x0; x < x1; x++) {
+ for (compno = 0; compno < volume_info->comp; compno++) {
+ int prec_max = volume_info->tile[tileno].prctno[0][resno] * volume_info->tile[tileno].prctno[1][resno] * volume_info->tile[tileno].prctno[2][resno];
+ for (precno = 0; precno < prec_max; precno++) {
+ int pcnx = volume_info->tile[tileno].prctno[0][resno];
+ int pcx = (int) pow( 2, volume_info->tile[tileno].prctsiz[0][resno] + volume_info->decomposition[0] - resno );
+ int pcy = (int) pow( 2, volume_info->tile[tileno].prctsiz[1][resno] + volume_info->decomposition[1] - resno );
+ int pcz = (int) pow( 2, volume_info->tile[tileno].prctsiz[2][resno] + volume_info->decomposition[2] - resno );
+ int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
+ int precno_y = (int) floor( (float)precno/(float)pcnx );
+ if (precno_y*pcy == y ) {
+ if (precno_x*pcx == x ) {
+ for (layno = 0; layno < volume_info->layer; layno++) {
+ start_pos = volume_info->tile[tileno].packet[pack_nb].start_pos;
+ end_pos = volume_info->tile[tileno].packet[pack_nb].end_pos;
+ disto = volume_info->tile[tileno].packet[pack_nb].disto;
+ fprintf(stream, "%4d %6d %5d %6d %6d %7d %9d %9d %8e\n",
+ pack_nb, tileno, resno, precno, compno, layno, start_pos, end_pos, disto);
+ total_disto += disto;
+ pack_nb++;
+ }
+ }
+ }
+ } /* precno */
+ } /* compno */
+ } /* x = x0..x1 */
+ } /* y = y0..y1 */
+ } /* z = z0..z1 */
+ } /* resno */
+ } /* RPCL */
+ else if (volume_info->prog == PCRL) { /* PCRL */
+ /* I suppose components have same XRsiz, YRsiz */
+ int x0 = volume_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tw * volume_info->tile_x;
+ int y0 = volume_info->tile_Ox + (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tile_y;
+ int z0 = volume_info->tile_Oz + (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tile_z;
+ int x1 = x0 + volume_info->tile_x;
+ int y1 = y0 + volume_info->tile_y;
+ int z1 = z0 + volume_info->tile_z;
+ /*
+ fprintf(stream, "\npack_nb tileno precno compno resno layno start_pos end_pos disto\n");
+ */
+ for(z = z0; z < z1; z++) {
+ for(y = y0; y < y1; y++) {
+ for(x = x0; x < x1; x++) {
+ for (compno = 0; compno < volume_info->comp; compno++) {
+ for (resno = 0; resno < volume_info->decomposition[0] + 1; resno++) {
+ int prec_max = volume_info->tile[tileno].prctno[0][resno] * volume_info->tile[tileno].prctno[1][resno];
+ for (precno = 0; precno < prec_max; precno++) {
+ int pcnx = volume_info->tile[tileno].prctno[0][resno];
+ int pcx = (int) pow( 2, volume_info->tile[tileno].prctsiz[0][resno] + volume_info->decomposition[0] - resno );
+ int pcy = (int) pow( 2, volume_info->tile[tileno].prctsiz[1][resno] + volume_info->decomposition[1] - resno );
+ int pcz = (int) pow( 2, volume_info->tile[tileno].prctsiz[2][resno] + volume_info->decomposition[2] - resno );
+ int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
+ int precno_y = (int) floor( (float)precno/(float)pcnx );
+ int precno_z = (int) floor( (float)precno/(float)pcnx );
+ if (precno_z*pcz == z ) {
+ if (precno_y*pcy == y ) {
+ if (precno_x*pcx == x ) {
+ for (layno = 0; layno < volume_info->layer; layno++) {
+ start_pos = volume_info->tile[tileno].packet[pack_nb].start_pos;
+ end_pos = volume_info->tile[tileno].packet[pack_nb].end_pos;
+ disto = volume_info->tile[tileno].packet[pack_nb].disto;
+ fprintf(stream, "%4d %6d %6d %6d %5d %7d %9d %9d %8e\n",
+ pack_nb, tileno, precno, compno, resno, layno, start_pos, end_pos, disto);
+ total_disto += disto;
+ pack_nb++;
+ }
+ }
+ }
+ }
+ } /* precno */
+ } /* resno */
+ } /* compno */
+ } /* x = x0..x1 */
+ } /* y = y0..y1 */
+ }
+ } /* PCRL */
+ else { /* CPRL */
+ /*
+ fprintf(stream, "\npack_nb tileno compno precno resno layno start_pos end_pos disto\n");
+ */
+ for (compno = 0; compno < volume_info->comp; compno++) {
+ /* I suppose components have same XRsiz, YRsiz */
+ int x0 = volume_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tw * volume_info->tile_x;
+ int y0 = volume_info->tile_Ox + (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tile_y;
+ int z0 = volume_info->tile_Oz + (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tile_z;
+ int x1 = x0 + volume_info->tile_x;
+ int y1 = y0 + volume_info->tile_y;
+ int z1 = z0 + volume_info->tile_z;
+ for(z = z0; z < z1; z++) {
+ for(y = y0; y < y1; y++) {
+ for(x = x0; x < x1; x++) {
+ for (resno = 0; resno < volume_info->decomposition[0] + 1; resno++) {
+ int prec_max = volume_info->tile[tileno].prctno[0][resno] * volume_info->tile[tileno].prctno[1][resno] * volume_info->tile[tileno].prctno[2][resno];
+ for (precno = 0; precno < prec_max; precno++) {
+ int pcnx = volume_info->tile[tileno].prctno[0][resno];
+ int pcny = volume_info->tile[tileno].prctno[1][resno];
+ int pcx = (int) pow( 2, volume_info->tile[tileno].prctsiz[0][resno] + volume_info->decomposition[0] - resno );
+ int pcy = (int) pow( 2, volume_info->tile[tileno].prctsiz[1][resno] + volume_info->decomposition[1] - resno );
+ int pcz = (int) pow( 2, volume_info->tile[tileno].prctsiz[2][resno] + volume_info->decomposition[2] - resno );
+ int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
+ int precno_y = (int) floor( (float)precno/(float)pcnx );
+ int precno_z = 0; /*???*/
+ if (precno_z*pcz == z ) {
+ if (precno_y*pcy == y ) {
+ if (precno_x*pcx == x ) {
+ for (layno = 0; layno < volume_info->layer; layno++) {
+ start_pos = volume_info->tile[tileno].packet[pack_nb].start_pos;
+ end_pos = volume_info->tile[tileno].packet[pack_nb].end_pos;
+ disto = volume_info->tile[tileno].packet[pack_nb].disto;
+ fprintf(stream, "%4d %6d %6d %6d %5d %7d %9d %9d %8e\n",
+ pack_nb, tileno, compno, precno, resno, layno, start_pos, end_pos, disto);
+ total_disto += disto;
+ pack_nb++;
+ }
+ }
+ }
+ }
+ } /* precno */
+ } /* resno */
+ } /* x = x0..x1 */
+ } /* y = y0..y1 */
+ } /* z = z0..z1 */
+ } /* comno */
+ } /* CPRL */
+ } /* tileno */
+
+ fprintf(stream, "SE_MAX\t%8e\n", volume_info->D_max); /* SE max */
+ fprintf(stream, "SE_TOTAL\t%.8e\n", total_disto); /* SE totale */
+
+
+ fclose(stream);
+
+ return 1;
+}
+
+bool j3d_encode(opj_j3d_t *j3d, opj_cio_t *cio, opj_volume_t *volume, char *index) {
+ int tileno, compno;
+ opj_volume_info_t *volume_info = NULL;
+ opj_cp_t *cp = NULL;
+ opj_tcd_t *tcd = NULL; /* TCD component */
+
+ j3d->cio = cio;
+ j3d->volume = volume;
+ cp = j3d->cp;
+
+ /*j3d_dump_volume(stdout, volume);
+ j3d_dump_cp(stdout, volume, cp);*/
+
+ /* INDEX >> */
+ volume_info = j3d->volume_info;
+ if (volume_info && cp->index_on) {
+ volume_info->index_on = cp->index_on;
+ volume_info->tile = (opj_tile_info_t *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(opj_tile_info_t));
+ volume_info->volume_w = volume->x1 - volume->x0;
+ volume_info->volume_h = volume->y1 - volume->y0;
+ volume_info->volume_l = volume->z1 - volume->z0;
+ volume_info->prog = (&cp->tcps[0])->prg;
+ volume_info->tw = cp->tw;
+ volume_info->th = cp->th;
+ volume_info->tl = cp->tl;
+ volume_info->tile_x = cp->tdx; /* new version parser */
+ volume_info->tile_y = cp->tdy; /* new version parser */
+ volume_info->tile_z = cp->tdz; /* new version parser */
+ volume_info->tile_Ox = cp->tx0; /* new version parser */
+ volume_info->tile_Oy = cp->ty0; /* new version parser */
+ volume_info->tile_Oz = cp->tz0; /* new version parser */
+ volume_info->transform_format = cp->transform_format;
+ volume_info->encoding_format = cp->encoding_format;
+ volume_info->comp = volume->numcomps;
+ volume_info->layer = (&cp->tcps[0])->numlayers;
+ volume_info->decomposition[0] = (&cp->tcps[0])->tccps->numresolution[0] - 1;
+ volume_info->decomposition[1] = (&cp->tcps[0])->tccps->numresolution[1] - 1;
+ volume_info->decomposition[2] = (&cp->tcps[0])->tccps->numresolution[2] - 1;
+ volume_info->D_max = 0; /* ADD Marcela */
+ }
+ /* << INDEX */
+
+ j3d_write_soc(j3d);
+ j3d_write_siz(j3d);
+ if (j3d->cinfo->codec_format == CODEC_J3D) {
+ j3d_write_cap(j3d);
+ j3d_write_zsi(j3d);
+ }
+ j3d_write_cod(j3d);
+ j3d_write_qcd(j3d);
+ for (compno = 0; compno < volume->numcomps; compno++) {
+ opj_tcp_t *tcp = &cp->tcps[0];
+ if (tcp->tccps[compno].roishift)
+ j3d_write_rgn(j3d, compno, 0);
+ }
+ /*Optional 15444-2 markers*/
+ if (j3d->cp->tcps->tccps[0].atk != NULL)
+ j3d_write_atk(j3d);
+ if (j3d->volume->comps[0].dcoffset != 0)
+ j3d_write_dco(j3d);
+
+ if (j3d->cp->transform_format != TRF_2D_DWT || j3d->cp->encoding_format != ENCOD_2EB)
+ j3d_write_com(j3d);
+
+ /* INDEX >> */
+ if(volume_info && volume_info->index_on) {
+ volume_info->main_head_end = cio_tell(cio) - 1;
+ }
+ /* << INDEX */
+
+ /* create the tile encoder */
+ tcd = tcd_create(j3d->cinfo);
+
+ /* encode each tile */
+ for (tileno = 0; tileno < cp->tw * cp->th * cp->tl; tileno++) {
+ opj_event_msg(j3d->cinfo, EVT_INFO, "tile number %d / %d\n", tileno + 1, cp->tw * cp->th * cp->tl);
+
+ j3d->curtileno = tileno;
+
+ /* initialisation before tile encoding */
+ if (tileno == 0) {
+ tcd_malloc_encode(tcd, volume, cp, j3d->curtileno);
+ } else {
+ tcd_init_encode(tcd, volume, cp, j3d->curtileno);
+ }
+
+ /* INDEX >> */
+ if(volume_info && volume_info->index_on) {
+ volume_info->tile[j3d->curtileno].num_tile = j3d->curtileno;
+ volume_info->tile[j3d->curtileno].start_pos = cio_tell(cio) + j3d->pos_correction;
+ }
+ /* << INDEX */
+
+ j3d_write_sot(j3d);
+
+ for (compno = 1; compno < volume->numcomps; compno++) {
+ j3d_write_coc(j3d, compno);
+ j3d_write_qcc(j3d, compno);
+ }
+
+ if (cp->tcps[tileno].numpocs) {
+ j3d_write_poc(j3d);
+ }
+ j3d_write_sod(j3d, tcd); //--> tcd_encode_tile
+
+ /* INDEX >> */
+ if(volume_info && volume_info->index_on) {
+ volume_info->tile[j3d->curtileno].end_pos = cio_tell(cio) + j3d->pos_correction - 1;
+ }
+ /* << INDEX */
+ }
+
+ /* destroy the tile encoder */
+ tcd_free_encode(tcd);
+ tcd_destroy(tcd);
+
+ j3d_write_eoc(j3d);
+
+ /* Creation of the index file */
+ if(volume_info && volume_info->index_on) {
+ if(!j3d_create_index(j3d, cio, volume_info, index)) {
+ opj_event_msg(j3d->cinfo, EVT_ERROR, "failed to create index file %s\n", index);
+ return false;
+ }
+ }
+
+ return true;
+}
+
diff --git a/libopenjpeg3d/jp3d.h b/libopenjpeg3d/jp3d.h
new file mode 100755
index 00000000..5d0978c0
--- /dev/null
+++ b/libopenjpeg3d/jp3d.h
@@ -0,0 +1,518 @@
+/*
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * Copyright (c) 2006, Mónica Díez García, Image Processing Laboratory, University of Valladolid, Spain
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef __J3D_H
+#define __J3D_H
+/**
+@file j3d.h
+@brief The JPEG-2000 Codestream Reader/Writer (J3D)
+
+The functions in J3D.C have for goal to read/write the several parts of the codestream: markers and data.
+*/
+
+/** @defgroup J3D J3D - JPEG-2000 codestream reader/writer */
+/*@{*/
+
+#define J3D_CP_CSTY_PRT 0x01
+#define J3D_CP_CSTY_SOP 0x02
+#define J3D_CP_CSTY_EPH 0x04
+#define J3D_CCP_CSTY_PRT 0x01
+/** Table A-8 */
+#define J3D_CCP_CBLKSTY_LAZY 0x01 /* Selective arithmetic coding bypass */
+#define J3D_CCP_CBLKSTY_RESET 0x02 /* Reset context probabilities on coding pass boundaries */
+#define J3D_CCP_CBLKSTY_TERMALL 0x04 /* Termination on each coding pass */
+#define J3D_CCP_CBLKSTY_VSC 0x08 /* Vertically causal context, add also hook for switching off and on 3D context models */
+#define J3D_CCP_CBLKSTY_PTERM 0x10 /* Predictable termination */
+#define J3D_CCP_CBLKSTY_SEGSYM 0x20 /* Segmentation symbols are used */
+#define J3D_CCP_CBLKSTY_3DCTXT 0x40 /* 3D context models (3D-EBCOT) vs 2D context models */
+
+#define J3D_CCP_QNTSTY_NOQNT 0 /* Quantization style : no quantization */
+#define J3D_CCP_QNTSTY_SIQNT 1 /* Quantization style : scalar derived (values signalled only in LLL subband) */
+#define J3D_CCP_QNTSTY_SEQNT 2 /* Quantization style : scalar expounded (values signalled for each subband) */
+
+/* ----------------------------------------------------------------------- */
+
+#define J3D_MS_SOC 0xff4f /**< SOC marker value */
+#define J3D_MS_SOT 0xff90 /**< SOT marker value */
+#define J3D_MS_SOD 0xff93 /**< SOD marker value */
+#define J3D_MS_EOC 0xffd9 /**< EOC marker value */
+#define J3D_MS_CAP 0xff50 /**< CAP marker value */
+#define J3D_MS_SIZ 0xff51 /**< SIZ marker value */
+#define J3D_MS_ZSI 0xff54 /**< ZSI marker value */
+#define J3D_MS_COD 0xff52 /**< COD marker value */
+#define J3D_MS_COC 0xff53 /**< COC marker value */
+#define J3D_MS_RGN 0xff5e /**< RGN marker value */
+#define J3D_MS_QCD 0xff5c /**< QCD marker value */
+#define J3D_MS_QCC 0xff5d /**< QCC marker value */
+#define J3D_MS_POC 0xff5f /**< POC marker value */
+#define J3D_MS_TLM 0xff55 /**< TLM marker value */
+#define J3D_MS_PLM 0xff57 /**< PLM marker value */
+#define J3D_MS_PLT 0xff58 /**< PLT marker value */
+#define J3D_MS_PPM 0xff60 /**< PPM marker value */
+#define J3D_MS_PPT 0xff61 /**< PPT marker value */
+#define J3D_MS_SOP 0xff91 /**< SOP marker value */
+#define J3D_MS_EPH 0xff92 /**< EPH marker value */
+#define J3D_MS_CRG 0xff63 /**< CRG marker value */
+#define J3D_MS_COM 0xff64 /**< COM marker value */
+//15444-2
+#define J3D_MS_DCO 0xff70 /**< DCO marker value */
+#define J3D_MS_VMS 0xff71 /**< VMS marker value */
+#define J3D_MS_DFS 0xff72 /**< DFS marker value */
+#define J3D_MS_ADS 0xff73 /**< ADS marker value */
+#define J3D_MS_ATK 0xff79 /**< ATK marker value */
+#define J3D_MS_CBD 0xff78 /**< CBD marker value */
+#define J3D_MS_MCT 0xff74 /**< MCT marker value */
+#define J3D_MS_MCC 0xff75 /**< MCC marker value */
+#define J3D_MS_MCO 0xff77 /**< MCO marker value */
+#define J3D_MS_NLT 0xff76 /**< NLT marker value */
+#define J3D_MS_QPD 0xff5a /**< QPD marker value */
+#define J3D_MS_QPC 0xff5b /**< QPC marker value */
+
+/* ----------------------------------------------------------------------- */
+/* Capability RSIZ parameter, extended */
+#define J3D_RSIZ_BASIC 0x0000
+
+#define J3D_RSIZ_DCO 0x8001 /* Required */
+#define J3D_RSIZ_VSQNT 0x8002
+#define J3D_RSIZ_TCQNT 0x8004
+#define J3D_RSIZ_VMASK 0x8008
+#define J3D_RSIZ_SSOVL 0x8010
+#define J3D_RSIZ_ADECS 0x8020
+#define J3D_RSIZ_ATK 0x8040 /*Required*/
+#define J3D_RSIZ_SSYMK 0x8080
+#define J3D_RSIZ_MCT 0x8100 /*Not compatible with DCO*/
+#define J3D_RSIZ_NLT 0x8200 /*Required*/
+#define J3D_RSIZ_ASHAP 0x8400
+#define J3D_RSIZ_PRQNT 0x8800
+
+#define J3D_CAP_10 0x00400000
+/* Arbitrary transformation kernel, 15444-2 */
+#define J3D_ATK_IRR 0
+#define J3D_ATK_REV 1
+#define J3D_ATK_ARB 0
+#define J3D_ATK_WS 1
+#define J3D_ATK_CON 0
+/* ----------------------------------------------------------------------- */
+
+/**
+Values that specify the status of the decoding process when decoding the main header.
+These values may be combined with a | operator.
+*/
+typedef enum J3D_STATUS {
+ /**< a SOC marker is expected */
+ J3D_STATE_MHSOC = 0x0001,
+ /**< a SIZ marker is expected */
+ J3D_STATE_MHSIZ = 0x0002,
+ /**< the decoding process is in the main header */
+ J3D_STATE_MH = 0x0004,
+ /**< the decoding process is in a tile part header and expects a SOT marker */
+ J3D_STATE_TPHSOT = 0x0008,
+ /**< the decoding process is in a tile part header */
+ J3D_STATE_TPH = 0x0010,
+ /**< the EOC marker has just been read */
+ J3D_STATE_MT = 0x0020,
+ /**< the decoding process must not expect a EOC marker because the codestream is truncated */
+ J3D_STATE_NEOC = 0x0040
+} J3D_STATUS;
+
+
+
+/**
+Arbitrary transformation kernel
+*/
+typedef struct opj_atk {
+/** index of wavelet kernel */
+ int index;
+/** Numerical type of scaling factor and lifting step parameters */
+ int coeff_typ;
+/** Wavelet filter category */
+ int filt_cat;
+/** Wavelet transformation type (REV/IRR) */
+ int wt_typ;
+/** Initial odd/even subsequence */
+ int minit;
+/** Boundary extension method (constant CON / whole-sample symmetric WS) */
+ int exten;
+/** Scaling factor. Only for wt_typ=IRR */
+ double Katk;
+/** Number of lifting steps */
+ int Natk;
+/** Offset for lifting step s. Only for filt_cat=ARB */
+ int Oatk[256];
+/** Base 2 scaling exponent for lifting step s. Only for wt_typ=REV */
+ int Eatk[256];
+/** Additive residue for lifting step s. Only for wt_typ=REV */
+ int Batk[256];
+/** Number of lifting coefficients signaled for lifting step s */
+ int LCatk[256];
+/** Lifting coefficient k for lifting step s */
+ double Aatk[256][256];
+} opj_atk_t;
+
+
+/**
+Quantization stepsize
+*/
+typedef struct opj_stepsize {
+/** exponent */
+ int expn;
+/** mantissa */
+ int mant;
+} opj_stepsize_t;
+
+/**
+Tile-component coding parameters
+*/
+typedef struct opj_tccp {
+ /** coding style */
+ int csty;
+ /** number of resolutions of x, y and z-axis */
+ int numresolution[3];
+ /** code-blocks width height & depth*/
+ int cblk[3];
+ /** code-block coding style */
+ int cblksty;
+ /** 0: no ATK (only 9-7 or 5-3) 1: ATK defined WT*/
+ int atk_wt[3];
+ /** Arbitrary transformation kernel (15444-2)*/
+ opj_atk_t *atk;
+ /** DWT identifier for x, y and z-axis (0:WT9-7 1:WT5-3 >1:WT-atk->index) */
+ int dwtid[3];
+ /** reversible/irreversible wavelet transfomation (0:irrev 1:reversible)*/
+ int reversible;
+ /** quantisation style */
+ int qntsty;
+ /** stepsizes used for quantization */
+ opj_stepsize_t stepsizes[J3D_MAXBANDS];
+ /** number of guard bits. Table A28 de 15444-1*/
+ int numgbits;
+ /** Region Of Interest shift */
+ int roishift;
+ /** precinct width heigth & depth*/
+ int prctsiz[3][J3D_MAXRLVLS];
+} opj_tccp_t;
+
+/**
+Tile coding parameters : coding/decoding parameters common to all tiles
+(information like COD, COC in main header)
+*/
+typedef struct opj_tcp {
+/** 1 : first part-tile of a tile */
+ int first;
+ /** coding style */
+ int csty;
+ /** progression order */
+ OPJ_PROG_ORDER prg;
+ /** number of layers */
+ int numlayers;
+ /** multi-component transform identifier */
+ int mct;
+ /** rates of layers */
+ float rates[100];
+ /** number of progression order changes */
+ int numpocs;
+ /** indicates if a POC marker has been used O:NO, 1:YES */
+ int POC;
+ /** progression order changes */
+ opj_poc_t pocs[J3D_MAXRLVLS - 1];
+ /** add fixed_quality */
+ float distoratio[100];
+ /** tile-component coding parameters */
+ opj_tccp_t *tccps;
+/** packet header store there for futur use in t2_decode_packet */
+ unsigned char *ppt_data;
+ /** pointer remaining on the first byte of the first header if ppt is used */
+ unsigned char *ppt_data_first;
+ /** If ppt == 1 --> there was a PPT marker for the present tile */
+ int ppt;
+ /** used in case of multiple marker PPT (number of info already stored) */
+ int ppt_store;
+ int ppt_len;
+} opj_tcp_t;
+
+/**
+Coding parameters
+*/
+typedef struct opj_cp {
+/** transform format 0: 2DWT, 1: 2D1P, 2: 3DWT, 3: 3RLS */
+ OPJ_TRANSFORM transform_format;
+ /** entropy coding format 0: 2EB, 1: 3EB, 2: 2GR, 3: 3GR, 4: GRI*/
+ OPJ_ENTROPY_CODING encoding_format;
+ /** allocation by rate/distortion */
+ int disto_alloc;
+ /** allocation by fixed layer */
+ int fixed_alloc;
+ /** add fixed_quality */
+ int fixed_quality;
+ /** Rsiz: capabilities */
+ int rsiz;
+ /** if != 0, then original dimension divided by 2^(reduce); if == 0 or not used, volume is decoded to the full resolution */
+ int reduce[3];
+ /** if != 0, then only the first "layer" layers are decoded; if == 0 or not used, all the quality layers are decoded */
+ int layer;
+ /** 0 = no index || 1 = index */
+ int index_on;
+ /** Big-Endian/Little-endian order */
+ int bigendian;
+ /** XTOsiz */
+ int tx0;
+ /** YTOsiz */
+ int ty0;
+ /** ZTOsiz */
+ int tz0;
+ /** XTsiz */
+ int tdx;
+ /** YTsiz */
+ int tdy;
+ /** ZTsiz */
+ int tdz;
+ /** comment for coding */
+ char *comment;
+ /** number of tiles in width, heigth and depth */
+ int tw;
+ int th;
+ int tl;
+ /** ID number of the tiles present in the codestream */
+ int *tileno;
+ /** size of the vector tileno */
+ int tileno_size;
+ /** tile coding parameters */
+ opj_tcp_t *tcps;
+ /** fixed layer */
+ int *matrice;
+
+ /** packet header store there for futur use in t2_decode_packet */
+ unsigned char *ppm_data;
+ /** pointer remaining on the first byte of the first header if ppm is used */
+ unsigned char *ppm_data_first;
+ /** if ppm == 1 --> there was a PPM marker for the present tile */
+ int ppm;
+ /** use in case of multiple marker PPM (number of info already store) */
+ int ppm_store;
+ /** use in case of multiple marker PPM (case on non-finished previous info) */
+ int ppm_previous;
+ int ppm_len;
+} opj_cp_t;
+
+/**
+Information concerning a packet inside tile
+*/
+typedef struct opj_packet_info {
+ /** start position */
+ int start_pos;
+ /** end position */
+ int end_pos;
+ /** distorsion introduced */
+ double disto;
+} opj_packet_info_t;
+
+/**
+Index structure : information regarding tiles inside volume
+*/
+typedef struct opj_tile_info {
+ /** value of thresh for each layer by tile cfr. Marcela */
+ double *thresh;
+ /** number of tile */
+ int num_tile;
+ /** start position */
+ int start_pos;
+ /** end position of the header */
+ int end_header;
+ /** end position */
+ int end_pos;
+ /** precinct number for each resolution level (width, heigth and depth) */
+ int prctno[3][J3D_MAXRLVLS];
+ /** precinct size (in power of 2), in X for each resolution level */
+ int prctsiz[3][J3D_MAXRLVLS];
+ /** information concerning packets inside tile */
+ opj_packet_info_t *packet;
+
+ /** add fixed_quality */
+ int nbpix;
+ /** add fixed_quality */
+ double distotile;
+} opj_tile_info_t;
+
+/**
+Index structure
+*/
+typedef struct opj_volume_info {
+
+ /** transform format 0: 2DWT, 1: 2D1P, 2: 3DWT, 3: 3RLS */
+ OPJ_TRANSFORM transform_format;
+ /** output file format 0: 2EB, 1: 3EB, 2: 2GR, 3: 3GR, 4: GRI*/
+ OPJ_ENTROPY_CODING encoding_format; /** 0 = no index || 1 = index */
+ int index_on;
+ /** 0 = wt 9-7 || 1 = wt 5-3 || >=2 wt atk defined */
+ int dwtid[3];
+ /** maximum distortion reduction on the whole volume (add for Marcela) */
+ double D_max;
+ /** packet number */
+ int num;
+ /** writing the packet in the index with t2_encode_packets */
+ int index_write;
+ /** volume width, height and depth */
+ int volume_w;
+ int volume_h;
+ int volume_l;
+ /** progression order */
+ OPJ_PROG_ORDER prog;
+ /** tile size in x, y and z */
+ int tile_x;
+ int tile_y;
+ int tile_z;
+ /** tile origin in x, y and z */
+ int tile_Ox;
+ int tile_Oy;
+ int tile_Oz;
+ /** number of tiles in X, Y and Z */
+ int tw;
+ int th;
+ int tl;
+ /** component numbers */
+ int comp;
+ /** number of layer */
+ int layer;
+ /** number of decomposition in X, Y and Z*/
+ int decomposition[3];
+ /** DC offset (15444-2) */
+ int dcoffset;
+ /** main header position */
+ int main_head_end;
+ /** codestream's size */
+ int codestream_size;
+ /** information regarding tiles inside volume */
+ opj_tile_info_t *tile;
+} opj_volume_info_t;
+
+/**
+JPEG-2000 codestream reader/writer
+*/
+typedef struct opj_j3d {
+ /** codec context */
+ opj_common_ptr cinfo;
+ /** locate in which part of the codestream the decoder is (main header, tile header, end) */
+ int state;
+ /** number of the tile curently concern by coding/decoding */
+ int curtileno;
+ /** locate the position of the end of the tile in the codestream, used to detect a truncated codestream (in j3d_read_sod) */
+ unsigned char *eot;
+ /** locate the start position of the SOT marker of the current coded tile: */
+ int sot_start;
+ /* after encoding the tile, a jump (in j3d_write_sod) is done to the SOT marker to store the value of its length. */
+ int sod_start;
+ /** as the J3D-file is written in several parts during encoding, it enables to make the right correction in position return by cio_tell */
+ int pos_correction;
+ /** array used to store the data of each tile */
+ unsigned char **tile_data;
+ /** array used to store the length of each tile */
+ int *tile_len;
+
+ /** decompression only : store decoding parameters common to all tiles */
+ opj_tcp_t *default_tcp;
+ /** pointer to the encoded / decoded volume */
+ opj_volume_t *volume;
+ /** pointer to the coding parameters */
+ opj_cp_t *cp;
+ /** helper used to write the index file */
+ opj_volume_info_t *volume_info;
+ /** pointer to the byte i/o stream */
+ opj_cio_t *cio;
+} opj_j3d_t;
+
+/** @name Funciones generales */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+/**
+Creates a J3D decompression structure
+@param cinfo Codec context info
+@return Returns a handle to a J3D decompressor if successful, returns NULL otherwise
+*/
+opj_j3d_t* j3d_create_decompress(opj_common_ptr cinfo);
+/**
+Destroy a J3D decompressor handle
+@param j3d J3D decompressor handle to destroy
+*/
+void j3d_destroy_decompress(opj_j3d_t *j3d);
+/**
+Setup the decoder decoding parameters using user parameters.
+Decoding parameters are returned in j3d->cp.
+@param j3d J3D decompressor handle
+@param parameters decompression parameters
+*/
+void j3d_setup_decoder(opj_j3d_t *j3d, opj_dparameters_t *parameters);
+/**
+Decode an volume from a JPEG-2000 codestream
+@param j3d J3D decompressor handle
+@param cio Input buffer stream
+@return Returns a decoded volume if successful, returns NULL otherwise
+*/
+opj_volume_t* j3d_decode(opj_j3d_t *j3d, opj_cio_t *cio);
+/**
+Decode an volume form a JPT-stream (JPEG 2000, JPIP)
+@param j3d J3D decompressor handle
+@param cio Input buffer stream
+@return Returns a decoded volume if successful, returns NULL otherwise
+*/
+opj_volume_t* j3d_decode_jpt_stream(opj_j3d_t *j3d, opj_cio_t *cio);
+/**
+Creates a J3D compression structure
+@param cinfo Codec context info
+@return Returns a handle to a J3D compressor if successful, returns NULL otherwise
+*/
+opj_j3d_t* j3d_create_compress(opj_common_ptr cinfo);
+/**
+Destroy a J3D compressor handle
+@param j3d J3D compressor handle to destroy
+*/
+void j3d_destroy_compress(opj_j3d_t *j3d);
+/**
+Setup the encoder parameters using the current volume and using user parameters.
+Coding parameters are returned in j3d->cp.
+@param j3d J3D compressor handle
+@param parameters compression parameters
+@param volume input filled volume
+*/
+void j3d_setup_encoder(opj_j3d_t *j3d, opj_cparameters_t *parameters, opj_volume_t *volume);
+/**
+Encode an volume into a JPEG-2000 codestream
+@param j3d J3D compressor handle
+@param cio Output buffer stream
+@param volume Volume to encode
+@param index Name of the index file if required, NULL otherwise
+@return Returns true if successful, returns false otherwise
+*/
+bool j3d_encode(opj_j3d_t *j3d, opj_cio_t *cio, opj_volume_t *volume, char *index);
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+#endif /* __J3D_H */
diff --git a/libopenjpeg3d/jp3d_lib.c b/libopenjpeg3d/jp3d_lib.c
new file mode 100755
index 00000000..4445e859
--- /dev/null
+++ b/libopenjpeg3d/jp3d_lib.c
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/times.h>
+#endif /* _WIN32 */
+#include "opj_includes.h"
+
+double opj_clock() {
+#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 ( t.QuadPart /(double) freq.QuadPart ) ;
+#else
+ /* Unix or Linux: use resource usage */
+ struct rusage t;
+ double 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 = t.ru_utime.tv_sec + t.ru_stime.tv_sec;
+ /* (2b) More precisely! Get the microseconds part ! */
+ return ( procTime + (t.ru_utime.tv_usec + t.ru_stime.tv_usec) * 1e-6 ) ;
+#endif /* _WIN32 */
+}
+
+void* opj_malloc( size_t size ) {
+ void *memblock = malloc(size);
+ if(memblock) {
+ memset(memblock, 0, size);
+ }
+ return memblock;
+}
+
+void* opj_realloc( void *memblock, size_t size ) {
+ return realloc(memblock, size);
+}
+
+void opj_free( void *memblock ) {
+ free(memblock);
+}
+
+
diff --git a/libopenjpeg3d/jp3d_lib.h b/libopenjpeg3d/jp3d_lib.h
new file mode 100755
index 00000000..a2fb05ba
--- /dev/null
+++ b/libopenjpeg3d/jp3d_lib.h
@@ -0,0 +1,75 @@
+/*
+ * 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 __J3D_LIB_H
+#define __J3D_LIB_H
+/**
+@file jp3d_lib.h
+@brief Internal functions
+
+The functions in JP3D_LIB.C are internal utilities mainly used for memory management.
+*/
+
+/** @defgroup MISC MISC - Miscellaneous internal functions */
+/*@{*/
+
+/** @name Funciones generales */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+
+/**
+Difference in successive opj_clock() calls tells you the elapsed time
+@return Returns time in seconds
+*/
+double opj_clock();
+
+/**
+Allocate a memory block with elements initialized to 0
+@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 );
+
+/**
+Reallocate memory blocks.
+@param memblock Pointer to previously allocated memory block
+@param size New size in bytes
+@return Returns a void pointer to the reallocated (and possibly moved) memory block
+*/
+void* opj_realloc( void *memblock, size_t size );
+
+/**
+Deallocates or frees a memory block.
+@param memblock Previously allocated memory block to be freed
+*/
+void opj_free( void *memblock );
+
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+#endif /* __J3D_LIB_H */
+
diff --git a/libopenjpeg3d/mct.c b/libopenjpeg3d/mct.c
new file mode 100755
index 00000000..e915e390
--- /dev/null
+++ b/libopenjpeg3d/mct.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * 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"
+
+/* <summary> */
+/* This table contains the norms of the basis function of the reversible MCT. */
+/* </summary> */
+static const double mct_norms[3] = { 1.732, .8292, .8292 };
+
+/* <summary> */
+/* This table contains the norms of the basis function of the irreversible MCT. */
+/* </summary> */
+static const double mct_norms_real[3] = { 1.732, 1.805, 1.573 };
+
+/* <summary> */
+/* Foward reversible MCT. */
+/* </summary> */
+void mct_encode(int *c0, int *c1, int *c2, int n) {
+ int i;
+ for (i = 0; i < n; i++) {
+ int r, g, b, y, u, v;
+ r = c0[i];
+ g = c1[i];
+ b = c2[i];
+ y = (r + (g << 1) + b) >> 2;
+ u = b - g;
+ v = r - g;
+ c0[i] = y;
+ c1[i] = u;
+ c2[i] = v;
+ }
+}
+
+/* <summary> */
+/* Inverse reversible MCT. */
+/* </summary> */
+void mct_decode(int *c0, int *c1, int *c2, int n) {
+ int i;
+ for (i = 0; i < n; i++) {
+ int y, u, v, r, g, b;
+ y = c0[i];
+ u = c1[i];
+ v = c2[i];
+ g = y - ((u + v) >> 2);
+ r = v + g;
+ b = u + g;
+ c0[i] = r;
+ c1[i] = g;
+ c2[i] = b;
+ }
+}
+
+/* <summary> */
+/* Get norm of basis function of reversible MCT. */
+/* </summary> */
+double mct_getnorm(int compno) {
+ return mct_norms[compno];
+}
+
+/* <summary> */
+/* Foward irreversible MCT. */
+/* </summary> */
+void mct_encode_real(int *c0, int *c1, int *c2, int n) {
+ int i;
+ for (i = 0; i < n; i++) {
+ int r, g, b, y, u, v;
+ r = c0[i];
+ g = c1[i];
+ b = c2[i];
+ y = fix_mul(r, 2449) + fix_mul(g, 4809) + fix_mul(b, 934);
+ u = -fix_mul(r, 1382) - fix_mul(g, 2714) + fix_mul(b, 4096);
+ v = fix_mul(r, 4096) - fix_mul(g, 3430) - fix_mul(b, 666);
+ c0[i] = y;
+ c1[i] = u;
+ c2[i] = v;
+ }
+}
+
+/* <summary> */
+/* Inverse irreversible MCT. */
+/* </summary> */
+void mct_decode_real(int *c0, int *c1, int *c2, int n) {
+ int i;
+ for (i = 0; i < n; i++) {
+ int y, u, v, r, g, b;
+ y = c0[i];
+ u = c1[i];
+ v = c2[i];
+ r = y + fix_mul(v, 11485);
+ g = y - fix_mul(u, 2819) - fix_mul(v, 5850);
+ b = y + fix_mul(u, 14516);
+ c0[i] = r;
+ c1[i] = g;
+ c2[i] = b;
+ }
+}
+
+/* <summary> */
+/* Get norm of basis function of irreversible MCT. */
+/* </summary> */
+double mct_getnorm_real(int compno) {
+ return mct_norms_real[compno];
+}
diff --git a/libopenjpeg3d/mct.h b/libopenjpeg3d/mct.h
new file mode 100755
index 00000000..0b8edb7b
--- /dev/null
+++ b/libopenjpeg3d/mct.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * 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 __MCT_H
+#define __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 Funciones generales */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+/**
+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 mct_encode(int *c0, int *c1, int *c2, int 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 mct_decode(int *c0, int *c1, int *c2, int 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
+*/
+double mct_getnorm(int 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 mct_encode_real(int *c0, int *c1, int *c2, int 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 mct_decode_real(int *c0, int *c1, int *c2, int 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
+*/
+double mct_getnorm_real(int compno);
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+#endif /* __MCT_H */
diff --git a/libopenjpeg3d/mqc.c b/libopenjpeg3d/mqc.c
new file mode 100755
index 00000000..12ac90d6
--- /dev/null
+++ b/libopenjpeg3d/mqc.c
@@ -0,0 +1,548 @@
+/*
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * 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 MQC MQC - Implementation of an MQ-Coder */
+/*@{*/
+
+/** @name Local static functions */
+/*@{*/
+
+/**
+Output a byte, doing bit-stuffing if necessary.
+After a 0xff byte, the next byte must be smaller than 0x90.
+@param mqc MQC handle
+*/
+static void mqc_byteout(opj_mqc_t *mqc);
+/**
+Renormalize mqc->a and mqc->c while encoding, so that mqc->a stays between 0x8000 and 0x10000
+@param mqc MQC handle
+*/
+static void mqc_renorme(opj_mqc_t *mqc);
+/**
+Encode the most probable symbol
+@param mqc MQC handle
+*/
+static void mqc_codemps(opj_mqc_t *mqc);
+/**
+Encode the most least symbol
+@param mqc MQC handle
+*/
+static void mqc_codelps(opj_mqc_t *mqc);
+/**
+Fill mqc->c with 1's for flushing
+@param mqc MQC handle
+*/
+static void mqc_setbits(opj_mqc_t *mqc);
+/**
+Exchange MPS with LPS
+@param mqc MQC handle
+@return
+*/
+static int mqc_mpsexchange(opj_mqc_t *mqc);
+/**
+Exchange LPS with MPS
+@param mqc MQC handle
+@return
+*/
+static int mqc_lpsexchange(opj_mqc_t *mqc);
+/**
+Input a byte
+@param mqc MQC handle
+*/
+static void mqc_bytein(opj_mqc_t *mqc);
+/**
+Renormalize mqc->a and mqc->c while decoding
+@param mqc MQC handle
+*/
+static void mqc_renormd(opj_mqc_t *mqc);
+
+/*@}*/
+
+/*@}*/
+
+/* <summary> */
+/* This array defines all the possible states for a context. */
+/* </summary> */
+static 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 mqc_byteout(opj_mqc_t *mqc) {
+ if (*mqc->bp == 0xff) {
+ mqc->bp++;
+ *mqc->bp = mqc->c >> 20;
+ mqc->c &= 0xfffff;
+ mqc->ct = 7;
+ } else {
+ if ((mqc->c & 0x8000000) == 0) { /* ((mqc->c&0x8000000)==0) CHANGE */
+ mqc->bp++;
+ *mqc->bp = mqc->c >> 19;
+ mqc->c &= 0x7ffff;
+ mqc->ct = 8;
+ } else {
+ (*mqc->bp)++;
+ if (*mqc->bp == 0xff) {
+ mqc->c &= 0x7ffffff;
+ mqc->bp++;
+ *mqc->bp = mqc->c >> 20;
+ mqc->c &= 0xfffff;
+ mqc->ct = 7;
+ } else {
+ mqc->bp++;
+ *mqc->bp = mqc->c >> 19;
+ mqc->c &= 0x7ffff;
+ mqc->ct = 8;
+ }
+ }
+ }
+}
+
+static void mqc_renorme(opj_mqc_t *mqc) {
+ do {
+ mqc->a <<= 1;
+ mqc->c <<= 1;
+ mqc->ct--;
+ if (mqc->ct == 0) {
+ mqc_byteout(mqc);
+ }
+ } while ((mqc->a & 0x8000) == 0);
+}
+
+static void mqc_codemps(opj_mqc_t *mqc) {
+ mqc->a -= (*mqc->curctx)->qeval;
+ if ((mqc->a & 0x8000) == 0) {
+ if (mqc->a < (*mqc->curctx)->qeval) {
+ mqc->a = (*mqc->curctx)->qeval;
+ } else {
+ mqc->c += (*mqc->curctx)->qeval;
+ }
+ *mqc->curctx = (*mqc->curctx)->nmps;
+ mqc_renorme(mqc);
+ } else {
+ mqc->c += (*mqc->curctx)->qeval;
+ }
+}
+
+static void mqc_codelps(opj_mqc_t *mqc) {
+ mqc->a -= (*mqc->curctx)->qeval;
+ if (mqc->a < (*mqc->curctx)->qeval) {
+ mqc->c += (*mqc->curctx)->qeval;
+ } else {
+ mqc->a = (*mqc->curctx)->qeval;
+ }
+ *mqc->curctx = (*mqc->curctx)->nlps;
+ mqc_renorme(mqc);
+}
+
+static void mqc_setbits(opj_mqc_t *mqc) {
+ unsigned int tempc = mqc->c + mqc->a;
+ mqc->c |= 0xffff;
+ if (mqc->c >= tempc) {
+ mqc->c -= 0x8000;
+ }
+}
+
+static int mqc_mpsexchange(opj_mqc_t *mqc) {
+ int d;
+ if (mqc->a < (*mqc->curctx)->qeval) {
+ d = 1 - (*mqc->curctx)->mps;
+ *mqc->curctx = (*mqc->curctx)->nlps;
+ } else {
+ d = (*mqc->curctx)->mps;
+ *mqc->curctx = (*mqc->curctx)->nmps;
+ }
+
+ return d;
+}
+
+static int mqc_lpsexchange(opj_mqc_t *mqc) {
+ int d;
+ if (mqc->a < (*mqc->curctx)->qeval) {
+ mqc->a = (*mqc->curctx)->qeval;
+ d = (*mqc->curctx)->mps;
+ *mqc->curctx = (*mqc->curctx)->nmps;
+ } else {
+ mqc->a = (*mqc->curctx)->qeval;
+ d = 1 - (*mqc->curctx)->mps;
+ *mqc->curctx = (*mqc->curctx)->nlps;
+ }
+
+ return d;
+}
+
+static void mqc_bytein(opj_mqc_t *mqc) {
+ if (mqc->bp != mqc->end) {
+ unsigned int c;
+ if (mqc->bp + 1 != mqc->end) {
+ c = *(mqc->bp + 1);
+ } else {
+ c = 0xff;
+ }
+ if (*mqc->bp == 0xff) {
+ if (c > 0x8f) {
+ mqc->c += 0xff00;
+ mqc->ct = 8;
+ } else {
+ mqc->bp++;
+ mqc->c += c << 9;
+ mqc->ct = 7;
+ }
+ } else {
+ mqc->bp++;
+ mqc->c += c << 8;
+ mqc->ct = 8;
+ }
+ } else {
+ mqc->c += 0xff00;
+ mqc->ct = 8;
+ }
+}
+
+static void mqc_renormd(opj_mqc_t *mqc) {
+ do {
+ if (mqc->ct == 0) {
+ mqc_bytein(mqc);
+ }
+ mqc->a <<= 1;
+ mqc->c <<= 1;
+ mqc->ct--;
+ } while (mqc->a < 0x8000);
+}
+
+/*
+==========================================================
+ MQ-Coder interface
+==========================================================
+*/
+
+opj_mqc_t* mqc_create() {
+ opj_mqc_t *mqc = (opj_mqc_t*)opj_malloc(sizeof(opj_mqc_t));
+ return mqc;
+}
+
+void mqc_destroy(opj_mqc_t *mqc) {
+ if(mqc) {
+ opj_free(mqc);
+ }
+}
+
+int mqc_numbytes(opj_mqc_t *mqc) {
+ return mqc->bp - mqc->start;
+}
+
+void mqc_init_enc(opj_mqc_t *mqc, unsigned char *bp) {
+ mqc_setcurctx(mqc, 0);
+ mqc->a = 0x8000;
+ mqc->c = 0;
+ mqc->bp = bp - 1;
+ mqc->ct = 12;
+ if (*mqc->bp == 0xff) {
+ mqc->ct = 13;
+ }
+ mqc->start = bp;
+}
+
+void mqc_setcurctx(opj_mqc_t *mqc, int ctxno) {
+ mqc->curctx = &mqc->ctxs[ctxno];
+}
+
+void mqc_encode(opj_mqc_t *mqc, int d) {
+ if ((*mqc->curctx)->mps == d) {
+ mqc_codemps(mqc);
+ } else {
+ mqc_codelps(mqc);
+ }
+}
+
+void mqc_flush(opj_mqc_t *mqc) {
+ mqc_setbits(mqc);
+ mqc->c <<= mqc->ct;
+ mqc_byteout(mqc);
+ mqc->c <<= mqc->ct;
+ mqc_byteout(mqc);
+
+ if (*mqc->bp != 0xff) {
+ mqc->bp++;
+ }
+}
+
+void mqc_bypass_init_enc(opj_mqc_t *mqc) {
+ mqc->c = 0;
+ mqc->ct = 8;
+ /*if (*mqc->bp == 0xff) {
+ mqc->ct = 7;
+ } */
+}
+
+void mqc_bypass_enc(opj_mqc_t *mqc, int d) {
+ mqc->ct--;
+ mqc->c = mqc->c + (d << mqc->ct);
+ if (mqc->ct == 0) {
+ mqc->bp++;
+ *mqc->bp = mqc->c;
+ mqc->ct = 8;
+ if (*mqc->bp == 0xff) {
+ mqc->ct = 7;
+ }
+ mqc->c = 0;
+ }
+}
+
+int mqc_bypass_flush_enc(opj_mqc_t *mqc) {
+ unsigned char bit_padding;
+
+ bit_padding = 0;
+
+ if (mqc->ct != 0) {
+ while (mqc->ct > 0) {
+ mqc->ct--;
+ mqc->c += bit_padding << mqc->ct;
+ bit_padding = (bit_padding + 1) & 0x01;
+ }
+ mqc->bp++;
+ *mqc->bp = mqc->c;
+ mqc->ct = 8;
+ mqc->c = 0;
+ }
+
+ return 1;
+}
+
+void mqc_reset_enc(opj_mqc_t *mqc) {
+ mqc_resetstates(mqc);
+ mqc_setstate(mqc, 18, 0, 46);
+ mqc_setstate(mqc, 0, 0, 3);
+ mqc_setstate(mqc, 1, 0, 4);
+}
+
+void mqc_reset_enc_3(opj_mqc_t *mqc) {
+ mqc_resetstates(mqc);
+ mqc_setstate(mqc, T1_3D_CTXNO_UNI, 0, 46);
+ mqc_setstate(mqc, T1_3D_CTXNO_AGG, 0, 3);
+ mqc_setstate(mqc, T1_3D_CTXNO_ZC, 0, 4);
+}
+
+int mqc_restart_enc(opj_mqc_t *mqc) {
+ int correction = 1;
+
+ /* <flush part> */
+ int n = 27 - 15 - mqc->ct;
+ mqc->c <<= mqc->ct;
+ while (n > 0) {
+ mqc_byteout(mqc);
+ n -= mqc->ct;
+ mqc->c <<= mqc->ct;
+ }
+ mqc_byteout(mqc);
+
+ return correction;
+}
+
+void mqc_restart_init_enc(opj_mqc_t *mqc) {
+ /* <Re-init part> */
+ mqc_setcurctx(mqc, 0);
+ mqc->a = 0x8000;
+ mqc->c = 0;
+ mqc->ct = 12;
+ mqc->bp--;
+ if (*mqc->bp == 0xff) {
+ mqc->ct = 13;
+ }
+}
+
+void mqc_erterm_enc(opj_mqc_t *mqc) {
+ int k = 11 - mqc->ct + 1;
+
+ while (k > 0) {
+ mqc->c <<= mqc->ct;
+ mqc->ct = 0;
+ mqc_byteout(mqc);
+ k -= mqc->ct;
+ }
+
+ if (*mqc->bp != 0xff) {
+ mqc_byteout(mqc);
+ }
+}
+
+void mqc_segmark_enc(opj_mqc_t *mqc) {
+ int i;
+ mqc_setcurctx(mqc, 18);
+
+ for (i = 1; i < 5; i++) {
+ mqc_encode(mqc, i % 2);
+ }
+}
+
+void mqc_init_dec(opj_mqc_t *mqc, unsigned char *bp, int len) {
+ mqc_setcurctx(mqc, 0);
+ mqc->start = bp;
+ mqc->end = bp + len;
+ mqc->bp = bp;
+ if (len==0) mqc->c = 0xff << 16;
+ else mqc->c = *mqc->bp << 16;
+ mqc_bytein(mqc);
+ mqc->c <<= 7;
+ mqc->ct -= 7;
+ mqc->a = 0x8000;
+}
+
+int mqc_decode(opj_mqc_t *mqc) {
+ int d;
+ mqc->a -= (*mqc->curctx)->qeval;
+ if ((mqc->c >> 16) < (*mqc->curctx)->qeval) {
+ d = mqc_lpsexchange(mqc);
+ mqc_renormd(mqc);
+ } else {
+ mqc->c -= (*mqc->curctx)->qeval << 16;
+ if ((mqc->a & 0x8000) == 0) {
+ d = mqc_mpsexchange(mqc);
+ mqc_renormd(mqc);
+ } else {
+ d = (*mqc->curctx)->mps;
+ }
+ }
+
+ return d;
+}
+
+void mqc_resetstates(opj_mqc_t *mqc) {
+ int i;
+ for (i = 0; i < MQC_NUMCTXS; i++) {
+ mqc->ctxs[i] = mqc_states;
+ }
+}
+
+void mqc_setstate(opj_mqc_t *mqc, int ctxno, int msb, int prob) {
+ mqc->ctxs[ctxno] = &mqc_states[msb + (prob << 1)];
+}
+
+
diff --git a/libopenjpeg3d/mqc.h b/libopenjpeg3d/mqc.h
new file mode 100755
index 00000000..90253356
--- /dev/null
+++ b/libopenjpeg3d/mqc.h
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * 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 __MQC_H
+#define __MQC_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) */
+ unsigned int qeval;
+ /** the Most Probable Symbol (0 or 1) */
+ int mps;
+ /** next state if the next encoded symbol is the MPS */
+ struct opj_mqc_state *nmps;
+ /** next state if the next encoded symbol is the LPS */
+ struct opj_mqc_state *nlps;
+} opj_mqc_state_t;
+
+#define MQC_NUMCTXS 32
+
+/**
+MQ coder
+*/
+typedef struct opj_mqc {
+ unsigned int c;
+ unsigned int a;
+ unsigned int ct;
+ unsigned char *bp;
+ unsigned char *start;
+ unsigned char *end;
+ opj_mqc_state_t *ctxs[MQC_NUMCTXS];
+ opj_mqc_state_t **curctx;
+} opj_mqc_t;
+
+/** @name Exported functions */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+/**
+Create a new MQC handle
+@return Returns a new MQC handle if successful, returns NULL otherwise
+*/
+opj_mqc_t* mqc_create();
+/**
+Destroy a previously created MQC handle
+@param mqc MQC handle to destroy
+*/
+void mqc_destroy(opj_mqc_t *mqc);
+/**
+Return the number of bytes written/read since initialisation
+@param mqc MQC handle
+@return Returns the number of bytes already encoded
+*/
+int 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 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 mqc_setstate(opj_mqc_t *mqc, int ctxno, int msb, int prob);
+/**
+Initialize the encoder
+@param mqc MQC handle
+@param bp Pointer to the start of the buffer where the bytes will be written
+*/
+void mqc_init_enc(opj_mqc_t *mqc, unsigned char *bp);
+/**
+Set the current context used for coding/decoding
+@param mqc MQC handle
+@param ctxno Number that identifies the context
+*/
+void mqc_setcurctx(opj_mqc_t *mqc, int ctxno);
+/**
+Encode a symbol using the MQ-coder
+@param mqc MQC handle
+@param d The symbol to be encoded (0 or 1)
+*/
+void mqc_encode(opj_mqc_t *mqc, int d);
+/**
+Flush the encoder, so that all remaining data is written
+@param mqc MQC handle
+*/
+void mqc_flush(opj_mqc_t *mqc);
+/**
+BYPASS mode switch, initialization operation.
+JPEG 2000 p 505.
+<h2>Not fully implemented and tested !!</h2>
+@param mqc MQC handle
+*/
+void mqc_bypass_init_enc(opj_mqc_t *mqc);
+/**
+BYPASS mode switch, coding operation.
+JPEG 2000 p 505.
+<h2>Not fully implemented and tested !!</h2>
+@param mqc MQC handle
+@param d The symbol to be encoded (0 or 1)
+*/
+void mqc_bypass_enc(opj_mqc_t *mqc, int d);
+/**
+BYPASS mode switch, flush operation
+<h2>Not fully implemented and tested !!</h2>
+@param mqc MQC handle
+@return Returns 1 (always)
+*/
+int mqc_bypass_flush_enc(opj_mqc_t *mqc);
+/**
+RESET mode switch
+@param mqc MQC handle
+*/
+void mqc_reset_enc(opj_mqc_t *mqc);
+/**
+RESET mode switch
+@param mqc MQC handle
+*/
+void mqc_reset_enc_3(opj_mqc_t *mqc);
+/**
+RESTART mode switch (TERMALL)
+@param mqc MQC handle
+@return Returns 1 (always)
+*/
+int mqc_restart_enc(opj_mqc_t *mqc);
+/**
+RESTART mode switch (TERMALL) reinitialisation
+@param mqc MQC handle
+*/
+void mqc_restart_init_enc(opj_mqc_t *mqc);
+/**
+ERTERM mode switch (PTERM)
+@param mqc MQC handle
+*/
+void mqc_erterm_enc(opj_mqc_t *mqc);
+/**
+SEGMARK mode switch (SEGSYM)
+@param mqc MQC handle
+*/
+void mqc_segmark_enc(opj_mqc_t *mqc);
+/**
+Initialize the decoder
+@param mqc MQC handle
+@param bp Pointer to the start of the buffer from which the bytes will be read
+@param len Length of the input buffer
+*/
+void mqc_init_dec(opj_mqc_t *mqc, unsigned char *bp, int len);
+/**
+Decode a symbol
+@param mqc MQC handle
+@return Returns the decoded symbol (0 or 1)
+*/
+int mqc_decode(opj_mqc_t *mqc);
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+#endif /* __MQC_H */
diff --git a/libopenjpeg3d/openjpeg.c b/libopenjpeg3d/openjpeg.c
new file mode 100755
index 00000000..ab2744e1
--- /dev/null
+++ b/libopenjpeg3d/openjpeg.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2006, Mónica Díez García, Image Processing Laboratory, University of Valladolid, Spain
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef _WIN32
+#include <windows.h>
+#endif /* _WIN32 */
+
+#include "opj_includes.h"
+#define JP3D_VERSION "1.3.0"
+/* ---------------------------------------------------------------------- */
+#ifdef _WIN32
+#ifndef OPJ_STATIC
+BOOL APIENTRY
+DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
+ switch (ul_reason_for_call) {
+ case DLL_PROCESS_ATTACH :
+ break;
+ case DLL_PROCESS_DETACH :
+ break;
+ case DLL_THREAD_ATTACH :
+ case DLL_THREAD_DETACH :
+ break;
+ }
+
+ return TRUE;
+}
+#endif /* OPJ_STATIC */
+#endif /* _WIN32 */
+
+/* ---------------------------------------------------------------------- */
+
+const char* OPJ_CALLCONV opj_version() {
+ return JP3D_VERSION;
+}
+opj_dinfo_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT format) {
+ opj_dinfo_t *dinfo = (opj_dinfo_t*)opj_malloc(sizeof(opj_dinfo_t));
+ if(!dinfo) return NULL;
+ dinfo->is_decompressor = true;
+ switch(format) {
+ case CODEC_J3D:
+ case CODEC_J2K:
+ /* get a J3D decoder handle */
+ dinfo->j3d_handle = (void*)j3d_create_decompress((opj_common_ptr)dinfo);
+ if(!dinfo->j3d_handle) {
+ opj_free(dinfo);
+ return NULL;
+ }
+ break;
+ default:
+ opj_free(dinfo);
+ return NULL;
+ }
+
+ dinfo->codec_format = format;
+
+ return dinfo;
+}
+
+void OPJ_CALLCONV opj_destroy_decompress(opj_dinfo_t *dinfo) {
+ if(dinfo) {
+ /* destroy the codec */
+ if(dinfo->codec_format != CODEC_UNKNOWN) {
+ j3d_destroy_decompress((opj_j3d_t*)dinfo->j3d_handle);
+ }
+ /* destroy the decompressor */
+ opj_free(dinfo);
+ }
+}
+
+void OPJ_CALLCONV opj_set_default_decoder_parameters(opj_dparameters_t *parameters) {
+ if(parameters) {
+ memset(parameters, 0, sizeof(opj_dparameters_t));
+ /* default decoding parameters */
+ parameters->cp_layer = 0;
+ parameters->cp_reduce[0] = 0;
+ parameters->cp_reduce[1] = 0;
+ parameters->cp_reduce[2] = 0;
+ parameters->bigendian = 0;
+
+ parameters->decod_format = -1;
+ parameters->cod_format = -1;
+ }
+}
+
+void OPJ_CALLCONV opj_setup_decoder(opj_dinfo_t *dinfo, opj_dparameters_t *parameters) {
+ if(dinfo && parameters) {
+ if (dinfo->codec_format != CODEC_UNKNOWN) {
+ j3d_setup_decoder((opj_j3d_t*)dinfo->j3d_handle, parameters);
+ }
+ }
+}
+
+opj_volume_t* OPJ_CALLCONV opj_decode(opj_dinfo_t *dinfo, opj_cio_t *cio) {
+ if(dinfo && cio) {
+ if (dinfo->codec_format != CODEC_UNKNOWN) {
+ return j3d_decode((opj_j3d_t*)dinfo->j3d_handle, cio);
+ }
+ }
+
+ return NULL;
+}
+
+opj_cinfo_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT format) {
+ opj_cinfo_t *cinfo = (opj_cinfo_t*)opj_malloc(sizeof(opj_cinfo_t));
+ if(!cinfo) return NULL;
+ cinfo->is_decompressor = false;
+ switch(format) {
+ case CODEC_J3D:
+ case CODEC_J2K:
+ /* get a J3D coder handle */
+ cinfo->j3d_handle = (void*)j3d_create_compress((opj_common_ptr)cinfo);
+ if(!cinfo->j3d_handle) {
+ opj_free(cinfo);
+ return NULL;
+ }
+ break;
+ default:
+ opj_free(cinfo);
+ return NULL;
+ }
+
+ cinfo->codec_format = format;
+
+ return cinfo;
+}
+
+void OPJ_CALLCONV opj_destroy_compress(opj_cinfo_t *cinfo) {
+ if(cinfo) {
+ /* destroy the codec */
+ if (cinfo->codec_format != CODEC_UNKNOWN) {
+ j3d_destroy_compress((opj_j3d_t*)cinfo->j3d_handle);
+ }
+ /* destroy the decompressor */
+ opj_free(cinfo);
+ }
+}
+
+void OPJ_CALLCONV opj_set_default_encoder_parameters(opj_cparameters_t *parameters) {
+ if(parameters) {
+ memset(parameters, 0, sizeof(opj_cparameters_t));
+ /* default coding parameters */
+ parameters->numresolution[0] = 3;
+ parameters->numresolution[1] = 3;
+ parameters->numresolution[2] = 1;
+ parameters->cblock_init[0] = 64;
+ parameters->cblock_init[1] = 64;
+ parameters->cblock_init[2] = 64;
+ parameters->prog_order = LRCP;
+ parameters->roi_compno = -1; /* no ROI */
+ parameters->atk_wt[0] = 1; /* 5-3 WT */
+ parameters->atk_wt[1] = 1; /* 5-3 WT */
+ parameters->atk_wt[2] = 1; /* 5-3 WT */
+ parameters->irreversible = 0;
+ parameters->subsampling_dx = 1;
+ parameters->subsampling_dy = 1;
+ parameters->subsampling_dz = 1;
+
+ parameters->decod_format = -1;
+ parameters->cod_format = -1;
+ parameters->encoding_format = ENCOD_2EB;
+ parameters->transform_format = TRF_2D_DWT;
+ }
+}
+
+void OPJ_CALLCONV opj_setup_encoder(opj_cinfo_t *cinfo, opj_cparameters_t *parameters, opj_volume_t *volume) {
+ if(cinfo && parameters && volume) {
+ if (cinfo->codec_format != CODEC_UNKNOWN) {
+ j3d_setup_encoder((opj_j3d_t*)cinfo->j3d_handle, parameters, volume);
+ }
+ }
+}
+
+bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_volume_t *volume, char *index) {
+ if(cinfo && cio && volume) {
+ if (cinfo->codec_format != CODEC_UNKNOWN) {
+ return j3d_encode((opj_j3d_t*)cinfo->j3d_handle, cio, volume, index);
+ }
+ }
+
+ return false;
+}
+
+
diff --git a/libopenjpeg3d/openjpeg3d.h b/libopenjpeg3d/openjpeg3d.h
new file mode 100755
index 00000000..e6829d91
--- /dev/null
+++ b/libopenjpeg3d/openjpeg3d.h
@@ -0,0 +1,713 @@
+/*
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * Copyright (c) 2006, Mónica Díez García, Image Processing Laboratory, University of Valladolid, Spain
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef OPENJPEG_H
+#define OPENJPEG_H
+
+/*
+==========================================================
+ Compiler directives
+==========================================================
+*/
+
+#if defined(OPJ_STATIC) || !defined(_WIN32)
+#define OPJ_API
+#define OPJ_CALLCONV
+#else
+#define OPJ_CALLCONV __stdcall
+/*
+The following ifdef block is the standard way of creating macros which make exporting
+from a DLL simpler. All files within this DLL are compiled with the OPJ_EXPORTS
+symbol defined on the command line. this symbol should not be defined on any project
+that uses this DLL. This way any other project whose source files include this file see
+OPJ_API functions as being imported from a DLL, wheras this DLL sees symbols
+defined with this macro as being exported.
+*/
+#if defined(OPJ_EXPORTS) || defined(DLL_EXPORT)
+#define OPJ_API __declspec(dllexport)
+#else
+#define OPJ_API __declspec(dllimport)
+#endif /* OPJ_EXPORTS */
+#endif /* !OPJ_STATIC || !WIN32 */
+
+#ifndef __cplusplus
+#if defined(HAVE_STDBOOL_H)
+/*
+The C language implementation does correctly provide the standard header
+file "stdbool.h".
+ */
+#include <stdbool.h>
+#else
+/*
+The C language implementation does not provide the standard header file
+"stdbool.h" as required by ISO/IEC 9899:1999. Try to compensate for this
+braindamage below.
+*/
+#if !defined(bool)
+#define bool int
+#endif
+#if !defined(true)
+#define true 1
+#endif
+#if !defined(false)
+#define false 0
+#endif
+#endif
+#endif /* __cplusplus */
+
+/*
+==========================================================
+ Useful constant definitions
+==========================================================
+*/
+#ifndef MAX_SLICES
+#define MAX_SLICES 300 /**< Maximum allowed size for slices */
+#endif /* MAX_PATH */
+
+#ifndef MAX_PATH
+#define MAX_PATH 260 /**< Maximum allowed size for filenames */
+#endif /* MAX_PATH */
+
+#define J3D_MAXRLVLS 32 /**< Number of maximum resolution level authorized */
+#define J3D_MAXBANDS (7*J3D_MAXRLVLS + 1) /**< Number of maximum sub-band linked to number of resolution level */
+
+#define TINY 1.0E-20
+/*
+==========================================================
+ enum definitions
+==========================================================
+*/
+
+#define J2K_CFMT 0
+#define J3D_CFMT 1
+#define LSE_CFMT 2
+
+#define BIN_DFMT 0
+#define PGX_DFMT 1
+#define IMG_DFMT 2
+/* ----------------------------------------------------------------------- */
+
+/** Progression order */
+typedef enum PROG_ORDER {
+/**< place-holder */
+ PROG_UNKNOWN = -1,
+/**< layer-resolution-component-precinct order */
+ LRCP = 0,
+/**< resolution-layer-component-precinct order */
+ RLCP = 1,
+/**< resolution-precinct-component-layer order */
+ RPCL = 2,
+/**< precinct-component-resolution-layer order */
+ PCRL = 3,
+/**< component-precinct-resolution-layer order */
+ CPRL = 4
+} OPJ_PROG_ORDER;
+
+/**
+Supported volume color spaces
+*/
+typedef enum COLOR_SPACE {
+/**< place-holder */
+ CLRSPC_UNKNOWN = -1,
+/**< sRGB */
+ CLRSPC_SRGB = 1,
+/**< grayscale */
+ CLRSPC_GRAY = 2,
+/**< YUV */
+ CLRSPC_SYCC = 3
+} OPJ_COLOR_SPACE;
+
+/**
+Supported codec
+*/
+typedef enum CODEC_FORMAT {
+ /**< place-holder */
+ CODEC_UNKNOWN = -1,
+/**< JPEG-2000 codestream : read/write */
+ CODEC_J2K = 0,
+/**< JPEG-2000 Part 10 file format : read/write */
+ CODEC_J3D = 1
+} OPJ_CODEC_FORMAT;
+
+/**
+Supported entropy coding algorithms
+*/
+typedef enum ENTROPY_CODING {
+/**< place-holder */
+ ENCOD_UNKNOWN = -1,
+/**< 2D EBCOT encoding */
+ ENCOD_2EB = 0,
+/**< 3D EBCOT encoding */
+ ENCOD_3EB = 1,
+/**< Golomb-Rice coding with 2D context */
+ ENCOD_2GR = 2,
+/**< Golomb-Rice coding with 3D context */
+ ENCOD_3GR = 3
+} OPJ_ENTROPY_CODING;
+
+/**
+Supported transforms
+*/
+typedef enum TRANSFORM {
+/**< place-holder */
+ TRF_UNKNOWN = -1,
+/**< 2D DWT, no transform in axial dim */
+ TRF_2D_DWT = 0,
+/**< 3D DWT */
+ TRF_3D_DWT = 1,
+/**< 3D prediction*/
+ TRF_3D_RLS = 2,
+ TRF_3D_LSE = 3
+} OPJ_TRANSFORM;
+/*
+==========================================================
+ event manager typedef definitions
+==========================================================
+*/
+
+/**
+Callback function prototype for events
+@param msg Event message
+@param client_data
+*/
+typedef void (*opj_msg_callback) (const char *msg, void *client_data);
+
+/**
+Message handler object
+used for
+<ul>
+<li>Error messages
+<li>Warning messages
+<li>Debugging messages
+</ul>
+*/
+typedef struct opj_event_mgr {
+ /** 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;
+
+
+/*
+==========================================================
+ codec typedef definitions
+==========================================================
+*/
+
+/**
+Progression order changes
+*/
+typedef struct opj_poc {
+ int resno0, compno0;
+ int layno1, resno1, compno1;
+ OPJ_PROG_ORDER prg;
+ int tile;
+ char progorder[4];
+} opj_poc_t;
+
+
+/**
+Compression parameters
+*/
+typedef struct opj_cparameters {
+/** size of tile: tile_size_on = false (not in argument) or = true (in argument) */
+ bool tile_size_on;
+/** XTOsiz */
+ int cp_tx0;
+/** YTOsiz */
+ int cp_ty0;
+/** ZTOsiz */
+ int cp_tz0;
+
+/** XTsiz */
+ int cp_tdx;
+/** YTsiz */
+ int cp_tdy;
+/** ZTsiz */
+ int cp_tdz;
+
+/** allocation by rate/distortion */
+ int cp_disto_alloc;
+/** allocation by fixed layer */
+ int cp_fixed_alloc;
+/** add fixed_quality */
+ int cp_fixed_quality;
+/** fixed layer */
+ int *cp_matrice;
+/** number of layers */
+ int tcp_numlayers;
+/** rates for successive layers */
+ float tcp_rates[100];
+/** psnr's for successive layers */
+ float tcp_distoratio[100];
+/** comment for coding */
+ char *cp_comment;
+/** csty : coding style */
+ int csty;
+/** DC offset (DCO) */
+ int dcoffset;
+/** progression order (default LRCP) */
+ OPJ_PROG_ORDER prog_order;
+/** progression order changes */
+ opj_poc_t POC[J3D_MAXRLVLS-1];
+/** number of progression order changes (POC), default to 0 */
+ int numpocs;
+
+/** number of resolutions */
+ int numresolution[3];
+/** initial code block width, height and depth, default to 64 */
+ int cblock_init[3];
+/** mode switch (1=BYPASS(LAZY) 2=RESET 4=RESTART(TERMALL) 8=VSC 16=ERTERM(SEGTERM) 32=SEGMARK(SEGSYM)) */
+ int mode;
+
+/** 1 : use the irreversible DWT 9-7, 0 : use lossless compression (default) */
+ int irreversible;
+/** WT from ATK, default to 0 (false), no of atk used */
+ int atk_wt[3];
+/** region of interest: affected component in [0..3], -1 means no ROI */
+ int roi_compno;
+/** region of interest: upshift value */
+ int roi_shift;
+
+/* number of precinct size specifications */
+ int res_spec;
+/** initial precinct width */
+ int prct_init[3][J3D_MAXRLVLS];
+
+/** transform format 0: 0: 2DWT, 1: 2D1P, 2: 3DWT, 3: 3RLS */
+ OPJ_TRANSFORM transform_format;
+/** output file format 0: 2EB, 1: 3EB, 2: 2GR, 3: 3GR, 4: GRI */
+ OPJ_ENTROPY_CODING encoding_format;
+
+ /**@name command line encoder parameters (not used inside the library) */
+ /*@{*/
+ char infile[MAX_PATH]; /** input file name */
+ char outfile[MAX_PATH]; /** output file name */
+ char imgfile[MAX_PATH]; /** IMG file name for BIN volumes*/
+ int index_on; /** creation of an index file, default to 0 (false) */
+ char index[MAX_PATH]; /** index file name */
+
+ int volume_offset_x0; /** subvolume encoding: origin volume offset in x, y and z direction */
+ int volume_offset_y0;
+ int volume_offset_z0;
+
+ int subsampling_dx; /** subsampling value for dx */
+ int subsampling_dy;
+ int subsampling_dz;
+
+ int decod_format; /** input file format 0: BIN, 1: PGX */
+ int cod_format; /** output file format 0: JP3D */
+ /*@}*/
+} opj_cparameters_t;
+
+/**
+Decompression parameters
+*/
+typedef struct opj_dparameters {
+/** Set the number of highest resolution levels to be discarded. if != 0, then original dimension divided by 2^(reduce); if == 0 or not used, volume is decoded to the full resolution */
+ int cp_reduce[3];
+/** Set the maximum number of quality layers to decode. if != 0, then only the first "layer" layers are decoded; if == 0 or not used, all the quality layers are decoded */
+ int cp_layer;
+ int bigendian;
+
+ /**@name command line encoder parameters (not used inside the library) */
+ /*@{*/
+/** input file name */
+ char infile[MAX_PATH];
+/** output file name */
+ char outfile[MAX_PATH];
+/** IMG file name for BIN volumes*/
+ char imgfile[MAX_PATH];
+/** Original file name for PSNR measures*/
+ char original[MAX_PATH];
+/** input file format 0: J2K, 1: JP3D */
+ int decod_format;
+/** input file format 0: BIN, 1: PGM */
+ int cod_format;
+/** original file format 0: BIN, 1: PGM */
+ int orig_format;
+ /*@}*/
+} opj_dparameters_t;
+
+/** Common fields between JPEG-2000 compression and decompression master structs. */
+#define opj_common_fields \
+ opj_event_mgr_t *event_mgr; /**< pointer to the event manager */\
+ void * client_data; /**< Available for use by application */\
+ bool is_decompressor; /**< So common code can tell which is which */\
+ OPJ_CODEC_FORMAT codec_format; /**< selected codec */\
+ OPJ_ENTROPY_CODING encoding_format; /**< selected entropy coding */\
+ OPJ_TRANSFORM transform_format; /**< selected transform */\
+ void *j3d_handle /**< pointer to the J3D codec */
+
+/* Routines that are to be used by both halves of the library are declared
+ * to receive a pointer to this structure. There are no actual instances of
+ * opj_common_struct_t, only of opj_cinfo_t and opj_dinfo_t.
+ */
+typedef struct opj_common_struct {
+ opj_common_fields; /* Fields common to both master struct types */
+ /* Additional fields follow in an actual opj_cinfo_t or
+ * opj_dinfo_t. All three structs must agree on these
+ * initial fields! (This would be a lot cleaner in C++.)
+ */
+} opj_common_struct_t;
+
+typedef opj_common_struct_t * opj_common_ptr;
+
+/**
+Compression context info
+*/
+typedef struct opj_cinfo {
+ /** Fields shared with opj_dinfo_t */
+ opj_common_fields;
+ /* other specific fields go here */
+} opj_cinfo_t;
+
+/**
+Decompression context info
+*/
+typedef struct opj_dinfo {
+ /** Fields shared with opj_cinfo_t */
+ opj_common_fields;
+ /* other specific fields go here */
+} opj_dinfo_t;
+
+/*
+==========================================================
+ I/O stream typedef definitions
+==========================================================
+*/
+
+/*
+ * Stream open flags.
+ */
+/** The stream was opened for reading. */
+#define OPJ_STREAM_READ 0x0001
+/** The stream was opened for writing. */
+#define OPJ_STREAM_WRITE 0x0002
+
+/**
+Byte input-output stream (CIO)
+*/
+typedef struct opj_cio {
+/** codec context */
+ opj_common_ptr cinfo;
+/** open mode (read/write) either OPJ_STREAM_READ or OPJ_STREAM_WRITE */
+ int openmode;
+/** pointer to the start of the buffer */
+ unsigned char *buffer;
+/** buffer size in bytes */
+ int length;
+/** pointer to the start of the stream */
+ unsigned char *start;
+/** pointer to the end of the stream */
+ unsigned char *end;
+/** pointer to the current position */
+ unsigned char *bp;
+} opj_cio_t;
+
+/*
+==========================================================
+ volume typedef definitions
+==========================================================
+*/
+
+/**
+Defines a single volume component
+*/
+typedef struct opj_volume_comp {
+/** XRsiz: horizontal separation of a sample of ith component with respect to the reference grid */
+ int dx;
+/** YRsiz: vertical separation of a sample of ith component with respect to the reference grid */
+ int dy;
+/** ZRsiz: vertical separation of a sample of ith component with respect to the reference grid */
+ int dz;
+/** data width */
+ int w;
+ /** data height */
+ int h;
+ /** data length : no of slices */
+ int l;
+ /** x component offset compared to the whole volume */
+ int x0;
+ /** y component offset compared to the whole volume */
+ int y0;
+ /** z component offset compared to the whole volume */
+ int z0;
+ /** precision */
+ int prec;
+ /** volume depth in bits */
+ int bpp;
+ /** DC offset (15444-2) */
+ int dcoffset;
+ /** signed (1) / unsigned (0) */
+ int sgnd;
+ /** BE byte order (1) / LE byte order (0) */
+ int bigendian;
+ /** number of decoded resolution */
+ int resno_decoded[3];
+ /** number of division by 2 of the out volume compared to the original size of volume */
+ int factor[3];
+ /** volume component data */
+ int *data;
+} opj_volume_comp_t;
+
+/**
+Defines volume data and characteristics
+*/
+typedef struct opj_volume {
+/** XOsiz: horizontal offset from the origin of the reference grid to the left side of the volume area */
+ int x0;
+/** YOsiz: vertical offset from the origin of the reference grid to the top side of the volume area */
+ int y0;
+/** ZOsiz: vertical offset from the origin of the reference grid to the top side of the volume area */
+ int z0;
+/** Xsiz: width of the reference grid */
+ int x1;
+/** Ysiz: height of the reference grid */
+ int y1;
+/** Zsiz: length of the reference grid */
+ int z1;
+/** number of components in the volume */
+ int numcomps;
+/** number of slices in the volume */
+ int numslices;
+/** color space: sRGB, Greyscale or YUV */
+ OPJ_COLOR_SPACE color_space;
+/** volume components */
+ opj_volume_comp_t *comps;
+} opj_volume_t;
+
+/**
+Component parameters structure used by the opj_volume_create function
+*/
+typedef struct opj_volume_comptparm {
+ /** XRsiz: horizontal separation of a sample of ith component with respect to the reference grid */
+ int dx;
+ /** YRsiz: vertical separation of a sample of ith component with respect to the reference grid */
+ int dy;
+ /** ZRsiz: axial separation of a sample of ith component with respect to the reference grid */
+ int dz;
+ /** data width */
+ int w;
+ /** data height */
+ int h;
+ /** data length */
+ int l;
+ /** x component offset compared to the whole volume */
+ int x0;
+ /** y component offset compared to the whole volume */
+ int y0;
+ /** z component offset compared to the whole volume */
+ int z0;
+ /** precision */
+ int prec;
+ /** volume depth in bits */
+ int bpp;
+ /** signed (1) / unsigned (0) */
+ int sgnd;
+ /** DC offset*/
+ int dcoffset;
+ /** BE byte order (1) / LE byte order (0) */
+ int bigendian;
+} opj_volume_cmptparm_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+==========================================================
+ openjpeg version
+==========================================================
+*/
+
+OPJ_API const char * OPJ_CALLCONV opj_version();
+
+/*
+==========================================================
+ volume functions definitions
+==========================================================
+*/
+
+/**
+Create an volume
+@param numcmpts number of components
+@param cmptparms components parameters
+@param clrspc volume color space
+@return returns a new volume structure if successful, returns NULL otherwise
+*/
+OPJ_API opj_volume_t* OPJ_CALLCONV opj_volume_create(int numcmpts, opj_volume_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc);
+
+/**
+Deallocate any resources associated with an volume
+@param volume volume to be destroyed
+*/
+OPJ_API void OPJ_CALLCONV opj_volume_destroy(opj_volume_t *volume);
+
+/*
+==========================================================
+ stream functions definitions
+==========================================================
+*/
+
+/**
+Open and allocate a memory stream for read / write.
+On reading, the user must provide a buffer containing encoded data. The buffer will be
+wrapped by the returned CIO handle.
+On writing, buffer parameters must be set to 0: a buffer will be allocated by the library
+to contain encoded data.
+@param cinfo Codec context info
+@param buffer Reading: buffer address. Writing: NULL
+@param length Reading: buffer length. Writing: 0
+@return Returns a CIO handle if successful, returns NULL otherwise
+*/
+OPJ_API opj_cio_t* OPJ_CALLCONV opj_cio_open(opj_common_ptr cinfo, unsigned char *buffer, int length);
+
+/**
+Close and free a CIO handle
+@param cio CIO handle to free
+*/
+OPJ_API void OPJ_CALLCONV opj_cio_close(opj_cio_t *cio);
+
+/**
+Get position in byte stream
+@param cio CIO handle
+@return Returns the position in bytes
+*/
+OPJ_API int OPJ_CALLCONV cio_tell(opj_cio_t *cio);
+/**
+Set position in byte stream
+@param cio CIO handle
+@param pos Position, in number of bytes, from the beginning of the stream
+*/
+OPJ_API void OPJ_CALLCONV cio_seek(opj_cio_t *cio, int pos);
+
+/*
+==========================================================
+ event manager functions definitions
+==========================================================
+*/
+
+OPJ_API opj_event_mgr_t* OPJ_CALLCONV opj_set_event_mgr(opj_common_ptr cinfo, opj_event_mgr_t *event_mgr, void *context);
+
+/*
+==========================================================
+ codec functions definitions
+==========================================================
+*/
+/**
+Creates a J3D decompression structure
+@param format Decoder to select
+@return Returns a handle to a decompressor if successful, returns NULL otherwise
+*/
+OPJ_API opj_dinfo_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT format);
+/**
+Destroy a decompressor handle
+@param dinfo decompressor handle to destroy
+*/
+OPJ_API void OPJ_CALLCONV opj_destroy_decompress(opj_dinfo_t *dinfo);
+/**
+Set decoding parameters to default values
+@param parameters Decompression parameters
+*/
+OPJ_API void OPJ_CALLCONV opj_set_default_decoder_parameters(opj_dparameters_t *parameters);
+/**
+Setup the decoder decoding parameters using user parameters.
+Decoding parameters are returned in j3d->cp.
+@param dinfo decompressor handle
+@param parameters decompression parameters
+*/
+OPJ_API void OPJ_CALLCONV opj_setup_decoder(opj_dinfo_t *dinfo, opj_dparameters_t *parameters);
+/**
+Decode an volume from a JPEG-2000 codestream
+@param dinfo decompressor handle
+@param cio Input buffer stream
+@return Returns a decoded volume if successful, returns NULL otherwise
+*/
+OPJ_API opj_volume_t* OPJ_CALLCONV opj_decode(opj_dinfo_t *dinfo, opj_cio_t *cio);
+/**
+Creates a J3D/JP2 compression structure
+@param format Coder to select
+@return Returns a handle to a compressor if successful, returns NULL otherwise
+*/
+OPJ_API opj_cinfo_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT format);
+/**
+Destroy a compressor handle
+@param cinfo compressor handle to destroy
+*/
+OPJ_API void OPJ_CALLCONV opj_destroy_compress(opj_cinfo_t *cinfo);
+/**
+Set encoding parameters to default values, that means :
+<ul>
+<li>Lossless
+<li>1 tile
+<li>Size of precinct : 2^15 x 2^15 (means 1 precinct)
+<li>Size of code-block : 64 x 64
+<li>Number of resolutions: 6
+<li>No SOP marker in the codestream
+<li>No EPH marker in the codestream
+<li>No sub-sampling in x or y direction
+<li>No mode switch activated
+<li>Progression order: LRCP
+<li>No index file
+<li>No ROI upshifted
+<li>No offset of the origin of the volume
+<li>No offset of the origin of the tiles
+<li>Reversible DWT 5-3
+</ul>
+@param parameters Compression parameters
+*/
+OPJ_API void OPJ_CALLCONV opj_set_default_encoder_parameters(opj_cparameters_t *parameters);
+/**
+Setup the encoder parameters using the current volume and using user parameters.
+@param cinfo compressor handle
+@param parameters compression parameters
+@param volume input filled volume
+*/
+OPJ_API void OPJ_CALLCONV opj_setup_encoder(opj_cinfo_t *cinfo, opj_cparameters_t *parameters, opj_volume_t *volume);
+/**
+Encode an volume into a JPEG-2000 codestream
+@param cinfo compressor handle
+@param cio Output buffer stream
+@param volume Volume to encode
+@param index Name of the index file if required, NULL otherwise
+@return Returns true if successful, returns false otherwise
+*/
+OPJ_API bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_volume_t *volume, char *index);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OPENJPEG_H */
diff --git a/libopenjpeg3d/opj_includes.h b/libopenjpeg3d/opj_includes.h
new file mode 100755
index 00000000..0bff66ea
--- /dev/null
+++ b/libopenjpeg3d/opj_includes.h
@@ -0,0 +1,81 @@
+/*
+ * 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_INCLUDES_H
+#define OPJ_INCLUDES_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>
+/*
+ ==========================================================
+ OpenJPEG interface
+ ==========================================================
+ */
+#include "openjpeg3d.h"
+
+/*
+ ==========================================================
+ OpenJPEG modules
+ ==========================================================
+*/
+
+#include "jp3d_lib.h"
+#include "event.h"
+#include "cio.h"
+
+#include "volume.h"
+#include "jp3d.h"
+
+#include "mqc.h"
+#include "raw.h"
+#include "bio.h"
+#include "tgt.h"
+#include "tcd.h"
+#include "t1.h"
+#include "t1_3d.h"
+#include "dwt.h"
+#include "pi.h"
+#include "t2.h"
+#include "mct.h"
+#include "int.h"
+#include "fix.h"
+
+//#include "pred.h"
+//#include "golomb.h"
+
+#endif /* OPJ_INCLUDES_H */
diff --git a/libopenjpeg3d/pi.c b/libopenjpeg3d/pi.c
new file mode 100755
index 00000000..f9b8a963
--- /dev/null
+++ b/libopenjpeg3d/pi.c
@@ -0,0 +1,630 @@
+/*
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * Copyright (c) 2006, Mónica Díez, LPI-UVA, Spain
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opj_includes.h"
+
+/** @defgroup PI PI - Implementation of a packet iterator */
+/*@{*/
+
+/** @name Funciones locales */
+/*@{*/
+
+/**
+Get next packet in layer-resolution-component-precinct order.
+@param pi packet iterator to modify
+@return returns false if pi pointed to the last packet or else returns true
+*/
+static bool pi_next_lrcp(opj_pi_iterator_t * pi);
+/**
+Get next packet in resolution-layer-component-precinct order.
+@param pi packet iterator to modify
+@return returns false if pi pointed to the last packet or else returns true
+*/
+static bool pi_next_rlcp(opj_pi_iterator_t * pi);
+/**
+Get next packet in resolution-precinct-component-layer order.
+@param pi packet iterator to modify
+@return returns false if pi pointed to the last packet or else returns true
+*/
+static bool pi_next_rpcl(opj_pi_iterator_t * pi);
+/**
+Get next packet in precinct-component-resolution-layer order.
+@param pi packet iterator to modify
+@return returns false if pi pointed to the last packet or else returns true
+*/
+static bool pi_next_pcrl(opj_pi_iterator_t * pi);
+/**
+Get next packet in component-precinct-resolution-layer order.
+@param pi packet iterator to modify
+@return returns false if pi pointed to the last packet or else returns true
+*/
+static bool pi_next_cprl(opj_pi_iterator_t * pi);
+
+/*@}*/
+
+/*@}*/
+
+/*
+==========================================================
+ local functions
+==========================================================
+*/
+
+static bool pi_next_lrcp(opj_pi_iterator_t * pi) {
+ opj_pi_comp_t *comp = NULL;
+ opj_pi_resolution_t *res = NULL;
+ long index = 0;
+
+ if (!pi->first) {
+ comp = &pi->comps[pi->compno];
+ res = &comp->resolutions[pi->resno];
+ goto LABEL_SKIP;
+ } else {
+ pi->first = 0;
+ }
+
+ for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) {
+ for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) {
+ for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
+ comp = &pi->comps[pi->compno];
+ if (pi->resno >= comp->numresolution[0]) {
+ continue;
+ }
+ res = &comp->resolutions[pi->resno];
+ //for (pi->precno = 0; pi->precno < (res->prctno[0] * res->prctno[1]); pi->precno++) {
+ for (pi->precno = 0; pi->precno < (res->prctno[0] * res->prctno[1] * res->prctno[2]); pi->precno++) {
+ index = pi->layno * pi->step_l
+ + pi->resno * pi->step_r
+ + pi->compno * pi->step_c
+ + pi->precno * pi->step_p;
+ if (!pi->include[index]) {
+ pi->include[index] = 1;
+ return true;
+ }
+LABEL_SKIP:;
+
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+static bool pi_next_rlcp(opj_pi_iterator_t * pi) {
+ opj_pi_comp_t *comp = NULL;
+ opj_pi_resolution_t *res = NULL;
+ long index = 0;
+
+ if (!pi->first) {
+ comp = &pi->comps[pi->compno];
+ res = &comp->resolutions[pi->resno];
+ goto LABEL_SKIP;
+ } else {
+ pi->first = 0;
+ }
+
+ for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) {
+ for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) {
+ for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
+ comp = &pi->comps[pi->compno];
+ if (pi->resno >= comp->numresolution[0]) {
+ continue;
+ }
+ res = &comp->resolutions[pi->resno];
+ //for (pi->precno = 0; pi->precno < (res->prctno[0] * res->prctno[1]); pi->precno++) {
+ for (pi->precno = 0; pi->precno < (res->prctno[0] * res->prctno[1] * res->prctno[2]); pi->precno++) {
+ index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
+ if (!pi->include[index]) {
+ pi->include[index] = 1;
+ return true;
+ }
+LABEL_SKIP:;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+static bool pi_next_rpcl(opj_pi_iterator_t * pi) {
+ opj_pi_comp_t *comp = NULL;
+ opj_pi_resolution_t *res = NULL;
+ long index = 0;
+
+ if (!pi->first) {
+ goto LABEL_SKIP;
+ } else {
+ int compno, resno;
+ pi->first = 0;
+ pi->dx = 0;
+ pi->dy = 0;
+ for (compno = 0; compno < pi->numcomps; compno++) {
+ comp = &pi->comps[compno];
+ for (resno = 0; resno < comp->numresolution[0]; resno++) {
+ int dx, dy,dz;
+ res = &comp->resolutions[resno];
+ dx = comp->dx * (1 << (res->pdx + comp->numresolution[0] - 1 - resno));
+ dy = comp->dy * (1 << (res->pdy + comp->numresolution[1] - 1 - resno));
+ dz = comp->dz * (1 << (res->pdz + comp->numresolution[2] - 1 - resno));
+ pi->dx = !pi->dx ? dx : int_min(pi->dx, dx);
+ pi->dy = !pi->dy ? dy : int_min(pi->dy, dy);
+ pi->dz = !pi->dz ? dz : int_min(pi->dz, dz);
+ }
+ }
+ }
+
+ for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) {
+ for (pi->z = pi->tz0; pi->z < pi->tz1; pi->z += pi->dz - (pi->z % pi->dz)) {
+ for (pi->y = pi->ty0; pi->y < pi->ty1; pi->y += pi->dy - (pi->y % pi->dy)) {
+ for (pi->x = pi->tx0; pi->x < pi->tx1; pi->x += pi->dx - (pi->x % pi->dx)) {
+ for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
+ int levelnox, levelnoy, levelnoz;
+ int trx0, try0, trz0;
+ int trx1, try1, trz1;
+ int rpx, rpy, rpz;
+ int prci, prcj, prck;
+ comp = &pi->comps[pi->compno];
+ if (pi->resno >= comp->numresolution[0]) {
+ continue;
+ }
+ res = &comp->resolutions[pi->resno];
+ levelnox = comp->numresolution[0] - 1 - pi->resno;
+ levelnoy = comp->numresolution[1] - 1 - pi->resno;
+ levelnoz = comp->numresolution[2] - 1 - pi->resno;
+ trx0 = int_ceildiv(pi->tx0, comp->dx << levelnox);
+ try0 = int_ceildiv(pi->ty0, comp->dy << levelnoy);
+ trz0 = int_ceildiv(pi->tz0, comp->dz << levelnoz);
+ trx1 = int_ceildiv(pi->tx1, comp->dx << levelnox);
+ try1 = int_ceildiv(pi->ty1, comp->dy << levelnoy);
+ trz1 = int_ceildiv(pi->tz1, comp->dz << levelnoz);
+ rpx = res->pdx + levelnox;
+ rpy = res->pdy + levelnoy;
+ rpz = res->pdz + levelnoz;
+ if ((!(pi->x % (comp->dx << rpx) == 0) || (pi->x == pi->tx0 && (trx0 << levelnox) % (1 << rpx)))) {
+ continue;
+ }
+ if ((!(pi->y % (comp->dy << rpy) == 0) || (pi->y == pi->ty0 && (try0 << levelnoy) % (1 << rpx)))) {
+ continue;
+ }
+ if ((!(pi->z % (comp->dz << rpz) == 0) || (pi->z == pi->tz0 && (trz0 << levelnoz) % (1 << rpx)))) {
+ continue;
+ }
+ if ((res->prctno[0]==0)||(res->prctno[1]==0)||(res->prctno[2]==0)) continue;
+
+ if ((trx0==trx1)||(try0==try1)||(trz0==trz1)) continue;
+
+ prci = int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelnox), res->pdx)
+ - int_floordivpow2(trx0, res->pdx);
+ prcj = int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelnoy), res->pdy)
+ - int_floordivpow2(try0, res->pdy);
+ prck = int_floordivpow2(int_ceildiv(pi->z, comp->dz << levelnoz), res->pdz)
+ - int_floordivpow2(trz0, res->pdz);
+ pi->precno = prci + prcj * res->prctno[0] + prck * res->prctno[0] * res->prctno[1];
+ for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) {
+ index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
+ if (!pi->include[index]) {
+ pi->include[index] = 1;
+ return true;
+ }
+ LABEL_SKIP:;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+static bool pi_next_pcrl(opj_pi_iterator_t * pi) {
+ opj_pi_comp_t *comp = NULL;
+ opj_pi_resolution_t *res = NULL;
+ long index = 0;
+
+ if (!pi->first) {
+ comp = &pi->comps[pi->compno];
+ goto LABEL_SKIP;
+ } else {
+ int compno, resno;
+ pi->first = 0;
+ pi->dx = 0;
+ pi->dy = 0;
+ pi->dz = 0;
+ for (compno = 0; compno < pi->numcomps; compno++) {
+ comp = &pi->comps[compno];
+ for (resno = 0; resno < comp->numresolution[0]; resno++) {
+ int dx, dy, dz;
+ res = &comp->resolutions[resno];
+ dx = comp->dx * (1 << (res->pdx + comp->numresolution[0] - 1 - resno));
+ dy = comp->dy * (1 << (res->pdy + comp->numresolution[1] - 1 - resno));
+ dz = comp->dz * (1 << (res->pdy + comp->numresolution[2] - 1 - resno));
+ pi->dx = !pi->dx ? dx : int_min(pi->dx, dx);
+ pi->dy = !pi->dy ? dy : int_min(pi->dy, dy);
+ pi->dz = !pi->dz ? dz : int_min(pi->dz, dz);
+ }
+ }
+ }
+
+for (pi->z = pi->tz0; pi->z < pi->tz1; pi->z += pi->dz - (pi->z % pi->dz)) {
+ for (pi->y = pi->ty0; pi->y < pi->ty1; pi->y += pi->dy - (pi->y % pi->dy)) {
+ for (pi->x = pi->tx0; pi->x < pi->tx1; pi->x += pi->dx - (pi->x % pi->dx)) {
+ for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
+ comp = &pi->comps[pi->compno];
+ for (pi->resno = pi->poc.resno0; pi->resno < int_min(pi->poc.resno1, comp->numresolution[0]); pi->resno++) {
+ int levelnox, levelnoy, levelnoz;
+ int trx0, try0, trz0;
+ int trx1, try1, trz1;
+ int rpx, rpy, rpz;
+ int prci, prcj, prck;
+ comp = &pi->comps[pi->compno];
+ if (pi->resno >= comp->numresolution[0]) {
+ continue;
+ }
+ res = &comp->resolutions[pi->resno];
+ levelnox = comp->numresolution[0] - 1 - pi->resno;
+ levelnoy = comp->numresolution[1] - 1 - pi->resno;
+ levelnoz = comp->numresolution[2] - 1 - pi->resno;
+ trx0 = int_ceildiv(pi->tx0, comp->dx << levelnox);
+ try0 = int_ceildiv(pi->ty0, comp->dy << levelnoy);
+ trz0 = int_ceildiv(pi->tz0, comp->dz << levelnoz);
+ trx1 = int_ceildiv(pi->tx1, comp->dx << levelnox);
+ try1 = int_ceildiv(pi->ty1, comp->dy << levelnoy);
+ trz1 = int_ceildiv(pi->tz1, comp->dz << levelnoz);
+ rpx = res->pdx + levelnox;
+ rpy = res->pdy + levelnoy;
+ rpz = res->pdz + levelnoz;
+ if ((!(pi->x % (comp->dx << rpx) == 0) || (pi->x == pi->tx0 && (trx0 << levelnox) % (1 << rpx)))) {
+ continue;
+ }
+ if ((!(pi->y % (comp->dy << rpy) == 0) || (pi->y == pi->ty0 && (try0 << levelnoy) % (1 << rpx)))) {
+ continue;
+ }
+ if ((!(pi->z % (comp->dz << rpz) == 0) || (pi->z == pi->tz0 && (trz0 << levelnoz) % (1 << rpx)))) {
+ continue;
+ }
+ if ((res->prctno[0]==0)||(res->prctno[1]==0)||(res->prctno[2]==0)) continue;
+
+ if ((trx0==trx1)||(try0==try1)||(trz0==trz1)) continue;
+
+ prci = int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelnox), res->pdx)
+ - int_floordivpow2(trx0, res->pdx);
+ prcj = int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelnoy), res->pdy)
+ - int_floordivpow2(try0, res->pdy);
+ prck = int_floordivpow2(int_ceildiv(pi->z, comp->dz << levelnoz), res->pdz)
+ - int_floordivpow2(trz0, res->pdz);
+ pi->precno = prci + prcj * res->prctno[0] + prck * res->prctno[0] * res->prctno[1];
+ for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) {
+ index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
+ if (!pi->include[index]) {
+ pi->include[index] = 1;
+ return true;
+ }
+LABEL_SKIP:;
+ }
+ }
+ }
+ }
+ }
+}
+
+ return false;
+}
+
+static bool pi_next_cprl(opj_pi_iterator_t * pi) {
+ opj_pi_comp_t *comp = NULL;
+ opj_pi_resolution_t *res = NULL;
+ long index = 0;
+
+ if (!pi->first) {
+ comp = &pi->comps[pi->compno];
+ goto LABEL_SKIP;
+ } else {
+ pi->first = 0;
+ }
+
+ for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
+ int resno;
+ comp = &pi->comps[pi->compno];
+ pi->dx = 0;
+ pi->dy = 0;
+ for (resno = 0; resno < comp->numresolution[0]; resno++) {
+ int dx, dy;
+ res = &comp->resolutions[resno];
+ dx = comp->dx * (1 << (res->pdx + comp->numresolution[0] - 1 - resno));
+ dy = comp->dy * (1 << (res->pdy + comp->numresolution[0] - 1 - resno));
+ pi->dx = !pi->dx ? dx : int_min(pi->dx, dx);
+ pi->dy = !pi->dy ? dy : int_min(pi->dy, dy);
+ }
+ for (pi->z = pi->tz0; pi->z < pi->tz1; pi->z += pi->dz - (pi->z % pi->dz)) {
+ for (pi->y = pi->ty0; pi->y < pi->ty1; pi->y += pi->dy - (pi->y % pi->dy)) {
+ for (pi->x = pi->tx0; pi->x < pi->tx1; pi->x += pi->dx - (pi->x % pi->dx)) {
+ for (pi->resno = pi->poc.resno0; pi->resno < int_min(pi->poc.resno1, comp->numresolution[0]); pi->resno++) {
+ int levelnox, levelnoy, levelnoz;
+ int trx0, try0, trz0;
+ int trx1, try1, trz1;
+ int rpx, rpy, rpz;
+ int prci, prcj, prck;
+ comp = &pi->comps[pi->compno];
+ if (pi->resno >= comp->numresolution[0]) {
+ continue;
+ }
+ res = &comp->resolutions[pi->resno];
+ levelnox = comp->numresolution[0] - 1 - pi->resno;
+ levelnoy = comp->numresolution[1] - 1 - pi->resno;
+ levelnoz = comp->numresolution[2] - 1 - pi->resno;
+ trx0 = int_ceildiv(pi->tx0, comp->dx << levelnox);
+ try0 = int_ceildiv(pi->ty0, comp->dy << levelnoy);
+ trz0 = int_ceildiv(pi->tz0, comp->dz << levelnoz);
+ trx1 = int_ceildiv(pi->tx1, comp->dx << levelnox);
+ try1 = int_ceildiv(pi->ty1, comp->dy << levelnoy);
+ trz1 = int_ceildiv(pi->tz1, comp->dz << levelnoz);
+ rpx = res->pdx + levelnox;
+ rpy = res->pdy + levelnoy;
+ rpz = res->pdz + levelnoz;
+ if ((!(pi->x % (comp->dx << rpx) == 0) || (pi->x == pi->tx0 && (trx0 << levelnox) % (1 << rpx)))) {
+ continue;
+ }
+ if ((!(pi->y % (comp->dy << rpy) == 0) || (pi->y == pi->ty0 && (try0 << levelnoy) % (1 << rpx)))) {
+ continue;
+ }
+ if ((!(pi->z % (comp->dz << rpz) == 0) || (pi->z == pi->tz0 && (trz0 << levelnoz) % (1 << rpx)))) {
+ continue;
+ }
+ if ((res->prctno[0]==0)||(res->prctno[1]==0)||(res->prctno[2]==0)) continue;
+
+ if ((trx0==trx1)||(try0==try1)||(trz0==trz1)) continue;
+
+ prci = int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelnox), res->pdx)
+ - int_floordivpow2(trx0, res->pdx);
+ prcj = int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelnoy), res->pdy)
+ - int_floordivpow2(try0, res->pdy);
+ prck = int_floordivpow2(int_ceildiv(pi->z, comp->dz << levelnoz), res->pdz)
+ - int_floordivpow2(trz0, res->pdz);
+ pi->precno = prci + prcj * res->prctno[0] + prck * res->prctno[0] * res->prctno[1];
+ for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) {
+ index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
+ if (!pi->include[index]) {
+ pi->include[index] = 1;
+ return true;
+ }
+ LABEL_SKIP:;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+/*
+==========================================================
+ Packet iterator interface
+==========================================================
+*/
+
+opj_pi_iterator_t *pi_create(opj_volume_t *volume, opj_cp_t *cp, int tileno) {
+ int p, q, r;
+ int compno, resno, pino;
+ opj_pi_iterator_t *pi = NULL;
+ opj_tcp_t *tcp = NULL;
+ opj_tccp_t *tccp = NULL;
+ size_t array_size;
+
+ tcp = &cp->tcps[tileno];
+
+ array_size = (tcp->numpocs + 1) * sizeof(opj_pi_iterator_t);
+ pi = (opj_pi_iterator_t *) opj_malloc(array_size);
+ if(!pi) {
+ fprintf(stdout,"[ERROR] Malloc of opj_pi_iterator failed \n");
+ return NULL;
+ }
+
+ for (pino = 0; pino < tcp->numpocs + 1; pino++) { /* change */
+ int maxres = 0;
+ int maxprec = 0;
+ p = tileno % cp->tw;
+ q = tileno / cp->tw;
+ r = tileno / (cp->tw * cp->th);
+
+ pi[pino].tx0 = int_max(cp->tx0 + p * cp->tdx, volume->x0);
+ pi[pino].ty0 = int_max(cp->ty0 + q * cp->tdy, volume->y0);
+ pi[pino].tz0 = int_max(cp->tz0 + r * cp->tdz, volume->z0);
+ pi[pino].tx1 = int_min(cp->tx0 + (p + 1) * cp->tdx, volume->x1);
+ pi[pino].ty1 = int_min(cp->ty0 + (q + 1) * cp->tdy, volume->y1);
+ pi[pino].tz1 = int_min(cp->tz0 + (r + 1) * cp->tdz, volume->z1);
+ pi[pino].numcomps = volume->numcomps;
+
+ array_size = volume->numcomps * sizeof(opj_pi_comp_t);
+ pi[pino].comps = (opj_pi_comp_t *) opj_malloc(array_size);
+ if(!pi[pino].comps) {
+ fprintf(stdout,"[ERROR] Malloc of opj_pi_comp failed \n");
+ pi_destroy(pi, cp, tileno);
+ return NULL;
+ }
+ memset(pi[pino].comps, 0, array_size);
+
+ for (compno = 0; compno < pi->numcomps; compno++) {
+ int tcx0, tcx1, tcy0, tcy1, tcz0, tcz1;
+ int i;
+ opj_pi_comp_t *comp = &pi[pino].comps[compno];
+ tccp = &tcp->tccps[compno];
+
+ comp->dx = volume->comps[compno].dx;
+ comp->dy = volume->comps[compno].dy;
+ comp->dz = volume->comps[compno].dz;
+ for (i = 0; i < 3; i++) {
+ comp->numresolution[i] = tccp->numresolution[i];
+ if (comp->numresolution[i] > maxres) {
+ maxres = comp->numresolution[i];
+ }
+ }
+ array_size = comp->numresolution[0] * sizeof(opj_pi_resolution_t);
+ comp->resolutions = (opj_pi_resolution_t *) opj_malloc(array_size);
+ if(!comp->resolutions) {
+ fprintf(stdout,"[ERROR] Malloc of opj_pi_resolution failed \n");
+ pi_destroy(pi, cp, tileno);
+ return NULL;
+ }
+
+ tcx0 = int_ceildiv(pi->tx0, comp->dx);
+ tcy0 = int_ceildiv(pi->ty0, comp->dy);
+ tcz0 = int_ceildiv(pi->tz0, comp->dz);
+ tcx1 = int_ceildiv(pi->tx1, comp->dx);
+ tcy1 = int_ceildiv(pi->ty1, comp->dy);
+ tcz1 = int_ceildiv(pi->tz1, comp->dz);
+
+ for (resno = 0; resno < comp->numresolution[0]; resno++) {
+ int levelnox, levelnoy, levelnoz, diff;
+ int rx0, ry0, rz0, rx1, ry1, rz1;
+ int px0, py0, pz0, px1, py1, pz1;
+ opj_pi_resolution_t *res = &comp->resolutions[resno];
+ if (tccp->csty & J3D_CCP_CSTY_PRT) {
+ res->pdx = tccp->prctsiz[0][resno];
+ res->pdy = tccp->prctsiz[1][resno];
+ res->pdz = tccp->prctsiz[2][resno];
+ } else {
+ res->pdx = 15;
+ res->pdy = 15;
+ res->pdz = 15;
+ }
+ levelnox = comp->numresolution[0] - 1 - resno;
+ levelnoy = comp->numresolution[1] - 1 - resno;
+ levelnoz = comp->numresolution[2] - 1 - resno;
+ if (levelnoz < 0) levelnoz = 0;
+ diff = comp->numresolution[0] - comp->numresolution[2];
+
+ rx0 = int_ceildivpow2(tcx0, levelnox);
+ ry0 = int_ceildivpow2(tcy0, levelnoy);
+ rz0 = int_ceildivpow2(tcz0, levelnoz);
+ rx1 = int_ceildivpow2(tcx1, levelnox);
+ ry1 = int_ceildivpow2(tcy1, levelnoy);
+ rz1 = int_ceildivpow2(tcz1, levelnoz);
+ px0 = int_floordivpow2(rx0, res->pdx) << res->pdx;
+ py0 = int_floordivpow2(ry0, res->pdy) << res->pdy;
+ pz0 = int_floordivpow2(rz0, res->pdz) << res->pdz;
+ px1 = int_ceildivpow2(rx1, res->pdx) << res->pdx;
+ py1 = int_ceildivpow2(ry1, res->pdy) << res->pdy;
+ pz1 = int_ceildivpow2(rz1, res->pdz) << res->pdz;
+ res->prctno[0] = (rx0==rx1)? 0 : ((px1 - px0) >> res->pdx);
+ res->prctno[1] = (ry0==ry1)? 0 : ((py1 - py0) >> res->pdy);
+ res->prctno[2] = (rz0==rz1)? 0 : ((pz1 - pz0) >> res->pdz);
+
+ if (res->prctno[0]*res->prctno[1]*res->prctno[2] > maxprec) {
+ maxprec = res->prctno[0]*res->prctno[1]*res->prctno[2];
+ }
+ }
+ }
+
+ tccp = &tcp->tccps[0];
+ pi[pino].step_p = 1;
+ pi[pino].step_c = maxprec * pi[pino].step_p;
+ pi[pino].step_r = volume->numcomps * pi[pino].step_c;
+ pi[pino].step_l = maxres * pi[pino].step_r;
+
+ if (pino == 0) {
+ array_size = volume->numcomps * maxres * tcp->numlayers * maxprec * sizeof(short int);
+ pi[pino].include = (short int *) opj_malloc(array_size);
+ if(!pi[pino].include) {
+ fprintf(stdout,"[ERROR] Malloc of pi[pino].include failed \n");
+ pi_destroy(pi, cp, tileno);
+ return NULL;
+ }
+ }
+ else {
+ pi[pino].include = pi[pino - 1].include;
+ }
+
+ if (tcp->POC == 0) {
+ pi[pino].first = 1;
+ pi[pino].poc.resno0 = 0;
+ pi[pino].poc.compno0 = 0;
+ pi[pino].poc.layno1 = tcp->numlayers;
+ pi[pino].poc.resno1 = maxres;
+ pi[pino].poc.compno1 = volume->numcomps;
+ pi[pino].poc.prg = tcp->prg;
+ } else {
+ pi[pino].first = 1;
+ pi[pino].poc.resno0 = tcp->pocs[pino].resno0;
+ pi[pino].poc.compno0 = tcp->pocs[pino].compno0;
+ pi[pino].poc.layno1 = tcp->pocs[pino].layno1;
+ pi[pino].poc.resno1 = tcp->pocs[pino].resno1;
+ pi[pino].poc.compno1 = tcp->pocs[pino].compno1;
+ pi[pino].poc.prg = tcp->pocs[pino].prg;
+ }
+ }
+
+ return pi;
+}
+
+void pi_destroy(opj_pi_iterator_t *pi, opj_cp_t *cp, int tileno) {
+ int compno, pino;
+ opj_tcp_t *tcp = &cp->tcps[tileno];
+ if(pi) {
+ for (pino = 0; pino < tcp->numpocs + 1; pino++) {
+ if(pi[pino].comps) {
+ for (compno = 0; compno < pi->numcomps; compno++) {
+ opj_pi_comp_t *comp = &pi[pino].comps[compno];
+ if(comp->resolutions) {
+ opj_free(comp->resolutions);
+ }
+ }
+ opj_free(pi[pino].comps);
+ }
+ }
+ if(pi->include) {
+ opj_free(pi->include);
+ }
+ opj_free(pi);
+ }
+}
+
+bool pi_next(opj_pi_iterator_t * pi) {
+ switch (pi->poc.prg) {
+ case LRCP:
+ return pi_next_lrcp(pi);
+ case RLCP:
+ return pi_next_rlcp(pi);
+ case RPCL:
+ return pi_next_rpcl(pi);
+ case PCRL:
+ return pi_next_pcrl(pi);
+ case CPRL:
+ return pi_next_cprl(pi);
+ }
+
+ return false;
+}
+
diff --git a/libopenjpeg3d/pi.h b/libopenjpeg3d/pi.h
new file mode 100755
index 00000000..1edcc5fc
--- /dev/null
+++ b/libopenjpeg3d/pi.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * Copyright (c) 2006, Mónica Díez García, Image Processing Laboratory, University of Valladolid, Spain
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PI_H
+#define __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 */
+/*@{*/
+
+/**
+Packet iterator : resolution level information
+*/
+typedef struct opj_pi_resolution {
+/** Size of precints in horizontal axis */
+ int pdx;
+/** Size of precints in vertical axis */
+ int pdy;
+/** Size of precints in axial axis */
+ int pdz;
+/** Number of precints in each axis */
+ int prctno[3];
+} opj_pi_resolution_t;
+
+/**
+Packet iterator : component information
+*/
+typedef struct opj_pi_comp {
+/** Size in horizontal axis */
+ int dx;
+/** Size in vertical axis */
+ int dy;
+/** Size in axial axis */
+ int dz;
+/** Number of resolution levels */
+ int numresolution[3];
+/** Packet iterator : resolution level information */
+ opj_pi_resolution_t *resolutions;
+} opj_pi_comp_t;
+
+/**
+Packet iterator
+*/
+typedef struct opj_pi_iterator {
+/** precise if the packet has been already used (usefull for progression order change) */
+ short int *include;
+/** layer step used to localize the packet in the include vector */
+ int step_l;
+/** resolution step used to localize the packet in the include vector */
+ int step_r;
+/** component step used to localize the packet in the include vector */
+ int step_c;
+/** precinct step used to localize the packet in the include vector */
+ int step_p;
+/** component that identify the packet */
+ int compno;
+/** resolution that identify the packet */
+ int resno;
+/** precinct that identify the packet */
+ int precno;
+/** layer that identify the packet */
+ int layno;
+/** 0 if the first packet */
+ int first;
+/** progression order change information */
+ opj_poc_t poc;
+/** Packet iterator : component information */
+opj_pi_comp_t *comps;
+
+ int numcomps;
+ int tx0, ty0, tz0;
+ int tx1, ty1, tz1;
+ int x, y, z;
+ int dx, dy, dz;
+} opj_pi_iterator_t;
+
+/** @name Funciones generales */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+/**
+Create a packet iterator
+@param volume Raw volume for which the packets will be listed
+@param cp Coding parameters
+@param tileno Number that identifies the tile for which to list the packets
+@return Returns a packet iterator that points to the first packet of the tile
+@see pi_destroy
+*/
+opj_pi_iterator_t *pi_create(opj_volume_t * volume, opj_cp_t * cp, int tileno);
+
+/**
+Destroy a packet iterator
+@param pi Previously created packet iterator
+@param cp Coding parameters
+@param tileno Number that identifies the tile for which the packets were listed
+@see pi_create
+*/
+void pi_destroy(opj_pi_iterator_t *pi, opj_cp_t *cp, int tileno);
+
+/**
+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
+*/
+bool pi_next(opj_pi_iterator_t * pi);
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+#endif /* __PI_H */
diff --git a/libopenjpeg3d/raw.c b/libopenjpeg3d/raw.c
new file mode 100755
index 00000000..b6a58106
--- /dev/null
+++ b/libopenjpeg3d/raw.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * 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"
+
+/*
+==========================================================
+ local functions
+==========================================================
+*/
+
+
+/*
+==========================================================
+ RAW encoding interface
+==========================================================
+*/
+
+opj_raw_t* raw_create() {
+ opj_raw_t *raw = (opj_raw_t*)opj_malloc(sizeof(opj_raw_t));
+ return raw;
+}
+
+void raw_destroy(opj_raw_t *raw) {
+ if(raw) {
+ opj_free(raw);
+ }
+}
+
+int raw_numbytes(opj_raw_t *raw) {
+ return raw->bp - raw->start;
+}
+
+void raw_init_dec(opj_raw_t *raw, unsigned char *bp, int len) {
+ raw->start = bp;
+ raw->lenmax = len;
+ raw->len = 0;
+ raw->c = 0;
+ raw->ct = 0;
+}
+
+int raw_decode(opj_raw_t *raw) {
+ int d;
+ if (raw->ct == 0) {
+ raw->ct = 8;
+ if (raw->len == raw->lenmax) {
+ raw->c = 0xff;
+ } else {
+ if (raw->c == 0xff) {
+ raw->ct = 7;
+ }
+ raw->c = *(raw->start + raw->len);
+ raw->len++;
+ }
+ }
+ raw->ct--;
+ d = (raw->c >> raw->ct) & 0x01;
+
+ return d;
+}
+
diff --git a/libopenjpeg3d/raw.h b/libopenjpeg3d/raw.h
new file mode 100755
index 00000000..c26546ad
--- /dev/null
+++ b/libopenjpeg3d/raw.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * 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 __RAW_H
+#define __RAW_H
+/**
+@file raw.h
+@brief Implementation of operations for raw encoding (RAW)
+
+The functions in RAW.C have for goal to realize the operation of raw encoding linked
+with the corresponding mode switch.
+*/
+
+/** @defgroup RAW RAW - Implementation of operations for raw encoding */
+/*@{*/
+
+/**
+RAW encoding operations
+*/
+typedef struct opj_raw {
+/** Temporary buffer where bits are coded or decoded */
+ unsigned char c;
+/** Number of bits already read or free to write */
+ unsigned int ct;
+/** Maximum length to decode */
+ unsigned int lenmax;
+/** Length decoded */
+ unsigned int len;
+/** Pointer to the current position in the buffer */
+ unsigned char *bp;
+/** Pointer to the start of the buffer */
+ unsigned char *start;
+/** Pointer to the end of the buffer */
+ unsigned char *end;
+} opj_raw_t;
+
+/** @name Funciones generales */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+/**
+Create a new RAW handle
+@return Returns a new RAW handle if successful, returns NULL otherwise
+*/
+opj_raw_t* raw_create();
+/**
+Destroy a previously created RAW handle
+@param raw RAW handle to destroy
+*/
+void raw_destroy(opj_raw_t *raw);
+/**
+Return the number of bytes written/read since initialisation
+@param raw RAW handle to destroy
+@return Returns the number of bytes already encoded
+*/
+int raw_numbytes(opj_raw_t *raw);
+/**
+Initialize the decoder
+@param raw RAW handle
+@param bp Pointer to the start of the buffer from which the bytes will be read
+@param len Length of the input buffer
+*/
+void raw_init_dec(opj_raw_t *raw, unsigned char *bp, int len);
+/**
+Decode a symbol using raw-decoder. Cfr p.506 TAUBMAN
+@param raw RAW handle
+@return Returns the decoded symbol (0 or 1)
+*/
+int raw_decode(opj_raw_t *raw);
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+#endif /* __RAW_H */
diff --git a/libopenjpeg3d/t1.c b/libopenjpeg3d/t1.c
new file mode 100755
index 00000000..db1d2601
--- /dev/null
+++ b/libopenjpeg3d/t1.c
@@ -0,0 +1,1181 @@
+/*
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * 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 T1 T1 - Implementation of the tier-1 coding */
+/*@{*/
+
+/** @name Local static functions */
+/*@{*/
+
+static int t1_getctxno_zc(opj_t1_t *t1, int f, int orient);
+static int t1_getctxno_sc(opj_t1_t *t1, int f);
+static int t1_getctxno_mag(opj_t1_t *t1, int f);
+static int t1_getspb(opj_t1_t *t1, int f);
+static int t1_getnmsedec_sig(opj_t1_t *t1, int x, int bitpos);
+static int t1_getnmsedec_ref(opj_t1_t *t1, int x, int bitpos);
+static void t1_updateflags(int *fp, int s);
+/**
+Encode significant pass
+*/
+static void t1_enc_sigpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int bpno, int one, int *nmsedec, char type, int vsc);
+/**
+Decode significant pass
+*/
+static void t1_dec_sigpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int oneplushalf, char type, int vsc);
+/**
+Encode significant pass
+*/
+static void t1_enc_sigpass(opj_t1_t *t1, int w, int h, int l, int bpno, int orient, int *nmsedec, char type, int cblksty);
+/**
+Decode significant pass
+*/
+static void t1_dec_sigpass(opj_t1_t *t1, int w, int h, int l, int bpno, int orient, char type, int cblksty);
+/**
+Encode refinement pass
+*/
+static void t1_enc_refpass_step(opj_t1_t *t1, int *fp, int *dp, int bpno, int one, int *nmsedec, char type, int vsc);
+/**
+Decode refinement pass
+*/
+static void t1_dec_refpass_step(opj_t1_t *t1, int *fp, int *dp, int poshalf, int neghalf, char type, int vsc);
+/**
+Encode refinement pass
+*/
+static void t1_enc_refpass(opj_t1_t *t1, int w, int h, int l, int bpno, int *nmsedec, char type, int cblksty);
+/**
+Decode refinement pass
+*/
+static void t1_dec_refpass(opj_t1_t *t1, int w, int h, int l, int bpno, char type, int cblksty);
+/**
+Encode clean-up pass
+*/
+static void t1_enc_clnpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int bpno, int one, int *nmsedec, int partial, int vsc);
+/**
+Decode clean-up pass
+*/
+static void t1_dec_clnpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int oneplushalf, int partial, int vsc);
+/**
+Encode clean-up pass
+*/
+static void t1_enc_clnpass(opj_t1_t *t1, int w, int h, int l, int bpno, int orient, int *nmsedec, int cblksty);
+/**
+Decode clean-up pass
+*/
+static void t1_dec_clnpass(opj_t1_t *t1, int w, int h, int l, int bpno, int orient, int cblksty);
+/**
+Encode 1 code-block
+@param t1 T1 handle
+@param cblk Code-block coding parameters
+@param orient
+@param compno Component number
+@param level
+@param dwtid
+@param stepsize
+@param cblksty Code-block style
+@param numcomps
+@param tile
+*/
+static void t1_encode_cblk(opj_t1_t *t1, opj_tcd_cblk_t * cblk, int orient, int compno, int level[3], int dwtid[3], double stepsize, int cblksty, int numcomps, opj_tcd_tile_t * tile);
+/**
+Decode 1 code-block
+@param t1 T1 handle
+@param cblk Code-block coding parameters
+@param orient
+@param roishift Region of interest shifting value
+@param cblksty Code-block style
+*/
+static void t1_decode_cblk(opj_t1_t *t1, opj_tcd_cblk_t * cblk, int orient, int roishift, int cblksty);
+
+static int t1_init_ctxno_zc(int f, int orient);
+static int t1_init_ctxno_sc(int f);
+static int t1_init_ctxno_mag(int f);
+static int t1_init_spb(int f);
+/**
+Initialize the look-up tables of the Tier-1 coder/decoder
+@param t1 T1 handle
+*/
+static void t1_init_luts(opj_t1_t *t1);
+
+/*@}*/
+
+/*@}*/
+
+/* ----------------------------------------------------------------------- */
+
+static int t1_getctxno_zc(opj_t1_t *t1, int f, int orient) {
+ return t1->lut_ctxno_zc[(orient << 8) | (f & T1_SIG_OTH)];
+}
+
+static int t1_getctxno_sc(opj_t1_t *t1, int f) {
+ return t1->lut_ctxno_sc[(f & (T1_SIG_PRIM | T1_SGN)) >> 4];
+}
+
+static int t1_getctxno_mag(opj_t1_t *t1, int f) {
+ return t1->lut_ctxno_mag[(f & T1_SIG_OTH) | (((f & T1_REFINE) != 0) << 11)];
+}
+
+static int t1_getspb(opj_t1_t *t1, int f) {
+ return t1->lut_spb[(f & (T1_SIG_PRIM | T1_SGN)) >> 4];
+}
+
+static int t1_getnmsedec_sig(opj_t1_t *t1, int x, int bitpos) {
+ if (bitpos > T1_NMSEDEC_FRACBITS) {
+ return t1->lut_nmsedec_sig[(x >> (bitpos - T1_NMSEDEC_FRACBITS)) & ((1 << T1_NMSEDEC_BITS) - 1)];
+ }
+
+ return t1->lut_nmsedec_sig0[x & ((1 << T1_NMSEDEC_BITS) - 1)];
+}
+
+static int t1_getnmsedec_ref(opj_t1_t *t1, int x, int bitpos) {
+ if (bitpos > T1_NMSEDEC_FRACBITS) {
+ return t1->lut_nmsedec_ref[(x >> (bitpos - T1_NMSEDEC_FRACBITS)) & ((1 << T1_NMSEDEC_BITS) - 1)];
+ }
+
+ return t1->lut_nmsedec_ref0[x & ((1 << T1_NMSEDEC_BITS) - 1)];
+}
+
+static void t1_updateflags(int *fp, int s) {
+ int *np = fp - (T1_MAXCBLKW + 2);
+ int *sp = fp + (T1_MAXCBLKW + 2);
+ np[-1] |= T1_SIG_SE;
+ np[1] |= T1_SIG_SW;
+ sp[-1] |= T1_SIG_NE;
+ sp[1] |= T1_SIG_NW;
+ *np |= T1_SIG_S;
+ *sp |= T1_SIG_N;
+ fp[-1] |= T1_SIG_E;
+ fp[1] |= T1_SIG_W;
+ if (s) {
+ *np |= T1_SGN_S;
+ *sp |= T1_SGN_N;
+ fp[-1] |= T1_SGN_E;
+ fp[1] |= T1_SGN_W;
+ }
+}
+
+static void t1_enc_sigpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int bpno, int one, int *nmsedec, char type, int vsc) {
+ int v, flag;
+
+ opj_mqc_t *mqc = t1->mqc; /* MQC component */
+
+ flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*fp);
+ if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) {
+ v = int_abs(*dp) & one ? 1 : 0;
+ if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */
+ mqc_setcurctx(mqc, t1_getctxno_zc(t1, flag, orient)); /* ESSAI */
+ mqc_bypass_enc(mqc, v);
+ } else {
+ mqc_setcurctx(mqc, t1_getctxno_zc(t1, flag, orient));
+ mqc_encode(mqc, v);
+ }
+ if (v) {
+ v = *dp < 0 ? 1 : 0;
+ *nmsedec += t1_getnmsedec_sig(t1, int_abs(*dp), bpno + T1_NMSEDEC_FRACBITS);
+ if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */
+ mqc_setcurctx(mqc, t1_getctxno_sc(t1, flag)); /* ESSAI */
+ mqc_bypass_enc(mqc, v);
+ } else {
+ mqc_setcurctx(mqc, t1_getctxno_sc(t1, flag));
+ mqc_encode(mqc, v ^ t1_getspb(t1, flag));
+ }
+ t1_updateflags(fp, v);
+ *fp |= T1_SIG;
+ }
+ *fp |= T1_VISIT;
+ }
+}
+
+static void t1_dec_sigpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int oneplushalf, char type, int vsc) {
+ int v, flag;
+
+ opj_raw_t *raw = t1->raw; /* RAW component */
+ opj_mqc_t *mqc = t1->mqc; /* MQC component */
+
+ flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*fp);
+ if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) {
+ if (type == T1_TYPE_RAW) {
+ if (raw_decode(raw)) {
+ v = raw_decode(raw); /* ESSAI */
+ *dp = v ? -oneplushalf : oneplushalf;
+ t1_updateflags(fp, v);
+ *fp |= T1_SIG;
+ }
+ } else {
+ mqc_setcurctx(mqc, t1_getctxno_zc(t1, flag, orient));
+ if (mqc_decode(mqc)) {
+ mqc_setcurctx(mqc, t1_getctxno_sc(t1, flag));
+ v = mqc_decode(mqc) ^ t1_getspb(t1, flag);
+ *dp = v ? -oneplushalf : oneplushalf;
+ t1_updateflags(fp, v);
+ *fp |= T1_SIG;
+ }
+ }
+ *fp |= T1_VISIT;
+ }
+} /* VSC and BYPASS by Antonin */
+
+static void t1_enc_sigpass(opj_t1_t *t1, int w, int h, int l, int bpno, int orient, int *nmsedec, char type, int cblksty) {
+ int i, j, k, m, one, vsc;
+ *nmsedec = 0;
+ one = 1 << (bpno + T1_NMSEDEC_FRACBITS);
+ for (m = 0; m < l; m++) {
+ for (k = 0; k < h; k += 4) {
+ for (i = 0; i < w; i++) {
+ for (j = k; j < k + 4 && j < h; j++) {
+ vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0;
+ t1_enc_sigpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->data[m][j][i], orient, bpno, one, nmsedec, type, vsc);
+ }
+ }
+ }
+ }
+}
+
+static void t1_dec_sigpass(opj_t1_t *t1, int w, int h, int l, int bpno, int orient, char type, int cblksty) {
+ int i, j, k, m, one, half, oneplushalf, vsc;
+ one = 1 << bpno;
+ half = one >> 1;
+ oneplushalf = one | half;
+ for (m = 0; m < l; m++) {
+ for (k = 0; k < h; k += 4) {
+ for (i = 0; i < w; i++) {
+ for (j = k; j < k + 4 && j < h; j++) {
+ vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0;
+ t1_dec_sigpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->data[m][j][i], orient, oneplushalf, type, vsc);
+ }
+ }
+ }
+ }
+} /* VSC and BYPASS by Antonin */
+
+static void t1_enc_refpass_step(opj_t1_t *t1, int *fp, int *dp, int bpno, int one, int *nmsedec, char type, int vsc) {
+ int v, flag;
+
+ opj_mqc_t *mqc = t1->mqc; /* MQC component */
+
+ flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*fp);
+ if ((flag & (T1_SIG | T1_VISIT)) == T1_SIG) {
+ *nmsedec += t1_getnmsedec_ref(t1, int_abs(*dp), bpno + T1_NMSEDEC_FRACBITS);
+ v = int_abs(*dp) & one ? 1 : 0;
+ if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */
+ mqc_setcurctx(mqc, t1_getctxno_mag(t1, flag)); /* ESSAI */
+ mqc_bypass_enc(mqc, v);
+ } else {
+ mqc_setcurctx(mqc, t1_getctxno_mag(t1, flag));
+ mqc_encode(mqc, v);
+ }
+ *fp |= T1_REFINE;
+ }
+}
+
+static void t1_dec_refpass_step(opj_t1_t *t1, int *fp, int *dp, int poshalf, int neghalf, char type, int vsc) {
+ int v, t, flag;
+
+ opj_mqc_t *mqc = t1->mqc; /* MQC component */
+ opj_raw_t *raw = t1->raw; /* RAW component */
+
+ flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*fp);
+ if ((flag & (T1_SIG | T1_VISIT)) == T1_SIG) {
+ if (type == T1_TYPE_RAW) {
+ mqc_setcurctx(mqc, t1_getctxno_mag(t1, flag)); /* ESSAI */
+ v = raw_decode(raw);
+ } else {
+ mqc_setcurctx(mqc, t1_getctxno_mag(t1, flag));
+ v = mqc_decode(mqc);
+ }
+ t = v ? poshalf : neghalf;
+ *dp += *dp < 0 ? -t : t;
+ *fp |= T1_REFINE;
+ }
+} /* VSC and BYPASS by Antonin */
+
+static void t1_enc_refpass(opj_t1_t *t1, int w, int h, int l, int bpno, int *nmsedec, char type, int cblksty) {
+ int i, j, k, m, one, vsc;
+ *nmsedec = 0;
+ one = 1 << (bpno + T1_NMSEDEC_FRACBITS);
+ for (m = 0; m < l; m++) {
+ for (k = 0; k < h; k += 4) {
+ for (i = 0; i < w; i++) {
+ for (j = k; j < k + 4 && j < h; j++) {
+ vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0;
+ t1_enc_refpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->data[m][j][i], bpno, one, nmsedec, type, vsc);
+ }
+ }
+ }
+ }
+}
+
+static void t1_dec_refpass(opj_t1_t *t1, int w, int h, int l, int bpno, char type, int cblksty) {
+ int i, j, k, m, one, poshalf, neghalf;
+ int vsc;
+ one = 1 << bpno;
+ poshalf = one >> 1;
+ neghalf = bpno > 0 ? -poshalf : -1;
+ for (m = 0; m < l; m++) {
+ for (k = 0; k < h; k += 4) {
+ for (i = 0; i < w; i++) {
+ for (j = k; j < k + 4 && j < h; j++) {
+ vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0;
+ t1_dec_refpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->data[m][j][i], poshalf, neghalf, type, vsc);
+ }
+ }
+ }
+ }
+} /* VSC and BYPASS by Antonin */
+
+static void t1_enc_clnpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int bpno, int one, int *nmsedec, int partial, int vsc) {
+ int v, flag;
+
+ opj_mqc_t *mqc = t1->mqc; /* MQC component */
+
+ flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*fp);
+ if (partial) {
+ goto LABEL_PARTIAL;
+ }
+ if (!(*fp & (T1_SIG | T1_VISIT))) {
+ mqc_setcurctx(mqc, t1_getctxno_zc(t1, flag, orient));
+ v = int_abs(*dp) & one ? 1 : 0;
+ mqc_encode(mqc, v);
+ if (v) {
+LABEL_PARTIAL:
+ *nmsedec += t1_getnmsedec_sig(t1, int_abs(*dp), bpno + T1_NMSEDEC_FRACBITS);
+ mqc_setcurctx(mqc, t1_getctxno_sc(t1, flag));
+ v = *dp < 0 ? 1 : 0;
+ mqc_encode(mqc, v ^ t1_getspb(t1, flag));
+ t1_updateflags(fp, v);
+ *fp |= T1_SIG;
+ }
+ }
+ *fp &= ~T1_VISIT;
+}
+
+static void t1_dec_clnpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int oneplushalf, int partial, int vsc) {
+ int v, flag;
+
+ opj_mqc_t *mqc = t1->mqc; /* MQC component */
+
+ flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*fp);
+ if (partial) {
+ goto LABEL_PARTIAL;
+ }
+ if (!(flag & (T1_SIG | T1_VISIT))) {
+ mqc_setcurctx(mqc, t1_getctxno_zc(t1, flag, orient));
+ if (mqc_decode(mqc)) {
+LABEL_PARTIAL:
+ mqc_setcurctx(mqc, t1_getctxno_sc(t1, flag));
+ v = mqc_decode(mqc) ^ t1_getspb(t1, flag);
+ *dp = v ? -oneplushalf : oneplushalf;
+ t1_updateflags(fp, v);
+ *fp |= T1_SIG;
+ }
+ }
+ *fp &= ~T1_VISIT;
+} /* VSC and BYPASS by Antonin */
+
+static void t1_enc_clnpass(opj_t1_t *t1, int w, int h, int l, int bpno, int orient, int *nmsedec, int cblksty) {
+ int i, j, k, m, one, agg, runlen, vsc;
+
+ opj_mqc_t *mqc = t1->mqc; /* MQC component */
+
+ *nmsedec = 0;
+ one = 1 << (bpno + T1_NMSEDEC_FRACBITS);
+ for (m = 0; m < l; m++) {
+ for (k = 0; k < h; k += 4) {
+ for (i = 0; i < w; i++) {
+ if (k + 3 < h) {
+ if (cblksty & J3D_CCP_CBLKSTY_VSC) {
+ agg = !(t1->flags[1 + m][1 + k][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH)
+ || t1->flags[1 + m][1 + k + 1][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH)
+ || t1->flags[1 + m][1 + k + 2][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH)
+ || (t1->flags[1 + m][1 + k + 3][1 + i]
+ & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) & (T1_SIG | T1_VISIT | T1_SIG_OTH));
+ } else {
+ agg = !(t1->flags[1 + m][1 + k][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH)
+ || t1->flags[1 + m][1 + k + 1][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH)
+ || t1->flags[1 + m][1 + k + 2][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH)
+ || t1->flags[1 + m][1 + k + 3][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH));
+ }
+ } else {
+ agg = 0;
+ }
+ if (agg) {
+ for (runlen = 0; runlen < 4; runlen++) {
+ if (int_abs(t1->data[m][k + runlen][i]) & one)
+ break;
+ }
+ mqc_setcurctx(mqc, T1_CTXNO_AGG);
+ mqc_encode(mqc, runlen != 4);
+ if (runlen == 4) {
+ continue;
+ }
+ mqc_setcurctx(mqc, T1_CTXNO_UNI);
+ mqc_encode(mqc, runlen >> 1);
+ mqc_encode(mqc, runlen & 1);
+ } else {
+ runlen = 0;
+ }
+ for (j = k + runlen; j < k + 4 && j < h; j++) {
+ vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0;
+ t1_enc_clnpass_step(t1, &(t1->flags[1 + m][1 + j][1 + i]), &(t1->data[m][j][i]), orient, bpno, one, nmsedec, agg && (j == k + runlen), vsc);
+ }
+ }
+ }
+ }
+}
+
+static void t1_dec_clnpass(opj_t1_t *t1, int w, int h, int l, int bpno, int orient, int cblksty) {
+ int i, j, k, m, one, half, oneplushalf, agg, runlen, vsc;
+ int segsym = cblksty & J3D_CCP_CBLKSTY_SEGSYM;
+
+ opj_mqc_t *mqc = t1->mqc; /* MQC component */
+
+ one = 1 << bpno;
+ half = one >> 1;
+ oneplushalf = one | half;
+ for (m = 0; m < l; m++) {
+ for (k = 0; k < h; k += 4) {
+ for (i = 0; i < w; i++) {
+ if (k + 3 < h) {
+ if (cblksty & J3D_CCP_CBLKSTY_VSC) {
+ agg = !(t1->flags[1 + m][1 + k][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH)
+ || t1->flags[1 + m][1 + k + 1][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH)
+ || t1->flags[1 + m][1 + k + 2][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH)
+ || (t1->flags[1 + m][1 + k + 3][1 + i]
+ & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) & (T1_SIG | T1_VISIT | T1_SIG_OTH));
+ } else {
+ agg = !(t1->flags[1 + m][1 + k][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH)
+ || t1->flags[1 + m][1 + k + 1][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH)
+ || t1->flags[1 + m][1 + k + 2][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH)
+ || t1->flags[1 + m][1 + k + 3][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH));
+ }
+ } else {
+ agg = 0;
+ }
+ if (agg) {
+ mqc_setcurctx(mqc, T1_CTXNO_AGG);
+ if (!mqc_decode(mqc)) {
+ continue;
+ }
+ mqc_setcurctx(mqc, T1_CTXNO_UNI);
+ runlen = mqc_decode(mqc);
+ runlen = (runlen << 1) | mqc_decode(mqc);
+ } else {
+ runlen = 0;
+ }
+ for (j = k + runlen; j < k + 4 && j < h; j++) {
+ vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0;
+ t1_dec_clnpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->data[m][j][i], orient, oneplushalf, agg && (j == k + runlen), vsc);
+ }
+ }
+ }
+ }
+ if (segsym) {
+ int v = 0;
+ mqc_setcurctx(mqc, T1_CTXNO_UNI);
+ v = mqc_decode(mqc);
+ v = (v << 1) | mqc_decode(mqc);
+ v = (v << 1) | mqc_decode(mqc);
+ v = (v << 1) | mqc_decode(mqc);
+ /*
+ if (v!=0xa) {
+ opj_event_msg(t1->cinfo, EVT_WARNING, "Bad segmentation symbol %x\n", v);
+ }
+ */
+ }
+} /* VSC and BYPASS by Antonin */
+
+
+static void t1_encode_cblk(opj_t1_t *t1, opj_tcd_cblk_t * cblk, int orient, int compno, int level[3], int dwtid[3], double stepsize, int cblksty, int numcomps, opj_tcd_tile_t * tile) {
+ int i, j, k;
+ int w, h, l;
+ int passno;
+ int bpno, passtype;
+ int max;
+ int nmsedec = 0;
+ double cumwmsedec = 0;
+ char type = T1_TYPE_MQ;
+
+ opj_mqc_t *mqc = t1->mqc; /* MQC component */
+
+ w = cblk->x1 - cblk->x0;
+ h = cblk->y1 - cblk->y0;
+ l = cblk->z1 - cblk->z0;
+
+ max = 0;
+ for (k = 0; k < l; k++) {
+ for (j = 0; j < h; j++) {
+ for (i = 0; i < w; i++) {
+ max = int_max(max, int_abs(t1->data[k][j][i]));
+ }
+ }
+ }
+ for (k = 0; k <= l; k++) {
+ for (j = 0; j <= h; j++) {
+ for (i = 0; i <= w; i++) {
+ t1->flags[k][j][i] = 0;
+ }
+ }
+ }
+
+ cblk->numbps = max ? (int_floorlog2(max) + 1) - T1_NMSEDEC_FRACBITS : 0;
+
+ bpno = cblk->numbps - 1;
+ passtype = 2;
+
+ mqc_reset_enc(mqc);
+ mqc_init_enc(mqc, cblk->data);
+
+ for (passno = 0; bpno >= 0; passno++) {
+ opj_tcd_pass_t *pass = &cblk->passes[passno];
+ int correction = 3;
+ double tmpwmsedec;
+ type = ((bpno < (cblk->numbps - 4)) && (passtype < 2) && (cblksty & J3D_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ;
+ //fprintf(stdout,"passno %d passtype %d w %d h %d l %d bpno %d orient %d type %d cblksty %d\n",passno,passtype,w,h,l,bpno,orient,type,cblksty);
+
+ switch (passtype) {
+ case 0:
+ t1_enc_sigpass(t1, w, h, l, bpno, orient, &nmsedec, type, cblksty);
+ break;
+ case 1:
+ t1_enc_refpass(t1, w, h, l, bpno, &nmsedec, type, cblksty);
+ break;
+ case 2:
+ //fprintf(stdout,"w %d h %d l %d bpno %d orient %d \n",w,h,l,bpno,orient);
+ t1_enc_clnpass(t1, w, h, l, bpno, orient, &nmsedec, cblksty);
+ /* code switch SEGMARK (i.e. SEGSYM) */
+ if (cblksty & J3D_CCP_CBLKSTY_SEGSYM)
+ mqc_segmark_enc(mqc);
+ break;
+ }
+
+ /* fixed_quality */
+ tmpwmsedec = t1_getwmsedec(nmsedec, compno, level, orient, bpno, stepsize, numcomps, dwtid);
+ cumwmsedec += tmpwmsedec;
+ tile->distotile += tmpwmsedec;
+
+ /* Code switch "RESTART" (i.e. TERMALL) */
+ if ((cblksty & J3D_CCP_CBLKSTY_TERMALL) && !((passtype == 2) && (bpno - 1 < 0))) {
+ if (type == T1_TYPE_RAW) {
+ mqc_flush(mqc);
+ correction = 1;
+ /* correction = mqc_bypass_flush_enc(); */
+ } else { /* correction = mqc_restart_enc(); */
+ mqc_flush(mqc);
+ correction = 1;
+ }
+ pass->term = 1;
+ } else {
+ if (((bpno < (cblk->numbps - 4) && (passtype > 0))
+ || ((bpno == (cblk->numbps - 4)) && (passtype == 2))) && (cblksty & J3D_CCP_CBLKSTY_LAZY)) {
+ if (type == T1_TYPE_RAW) {
+ mqc_flush(mqc);
+ correction = 1;
+ /* correction = mqc_bypass_flush_enc(); */
+ } else { /* correction = mqc_restart_enc(); */
+ mqc_flush(mqc);
+ correction = 1;
+ }
+ pass->term = 1;
+ } else {
+ pass->term = 0;
+ }
+ }
+
+ if (++passtype == 3) {
+ passtype = 0;
+ bpno--;
+ }
+
+ if (pass->term && bpno > 0) {
+ type = ((bpno < (cblk->numbps - 4)) && (passtype < 2) && (cblksty & J3D_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ;
+ if (type == T1_TYPE_RAW)
+ mqc_bypass_init_enc(mqc);
+ else
+ mqc_restart_init_enc(mqc);
+ }
+
+ pass->distortiondec = cumwmsedec;
+ pass->rate = mqc_numbytes(mqc) + correction; /* FIXME */
+ pass->len = pass->rate - (passno == 0 ? 0 : cblk->passes[passno - 1].rate);
+
+ /* Code-switch "RESET" */
+ if (cblksty & J3D_CCP_CBLKSTY_RESET)
+ mqc_reset_enc(mqc);
+ }
+
+ /* Code switch "ERTERM" (i.e. PTERM) */
+ if (cblksty & J3D_CCP_CBLKSTY_PTERM)
+ mqc_erterm_enc(mqc);
+ else /* Default coding */ if (!(cblksty & J3D_CCP_CBLKSTY_LAZY))
+ mqc_flush(mqc);
+
+ cblk->totalpasses = passno;
+}
+
+static void t1_decode_cblk(opj_t1_t *t1, opj_tcd_cblk_t * cblk, int orient, int roishift, int cblksty) {
+ int i, j, k, w, h, l;
+ int bpno, passtype;
+ int segno, passno;
+ char type = T1_TYPE_MQ; /* BYPASS mode */
+
+ opj_raw_t *raw = t1->raw; /* RAW component */
+ opj_mqc_t *mqc = t1->mqc; /* MQC component */
+
+ w = cblk->x1 - cblk->x0;
+ h = cblk->y1 - cblk->y0;
+ l = cblk->z1 - cblk->z0;
+
+ for (k = 0; k < l; k++) {
+ for (j = 0; j < h; j++) {
+ for (i = 0; i < w; i++) {
+ t1->data[k][j][i] = 0;
+ }
+ }
+ }
+
+ for (k = 0; k <= l; k++) {
+ for (j = 0; j <= h; j++) {
+ for (i = 0; i <= w; i++) {
+ t1->flags[k][j][i] = 0;
+ }
+ }
+ }
+
+ bpno = roishift + cblk->numbps - 1;
+ passtype = 2;
+
+ mqc_reset_enc(mqc);
+
+ for (segno = 0; segno < cblk->numsegs; segno++) {
+ opj_tcd_seg_t *seg = &cblk->segs[segno];
+
+ /* BYPASS mode */
+ type = ((bpno <= (cblk->numbps - 1) - 4) && (passtype < 2) && (cblksty & J3D_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ;
+ if (type == T1_TYPE_RAW) {
+ raw_init_dec(raw, seg->data, seg->len);
+ } else {
+ mqc_init_dec(mqc, seg->data, seg->len);
+ }
+
+ for (passno = 0; passno < seg->numpasses; passno++) {
+ switch (passtype) {
+ case 0:
+ t1_dec_sigpass(t1, w, h, l, bpno+1, orient, type, cblksty);
+ break;
+ case 1:
+ t1_dec_refpass(t1, w, h, l, bpno+1, type, cblksty);
+ break;
+ case 2:
+ t1_dec_clnpass(t1, w, h, l, bpno+1, orient, cblksty);
+ break;
+ }
+
+ if ((cblksty & J3D_CCP_CBLKSTY_RESET) && type == T1_TYPE_MQ) {
+ mqc_reset_enc(mqc);
+ }
+ if (++passtype == 3) {
+ passtype = 0;
+ bpno--;
+ }
+ }
+ }
+}
+
+static int t1_init_ctxno_zc(int f, int orient) {
+ int h, v, d, n, t, hv;
+ n = 0;
+ h = ((f & T1_SIG_W) != 0) + ((f & T1_SIG_E) != 0);
+ v = ((f & T1_SIG_N) != 0) + ((f & T1_SIG_S) != 0);
+ d = ((f & T1_SIG_NW) != 0) + ((f & T1_SIG_NE) != 0) + ((f & T1_SIG_SE) != 0) + ((f & T1_SIG_SW) != 0);
+
+ switch (orient) {
+ case 2:
+ t = h;
+ h = v;
+ v = t;
+ case 0:
+ case 1:
+ if (!h) {
+ if (!v) {
+ if (!d)
+ n = 0;
+ else if (d == 1)
+ n = 1;
+ else
+ n = 2;
+ } else if (v == 1) {
+ n = 3;
+ } else {
+ n = 4;
+ }
+ } else if (h == 1) {
+ if (!v) {
+ if (!d)
+ n = 5;
+ else
+ n = 6;
+ } else {
+ n = 7;
+ }
+ } else
+ n = 8;
+ break;
+ case 3:
+ hv = h + v;
+ if (!d) {
+ if (!hv) {
+ n = 0;
+ } else if (hv == 1) {
+ n = 1;
+ } else {
+ n = 2;
+ }
+ } else if (d == 1) {
+ if (!hv) {
+ n = 3;
+ } else if (hv == 1) {
+ n = 4;
+ } else {
+ n = 5;
+ }
+ } else if (d == 2) {
+ if (!hv) {
+ n = 6;
+ } else {
+ n = 7;
+ }
+ } else {
+ n = 8;
+ }
+ break;
+ }
+
+ return (T1_CTXNO_ZC + n);
+}
+
+static int t1_init_ctxno_sc(int f) {
+ int hc, vc, n;
+ n = 0;
+
+ hc = int_min(((f & (T1_SIG_E | T1_SGN_E)) ==
+ T1_SIG_E) + ((f & (T1_SIG_W | T1_SGN_W)) == T1_SIG_W),
+ 1) - int_min(((f & (T1_SIG_E | T1_SGN_E)) ==
+ (T1_SIG_E | T1_SGN_E)) +
+ ((f & (T1_SIG_W | T1_SGN_W)) ==
+ (T1_SIG_W | T1_SGN_W)), 1);
+
+ vc = int_min(((f & (T1_SIG_N | T1_SGN_N)) ==
+ T1_SIG_N) + ((f & (T1_SIG_S | T1_SGN_S)) == T1_SIG_S),
+ 1) - int_min(((f & (T1_SIG_N | T1_SGN_N)) ==
+ (T1_SIG_N | T1_SGN_N)) +
+ ((f & (T1_SIG_S | T1_SGN_S)) ==
+ (T1_SIG_S | T1_SGN_S)), 1);
+
+ if (hc < 0) {
+ hc = -hc;
+ vc = -vc;
+ }
+ if (!hc) {
+ if (vc == -1)
+ n = 1;
+ else if (!vc)
+ n = 0;
+ else
+ n = 1;
+ } else if (hc == 1) {
+ if (vc == -1)
+ n = 2;
+ else if (!vc)
+ n = 3;
+ else
+ n = 4;
+ }
+
+ return (T1_CTXNO_SC + n);
+}
+
+static int t1_init_ctxno_mag(int f) {
+ int n;
+ if (!(f & T1_REFINE))
+ n = (f & (T1_SIG_OTH)) ? 1 : 0;
+ else
+ n = 2;
+
+ return (T1_CTXNO_MAG + n);
+}
+
+static int t1_init_spb(int f) {
+ int hc, vc, n;
+
+ hc = int_min(((f & (T1_SIG_E | T1_SGN_E)) ==
+ T1_SIG_E) + ((f & (T1_SIG_W | T1_SGN_W)) == T1_SIG_W),
+ 1) - int_min(((f & (T1_SIG_E | T1_SGN_E)) ==
+ (T1_SIG_E | T1_SGN_E)) +
+ ((f & (T1_SIG_W | T1_SGN_W)) ==
+ (T1_SIG_W | T1_SGN_W)), 1);
+
+ vc = int_min(((f & (T1_SIG_N | T1_SGN_N)) ==
+ T1_SIG_N) + ((f & (T1_SIG_S | T1_SGN_S)) == T1_SIG_S),
+ 1) - int_min(((f & (T1_SIG_N | T1_SGN_N)) ==
+ (T1_SIG_N | T1_SGN_N)) +
+ ((f & (T1_SIG_S | T1_SGN_S)) ==
+ (T1_SIG_S | T1_SGN_S)), 1);
+
+ if (!hc && !vc)
+ n = 0;
+ else
+ n = (!(hc > 0 || (!hc && vc > 0)));
+
+ return n;
+}
+
+static void t1_init_luts(opj_t1_t *t1) {
+ int i, j;
+ double u, v, t;
+ for (j = 0; j < 4; j++) {
+ for (i = 0; i < 256; ++i) {
+ t1->lut_ctxno_zc[(j << 8) | i] = t1_init_ctxno_zc(i, j);
+ }
+ }
+ for (i = 0; i < 256; i++) {
+ t1->lut_ctxno_sc[i] = t1_init_ctxno_sc(i << 4);
+ }
+ for (j = 0; j < 2; j++) {
+ for (i = 0; i < 2048; ++i) {
+ t1->lut_ctxno_mag[(j << 11) + i] = t1_init_ctxno_mag((j ? T1_REFINE : 0) | i);
+ }
+ }
+ for (i = 0; i < 256; ++i) {
+ t1->lut_spb[i] = t1_init_spb(i << 4);
+ }
+ /* FIXME FIXME FIXME */
+ /* fprintf(stdout,"nmsedec luts:\n"); */
+ for (i = 0; i < (1 << T1_NMSEDEC_BITS); i++) {
+ t = i / pow(2, T1_NMSEDEC_FRACBITS);
+ u = t;
+ v = t - 1.5;
+ t1->lut_nmsedec_sig[i] =
+ int_max(0,
+ (int) (floor((u * u - v * v) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0));
+ t1->lut_nmsedec_sig0[i] =
+ int_max(0,
+ (int) (floor((u * u) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0));
+ u = t - 1.0;
+ if (i & (1 << (T1_NMSEDEC_BITS - 1))) {
+ v = t - 1.5;
+ } else {
+ v = t - 0.5;
+ }
+ t1->lut_nmsedec_ref[i] =
+ int_max(0,
+ (int) (floor((u * u - v * v) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0));
+ t1->lut_nmsedec_ref0[i] =
+ int_max(0,
+ (int) (floor((u * u) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0));
+ }
+}
+
+/* ----------------------------------------------------------------------- */
+
+opj_t1_t* t1_create(opj_common_ptr cinfo) {
+ opj_t1_t *t1 = (opj_t1_t*)opj_malloc(sizeof(opj_t1_t));
+ if(t1) {
+ t1->cinfo = cinfo;
+ /* create MQC and RAW handles */
+ t1->mqc = mqc_create();
+ t1->raw = raw_create();
+ /* initialize the look-up tables of the Tier-1 coder/decoder */
+ t1_init_luts(t1);
+ }
+ return t1;
+}
+
+void t1_destroy(opj_t1_t *t1) {
+ if(t1) {
+ /* destroy MQC and RAW handles */
+ mqc_destroy(t1->mqc);
+ raw_destroy(t1->raw);
+ //opj_free(t1->data);
+ //opj_free(t1->flags);
+ opj_free(t1);
+ }
+}
+
+void t1_encode_cblks(opj_t1_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp) {
+ int compno, resno, bandno, precno, cblkno;
+ int x, y, z, i, j, k, orient;
+ int n=0;
+ int level[3];
+ FILE *fid = NULL;
+// char filename[10];
+ tile->distotile = 0; /* fixed_quality */
+
+ for (compno = 0; compno < tile->numcomps; compno++) {
+ opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
+
+ for (resno = 0; resno < tilec->numresolution[0]; resno++) {
+ opj_tcd_resolution_t *res = &tilec->resolutions[resno];
+
+ /* Weighted first order entropy
+ sprintf(filename,"res%d.txt",resno);
+ if ((fid = fopen(filename,"w")) == 0){
+ fprintf(stdout,"Error while opening %s\n", filename);
+ exit(1);
+ }
+ */
+ for (bandno = 0; bandno < res->numbands; bandno++) {
+ opj_tcd_band_t *band = &res->bands[bandno];
+ for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) {
+ opj_tcd_precinct_t *prc = &band->precincts[precno];
+
+ for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {
+ opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];
+
+ //fprintf(stdout,"Precno %d Cblkno %d \n",precno,cblkno);
+ if (band->bandno == 0) {
+ x = cblk->x0 - band->x0;
+ y = cblk->y0 - band->y0;
+ z = cblk->z0 - band->z0;
+ } else if (band->bandno == 1) {
+ opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+ x = pres->x1 - pres->x0 + cblk->x0 - band->x0;
+ y = cblk->y0 - band->y0;
+ z = cblk->z0 - band->z0;
+ } else if (band->bandno == 2) {
+ opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+ x = cblk->x0 - band->x0;
+ y = pres->y1 - pres->y0 + cblk->y0 - band->y0;
+ z = cblk->z0 - band->z0;
+ } else if (band->bandno == 3) {
+ opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+ x = pres->x1 - pres->x0 + cblk->x0 - band->x0;
+ y = pres->y1 - pres->y0 + cblk->y0 - band->y0;
+ z = cblk->z0 - band->z0;
+ } else if (band->bandno == 4) {
+ opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+ x = cblk->x0 - band->x0;
+ y = cblk->y0 - band->y0;
+ z = pres->z1 - pres->z0 + cblk->z0 - band->z0;
+ } else if (band->bandno == 5) {
+ opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+ x = pres->x1 - pres->x0 + cblk->x0 - band->x0;
+ y = cblk->y0 - band->y0;
+ z = pres->z1 - pres->z0 + cblk->z0 - band->z0;
+ } else if (band->bandno == 6) {
+ opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+ x = cblk->x0 - band->x0;
+ y = pres->y1 - pres->y0 + cblk->y0 - band->y0;
+ z = pres->z1 - pres->z0 + cblk->z0 - band->z0;
+ } else if (band->bandno == 7) {
+ opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+ x = pres->x1 - pres->x0 + cblk->x0 - band->x0;
+ y = pres->y1 - pres->y0 + cblk->y0 - band->y0;
+ z = pres->z1 - pres->z0 + cblk->z0 - band->z0;
+ }
+
+ if (tcp->tccps[compno].reversible == 1) {
+ for (k = 0; k < cblk->z1 - cblk->z0; k++) {
+ for (j = 0; j < cblk->y1 - cblk->y0; j++) {
+ for (i = 0; i < cblk->x1 - cblk->x0; i++) {
+ t1->data[k][j][i] =
+ tilec->data[(x + i) + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)] << T1_NMSEDEC_FRACBITS;
+//fprintf(fid," %d",t1->data[k][j][i]);
+ }
+ }
+ }
+ } else if (tcp->tccps[compno].reversible == 0) {
+ for (k = 0; k < cblk->z1 - cblk->z0; k++) {
+ for (j = 0; j < cblk->y1 - cblk->y0; j++) {
+ for (i = 0; i < cblk->x1 - cblk->x0; i++) {
+ t1->data[k][j][i] = fix_mul(
+ tilec->data[(x + i) + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)],
+ 8192 * 8192 / ((int) floor(band->stepsize * 8192))) >> (13 - T1_NMSEDEC_FRACBITS);
+ }
+ }
+ }
+ }
+
+ orient = band->bandno; /* FIXME */
+ if (orient == 2) {
+ orient = 1;
+ } else if (orient == 1) {
+ orient = 2;
+ }
+ for (i = 0; i < 3; i++)
+ level[i] = tilec->numresolution[i] - 1 - resno;
+ //fprintf(stdout,"t1_encode_cblk(t1, cblk, %d, %d, %d %d %d, %d, %f, %d, %d, tile);\n", orient, compno, level[0], level[1], level[2], tcp->tccps[compno].reversible, band->stepsize, tcp->tccps[compno].cblksty, tile->numcomps);
+ t1_encode_cblk(t1, cblk, orient, compno, level, tcp->tccps[compno].dwtid, band->stepsize, tcp->tccps[compno].cblksty, tile->numcomps, tile);
+
+ } /* cblkno */
+ } /* precno */
+//fprintf(fid,"\n");
+ } /* bandno */
+//fclose(fid);
+ } /* resno */
+ } /* compno */
+}
+
+void t1_decode_cblks(opj_t1_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp) {
+ int compno, resno, bandno, precno, cblkno;
+
+ for (compno = 0; compno < tile->numcomps; compno++) {
+ opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
+
+ for (resno = 0; resno < tilec->numresolution[0]; resno++) {
+ opj_tcd_resolution_t *res = &tilec->resolutions[resno];
+
+ for (bandno = 0; bandno < res->numbands; bandno++) {
+ opj_tcd_band_t *band = &res->bands[bandno];
+
+ for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) {
+ opj_tcd_precinct_t *prc = &band->precincts[precno];
+
+ for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {
+ int x, y, k, i, j, z, orient;
+ opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];
+
+ orient = band->bandno; /* FIXME */
+ if (orient == 2) {
+ orient = 1;
+ } else if (orient == 1) {
+ orient = 2;
+ }
+
+ t1_decode_cblk(t1, cblk, orient, tcp->tccps[compno].roishift, tcp->tccps[compno].cblksty);
+
+ if (band->bandno == 0) {
+ x = cblk->x0 - band->x0;
+ y = cblk->y0 - band->y0;
+ z = cblk->z0 - band->z0;
+ } else if (band->bandno == 1) {
+ opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+ x = pres->x1 - pres->x0 + cblk->x0 - band->x0;
+ y = cblk->y0 - band->y0;
+ z = cblk->z0 - band->z0;
+ } else if (band->bandno == 2) {
+ opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+ x = cblk->x0 - band->x0;
+ y = pres->y1 - pres->y0 + cblk->y0 - band->y0;
+ z = cblk->z0 - band->z0;
+ } else if (band->bandno == 3) {
+ opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+ x = pres->x1 - pres->x0 + cblk->x0 - band->x0;
+ y = pres->y1 - pres->y0 + cblk->y0 - band->y0;
+ z = cblk->z0 - band->z0;
+ } else if (band->bandno == 4) {
+ opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+ x = cblk->x0 - band->x0;
+ y = cblk->y0 - band->y0;
+ z = pres->z1 - pres->z0 + cblk->z0 - band->z0;
+ } else if (band->bandno == 5) {
+ opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+ x = pres->x1 - pres->x0 + cblk->x0 - band->x0;
+ y = cblk->y0 - band->y0;
+ z = pres->z1 - pres->z0 + cblk->z0 - band->z0;
+ } else if (band->bandno == 6) {
+ opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+ x = cblk->x0 - band->x0;
+ y = pres->y1 - pres->y0 + cblk->y0 - band->y0;
+ z = pres->z1 - pres->z0 + cblk->z0 - band->z0;
+ } else if (band->bandno == 7) {
+ opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+ x = pres->x1 - pres->x0 + cblk->x0 - band->x0;
+ y = pres->y1 - pres->y0 + cblk->y0 - band->y0;
+ z = pres->z1 - pres->z0 + cblk->z0 - band->z0;
+ }
+
+ if (tcp->tccps[compno].roishift) {
+ int thresh, val, mag;
+ thresh = 1 << tcp->tccps[compno].roishift;
+ for (k = 0; k < cblk->z1 - cblk->z0; k++) {
+ for (j = 0; j < cblk->y1 - cblk->y0; j++) {
+ for (i = 0; i < cblk->x1 - cblk->x0; i++) {
+ val = t1->data[k][j][i];
+ mag = int_abs(val);
+ if (mag >= thresh) {
+ mag >>= tcp->tccps[compno].roishift;
+ t1->data[k][j][i] = val < 0 ? -mag : mag;
+ }
+ }
+ }
+ }
+ }
+
+ if (tcp->tccps[compno].reversible == 1) {
+ for (k = 0; k < cblk->z1 - cblk->z0; k++) {
+ for (j = 0; j < cblk->y1 - cblk->y0; j++) {
+ for (i = 0; i < cblk->x1 - cblk->x0; i++) {
+ int tmp = t1->data[k][j][i];
+ tilec->data[x + i + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)] = tmp/2;
+ }
+ }
+ }
+ } else { /* if (tcp->tccps[compno].reversible == 0) */
+ for (k = 0; k < cblk->z1 - cblk->z0; k++) {
+ for (j = 0; j < cblk->y1 - cblk->y0; j++) {
+ for (i = 0; i < cblk->x1 - cblk->x0; i++) {
+ double tmp = (double)(t1->data[k][j][i] * band->stepsize * 4096.0);
+ if (t1->data[k][j][i] >> 1 == 0) {
+ tilec->data[x + i + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)] = 0;
+ } else {
+ int tmp2 = ((int) (floor(fabs(tmp)))) + ((int) floor(fabs(tmp*2))%2);
+ tilec->data[x + i + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)] = ((tmp<0)?-tmp2:tmp2);
+ }
+ }
+ }
+ }
+ }
+ } /* cblkno */
+ } /* precno */
+ } /* bandno */
+ } /* resno */
+ } /* compno */
+}
+
+
+/** mod fixed_quality */
+double t1_getwmsedec(int nmsedec, int compno, int level[3], int orient, int bpno, double stepsize, int numcomps, int dwtid[3]) {
+ double w1, w2, wmsedec;
+
+ if (dwtid[0] == 1 || dwtid[1] == 1 || dwtid[2] == 1) {
+ w1 = (numcomps > 1) ? mct_getnorm_real(compno) : 1;
+ } else {
+ w1 = (numcomps > 1) ? mct_getnorm(compno) : 1;
+ }
+ w2 = dwt_getnorm(orient, level, dwtid);
+
+ //fprintf(stdout,"nmsedec %d level %d %d %d orient %d bpno %d stepsize %f \n",nmsedec ,level[0],level[1],level[2],orient,bpno,stepsize);
+ wmsedec = w1 * w2 * stepsize * (1 << bpno);
+ wmsedec *= wmsedec * nmsedec / 8192.0;
+
+ return wmsedec;
+}
+/** mod fixed_quality */
diff --git a/libopenjpeg3d/t1.h b/libopenjpeg3d/t1.h
new file mode 100755
index 00000000..7b4a18f5
--- /dev/null
+++ b/libopenjpeg3d/t1.h
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * 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 __T1_H
+#define __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_MAXCBLKW 256 /*< Maximum size of code-block (width) */
+#define T1_MAXCBLKH 256 /*< Maximum size of code-block (heigth) */
+#define T1_MAXCBLKD 256 /*< Maximum size of code-block (depth) */
+#define T1_MINCBLKW 4 /*< Minimum size of code-block (width) */
+#define T1_MINCBLKH 4 /*< Minimum size of code-block (heigth) */
+#define T1_MINCBLKD 4 /*< Minimum size of code-block (depth) */
+#define T1_MAXWHD 18
+#define T1_CBLKW 256
+#define T1_CBLKH 256
+#define T1_CBLKD 256
+
+#define T1_SIG_NE 0x0001 /*< Context orientation : North-East direction */
+#define T1_SIG_SE 0x0002 /*< Context orientation : South-East direction */
+#define T1_SIG_SW 0x0004 /*< Context orientation : South-West direction */
+#define T1_SIG_NW 0x0008 /*< Context orientation : North-West direction */
+#define T1_SIG_N 0x0010 /*< Context orientation : North direction */
+#define T1_SIG_E 0x0020 /*< Context orientation : East direction */
+#define T1_SIG_S 0x0040 /*< Context orientation : South direction */
+#define T1_SIG_W 0x0080 /*< Context orientation : West direction */
+#define T1_SIG_OTH (T1_SIG_N|T1_SIG_NE|T1_SIG_E|T1_SIG_SE|T1_SIG_S|T1_SIG_SW|T1_SIG_W|T1_SIG_NW)
+#define T1_SIG_PRIM (T1_SIG_N|T1_SIG_E|T1_SIG_S|T1_SIG_W)
+
+#define T1_SGN_N 0x0100
+#define T1_SGN_E 0x0200
+#define T1_SGN_S 0x0400
+#define T1_SGN_W 0x0800
+#define T1_SGN (T1_SGN_N|T1_SGN_E|T1_SGN_S|T1_SGN_W)
+
+#define T1_SIG 0x1000
+#define T1_REFINE 0x2000
+#define T1_VISIT 0x4000
+
+#define T1_NUMCTXS_AGG 1
+#define T1_NUMCTXS_ZC 9
+#define T1_NUMCTXS_MAG 3
+#define T1_NUMCTXS_SC 5
+#define T1_NUMCTXS_UNI 1
+
+#define T1_CTXNO_AGG 0
+#define T1_CTXNO_ZC (T1_CTXNO_AGG+T1_NUMCTXS_AGG)
+#define T1_CTXNO_MAG (T1_CTXNO_ZC+T1_NUMCTXS_ZC)
+#define T1_CTXNO_SC (T1_CTXNO_MAG+T1_NUMCTXS_MAG)
+#define T1_CTXNO_UNI (T1_CTXNO_SC+T1_NUMCTXS_SC)
+#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)*/
+
+/* ----------------------------------------------------------------------- */
+
+/**
+Tier-1 coding (coding of code-block coefficients)
+*/
+typedef struct opj_t1 {
+ /** codec context */
+ opj_common_ptr cinfo;
+
+ /** MQC component */
+ opj_mqc_t *mqc;
+ /** RAW component */
+ opj_raw_t *raw;
+ /** LUTs for context-based coding */
+ int lut_ctxno_zc[1024];
+ int lut_ctxno_sc[256];
+ int lut_ctxno_mag[4096];
+ int lut_spb[256];
+ /** LUTs for decoding normalised MSE */
+ int lut_nmsedec_sig[1 << T1_NMSEDEC_BITS];
+ int lut_nmsedec_sig0[1 << T1_NMSEDEC_BITS];
+ int lut_nmsedec_ref[1 << T1_NMSEDEC_BITS];
+ int lut_nmsedec_ref0[1 << T1_NMSEDEC_BITS];
+ /** Codeblock data */
+ int data[T1_CBLKD][T1_CBLKH][T1_CBLKW];//int ***data;
+ /** Context information for each voxel in codeblock */
+ int flags[T1_CBLKD + 2][T1_CBLKH + 2][T1_CBLKH + 2];//int ***flags;
+} opj_t1_t;
+
+/** @name Exported functions */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+/**
+Create a new T1 handle
+and initialize the look-up tables of the Tier-1 coder/decoder
+@return Returns a new T1 handle if successful, returns NULL otherwise
+@see t1_init_luts
+*/
+opj_t1_t* t1_create(opj_common_ptr cinfo);
+/**
+Destroy a previously created T1 handle
+@param t1 T1 handle to destroy
+*/
+void t1_destroy(opj_t1_t *t1);
+/**
+Encode the code-blocks of a tile
+@param t1 T1 handle
+@param tile The tile to encode
+@param tcp Tile coding parameters
+*/
+void t1_encode_cblks(opj_t1_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp);
+/**
+Decode the code-blocks of a tile
+@param t1 T1 handle
+@param tile The tile to decode
+@param tcp Tile coding parameters
+*/
+void t1_decode_cblks(opj_t1_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp);
+/**
+Get weigths of MSE decoding
+@param nmsedec The normalized MSE reduction
+@param compno
+@param level
+@param orient
+@param bpno
+@param stepsize
+@param numcomps
+@param dwtid
+returns MSE associated to decoding pass
+*/
+double t1_getwmsedec(int nmsedec, int compno, int level[3], int orient, int bpno, double stepsize, int numcomps, int dwtid[3]);
+
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+#endif /* __T1_H */
diff --git a/libopenjpeg3d/t1_3d.c b/libopenjpeg3d/t1_3d.c
new file mode 100755
index 00000000..efdf2efc
--- /dev/null
+++ b/libopenjpeg3d/t1_3d.c
@@ -0,0 +1,1230 @@
+/*
+ * Copyrigth (c) 2006, Mónica Díez, LPI-UVA, Spain
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opj_includes.h"
+
+/** @defgroup T1_3D T1_3D - Implementation of the tier-1 coding */
+/*@{*/
+
+/** @name Local static functions */
+/*@{*/
+
+static int t1_3d_getctxno_zc(unsigned int f, int orient);
+static int t1_3d_getctxno_sc(unsigned int f);
+static int t1_3d_getctxno_mag(unsigned int f, int fsvr);
+static int t1_3d_getspb(unsigned int f);
+static int t1_3d_getnmsedec_sig(opj_t1_3d_t *t1, int x, int bitpos);
+static int t1_3d_getnmsedec_ref(opj_t1_3d_t *t1, int x, int bitpos);
+static void t1_3d_updateflags(unsigned int *fp, int s);
+/**
+Encode significant pass
+*/
+static void t1_3d_enc_sigpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int orient, int bpno, int one, int *nmsedec, char type, int vsc);
+/**
+Decode significant pass
+*/
+static void t1_3d_dec_sigpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int orient, int oneplushalf, char type, int vsc);
+/**
+Encode significant pass
+*/
+static void t1_3d_enc_sigpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int orient, int *nmsedec, char type, int cblksty);
+/**
+Decode significant pass
+*/
+static void t1_3d_dec_sigpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int orient, char type, int cblksty);
+/**
+Encode refinement pass
+*/
+static void t1_3d_enc_refpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int bpno, int one, int *nmsedec, char type, int vsc);
+/**
+Decode refinement pass
+*/
+static void t1_3d_dec_refpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int poshalf, int neghalf, char type, int vsc);
+/**
+Encode refinement pass
+*/
+static void t1_3d_enc_refpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int *nmsedec, char type, int cblksty);
+/**
+Decode refinement pass
+*/
+static void t1_3d_dec_refpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, char type, int cblksty);
+/**
+Encode clean-up pass
+*/
+static void t1_3d_enc_clnpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int orient, int bpno, int one, int *nmsedec, int partial, int vsc);
+/**
+Decode clean-up pass
+*/
+static void t1_3d_dec_clnpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int orient, int oneplushalf, int partial, int vsc);
+/**
+Encode clean-up pass
+*/
+static void t1_3d_enc_clnpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int orient, int *nmsedec, int cblksty);
+/**
+Decode clean-up pass
+*/
+static void t1_3d_dec_clnpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int orient, int cblksty);
+/**
+Encode 1 code-block
+@param t1 T1 handle
+@param cblk Code-block coding parameters
+@param orient
+@param compno Component number
+@param level[3]
+@param dwtid[3]
+@param stepsize
+@param cblksty Code-block style
+@param numcomps
+@param tile
+*/
+static void t1_3d_encode_cblk(opj_t1_3d_t *t1, opj_tcd_cblk_t * cblk, int orient, int compno, int level[3], int dwtid[3], double stepsize, int cblksty, int numcomps, opj_tcd_tile_t * tile);
+/**
+Decode 1 code-block
+@param t1 T1 handle
+@param cblk Code-block coding parameters
+@param orient
+@param roishift Region of interest shifting value
+@param cblksty Code-block style
+*/
+static void t1_3d_decode_cblk(opj_t1_3d_t *t1, opj_tcd_cblk_t * cblk, int orient, int roishift, int cblksty);
+static int t1_3d_init_ctxno_zc(unsigned int f, int orient);
+static int t1_3d_init_ctxno_sc(unsigned int f);
+static int t1_3d_init_ctxno_mag(unsigned int f, int f2);
+static int t1_3d_init_spb(unsigned int f);
+/**
+Initialize the look-up tables of the Tier-1 coder/decoder
+@param t1 T1 handle
+*/
+static void t1_3d_init_luts(opj_t1_3d_t *t1);
+
+/*@}*/
+
+/*@}*/
+
+/* ----------------------------------------------------------------------- */
+
+static int t1_3d_getctxno_zc(unsigned int f, int orient) {
+ return t1_3d_init_ctxno_zc((f & T1_3D_SIG_OTH), orient);
+}
+
+static int t1_3d_getctxno_sc(unsigned int f) {
+ return t1_3d_init_ctxno_sc((f & T1_3D_SIG_PRIM) | ((f >> 16) & T1_3D_SGN));
+ //return t1->lut_ctxno_sc[((f & T1_3D_SIG_PRIM) | ((f >> 16) & T1_3D_SGN)) >> 4];
+}
+
+static int t1_3d_getctxno_mag(unsigned int f, int fsvr) {
+ return t1_3d_init_ctxno_mag((f & T1_3D_SIG_OTH), fsvr);
+}
+
+static int t1_3d_getspb(unsigned int f) {
+ return t1_3d_init_spb((f & T1_3D_SIG_PRIM) | ((f >> 16) & T1_3D_SGN));
+ //return t1->lut_spb[((f & T1_3D_SIG_PRIM) | ((f >> 16) & T1_3D_SGN)) >> 4];
+}
+
+static int t1_3d_getnmsedec_sig(opj_t1_3d_t *t1, int x, int bitpos) {
+ if (bitpos > T1_NMSEDEC_FRACBITS) {
+ return t1->lut_nmsedec_sig[(x >> (bitpos - T1_NMSEDEC_FRACBITS)) & ((1 << T1_NMSEDEC_BITS) - 1)];
+ }
+
+ return t1->lut_nmsedec_sig0[x & ((1 << T1_NMSEDEC_BITS) - 1)];
+}
+
+static int t1_3d_getnmsedec_ref(opj_t1_3d_t *t1, int x, int bitpos) {
+ if (bitpos > T1_NMSEDEC_FRACBITS) {
+ return t1->lut_nmsedec_ref[(x >> (bitpos - T1_NMSEDEC_FRACBITS)) & ((1 << T1_NMSEDEC_BITS) - 1)];
+ }
+
+ return t1->lut_nmsedec_ref0[x & ((1 << T1_NMSEDEC_BITS) - 1)];
+}
+
+static void t1_3d_updateflags(unsigned int *fp, int s) {
+ unsigned int *np = fp - (T1_MAXCBLKW + 2);
+ unsigned int *sp = fp + (T1_MAXCBLKW + 2);
+
+ unsigned int *bwp = fp + ((T1_MAXCBLKW + 2)*(T1_MAXCBLKH +2));
+ unsigned int *bnp = bwp - (T1_MAXCBLKW + 2);
+ unsigned int *bsp = bwp + (T1_MAXCBLKW + 2);
+
+ unsigned int *fwp = fp - ((T1_MAXCBLKW + 2)*(T1_MAXCBLKH +2));
+ unsigned int *fnp = fwp - (T1_MAXCBLKW + 2);
+ unsigned int *fsp = fwp + (T1_MAXCBLKW + 2);
+
+ np[-1] |= T1_3D_SIG_SE;
+ np[1] |= T1_3D_SIG_SW;
+ sp[-1] |= T1_3D_SIG_NE;
+ sp[1] |= T1_3D_SIG_NW;
+ *np |= T1_3D_SIG_S;
+ *sp |= T1_3D_SIG_N;
+ fp[-1] |= T1_3D_SIG_E;
+ fp[1] |= T1_3D_SIG_W;
+
+ *fwp |= T1_3D_SIG_FC;
+ *bwp |= T1_3D_SIG_BC;
+
+ fnp[-1] |= T1_3D_SIG_FSE;
+ fnp[1] |= T1_3D_SIG_FSW;
+ fsp[-1] |= T1_3D_SIG_FNE;
+ fsp[1] |= T1_3D_SIG_FNW;
+ *fnp |= T1_3D_SIG_FS;
+ *fsp |= T1_3D_SIG_FN;
+ fwp[-1] |= T1_3D_SIG_FE;
+ fwp[1] |= T1_3D_SIG_FW;
+
+ bnp[-1] |= T1_3D_SIG_BSE;
+ bnp[1] |= T1_3D_SIG_BSW;
+ bsp[-1] |= T1_3D_SIG_BNE;
+ bsp[1] |= T1_3D_SIG_BNW;
+ *bnp |= T1_3D_SIG_BS;
+ *bsp |= T1_3D_SIG_BN;
+ bwp[-1] |= T1_3D_SIG_BE;
+ bwp[1] |= T1_3D_SIG_BW;
+
+ if (s) {
+ *np |= (T1_3D_SGN_S << 16);
+ *sp |= (T1_3D_SGN_N << 16);
+ fp[-1] |= (T1_3D_SGN_E << 16);
+ fp[1] |= (T1_3D_SGN_W << 16);
+ *fwp |= (T1_3D_SGN_F << 16);
+ *bwp |= (T1_3D_SGN_B << 16);
+ }
+}
+
+static void t1_3d_enc_sigpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int orient, int bpno, int one, int *nmsedec, char type, int vsc) {
+ int v, flagsvr;
+ unsigned int flag;
+
+ opj_mqc_t *mqc = t1->mqc; /* MQC component */
+
+ flag = vsc ? ((*fp) & (~(T1_3D_SIG_S | T1_3D_SIG_SE | T1_3D_SIG_SW | (T1_3D_SGN_S << 16)))) : (*fp);
+ flagsvr = (*fsvr);
+ if ((flag & T1_3D_SIG_OTH) && !(flagsvr & (T1_3D_SIG | T1_3D_VISIT))) {
+ v = int_abs(*dp) & one ? 1 : 0;
+ if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */
+ mqc_setcurctx(mqc, t1_3d_getctxno_zc(flag, orient)); /* ESSAI */
+ mqc_bypass_enc(mqc, v);
+ } else {
+ mqc_setcurctx(mqc, t1_3d_getctxno_zc(flag, orient));
+ mqc_encode(mqc, v);
+ }
+ if (v) {
+ v = *dp < 0 ? 1 : 0;
+ *nmsedec += t1_3d_getnmsedec_sig(t1, int_abs(*dp), bpno + T1_NMSEDEC_FRACBITS);
+ if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */
+ mqc_setcurctx(mqc, t1_3d_getctxno_sc(flag)); /* ESSAI */
+ mqc_bypass_enc(mqc, v);
+ } else {
+ mqc_setcurctx(mqc, t1_3d_getctxno_sc(flag));
+ mqc_encode(mqc, v ^ t1_3d_getspb(flag));
+ }
+ t1_3d_updateflags(fp, v);
+ *fsvr |= T1_3D_SIG;
+ }
+ *fsvr |= T1_3D_VISIT;
+ }
+}
+
+static void t1_3d_dec_sigpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int orient, int oneplushalf, char type, int vsc) {
+ int v, flagsvr;
+ unsigned int flag;
+
+ opj_raw_t *raw = t1->raw; /* RAW component */
+ opj_mqc_t *mqc = t1->mqc; /* MQC component */
+
+ flag = vsc ? ((*fp) & (~(T1_3D_SIG_S | T1_3D_SIG_SE | T1_3D_SIG_SW | (T1_3D_SGN_S << 16)))) : (*fp);
+ flagsvr = (*fsvr);
+ if ((flag & T1_3D_SIG_OTH) && !(flagsvr & (T1_3D_SIG | T1_3D_VISIT))) {
+ if (type == T1_TYPE_RAW) {
+ if (raw_decode(raw)) {
+ v = raw_decode(raw); /* ESSAI */
+ *dp = v ? -oneplushalf : oneplushalf;
+ t1_3d_updateflags(fp, v);
+ *fsvr |= T1_3D_SIG;
+ }
+ } else {
+ mqc_setcurctx(mqc, t1_3d_getctxno_zc(flag, orient));
+ if (mqc_decode(mqc)) {
+ mqc_setcurctx(mqc, t1_3d_getctxno_sc(flag));
+ v = mqc_decode(mqc) ^ t1_3d_getspb(flag);
+ *dp = v ? -oneplushalf : oneplushalf;
+ t1_3d_updateflags(fp, v);
+ *fsvr |= T1_3D_SIG;
+ }
+ }
+ *fsvr |= T1_3D_VISIT;
+ }
+} /* VSC and BYPASS by Antonin */
+
+static void t1_3d_enc_sigpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int orient, int *nmsedec, char type, int cblksty) {
+ int i, j, k, m, one, vsc;
+ *nmsedec = 0;
+ one = 1 << (bpno + T1_NMSEDEC_FRACBITS);
+ for (m = 0; m < l; m++) {
+ for (k = 0; k < h; k += 4) {
+ for (i = 0; i < w; i++) {
+ for (j = k; j < k + 4 && j < h; j++) {
+ vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0;
+ t1_3d_enc_sigpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->flagSVR[1 + m][1 + j][1 + i], &t1->data[m][j][i], orient, bpno, one, nmsedec, type, vsc);
+ }
+ }
+ }
+ }
+}
+
+static void t1_3d_dec_sigpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int orient, char type, int cblksty) {
+ int i, j, k, m, one, half, oneplushalf, vsc;
+ one = 1 << bpno;
+ half = one >> 1;
+ oneplushalf = one | half;
+ for (m = 0; m < l; m++) {
+ for (k = 0; k < h; k += 4) {
+ for (i = 0; i < w; i++) {
+ for (j = k; j < k + 4 && j < h; j++) {
+ vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0;
+ t1_3d_dec_sigpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->flagSVR[1 + m][1 + j][1 + i], &t1->data[m][j][i], orient, oneplushalf, type, vsc);
+ }
+ }
+ }
+ }
+} /* VSC and BYPASS by Antonin */
+
+static void t1_3d_enc_refpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int bpno, int one, int *nmsedec, char type, int vsc) {
+ int v, flagsvr;
+ unsigned int flag;
+
+ opj_mqc_t *mqc = t1->mqc; /* MQC component */
+
+ flag = vsc ? ((*fp) & (~(T1_3D_SIG_S | T1_3D_SIG_SE | T1_3D_SIG_SW | (T1_3D_SGN_S << 16)))) : (*fp);
+ flagsvr = (*fsvr);
+ if ((flagsvr & (T1_3D_SIG | T1_3D_VISIT)) == T1_3D_SIG) {
+ *nmsedec += t1_3d_getnmsedec_ref(t1, int_abs(*dp), bpno + T1_NMSEDEC_FRACBITS);
+ v = int_abs(*dp) & one ? 1 : 0;
+ if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */
+ mqc_setcurctx(mqc, t1_3d_getctxno_mag(flag, flagsvr)); /* ESSAI */
+ mqc_bypass_enc(mqc, v);
+ } else {
+ mqc_setcurctx(mqc, t1_3d_getctxno_mag(flag, flagsvr));
+ mqc_encode(mqc, v);
+ }
+ *fsvr |= T1_3D_REFINE;
+ }
+}
+
+static void t1_3d_dec_refpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int poshalf, int neghalf, char type, int vsc) {
+ int v, t, flagsvr;
+ unsigned int flag;
+
+ opj_mqc_t *mqc = t1->mqc; /* MQC component */
+ opj_raw_t *raw = t1->raw; /* RAW component */
+
+ flag = vsc ? ((*fp) & (~(T1_3D_SIG_S | T1_3D_SIG_SE | T1_3D_SIG_SW | (T1_3D_SGN_S << 16)))) : (*fp);
+ flagsvr = (*fsvr);
+ if ((flagsvr & (T1_3D_SIG | T1_3D_VISIT)) == T1_3D_SIG) {
+ if (type == T1_TYPE_RAW) {
+ mqc_setcurctx(mqc, t1_3d_getctxno_mag(flag, flagsvr)); /* ESSAI */
+ v = raw_decode(raw);
+ } else {
+ mqc_setcurctx(mqc, t1_3d_getctxno_mag(flag, flagsvr));
+ v = mqc_decode(mqc);
+ }
+ t = v ? poshalf : neghalf;
+ *dp += *dp < 0 ? -t : t;
+ *fsvr |= T1_3D_REFINE;
+ }
+} /* VSC and BYPASS by Antonin */
+
+static void t1_3d_enc_refpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int *nmsedec, char type, int cblksty) {
+ int i, j, k, m, one, vsc;
+ *nmsedec = 0;
+ one = 1 << (bpno + T1_NMSEDEC_FRACBITS);
+ for (m = 0; m < l; m++){
+ for (k = 0; k < h; k += 4) {
+ for (i = 0; i < w; i++) {
+ for (j = k; j < k + 4 && j < h; j++) {
+ vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0;
+ t1_3d_enc_refpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->flagSVR[1 + m][1 + j][1 + i], &t1->data[m][j][i], bpno, one, nmsedec, type, vsc);
+ }
+ }
+ }
+ }
+}
+
+static void t1_3d_dec_refpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, char type, int cblksty) {
+ int i, j, k, m, one, poshalf, neghalf;
+ int vsc;
+ one = 1 << bpno;
+ poshalf = one >> 1;
+ neghalf = bpno > 0 ? -poshalf : -1;
+ for (m = 0; m < l; m++) {
+ for (k = 0; k < h; k += 4) {
+ for (i = 0; i < w; i++) {
+ for (j = k; j < k + 4 && j < h; j++) {
+ vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0;
+ t1_3d_dec_refpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->flagSVR[1 + m][1 + j][1 + i], &t1->data[m][j][i], poshalf, neghalf, type, vsc);
+ }
+ }
+ }
+ }
+} /* VSC and BYPASS by Antonin */
+
+static void t1_3d_enc_clnpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int orient, int bpno, int one, int *nmsedec, int partial, int vsc) {
+ int v, flagsvr;
+ unsigned int flag;
+
+ opj_mqc_t *mqc = t1->mqc; /* MQC component */
+
+ flag = vsc ? ((*fp) & (~(T1_3D_SIG_S | T1_3D_SIG_SE | T1_3D_SIG_SW | (T1_3D_SGN_S << 16)))) : (*fp);
+ flagsvr = (*fsvr);
+ if (partial) {
+ goto LABEL_PARTIAL;
+ }
+ if (!(*fsvr & (T1_3D_SIG | T1_3D_VISIT))) {
+ mqc_setcurctx(mqc, t1_3d_getctxno_zc(flag, orient));
+ v = int_abs(*dp) & one ? 1 : 0;
+ mqc_encode(mqc, v);
+ if (v) {
+LABEL_PARTIAL:
+ *nmsedec += t1_3d_getnmsedec_sig(t1, int_abs(*dp), bpno + T1_NMSEDEC_FRACBITS);
+ mqc_setcurctx(mqc, t1_3d_getctxno_sc(flag));
+ v = *dp < 0 ? 1 : 0;
+ mqc_encode(mqc, v ^ t1_3d_getspb(flag));
+ t1_3d_updateflags(fp, v);
+ *fsvr |= T1_3D_SIG;
+ }
+ }
+ *fsvr &= ~T1_3D_VISIT;
+}
+
+static void t1_3d_dec_clnpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int orient, int oneplushalf, int partial, int vsc) {
+ int v, flagsvr;
+ unsigned int flag;
+
+ opj_mqc_t *mqc = t1->mqc; /* MQC component */
+
+ flag = vsc ? ((*fp) & (~(T1_3D_SIG_S | T1_3D_SIG_SE | T1_3D_SIG_SW | (T1_3D_SGN_S << 16)))) : (*fp);
+ flagsvr = (*fsvr);
+ if (partial) {
+ goto LABEL_PARTIAL;
+ }
+ if (!(flagsvr & (T1_3D_SIG | T1_3D_VISIT))) {
+ mqc_setcurctx(mqc, t1_3d_getctxno_zc(flag, orient));
+ if (mqc_decode(mqc)) {
+LABEL_PARTIAL:
+ mqc_setcurctx(mqc, t1_3d_getctxno_sc(flag));
+ v = mqc_decode(mqc) ^ t1_3d_getspb(flag);
+ *dp = v ? -oneplushalf : oneplushalf;
+ t1_3d_updateflags(fp, v);
+ *fsvr |= T1_3D_SIG;
+ }
+ }
+ *fsvr &= ~T1_3D_VISIT;
+} /* VSC and BYPASS by Antonin */
+
+static void t1_3d_enc_clnpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int orient, int *nmsedec, int cblksty) {
+ int i, j, k, m, one, agg, runlen, vsc;
+
+ opj_mqc_t *mqc = t1->mqc; /* MQC component */
+
+ *nmsedec = 0;
+ one = 1 << (bpno + T1_NMSEDEC_FRACBITS);
+ for (m = 0; m < l; m++) {
+ for (k = 0; k < h; k += 4) {
+ for (i = 0; i < w; i++) {
+ if (k + 3 < h) {
+ if (cblksty & J3D_CCP_CBLKSTY_VSC) {
+ agg = !( ((t1->flagSVR[1 + m][1 + k][1 + i] | (T1_3D_SIG | T1_3D_VISIT)) & (t1->flags[1 + m][1 + k][1 + i] & T1_3D_SIG_OTH))
+ || ((t1->flagSVR[1 + m][1 + k + 1][1 + i] | (T1_3D_SIG | T1_3D_VISIT)) & (t1->flags[1 + m][1 + k + 1][1 + i] & T1_3D_SIG_OTH))
+ || ((t1->flagSVR[1 + m][1 + k + 2][1 + i] | (T1_3D_SIG | T1_3D_VISIT)) & (t1->flags[1 + m][1 + k + 2][1 + i] & T1_3D_SIG_OTH))
+ || ((t1->flagSVR[1 + m][1 + k + 3][1 + i] | (T1_3D_SIG | T1_3D_VISIT)) & ((t1->flags[1 + m][1 + k + 3][1 + i] & (~(T1_3D_SIG_S | T1_3D_SIG_SE | T1_3D_SIG_SW | (T1_3D_SGN_S << 16)))) & (T1_3D_SIG_OTH)))
+ );
+ } else {
+ agg = !(
+ ((t1->flagSVR[1 + m][1 + k][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k][1 + i] & T1_3D_SIG_OTH))
+ || ((t1->flagSVR[1 + m][1 + k + 1][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k + 1][1 + i] & T1_3D_SIG_OTH))
+ || ((t1->flagSVR[1 + m][1 + k + 2][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k + 2][1 + i] & T1_3D_SIG_OTH))
+ || ((t1->flagSVR[1 + m][1 + k + 3][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k + 3][1 + i] & T1_3D_SIG_OTH))
+ );
+ }
+ } else {
+ agg = 0;
+ }
+ if (agg) {
+ for (runlen = 0; runlen < 4; runlen++) {
+ if (int_abs(t1->data[m][k + runlen][i]) & one)
+ break;
+ }
+ mqc_setcurctx(mqc, T1_CTXNO_AGG);
+ mqc_encode(mqc, runlen != 4);
+ if (runlen == 4) {
+ continue;
+ }
+ mqc_setcurctx(mqc, T1_CTXNO_UNI);
+ mqc_encode(mqc, runlen >> 1);
+ mqc_encode(mqc, runlen & 1);
+ } else {
+ runlen = 0;
+ }
+ for (j = k + runlen; j < k + 4 && j < h; j++) {
+ vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0;
+ t1_3d_enc_clnpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->flagSVR[1 + m][1 + j][1 + i], &t1->data[m][j][i], orient, bpno, one, nmsedec, agg && (j == k + runlen), vsc);
+ }
+ }
+ }
+ }
+}
+
+static void t1_3d_dec_clnpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int orient, int cblksty) {
+ int i, j, k, m, one, half, oneplushalf, agg, runlen, vsc;
+ int segsym = cblksty & J3D_CCP_CBLKSTY_SEGSYM;
+
+ opj_mqc_t *mqc = t1->mqc; /* MQC component */
+
+ one = 1 << bpno;
+ half = one >> 1;
+ oneplushalf = one | half;
+ for (m = 0; m < l; m++) {
+ for (k = 0; k < h; k += 4) {
+ for (i = 0; i < w; i++) {
+ if (k + 3 < h) {
+ if (cblksty & J3D_CCP_CBLKSTY_VSC) {
+ agg = !(
+ ((t1->flagSVR[1 + m][1 + k][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k][1 + i] & T1_3D_SIG_OTH))
+ || ((t1->flagSVR[1 + m][1 + k + 1][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k + 1][1 + i] & T1_3D_SIG_OTH))
+ || ((t1->flagSVR[1 + m][1 + k + 2][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k + 2][1 + i] & T1_3D_SIG_OTH))
+ || ((t1->flagSVR[1 + m][1 + k + 3][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | ((t1->flags[1 + m][1 + k + 3][1 + i] & (~(T1_3D_SIG_S | T1_3D_SIG_SE | T1_3D_SIG_SW | (T1_3D_SGN_S << 16)))) & (T1_3D_SIG_OTH)))
+ );
+ } else {
+ agg = !(
+ ((t1->flagSVR[1 + m][1 + k][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k][1 + i] & T1_3D_SIG_OTH))
+ || ((t1->flagSVR[1 + m][1 + k + 1][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k + 1][1 + i] & T1_3D_SIG_OTH))
+ || ((t1->flagSVR[1 + m][1 + k + 2][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k + 2][1 + i] & T1_3D_SIG_OTH))
+ || ((t1->flagSVR[1 + m][1 + k + 3][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k + 3][1 + i] & T1_3D_SIG_OTH))
+ );
+ }
+ } else {
+ agg = 0;
+ }
+ if (agg) {
+ mqc_setcurctx(mqc, T1_CTXNO_AGG);
+ if (!mqc_decode(mqc)) {
+ continue;
+ }
+ mqc_setcurctx(mqc, T1_CTXNO_UNI);
+ runlen = mqc_decode(mqc);
+ runlen = (runlen << 1) | mqc_decode(mqc);
+ } else {
+ runlen = 0;
+ }
+ for (j = k + runlen; j < k + 4 && j < h; j++) {
+ vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0;
+ t1_3d_dec_clnpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->flagSVR[1 + m][1 + j][1 + i], &t1->data[m][j][i], orient, oneplushalf, agg && (j == k + runlen), vsc);
+ }
+ }
+ }
+ }
+ if (segsym) {
+ int v = 0;
+ mqc_setcurctx(mqc, T1_CTXNO_UNI);
+ v = mqc_decode(mqc);
+ v = (v << 1) | mqc_decode(mqc);
+ v = (v << 1) | mqc_decode(mqc);
+ v = (v << 1) | mqc_decode(mqc);
+ /*
+ if (v!=0xa) {
+ opj_event_msg(t1->cinfo, EVT_WARNING, "Bad segmentation symbol %x\n", v);
+ }
+ */
+ }
+} /* VSC and BYPASS by Antonin */
+
+
+static void t1_3d_encode_cblk(opj_t1_3d_t *t1, opj_tcd_cblk_t * cblk, int orient, int compno, int level[3], int dwtid[3], double stepsize, int cblksty, int numcomps, opj_tcd_tile_t * tile) {
+ int i, j, k;
+ int w, h, l;
+ int passno;
+ int bpno, passtype;
+ int max;
+ int nmsedec = 0;
+ double cumwmsedec = 0;
+ char type = T1_TYPE_MQ;
+
+ opj_mqc_t *mqc = t1->mqc; /* MQC component */
+
+ w = cblk->x1 - cblk->x0;
+ h = cblk->y1 - cblk->y0;
+ l = cblk->z1 - cblk->z0;
+
+ max = 0;
+ for (k = 0; k < l; k++) {
+ for (j = 0; j < h; j++) {
+ for (i = 0; i < w; i++) {
+ max = int_max(max, int_abs(t1->data[k][j][i]));
+ }
+ }
+ }
+ for (k = 0; k <= l; k++) {
+ for (j = 0; j <= h; j++) {
+ for (i = 0; i <= w; i++) {
+ t1->flags[k][j][i] = 0;
+ t1->flagSVR[k][j][i] = 0;
+ }
+ }
+ }
+
+ cblk->numbps = max ? (int_floorlog2(max) + 1) - T1_NMSEDEC_FRACBITS : 0;
+
+ bpno = cblk->numbps - 1;
+ passtype = 2;
+
+ mqc_reset_enc(mqc);
+ mqc_init_enc(mqc, cblk->data);
+
+ for (passno = 0; bpno >= 0; passno++) {
+ opj_tcd_pass_t *pass = &cblk->passes[passno];
+ int correction = 3;
+ double tmpwmsedec;
+ type = ((bpno < (cblk->numbps - 4)) && (passtype < 2) && (cblksty & J3D_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ;
+
+ switch (passtype) {
+ case 0:
+ t1_3d_enc_sigpass(t1, w, h, l, bpno, orient, &nmsedec, type, cblksty);
+ break;
+ case 1:
+ t1_3d_enc_refpass(t1, w, h, l, bpno, &nmsedec, type, cblksty);
+ break;
+ case 2:
+ t1_3d_enc_clnpass(t1, w, h, l, bpno, orient, &nmsedec, cblksty);
+ /* code switch SEGMARK (i.e. SEGSYM) */
+ if (cblksty & J3D_CCP_CBLKSTY_SEGSYM)
+ mqc_segmark_enc(mqc);
+ break;
+ }
+
+ /* fixed_quality */
+ tmpwmsedec = t1_getwmsedec(nmsedec, compno, level, orient, bpno, stepsize, numcomps, dwtid);
+ cumwmsedec += tmpwmsedec;
+ tile->distotile += tmpwmsedec;
+
+ /* Code switch "RESTART" (i.e. TERMALL) */
+ if ((cblksty & J3D_CCP_CBLKSTY_TERMALL) && !((passtype == 2) && (bpno - 1 < 0))) {
+ if (type == T1_TYPE_RAW) {
+ mqc_flush(mqc);
+ correction = 1;
+ /* correction = mqc_bypass_flush_enc(); */
+ } else { /* correction = mqc_restart_enc(); */
+ mqc_flush(mqc);
+ correction = 1;
+ }
+ pass->term = 1;
+ } else {
+ if (((bpno < (cblk->numbps - 4) && (passtype > 0))
+ || ((bpno == (cblk->numbps - 4)) && (passtype == 2))) && (cblksty & J3D_CCP_CBLKSTY_LAZY)) {
+ if (type == T1_TYPE_RAW) {
+ mqc_flush(mqc);
+ correction = 1;
+ } else {
+ mqc_flush(mqc);
+ correction = 1;
+ }
+ pass->term = 1;
+ } else {
+ pass->term = 0;
+ }
+ }
+
+ if (++passtype == 3) {
+ passtype = 0;
+ bpno--;
+ }
+
+ if (pass->term && bpno > 0) {
+ type = ((bpno < (cblk->numbps - 4)) && (passtype < 2) && (cblksty & J3D_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ;
+ if (type == T1_TYPE_RAW)
+ mqc_bypass_init_enc(mqc);
+ else
+ mqc_restart_init_enc(mqc);
+ }
+
+ pass->distortiondec = cumwmsedec;
+ pass->rate = mqc_numbytes(mqc) + correction; /* FIXME */
+ pass->len = pass->rate - (passno == 0 ? 0 : cblk->passes[passno - 1].rate);
+
+ /* Code-switch "RESET" */
+ if (cblksty & J3D_CCP_CBLKSTY_RESET)
+ mqc_reset_enc(mqc);
+ }
+
+ /* Code switch "ERTERM" (i.e. PTERM) */
+ if (cblksty & J3D_CCP_CBLKSTY_PTERM)
+ mqc_erterm_enc(mqc);
+ else /* Default coding */ if (!(cblksty & J3D_CCP_CBLKSTY_LAZY))
+ mqc_flush(mqc);
+
+ cblk->totalpasses = passno;
+}
+
+static void t1_3d_decode_cblk(opj_t1_3d_t *t1, opj_tcd_cblk_t * cblk, int orient, int roishift, int cblksty) {
+ int i, j, k;
+ int w, h, l;
+ int bpno, passtype;
+ int segno, passno;
+ char type = T1_TYPE_MQ; /* BYPASS mode */
+ opj_raw_t *raw = t1->raw; /* RAW component */
+ opj_mqc_t *mqc = t1->mqc; /* MQC component */
+
+ w = cblk->x1 - cblk->x0;
+ h = cblk->y1 - cblk->y0;
+ l = cblk->z1 - cblk->z0;
+
+ for (k = 0; k < l; k++) {
+ for (j = 0; j < h; j++) {
+ for (i = 0; i < w; i++) {
+ t1->data[k][j][i] = 0;
+ }
+ }
+ }
+
+ for (k = 0; k <= l; k++) {
+ for (j = 0; j <= h; j++) {
+ for (i = 0; i <= w; i++) {
+ t1->flags[k][j][i] = 0;
+ t1->flagSVR[k][j][i] = 0;
+ }
+ }
+ }
+
+
+ bpno = roishift + cblk->numbps - 1;
+ passtype = 2;
+
+ mqc_reset_enc(mqc);
+
+ for (segno = 0; segno < cblk->numsegs; segno++) {
+ opj_tcd_seg_t *seg = &cblk->segs[segno];
+
+ /* BYPASS mode */
+ type = ((bpno <= (cblk->numbps - 1) - 4) && (passtype < 2) && (cblksty & J3D_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ;
+ if (type == T1_TYPE_RAW) {
+ raw_init_dec(raw, seg->data, seg->len);
+ } else {
+ mqc_init_dec(mqc, seg->data, seg->len);
+ }
+
+ for (passno = 0; passno < seg->numpasses; passno++) {
+ switch (passtype) {
+ case 0:
+ t1_3d_dec_sigpass(t1, w, h, l, bpno+1, orient, type, cblksty);
+ break;
+ case 1:
+ t1_3d_dec_refpass(t1, w, h, l, bpno+1, type, cblksty);
+ break;
+ case 2:
+ t1_3d_dec_clnpass(t1, w, h, l, bpno+1, orient, cblksty);
+ break;
+ }
+
+ if ((cblksty & J3D_CCP_CBLKSTY_RESET) && type == T1_TYPE_MQ) {
+ mqc_reset_enc(mqc);
+ }
+ if (++passtype == 3) {
+ passtype = 0;
+ bpno--;
+ }
+
+ }
+ }
+}
+
+static int t1_3d_init_ctxno_zc(unsigned int f, int orient) {
+ unsigned int h, v, c;
+ unsigned int d2xy, d2xz, d2yz, d3;
+ int n;
+ unsigned int hvc, hc, d2, d2xy2yz, d2xy2xz;
+ n = 0;
+ h = ((f & T1_3D_SIG_W) != 0) + ((f & T1_3D_SIG_E) != 0);
+ v = ((f & T1_3D_SIG_N) != 0) + ((f & T1_3D_SIG_S) != 0);
+ c = ((f & T1_3D_SIG_FC) != 0) + ((f & T1_3D_SIG_BC) != 0);
+ d2xy = ((f & T1_3D_SIG_NW) != 0) + ((f & T1_3D_SIG_NE) != 0) + ((f & T1_3D_SIG_SE) != 0) + ((f & T1_3D_SIG_SW) != 0);
+ d2xz = ((f & T1_3D_SIG_FW) != 0) + ((f & T1_3D_SIG_BW) != 0) + ((f & T1_3D_SIG_FE) != 0) + ((f & T1_3D_SIG_BE) != 0);
+ d2yz = ((f & T1_3D_SIG_FN) != 0) + ((f & T1_3D_SIG_FS) != 0) + ((f & T1_3D_SIG_BN) != 0) + ((f & T1_3D_SIG_BS) != 0);
+ d3 = ((f & T1_3D_SIG_FNW) != 0) + ((f & T1_3D_SIG_FNE) != 0) + ((f & T1_3D_SIG_FSE) != 0) + ((f & T1_3D_SIG_FSW) != 0)
+ + ((f & T1_3D_SIG_BNW) != 0) + ((f & T1_3D_SIG_BNE) != 0) + ((f & T1_3D_SIG_BSE) != 0) + ((f & T1_3D_SIG_BSW) != 0);
+
+ switch (orient) {
+ case 0: //LLL
+ case 7: //HHH
+ hvc = h + v + c;
+ d2 = d2xy + d2xz + d2yz;
+ if (!hvc) {
+ if (!d2) {
+ n = (!d3) ? 0 : 1;
+ } else if (d2 == 1) {
+ n = (!d3) ? 2 : 3;
+ } else {
+ n = (!d3) ? 4 : 5;
+ }
+ } else if (hvc == 1) {
+ if (!d2) {
+ n = (!d3) ? 6 : 7;
+ } else if (d2 == 1) {
+ n = (!d3) ? 8 : 9;
+ } else {
+ n = 10;
+ }
+ } else if (hvc == 2) {
+ if (!d2) {
+ n = (!d3) ? 11 : 12;
+ } else {
+ n = 13;
+ }
+ } else if (hvc == 3) {
+ n = 14;
+ } else {
+ n = 15;
+ }
+ break;
+ //LHL, HLL, LLH
+ case 1:
+ case 2:
+ case 4:
+ hc = h + c;
+ d2xy2yz = d2xy + d2yz;
+ if (!hc) {
+ if (!v) {
+ if (!d2xy) {
+ n = (!d2xy2yz) ? ((!d3) ? 0 : 1) : ((!d3) ? 2 : 3);
+ } else if (d2xy == 1) {
+ n = (!d2xy2yz) ? ((!d3) ? 4 : 5) : 6;
+ } else { //>=2
+ n = 7;
+ }
+ } else {
+ n = (v == 1) ? 8 : 9; // =1 or =2
+ }
+ } else if (hc == 1) {
+ n = (!v) ? ( (!d2xy) ? ( (!d2xy2yz) ? ( (!d3) ? 10 : 11) : (12) ) : (13) ) : (14);
+ } else { //if (hc >= 2)
+ n = 15;
+ }
+ break;
+ //HLH, HHL, LHH
+ case 3:
+ case 5:
+ case 6:
+ hc = h + c;
+ d2xy2xz = d2xy + d2xz;
+ if (!v) {
+ if (!d2xz) {
+ if (!hc && !d2xy2xz) {
+ n = (!d3) ? 0 : 1;
+ } else if (hc == 1) {
+ n = (!d2xy2xz) ? 2 : 3;
+ } else { //if >= 2
+ n = 4;
+ }
+ } else if ( d2xz>=1 && !hc ) {
+ n = 5;
+ } else if ( hc>=1 ) {
+ n = (d2xz==1) ? 6 : 7;
+ }
+ } else if (v == 1) {
+ if (!d2xz) {
+ n = (!hc) ? 8 : 9;
+ } else if (d2xz == 1) {
+ n = (!hc) ? 10 : 11;
+ } else if (d2xz == 2) {
+ n = (!hc) ? 12 : 13;
+ } else { // if (d2xz >= 3) {
+ n = 14;
+ }
+ } else if (v == 2) {
+ n = 15;
+ }
+ break;
+ }
+
+ return (T1_3D_CTXNO_ZC + n);
+}
+
+static int t1_3d_init_ctxno_sc(unsigned int f) {
+ int hc, vc, cc;
+ int n = 0;
+
+ hc = int_min( ( (f & (T1_3D_SIG_E | T1_3D_SGN_E)) == T1_3D_SIG_E )
+ + ( (f & (T1_3D_SIG_W | T1_3D_SGN_W)) == T1_3D_SIG_W ) , 1)
+ - int_min( ( (f & (T1_3D_SIG_E | T1_3D_SGN_E)) == (T1_3D_SIG_E | T1_3D_SGN_E) )
+ + ( (f & (T1_3D_SIG_W | T1_3D_SGN_W) ) == (T1_3D_SIG_W | T1_3D_SGN_W)), 1);
+
+ vc = int_min(((f & (T1_3D_SIG_N | T1_3D_SGN_N)) == T1_3D_SIG_N)
+ + ((f & (T1_3D_SIG_S | T1_3D_SGN_S)) == T1_3D_SIG_S), 1)
+ - int_min(((f & (T1_3D_SIG_N | T1_3D_SGN_N)) == (T1_3D_SIG_N | T1_3D_SGN_N))
+ + ((f & (T1_3D_SIG_S | T1_3D_SGN_S)) == (T1_3D_SIG_S | T1_3D_SGN_S)), 1);
+
+ cc = int_min(((f & (T1_3D_SIG_FC | T1_3D_SGN_F)) == T1_3D_SIG_FC)
+ + ((f & (T1_3D_SIG_BC | T1_3D_SGN_B)) == T1_3D_SIG_BC), 1)
+ - int_min(((f & (T1_3D_SIG_FC | T1_3D_SGN_F)) == (T1_3D_SIG_FC | T1_3D_SGN_F))
+ + ((f & (T1_3D_SIG_BC | T1_3D_SGN_B)) == (T1_3D_SIG_BC | T1_3D_SGN_B)), 1);
+ if (hc < 0) {
+ hc = -hc;
+ vc = -vc;
+ cc = -cc;
+ }
+
+ if (!hc) {
+ if (!vc)
+ n = (!cc) ? 0 : 1;
+ else if (vc == -1)
+ n = (!cc) ? 1 : ( (cc>0) ? 2 : 4);
+ else if (vc == 1)
+ n = (!cc) ? 1 : ( (cc<0) ? 2 : 4);
+ } else if (hc == 1) {
+ if (!vc)
+ n = (!cc) ? 1 : ( (cc<0) ? 2 : 4);
+ else if (vc == 1)
+ n = (!cc) ? 4 : ( (cc>0) ? 5 : 3);
+ else if (vc == -1)
+ n = (!cc) ? 2 : 3;
+ } else if (hc == -1) {
+ if (!vc)
+ n = (!cc) ? 1 : ( (cc>0) ? 2 : 4);
+ else if (vc == 1)
+ n = (!cc) ? 2 : 3;
+ else if (vc == -1)
+ n = (!cc) ? 4 : ( (cc<0) ? 5 : 3);
+ }
+
+ return (T1_3D_CTXNO_SC + n);
+}
+
+static int t1_3d_init_ctxno_mag(unsigned int f, int f2) {
+ int n;
+ if (!(f2 & T1_3D_REFINE)) //First refinement for this coefficient (no previous refinement)
+ n = (f & (T1_3D_SIG_PRIM)) ? 1 : 0;
+ else
+ n = 2;
+
+ return (T1_3D_CTXNO_MAG + n);
+}
+
+static int t1_3d_init_spb(unsigned int f) {
+ int hc, vc, cc;
+ int n = 0;
+
+ hc = int_min( ( (f & (T1_3D_SIG_E | T1_3D_SGN_E)) == T1_3D_SIG_E )
+ + ( (f & (T1_3D_SIG_W | T1_3D_SGN_W)) == T1_3D_SIG_W ) , 1)
+ - int_min( ( (f & (T1_3D_SIG_E | T1_3D_SGN_E)) == (T1_3D_SIG_E | T1_3D_SGN_E) )
+ + ( (f & (T1_3D_SIG_W | T1_3D_SGN_W) ) == (T1_3D_SIG_W | T1_3D_SGN_W)), 1);
+
+ vc = int_min(((f & (T1_3D_SIG_N | T1_3D_SGN_N)) == T1_3D_SIG_N)
+ + ((f & (T1_3D_SIG_S | T1_3D_SGN_S)) == T1_3D_SIG_S), 1)
+ - int_min(((f & (T1_3D_SIG_N | T1_3D_SGN_N)) == (T1_3D_SIG_N | T1_3D_SGN_N))
+ + ((f & (T1_3D_SIG_S | T1_3D_SGN_S)) == (T1_3D_SIG_S | T1_3D_SGN_S)), 1);
+
+ cc = int_min(((f & (T1_3D_SIG_FC | T1_3D_SGN_F)) == T1_3D_SIG_FC)
+ + ((f & (T1_3D_SIG_BC | T1_3D_SGN_B)) == T1_3D_SIG_BC), 1)
+ - int_min(((f & (T1_3D_SIG_FC | T1_3D_SGN_F)) == (T1_3D_SIG_FC | T1_3D_SGN_F))
+ + ((f & (T1_3D_SIG_BC | T1_3D_SGN_B)) == (T1_3D_SIG_BC | T1_3D_SGN_B)), 1);
+
+ n = ((hc + vc + cc) < 0);
+
+ return n;
+}
+
+static void t1_3d_init_luts(opj_t1_3d_t *t1) {
+ int i;
+ double u, v, t;
+ /*for (j = 0; j < 4; j++) {
+ for (i = 0; i < 256; ++i) {
+ t1->lut_ctxno_zc[(j << 8) | i] = t1_3d_init_ctxno_zc(i, j);
+ }
+ }
+ for (i = 0; i < 4096; i++) {
+ t1->lut_ctxno_sc[i] = t1_3d_init_ctxno_sc(i << 4);
+ }
+ for (j = 0; j < 2; j++) {
+ for (i = 0; i < 2048; ++i) {
+ t1->lut_ctxno_mag[(j << 11) + i] = t1_3d_init_ctxno_mag((j ? T1_3D_REFINE : 0) | i);
+ }
+ }
+ for (i = 0; i < 4096; ++i) {
+ t1->lut_spb[i] = t1_3d_init_spb(i << 4);
+ }*/
+ /* FIXME FIXME FIXME */
+ for (i = 0; i < (1 << T1_NMSEDEC_BITS); i++) {
+ t = i / pow(2, T1_NMSEDEC_FRACBITS);
+ u = t;
+ v = t - 1.5;
+ t1->lut_nmsedec_sig[i] =
+ int_max(0,
+ (int) (floor((u * u - v * v) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0));
+ t1->lut_nmsedec_sig0[i] =
+ int_max(0,
+ (int) (floor((u * u) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0));
+ u = t - 1.0;
+ if (i & (1 << (T1_NMSEDEC_BITS - 1))) {
+ v = t - 1.5;
+ } else {
+ v = t - 0.5;
+ }
+ t1->lut_nmsedec_ref[i] =
+ int_max(0,
+ (int) (floor((u * u - v * v) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0));
+ t1->lut_nmsedec_ref0[i] =
+ int_max(0,
+ (int) (floor((u * u) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0));
+ }
+}
+
+/* ----------------------------------------------------------------------- */
+
+opj_t1_3d_t* t1_3d_create(opj_common_ptr cinfo) {
+ opj_t1_3d_t *t1 = (opj_t1_3d_t*)opj_malloc(sizeof(opj_t1_3d_t));
+ if(t1) {
+ t1->cinfo = cinfo;
+ /* create MQC and RAW handles */
+ t1->mqc = mqc_create();
+ t1->raw = raw_create();
+ /* initialize the look-up tables of the Tier-1 coder/decoder */
+ t1_3d_init_luts(t1);
+ }
+ return t1;
+}
+
+void t1_3d_destroy(opj_t1_3d_t *t1) {
+ if(t1) {
+ /* destroy MQC and RAW handles */
+ mqc_destroy(t1->mqc);
+ raw_destroy(t1->raw);
+ opj_free(t1);
+ }
+}
+
+void t1_3d_encode_cblks(opj_t1_3d_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp) {
+ int compno, resno, bandno, precno, cblkno;
+ int x, y, z, i, j, k, orient;
+ int level[3];
+ tile->distotile = 0; /* fixed_quality */
+
+ for (compno = 0; compno < tile->numcomps; compno++) {
+ opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
+
+ for (resno = 0; resno < tilec->numresolution[0]; resno++) {
+ opj_tcd_resolution_t *res = &tilec->resolutions[resno];
+
+ for (bandno = 0; bandno < res->numbands; bandno++) {
+ opj_tcd_band_t *band = &res->bands[bandno];
+
+ for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) {
+ opj_tcd_precinct_t *prc = &band->precincts[precno];
+
+ for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {
+ opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];
+
+ if (band->bandno == 0) {
+ x = cblk->x0 - band->x0;
+ y = cblk->y0 - band->y0;
+ z = cblk->z0 - band->z0;
+ } else if (band->bandno == 1) {
+ opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+ x = pres->x1 - pres->x0 + cblk->x0 - band->x0;
+ y = cblk->y0 - band->y0;
+ z = cblk->z0 - band->z0;
+ } else if (band->bandno == 2) {
+ opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+ x = cblk->x0 - band->x0;
+ y = pres->y1 - pres->y0 + cblk->y0 - band->y0;
+ z = cblk->z0 - band->z0;
+ } else if (band->bandno == 3) {
+ opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+ x = pres->x1 - pres->x0 + cblk->x0 - band->x0;
+ y = pres->y1 - pres->y0 + cblk->y0 - band->y0;
+ z = cblk->z0 - band->z0;
+ } else if (band->bandno == 4) {
+ opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+ x = cblk->x0 - band->x0;
+ y = cblk->y0 - band->y0;
+ z = pres->z1 - pres->z0 + cblk->z0 - band->z0;
+ } else if (band->bandno == 5) {
+ opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+ x = pres->x1 - pres->x0 + cblk->x0 - band->x0;
+ y = cblk->y0 - band->y0;
+ z = pres->z1 - pres->z0 + cblk->z0 - band->z0;
+ } else if (band->bandno == 6) {
+ opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+ x = cblk->x0 - band->x0;
+ y = pres->y1 - pres->y0 + cblk->y0 - band->y0;
+ z = pres->z1 - pres->z0 + cblk->z0 - band->z0;
+ } else if (band->bandno == 7) {
+ opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+ x = pres->x1 - pres->x0 + cblk->x0 - band->x0;
+ y = pres->y1 - pres->y0 + cblk->y0 - band->y0;
+ z = pres->z1 - pres->z0 + cblk->z0 - band->z0;
+ }
+
+ if (tcp->tccps[compno].reversible == 1) {
+ for (k = 0; k < cblk->z1 - cblk->z0; k++) {
+ for (j = 0; j < cblk->y1 - cblk->y0; j++) {
+ for (i = 0; i < cblk->x1 - cblk->x0; i++) {
+ t1->data[k][j][i] =
+ tilec->data[(x + i) + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)] << T1_NMSEDEC_FRACBITS;
+ }
+ }
+ }
+ } else if (tcp->tccps[compno].reversible == 0) {
+ for (k = 0; k < cblk->z1 - cblk->z0; k++) {
+ for (j = 0; j < cblk->y1 - cblk->y0; j++) {
+ for (i = 0; i < cblk->x1 - cblk->x0; i++) {
+ t1->data[k][j][i] = fix_mul(
+ tilec->data[(x + i) + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)],
+ 8192 * 8192 / ((int) floor(band->stepsize * 8192))) >> (13 - T1_NMSEDEC_FRACBITS);
+ }
+ }
+ }
+ }
+ orient = band->bandno; /* FIXME */
+ for (i = 0; i < 3; i++)
+ level[i] = tilec->numresolution[i] - 1 - resno;
+
+ t1_3d_encode_cblk(t1, cblk, orient, compno, level, tcp->tccps[compno].dwtid, band->stepsize, tcp->tccps[compno].cblksty, tile->numcomps, tile);
+
+ } /* cblkno */
+ } /* precno */
+ } /* bandno */
+ } /* resno */
+ } /* compno */
+}
+
+void t1_3d_decode_cblks(opj_t1_3d_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp) {
+ int compno, resno, bandno, precno, cblkno;
+
+ for (compno = 0; compno < tile->numcomps; compno++) {
+ opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
+
+ for (resno = 0; resno < tilec->numresolution[0]; resno++) {
+ opj_tcd_resolution_t *res = &tilec->resolutions[resno];
+
+ for (bandno = 0; bandno < res->numbands; bandno++) {
+ opj_tcd_band_t *band = &res->bands[bandno];
+
+ for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) {
+ opj_tcd_precinct_t *prc = &band->precincts[precno];
+
+ for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {
+ int x, y, z, i, j, k, orient;
+ opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];
+
+ orient = band->bandno; /* FIXME */
+
+ //fprintf(stdout,"[INFO] t1_3d_decode_cblk(t1, cblk, orient(%d), tcp->tccps[compno].roishift (%d), tcp->tccps[compno].cblksty (%d));\n",orient,tcp->tccps[compno].roishift, tcp->tccps[compno].cblksty);
+ t1_3d_decode_cblk(t1, cblk, orient, tcp->tccps[compno].roishift, tcp->tccps[compno].cblksty);
+
+ if (band->bandno == 0) {
+ x = cblk->x0 - band->x0;
+ y = cblk->y0 - band->y0;
+ z = cblk->z0 - band->z0;
+ } else if (band->bandno == 1) {
+ opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+ x = pres->x1 - pres->x0 + cblk->x0 - band->x0;
+ y = cblk->y0 - band->y0;
+ z = cblk->z0 - band->z0;
+ } else if (band->bandno == 2) {
+ opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+ x = cblk->x0 - band->x0;
+ y = pres->y1 - pres->y0 + cblk->y0 - band->y0;
+ z = cblk->z0 - band->z0;
+ } else if (band->bandno == 3) {
+ opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+ x = pres->x1 - pres->x0 + cblk->x0 - band->x0;
+ y = pres->y1 - pres->y0 + cblk->y0 - band->y0;
+ z = cblk->z0 - band->z0;
+ } else if (band->bandno == 4) {
+ opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+ x = cblk->x0 - band->x0;
+ y = cblk->y0 - band->y0;
+ z = pres->z1 - pres->z0 + cblk->z0 - band->z0;
+ } else if (band->bandno == 5) {
+ opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+ x = pres->x1 - pres->x0 + cblk->x0 - band->x0;
+ y = cblk->y0 - band->y0;
+ z = pres->z1 - pres->z0 + cblk->z0 - band->z0;
+ } else if (band->bandno == 6) {
+ opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+ x = cblk->x0 - band->x0;
+ y = pres->y1 - pres->y0 + cblk->y0 - band->y0;
+ z = pres->z1 - pres->z0 + cblk->z0 - band->z0;
+ } else if (band->bandno == 7) {
+ opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+ x = pres->x1 - pres->x0 + cblk->x0 - band->x0;
+ y = pres->y1 - pres->y0 + cblk->y0 - band->y0;
+ z = pres->z1 - pres->z0 + cblk->z0 - band->z0;
+ }
+
+ if (tcp->tccps[compno].roishift) {
+ int thresh, val, mag;
+ thresh = 1 << tcp->tccps[compno].roishift;
+ for (k = 0; k < cblk->z1 - cblk->z0; k++) {
+ for (j = 0; j < cblk->y1 - cblk->y0; j++) {
+ for (i = 0; i < cblk->x1 - cblk->x0; i++) {
+ val = t1->data[k][j][i];
+ mag = int_abs(val);
+ if (mag >= thresh) {
+ mag >>= tcp->tccps[compno].roishift;
+ t1->data[k][j][i] = val < 0 ? -mag : mag;
+ }
+ }
+ }
+ }
+ }
+
+ if (tcp->tccps[compno].reversible == 1) {
+ for (k = 0; k < cblk->z1 - cblk->z0; k++) {
+ for (j = 0; j < cblk->y1 - cblk->y0; j++) {
+ for (i = 0; i < cblk->x1 - cblk->x0; i++) {
+ int tmp = t1->data[k][j][i];
+ tilec->data[x + i + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)] = tmp/2;
+ }
+ }
+ }
+ } else { /* if (tcp->tccps[compno].reversible == 0) */
+ for (k = 0; k < cblk->z1 - cblk->z0; k++) {
+ for (j = 0; j < cblk->y1 - cblk->y0; j++) {
+ for (i = 0; i < cblk->x1 - cblk->x0; i++) {
+ double tmp = (double)(t1->data[k][j][i] * band->stepsize * 4096.0);
+ if (t1->data[k][j][i] >> 1 == 0) {
+ tilec->data[x + i + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)] = 0;
+ } else {
+ int tmp2 = ((int) (floor(fabs(tmp)))) + ((int) floor(fabs(tmp*2))%2);
+ tilec->data[x + i + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)] = ((tmp<0)?-tmp2:tmp2);
+ }
+ }
+ }
+ }
+ }
+ } /* cblkno */
+ } /* precno */
+ } /* bandno */
+ } /* resno */
+ } /* compno */
+}
diff --git a/libopenjpeg3d/t1_3d.h b/libopenjpeg3d/t1_3d.h
new file mode 100755
index 00000000..dd73763d
--- /dev/null
+++ b/libopenjpeg3d/t1_3d.h
@@ -0,0 +1,173 @@
+/*
+ * Copyrigth (c) 2006, Mónica Díez, LPI-UVA, Spain
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef __T1_3D_H
+#define __T1_3D_H
+/**
+@file t1_3d.h
+@brief Implementation of the tier-1 coding (coding of code-block coefficients) (T1)
+
+The functions in T1_3D.C have for goal to realize the tier-1 coding operation of 3D-EBCOT.
+The functions in T1_3D.C are used by some function in TCD.C.
+*/
+
+/** @defgroup T1_3D T1_3D - Implementation of the tier-1 coding */
+/*@{*/
+
+/* ----------------------------------------------------------------------- */
+
+/* Neighbourhood of 3D EBCOT (Significance context)*/
+#define T1_3D_SIG_NE 0x00000001 /*< Context orientation : North-East direction */
+#define T1_3D_SIG_SE 0x00000002 /*< Context orientation : South-East direction */
+#define T1_3D_SIG_SW 0x00000004 /*< Context orientation : South-West direction */
+#define T1_3D_SIG_NW 0x00000008 /* Context orientation : North-West direction */
+#define T1_3D_SIG_N 0x00000010 /*< Context orientation : North direction */
+#define T1_3D_SIG_E 0x00000020 /*< Context orientation : East direction */
+#define T1_3D_SIG_S 0x00000040 /*< Context orientation : South direction */
+#define T1_3D_SIG_W 0x00000080 /*< Context orientation : West direction */
+#define T1_3D_SIG_FC 0x00000100 /*< Context orientation : Forward Central direction */
+#define T1_3D_SIG_BC 0x00000200 /*< Context orientation : Backward Central direction */
+#define T1_3D_SIG_FNE 0x00000400 /*< Context orientation : Forward North-East direction */
+#define T1_3D_SIG_FSE 0x00000800 /*< Context orientation : Forward South-East direction */
+#define T1_3D_SIG_FSW 0x00001000 /*< Context orientation : Forward South-West direction */
+#define T1_3D_SIG_FNW 0x00002000 /*< Context orientation : Forward North-West direction */
+#define T1_3D_SIG_FN 0x00004000 /*< Context orientation : Forward North direction */
+#define T1_3D_SIG_FE 0x00008000 /*< Context orientation : Forward East direction */
+#define T1_3D_SIG_FS 0x00010000 /*< Context orientation : Forward South direction */
+#define T1_3D_SIG_FW 0x00020000 /*< Context orientation : Forward West direction */
+#define T1_3D_SIG_BNE 0x00040000 /*< Context orientation : Backward North-East direction */
+#define T1_3D_SIG_BSE 0x00080000 /*< Context orientation : Backward South-East direction */
+#define T1_3D_SIG_BSW 0x00100000 /*< Context orientation : Backward South-West direction */
+#define T1_3D_SIG_BNW 0x00200000 /*< Context orientation : Backward North-West direction */
+#define T1_3D_SIG_BN 0x00400000 /*< Context orientation : Backward North direction */
+#define T1_3D_SIG_BE 0x00800000 /*< Context orientation : Backward East direction */
+#define T1_3D_SIG_BS 0x01000000 /*< Context orientation : Backward South direction */
+#define T1_3D_SIG_BW 0x02000000 /*< Context orientation : Backward West direction */
+#define T1_3D_SIG_COTH (T1_3D_SIG_N|T1_3D_SIG_NE|T1_3D_SIG_E|T1_3D_SIG_SE|T1_3D_SIG_S|T1_3D_SIG_SW|T1_3D_SIG_W|T1_3D_SIG_NW)
+#define T1_3D_SIG_BOTH (T1_3D_SIG_BN|T1_3D_SIG_BNE|T1_3D_SIG_BE|T1_3D_SIG_BSE|T1_3D_SIG_BS|T1_3D_SIG_BSW|T1_3D_SIG_BW|T1_3D_SIG_BNW|T1_3D_SIG_BC)
+#define T1_3D_SIG_FOTH (T1_3D_SIG_FN|T1_3D_SIG_FNE|T1_3D_SIG_FE|T1_3D_SIG_FSE|T1_3D_SIG_FS|T1_3D_SIG_FSW|T1_3D_SIG_FW|T1_3D_SIG_FNW|T1_3D_SIG_FC)
+#define T1_3D_SIG_OTH (T1_3D_SIG_FOTH|T1_3D_SIG_BOTH|T1_3D_SIG_COTH)
+#define T1_3D_SIG_PRIM (T1_3D_SIG_N|T1_3D_SIG_E|T1_3D_SIG_S|T1_3D_SIG_W|T1_3D_SIG_FC|T1_3D_SIG_BC)
+
+#define T1_3D_SGN_N 0x0400
+#define T1_3D_SGN_E 0x0800
+#define T1_3D_SGN_S 0x1000
+#define T1_3D_SGN_W 0x2000
+#define T1_3D_SGN_F 0x4000
+#define T1_3D_SGN_B 0x8000
+#define T1_3D_SGN (T1_3D_SGN_N|T1_3D_SGN_E|T1_3D_SGN_S|T1_3D_SGN_W|T1_3D_SGN_F|T1_3D_SGN_B)
+
+#define T1_3D_SIG 0x0001 //Significance state
+#define T1_3D_REFINE 0x0002 //Delayed significance
+#define T1_3D_VISIT 0x0004 //First-pass membership
+
+#define T1_3D_NUMCTXS_AGG 1
+#define T1_3D_NUMCTXS_ZC 16
+#define T1_3D_NUMCTXS_MAG 3
+#define T1_3D_NUMCTXS_SC 6
+#define T1_3D_NUMCTXS_UNI 1
+
+#define T1_3D_CTXNO_AGG 0
+#define T1_3D_CTXNO_ZC (T1_3D_CTXNO_AGG+T1_3D_NUMCTXS_AGG) //1
+#define T1_3D_CTXNO_MAG (T1_3D_CTXNO_ZC+T1_3D_NUMCTXS_ZC) //17
+#define T1_3D_CTXNO_SC (T1_3D_CTXNO_MAG+T1_3D_NUMCTXS_MAG) //20
+#define T1_3D_CTXNO_UNI (T1_3D_CTXNO_SC+T1_3D_NUMCTXS_SC) //26
+#define T1_3D_NUMCTXS (T1_3D_CTXNO_UNI+T1_3D_NUMCTXS_UNI) //27
+
+
+/* ----------------------------------------------------------------------- */
+
+/**
+Tier-1 coding (coding of code-block coefficients)
+*/
+typedef struct opj_t1_3d {
+ /** Codec context */
+ opj_common_ptr cinfo;
+ /** MQC component */
+ opj_mqc_t *mqc;
+ /** RAW component */
+ opj_raw_t *raw;
+ /** LUTs for decoding normalised MSE */
+ int lut_nmsedec_sig[1 << T1_NMSEDEC_BITS];
+ int lut_nmsedec_sig0[1 << T1_NMSEDEC_BITS];
+ int lut_nmsedec_ref[1 << T1_NMSEDEC_BITS];
+ int lut_nmsedec_ref0[1 << T1_NMSEDEC_BITS];
+ /** Codeblock data */
+ int data[T1_CBLKD][T1_CBLKH][T1_CBLKW];
+ /** Context information for each voxel in codeblock */
+ unsigned int flags[T1_CBLKD + 2][T1_CBLKH + 2][T1_CBLKH + 2];
+ /** Voxel information (significance/visited/refined) */
+ int flagSVR[T1_CBLKD + 2][T1_CBLKH + 2][T1_CBLKH + 2];
+} opj_t1_3d_t;
+
+/** @name Exported functions */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+/**
+Create a new T1_3D handle
+and initialize the look-up tables of the Tier-1 coder/decoder
+@return Returns a new T1 handle if successful, returns NULL otherwise
+@see t1_init_luts
+*/
+opj_t1_3d_t* t1_3d_create(opj_common_ptr cinfo);
+/**
+Destroy a previously created T1_3D handle
+@param t1 T1_3D handle to destroy
+*/
+void t1_3d_destroy(opj_t1_3d_t *t1);
+/**
+Encode the code-blocks of a tile
+@param t1 T1_3D handle
+@param tile The tile to encode
+@param tcp Tile coding parameters
+*/
+void t1_3d_encode_cblks(opj_t1_3d_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp);
+/**
+Decode the code-blocks of a tile
+@param t1 T1_3D handle
+@param tile The tile to decode
+@param tcp Tile coding parameters
+*/
+void t1_3d_decode_cblks(opj_t1_3d_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp);
+/**
+Get weigths of MSE decoding
+@param nmsedec The normalized MSE reduction
+@param compno
+@param level
+@param orient
+@param bpno
+@param reversible
+@param stepsize
+@param numcomps
+@param dwtid
+returns MSE associated to decoding pass
+double t1_3d_getwmsedec(int nmsedec, int compno, int levelxy, int levelz, int orient, int bpno, int reversible, double stepsize, int numcomps, int dwtid);
+*/
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+#endif /* __T1_H */
diff --git a/libopenjpeg3d/t2.c b/libopenjpeg3d/t2.c
new file mode 100755
index 00000000..6638b328
--- /dev/null
+++ b/libopenjpeg3d/t2.c
@@ -0,0 +1,675 @@
+/*
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * 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 T2 T2 - Implementation of a tier-2 coding */
+/*@{*/
+
+/** @name Local static functions */
+/*@{*/
+
+static void t2_putcommacode(opj_bio_t *bio, int n);
+static int t2_getcommacode(opj_bio_t *bio);
+/**
+Variable length code for signalling delta Zil (truncation point)
+@param bio Bit Input/Output component
+@param n delta Zil
+*/
+static void t2_putnumpasses(opj_bio_t *bio, int n);
+static int t2_getnumpasses(opj_bio_t *bio);
+/**
+Encode a packet of a tile to a destination buffer
+@param tile Tile for which to write the packets
+@param tcp Tile coding parameters
+@param pi Packet identity
+@param dest Destination buffer
+@param len Length of the destination buffer
+@param volume_info Structure to create an index file
+@param tileno Number of the tile encoded
+@param cp Coding parameters
+@return Number of bytes encoded from the packet
+*/
+static int t2_encode_packet(opj_tcd_tile_t *tile, opj_tcp_t *tcp, opj_pi_iterator_t *pi, unsigned char *dest, int len, opj_volume_info_t *volume_info, int tileno, opj_cp_t *cp);
+/**
+Initialize the segment decoder
+@param seg Segment instance
+@param cblksty Codeblock style
+@param first Is first segment
+*/
+static void t2_init_seg(opj_tcd_seg_t *seg, int cblksty, int first);
+/**
+Decode a packet of a tile from a source buffer
+@param t2 T2 handle
+@param src Source buffer
+@param len Length of the source buffer
+@param tile Tile for which to write the packets
+@param tcp Tile coding parameters
+@param pi Packet identity
+@return Number of bytes decoded from the packet
+*/
+int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile, opj_tcp_t *tcp, opj_pi_iterator_t *pi);
+
+/*@}*/
+
+/*@}*/
+
+/* ----------------------------------------------------------------------- */
+
+/* #define RESTART 0x04 */
+static void t2_putcommacode(opj_bio_t *bio, int n) {
+ while (--n >= 0) {
+ bio_write(bio, 1, 1);
+ }
+ bio_write(bio, 0, 1);
+}
+
+static int t2_getcommacode(opj_bio_t *bio) {
+ int n;
+ for (n = 0; bio_read(bio, 1); n++) {
+ ;
+ }
+ return n;
+}
+
+static void t2_putnumpasses(opj_bio_t *bio, int n) {
+ if (n == 1) {
+ bio_write(bio, 0, 1);
+ } else if (n == 2) {
+ bio_write(bio, 2, 2);
+ } else if (n <= 5) {
+ bio_write(bio, 0xc | (n - 3), 4);
+ } else if (n <= 36) {
+ bio_write(bio, 0x1e0 | (n - 6), 9);
+ } else if (n <= 164) {
+ bio_write(bio, 0xff80 | (n - 37), 16);
+ }
+}
+
+static int t2_getnumpasses(opj_bio_t *bio) {
+ int n;
+ if (!bio_read(bio, 1))
+ return 1;
+ if (!bio_read(bio, 1))
+ return 2;
+ if ((n = bio_read(bio, 2)) != 3)
+ return (3 + n);
+ if ((n = bio_read(bio, 5)) != 31)
+ return (6 + n);
+ return (37 + bio_read(bio, 7));
+}
+
+static int t2_encode_packet(opj_tcd_tile_t * tile, opj_tcp_t * tcp, opj_pi_iterator_t *pi, unsigned char *dest, int len, opj_volume_info_t * volume_info, int tileno, opj_cp_t *cp) {
+ int bandno, cblkno;
+ unsigned char *sop = 0, *eph = 0;
+ unsigned char *c = dest;
+
+ int compno = pi->compno; /* component value */
+ int resno = pi->resno; /* resolution level value */
+ int precno = pi->precno; /* precinct value */
+ int layno = pi->layno; /* quality layer value */
+
+ opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
+ opj_tcd_resolution_t *res = &tilec->resolutions[resno];
+
+ opj_bio_t *bio = NULL; /* BIO component */
+
+ /* <SOP 0xff91> */
+ if ((tcp->csty & J3D_CP_CSTY_SOP)) {
+ sop = (unsigned char *) opj_malloc(6 * sizeof(unsigned char));
+ sop[0] = 255;
+ sop[1] = 145;
+ sop[2] = 0;
+ sop[3] = 4;
+ sop[4] = (volume_info) ? (volume_info->num % 65536) / 256 : (0 % 65536) / 256 ;
+ sop[5] = (volume_info) ? (volume_info->num % 65536) % 256 : (0 % 65536) % 256 ;
+ memcpy(c, sop, 6);
+ opj_free(sop);
+ c += 6;
+ }
+ /* </SOP> */
+
+ if (!layno) {
+ for (bandno = 0; bandno < res->numbands; bandno++) {
+ opj_tcd_band_t *band = &res->bands[bandno];
+ opj_tcd_precinct_t *prc = &band->precincts[precno];
+ tgt_reset(prc->incltree);
+ tgt_reset(prc->imsbtree);
+ for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {
+ opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];
+ cblk->numpasses = 0;
+ tgt_setvalue(prc->imsbtree, cblkno, band->numbps - cblk->numbps);
+ }
+ }
+ }
+
+ bio = bio_create();
+ bio_init_enc(bio, c, len);
+ bio_write(bio, 1, 1); /* Empty header bit */
+
+ /* Writing Packet header */
+ for (bandno = 0; bandno < res->numbands; bandno++) {
+ opj_tcd_band_t *band = &res->bands[bandno];
+ opj_tcd_precinct_t *prc = &band->precincts[precno];
+ for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {
+ opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];
+ opj_tcd_layer_t *layer = &cblk->layers[layno];
+ if (!cblk->numpasses && layer->numpasses) {
+ tgt_setvalue(prc->incltree, cblkno, layno);
+ }
+ }
+
+ for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {
+ opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];
+ opj_tcd_layer_t *layer = &cblk->layers[layno];
+ int increment = 0;
+ int nump = 0;
+ int len = 0, passno;
+ /* cblk inclusion bits */
+ if (!cblk->numpasses) {
+ tgt_encode(bio, prc->incltree, cblkno, layno + 1);
+ } else {
+ bio_write(bio, layer->numpasses != 0, 1);
+ }
+ /* if cblk not included, go to the next cblk */
+ if (!layer->numpasses) {
+ continue;
+ }
+ /* if first instance of cblk --> zero bit-planes information */
+ if (!cblk->numpasses) {
+ cblk->numlenbits = 3;
+ tgt_encode(bio, prc->imsbtree, cblkno, 999);
+ }
+ /* number of coding passes included */
+ t2_putnumpasses(bio, layer->numpasses);
+
+ /* computation of the increase of the length indicator and insertion in the header */
+ for (passno = cblk->numpasses; passno < cblk->numpasses + layer->numpasses; passno++) {
+ opj_tcd_pass_t *pass = &cblk->passes[passno];
+ nump++;
+ len += pass->len;
+ if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) {
+ increment = int_max(increment, int_floorlog2(len) + 1 - (cblk->numlenbits + int_floorlog2(nump)));
+ len = 0;
+ nump = 0;
+ }
+ }
+ t2_putcommacode(bio, increment);
+
+ /* computation of the new Length indicator */
+ cblk->numlenbits += increment;
+
+ /* insertion of the codeword segment length */
+ for (passno = cblk->numpasses; passno < cblk->numpasses + layer->numpasses; passno++) {
+ opj_tcd_pass_t *pass = &cblk->passes[passno];
+ nump++;
+ len += pass->len;
+ if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) {
+ bio_write(bio, len, cblk->numlenbits + int_floorlog2(nump));
+ len = 0;
+ nump = 0;
+ }
+ }
+
+ }
+ }
+
+
+ if (bio_flush(bio)) {
+ return -999; /* modified to eliminate longjmp !! */
+ }
+
+ c += bio_numbytes(bio);
+
+ bio_destroy(bio);
+
+ /* <EPH 0xff92> */
+ if (tcp->csty & J3D_CP_CSTY_EPH) {
+ eph = (unsigned char *) opj_malloc(2 * sizeof(unsigned char));
+ eph[0] = 255;
+ eph[1] = 146;
+ memcpy(c, eph, 2);
+ opj_free(eph);
+ c += 2;
+ }
+ /* </EPH> */
+
+ /* Writing the packet body */
+
+ for (bandno = 0; bandno < res->numbands; bandno++) {
+ opj_tcd_band_t *band = &res->bands[bandno];
+ opj_tcd_precinct_t *prc = &band->precincts[precno];
+ for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {
+ opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];
+ opj_tcd_layer_t *layer = &cblk->layers[layno];
+ if (!layer->numpasses) {
+ continue;
+ }
+ if (c + layer->len > dest + len) {
+ return -999;
+ }
+
+ memcpy(c, layer->data, layer->len);
+ cblk->numpasses += layer->numpasses;
+ c += layer->len;
+ /* ADD for index Cfr. Marcela --> delta disto by packet */
+ if(volume_info && volume_info->index_write && volume_info->index_on) {
+ opj_tile_info_t *info_TL = &volume_info->tile[tileno];
+ opj_packet_info_t *info_PK = &info_TL->packet[volume_info->num];
+ info_PK->disto += layer->disto;
+ if (volume_info->D_max < info_PK->disto) {
+ volume_info->D_max = info_PK->disto;
+ }
+ }
+ /* </ADD> */
+ }
+ }
+
+ return (c - dest);
+}
+
+static void t2_init_seg(opj_tcd_seg_t * seg, int cblksty, int first) {
+ seg->numpasses = 0;
+ seg->len = 0;
+ if (cblksty & J3D_CCP_CBLKSTY_TERMALL) {
+ seg->maxpasses = 1;
+ }
+ else if (cblksty & J3D_CCP_CBLKSTY_LAZY) {
+ if (first) {
+ seg->maxpasses = 10;
+ } else {
+ seg->maxpasses = (((seg - 1)->maxpasses == 1) || ((seg - 1)->maxpasses == 10)) ? 2 : 1;
+ }
+ } else {
+ seg->maxpasses = 109;
+ }
+}
+
+int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile, opj_tcp_t *tcp, opj_pi_iterator_t *pi) {
+ int bandno, cblkno;
+ unsigned char *c = src;
+
+ opj_cp_t *cp = t2->cp;
+
+ int compno = pi->compno; /* component value */
+ int resno = pi->resno; /* resolution level value */
+ int precno = pi->precno; /* precinct value */
+ int layno = pi->layno; /* quality layer value */
+
+ opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
+ opj_tcd_resolution_t *res = &tilec->resolutions[resno];
+
+ unsigned char *hd = NULL;
+ int present;
+
+ opj_bio_t *bio = NULL; /* BIO component */
+
+ if (layno == 0) {
+ for (bandno = 0; bandno < res->numbands; bandno++) {
+ opj_tcd_band_t *band = &res->bands[bandno];
+ opj_tcd_precinct_t *prc = &band->precincts[precno];
+
+ if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)||(band->z1-band->z0 == 0)) continue;
+
+ tgt_reset(prc->incltree);
+ tgt_reset(prc->imsbtree);
+ for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {
+ opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];
+ cblk->numsegs = 0;
+ }
+ }
+ }
+
+ /* SOP markers */
+
+ if (tcp->csty & J3D_CP_CSTY_SOP) {
+ if ((*c) != 0xff || (*(c + 1) != 0x91)) {
+ opj_event_msg(t2->cinfo, EVT_WARNING, "Expected SOP marker\n");
+ } else {
+ c += 6;
+ }
+
+ /** TODO : check the Nsop value */
+ }
+
+ /*
+ When the marker PPT/PPM is used the packet header are store in PPT/PPM marker
+ This part deal with this caracteristic
+ step 1: Read packet header in the saved structure
+ step 2: Return to codestream for decoding
+ */
+
+ bio = bio_create();
+
+ if (cp->ppm == 1) { /* PPM */
+ hd = cp->ppm_data;
+ bio_init_dec(bio, hd, cp->ppm_len);
+ } else if (tcp->ppt == 1) { /* PPT */
+ hd = tcp->ppt_data;
+ bio_init_dec(bio, hd, tcp->ppt_len);
+ } else { /* Normal Case */
+ hd = c;
+ bio_init_dec(bio, hd, src+len-hd);
+ }
+
+ present = bio_read(bio, 1);
+
+ if (!present) {
+ bio_inalign(bio);
+ hd += bio_numbytes(bio);
+ bio_destroy(bio);
+
+ /* EPH markers */
+
+ if (tcp->csty & J3D_CP_CSTY_EPH) {
+ if ((*hd) != 0xff || (*(hd + 1) != 0x92)) {
+ printf("Error : expected EPH marker\n");
+ } else {
+ hd += 2;
+ }
+ }
+
+ if (cp->ppm == 1) { /* PPM case */
+ cp->ppm_len += cp->ppm_data-hd;
+ cp->ppm_data = hd;
+ return (c - src);
+ }
+ if (tcp->ppt == 1) { /* PPT case */
+ tcp->ppt_len+=tcp->ppt_data-hd;
+ tcp->ppt_data = hd;
+ return (c - src);
+ }
+
+ return (hd - src);
+ }
+
+ for (bandno = 0; bandno < res->numbands; bandno++) {
+ opj_tcd_band_t *band = &res->bands[bandno];
+ opj_tcd_precinct_t *prc = &band->precincts[precno];
+
+ if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)||(band->z1-band->z0 == 0)) continue;
+
+ for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {
+ int included, increment, n;
+ opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];
+ opj_tcd_seg_t *seg = NULL;
+ /* if cblk not yet included before --> inclusion tagtree */
+ if (!cblk->numsegs) {
+ included = tgt_decode(bio, prc->incltree, cblkno, layno + 1);
+ /* else one bit */
+ } else {
+ included = bio_read(bio, 1);
+ }
+ /* if cblk not included */
+ if (!included) {
+ cblk->numnewpasses = 0;
+ continue;
+ }
+ /* if cblk not yet included --> zero-bitplane tagtree */
+ if (!cblk->numsegs) {
+ int i, numimsbs;
+ for (i = 0; !tgt_decode(bio, prc->imsbtree, cblkno, i); i++);
+ numimsbs = i - 1;
+ cblk->numbps = band->numbps - numimsbs;
+ cblk->numlenbits = 3;
+ }
+ /* number of coding passes */
+ cblk->numnewpasses = t2_getnumpasses(bio);
+ increment = t2_getcommacode(bio);
+ /* length indicator increment */
+ cblk->numlenbits += increment;
+ if (!cblk->numsegs) {
+ seg = &cblk->segs[0];
+ t2_init_seg(seg, tcp->tccps[compno].cblksty, 1);
+ } else {
+ seg = &cblk->segs[cblk->numsegs - 1];
+ if (seg->numpasses == seg->maxpasses) {
+ t2_init_seg(++seg, tcp->tccps[compno].cblksty, 0);
+ }
+ }
+ n = cblk->numnewpasses;
+
+ do {
+ seg->numnewpasses = int_min(seg->maxpasses - seg->numpasses, n);
+ seg->newlen = bio_read(bio, cblk->numlenbits + int_floorlog2(seg->numnewpasses));
+ n -= seg->numnewpasses;
+ if (n > 0) {
+ t2_init_seg(++seg, tcp->tccps[compno].cblksty, 0);
+ }
+ } while (n > 0);
+ }
+ }
+
+ if (bio_inalign(bio)) {
+ bio_destroy(bio);
+ return -999;
+ }
+
+ hd += bio_numbytes(bio);
+ bio_destroy(bio);
+
+ /* EPH markers */
+ if (tcp->csty & J3D_CP_CSTY_EPH) {
+ if ((*hd) != 0xff || (*(hd + 1) != 0x92)) {
+ opj_event_msg(t2->cinfo, EVT_ERROR, "Expected EPH marker\n");
+ } else {
+ hd += 2;
+ }
+ }
+
+ if (cp->ppm==1) {
+ cp->ppm_len+=cp->ppm_data-hd;
+ cp->ppm_data = hd;
+ } else if (tcp->ppt == 1) {
+ tcp->ppt_len+=tcp->ppt_data-hd;
+ tcp->ppt_data = hd;
+ } else {
+ c=hd;
+ }
+
+ for (bandno = 0; bandno < res->numbands; bandno++) {
+ opj_tcd_band_t *band = &res->bands[bandno];
+ opj_tcd_precinct_t *prc = &band->precincts[precno];
+
+ if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)||(band->z1-band->z0 == 0)) continue;
+
+ for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {
+ opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];
+ opj_tcd_seg_t *seg = NULL;
+ if (!cblk->numnewpasses)
+ continue;
+ if (!cblk->numsegs) {
+ seg = &cblk->segs[0];
+ cblk->numsegs++;
+ cblk->len = 0;
+ } else {
+ seg = &cblk->segs[cblk->numsegs - 1];
+ if (seg->numpasses == seg->maxpasses) {
+ seg++;
+ cblk->numsegs++;
+ }
+ }
+
+ do {
+ if (c + seg->newlen > src + len) {
+ return -999;
+ }
+
+ memcpy(cblk->data + cblk->len, c, seg->newlen);
+ if (seg->numpasses == 0) {
+ seg->data = cblk->data + cblk->len;
+ }
+ c += seg->newlen;
+ cblk->len += seg->newlen;
+ seg->len += seg->newlen;
+ seg->numpasses += seg->numnewpasses;
+ cblk->numnewpasses -= seg->numnewpasses;
+ if (cblk->numnewpasses > 0) {
+ seg++;
+ cblk->numsegs++;
+ }
+ } while (cblk->numnewpasses > 0);
+ }
+ }
+
+ return (c - src);
+}
+
+/* ----------------------------------------------------------------------- */
+
+int t2_encode_packets(opj_t2_t* t2, int tileno, opj_tcd_tile_t *tile, int maxlayers, unsigned char *dest, int len, opj_volume_info_t *volume_info) {
+ unsigned char *c = dest;
+ int e = 0;
+ opj_pi_iterator_t *pi = NULL;
+ int pino;
+
+ opj_volume_t *volume = t2->volume;
+ opj_cp_t *cp = t2->cp;
+
+ /* create a packet iterator */
+ pi = pi_create(volume, cp, tileno);
+ if(!pi) {
+ fprintf(stdout,"[ERROR] Failed to create a pi structure\n");
+ return -999;
+ }
+
+ if(volume_info) {
+ volume_info->num = 0;
+ }
+
+ for (pino = 0; pino <= cp->tcps[tileno].numpocs; pino++) {
+ while (pi_next(&pi[pino])) {
+ if (pi[pino].layno < maxlayers) {
+ e = t2_encode_packet(tile, &cp->tcps[tileno], &pi[pino], c, dest + len - c, volume_info, tileno, cp);
+ //opj_event_msg(t2->cinfo, EVT_INFO, " t2_encode_packet: %d bytes coded\n",e);
+ if (e == -999) {
+ break;
+ } else {
+ c += e;
+ }
+
+ /* INDEX >> */
+ if(volume_info && volume_info->index_on) {
+ if(volume_info->index_write) {
+ opj_tile_info_t *info_TL = &volume_info->tile[tileno];
+ opj_packet_info_t *info_PK = &info_TL->packet[volume_info->num];
+ if (!volume_info->num) {
+ info_PK->start_pos = info_TL->end_header + 1;
+ } else {
+ info_PK->start_pos = info_TL->packet[volume_info->num - 1].end_pos + 1;
+ }
+ info_PK->end_pos = info_PK->start_pos + e - 1;
+ }
+
+ volume_info->num++;
+ }
+ /* << INDEX */
+ }
+ }
+ }
+
+ /* don't forget to release pi */
+ pi_destroy(pi, cp, tileno);
+
+ if (e == -999) {
+ return e;
+ }
+
+ return (c - dest);
+}
+
+int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj_tcd_tile_t *tile) {
+ unsigned char *c = src;
+ opj_pi_iterator_t *pi;
+ int pino, e = 0;
+ int n = 0,i;
+
+ opj_volume_t *volume = t2->volume;
+ opj_cp_t *cp = t2->cp;
+
+ /* create a packet iterator */
+ pi = pi_create(volume, cp, tileno);
+ if(!pi) {
+ /* TODO: throw an error */
+ return -999;
+ }
+
+ for (pino = 0; pino <= cp->tcps[tileno].numpocs; pino++) {
+ while (pi_next(&pi[pino])) {
+ if ((cp->layer==0) || (cp->layer>=((pi[pino].layno)+1))) {
+ e = t2_decode_packet(t2, c, src + len - c, tile, &cp->tcps[tileno], &pi[pino]);
+ } else {
+ e = 0;
+ }
+
+ /* progression in resolution */
+ for (i = 0; i < 3; i++){
+ volume->comps[pi[pino].compno].resno_decoded[i] = (e > 0) ? int_max(pi[pino].resno, volume->comps[pi[pino].compno].resno_decoded[i]) : volume->comps[pi[pino].compno].resno_decoded[i];
+ }
+ n++;
+
+ if (e == -999) { /* ADD */
+ break;
+ } else {
+ opj_event_msg(t2->cinfo, EVT_INFO, " t2_decode_packet: %d bytes decoded\n",e);
+ c += e;
+ }
+ }
+ }
+
+ /* don't forget to release pi */
+ pi_destroy(pi, cp, tileno);
+
+ if (e == -999) {
+ return e;
+ }
+
+ return (c - src);
+}
+
+/* ----------------------------------------------------------------------- */
+
+opj_t2_t* t2_create(opj_common_ptr cinfo, opj_volume_t *volume, opj_cp_t *cp) {
+ /* create the tcd structure */
+ opj_t2_t *t2 = (opj_t2_t*)opj_malloc(sizeof(opj_t2_t));
+ if(!t2) return NULL;
+ t2->cinfo = cinfo;
+ t2->volume = volume;
+ t2->cp = cp;
+
+ return t2;
+}
+
+void t2_destroy(opj_t2_t *t2) {
+ if(t2) {
+ opj_free(t2);
+ }
+}
+
diff --git a/libopenjpeg3d/t2.h b/libopenjpeg3d/t2.h
new file mode 100755
index 00000000..b937290b
--- /dev/null
+++ b/libopenjpeg3d/t2.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * Copyright (c) 2006, Mónica Díez García, Image Processing Laboratory, University of Valladolid, Spain
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef __T2_H
+#define __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 {
+/** Codec context */
+ opj_common_ptr cinfo;
+/** Encoding: pointer to the src volume. Decoding: pointer to the dst volume. */
+ opj_volume_t *volume;
+/** Pointer to the volume coding parameters */
+ opj_cp_t *cp;
+} opj_t2_t;
+
+/** @name Funciones generales */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+
+/**
+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 len the length of the destination buffer
+@param volume_info structure to create an index file
+@return Number of bytes written from packets
+*/
+int t2_encode_packets(opj_t2_t* t2, int tileno, opj_tcd_tile_t *tile, int maxlayers, unsigned char *dest, int len, opj_volume_info_t *volume_info);
+
+/**
+Decode the packets of a tile from a source buffer
+@param t2 T2 handle
+@param src the source buffer
+@param len length of the source buffer
+@param tileno number that identifies the tile for which to decode the packets
+@param tile tile for which to decode the packets
+@return Number of bytes read from packets
+ */
+int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj_tcd_tile_t *tile);
+
+/**
+Create a T2 handle
+@param cinfo Codec context info
+@param volume Source or destination volume
+@param cp Volume coding parameters
+@return Returns a new T2 handle if successful, returns NULL otherwise
+*/
+opj_t2_t* t2_create(opj_common_ptr cinfo, opj_volume_t *volume, opj_cp_t *cp);
+/**
+Destroy a T2 handle
+@param t2 T2 handle to destroy
+*/
+void t2_destroy(opj_t2_t *t2);
+
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+#endif /* __T2_H */
diff --git a/libopenjpeg3d/tcd.c b/libopenjpeg3d/tcd.c
new file mode 100755
index 00000000..e5147e29
--- /dev/null
+++ b/libopenjpeg3d/tcd.c
@@ -0,0 +1,1738 @@
+/*
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * Copyright (c) 2006, Mónica Díez, LPI-UVA, Spain
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opj_includes.h"
+
+void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_volume_t * vol) {
+ int tileno, compno, resno, bandno, precno, cblkno;
+
+ fprintf(fd, "volume {\n");
+ fprintf(fd, " tw=%d, th=%d, tl=%d, x0=%d x1=%d y0=%d y1=%d z0=%d z1=%d\n",
+ vol->tw, vol->th, vol->tl, tcd->volume->x0, tcd->volume->x1, tcd->volume->y0, tcd->volume->y1, tcd->volume->z0, tcd->volume->z1);
+
+ for (tileno = 0; tileno < vol->th * vol->tw * vol->tl; tileno++) {
+ opj_tcd_tile_t *tile = &tcd->tcd_volume->tiles[tileno];
+ fprintf(fd, " tile {\n");
+ fprintf(fd, " x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d, numcomps=%d\n",
+ tile->x0, tile->y0, tile->z0, tile->x1, tile->y1, tile->z1, tile->numcomps);
+ for (compno = 0; compno < tile->numcomps; compno++) {
+ opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
+ fprintf(fd, " tilecomp %d {\n",compno);
+ fprintf(fd, " x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d, numresx=%d, numresy=%d, numresz=%d\n",
+ tilec->x0, tilec->y0, tilec->z0, tilec->x1, tilec->y1, tilec->z1, tilec->numresolution[0], tilec->numresolution[1], tilec->numresolution[2]);
+ for (resno = 0; resno < tilec->numresolution[0]; resno++) {
+ opj_tcd_resolution_t *res = &tilec->resolutions[resno];
+ fprintf(fd, " res %d{\n",resno);
+ fprintf(fd," x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d, pw=%d, ph=%d, pl=%d, numbands=%d\n",
+ res->x0, res->y0, res->z0, res->x1, res->y1, res->z1, res->prctno[0], res->prctno[1], res->prctno[2], res->numbands);
+ for (bandno = 0; bandno < res->numbands; bandno++) {
+ opj_tcd_band_t *band = &res->bands[bandno];
+ fprintf(fd, " band %d{\n", bandno);
+ fprintf(fd, " x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d, stepsize=%f, numbps=%d\n",
+ band->x0, band->y0, band->z0, band->x1, band->y1, band->z1, band->stepsize, band->numbps);
+ for (precno = 0; precno < (res->prctno[0] * res->prctno[1] * res->prctno[2]); precno++) {
+ opj_tcd_precinct_t *prec = &band->precincts[precno];
+ fprintf(fd, " prec %d{\n",precno);
+ fprintf(fd, " x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d, cw=%d, ch=%d, cl=%d,\n",
+ prec->x0, prec->y0, prec->z0, prec->x1, prec->y1, prec->z1, prec->cblkno[0], prec->cblkno[1], prec->cblkno[2]);
+ for (cblkno = 0; cblkno < (prec->cblkno[0] * prec->cblkno[1] * prec->cblkno[2]); cblkno++) {
+ opj_tcd_cblk_t *cblk = &prec->cblks[cblkno];
+ fprintf(fd, " cblk %d{\n",cblkno);
+ fprintf(fd, " x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d\n", cblk->x0, cblk->y0, cblk->z0, cblk->x1, cblk->y1, cblk->z1);
+ fprintf(fd, " }\n");
+ }
+ fprintf(fd, " }\n");
+ }
+ fprintf(fd, " }\n");
+ }
+ fprintf(fd, " }\n");
+ }
+ fprintf(fd, " }\n");
+ }
+ fprintf(fd, " }\n");
+ }
+ fprintf(fd, "}\n");
+}
+
+void tilec_dump(FILE *fd, opj_tcd_tilecomp_t *tilec) {
+
+ int i=0,k;
+ int datalen;
+ int *a;
+
+ fprintf(fd, " tilecomp{\n");
+ fprintf(fd, " x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d, numresx=%d, numresy=%d, numresz=%d\n",
+ tilec->x0, tilec->y0, tilec->z0, tilec->x1, tilec->y1, tilec->z1, tilec->numresolution[0], tilec->numresolution[1], tilec->numresolution[2]);
+ fprintf(fd, " data {\n");
+ datalen = (tilec->z1 - tilec->z0) * (tilec->y1 - tilec->y0) * (tilec->x1 - tilec->x0);
+ a = tilec->data;
+ for (k = 0; k < datalen; k++) {
+ if (!(k % tilec->x1)){
+ fprintf(fd, "\n");
+ }
+ if (!(k % (tilec->y1 * tilec->x1))){
+ fprintf(fd, "Slice %d\n",i++);
+ }
+ fprintf(fd," %d",a[k]);
+
+
+ }
+ fprintf(fd, " }\n");
+ /*i=0;
+ fprintf(fd, "Slice %d\n");
+ if (tilec->prediction->prederr) {
+ fprintf(fd, " prederror {\n");
+ a = tilec->prediction->prederr;
+ for (k = 0; k < datalen; k++) {
+ fprintf(fd," %d",*(a++));
+ if (!(k % (tilec->y1 - tilec->y0) * (tilec->x1 - tilec->x0))){
+ fprintf(fd, "\n");fprintf(fd, "Slice %d\n",i++);
+ }
+ if (!(k % (tilec->x1 - tilec->x0))){
+ fprintf(fd, "\n");
+ }
+ }
+ }
+ fprintf(fd, " }\n");*/
+ fprintf(fd, "}\n");
+}
+
+/* ----------------------------------------------------------------------- */
+
+/**
+Create a new TCD handle
+*/
+opj_tcd_t* tcd_create(opj_common_ptr cinfo) {
+ /* create the tcd structure */
+ opj_tcd_t *tcd = (opj_tcd_t*)opj_malloc(sizeof(opj_tcd_t));
+ if(!tcd) return NULL;
+ tcd->cinfo = cinfo;
+ tcd->tcd_volume = (opj_tcd_volume_t*)opj_malloc(sizeof(opj_tcd_volume_t));
+ if(!tcd->tcd_volume) {
+ opj_free(tcd);
+ return NULL;
+ }
+
+ return tcd;
+}
+
+/**
+Destroy a previously created TCD handle
+*/
+void tcd_destroy(opj_tcd_t *tcd) {
+ if(tcd) {
+ opj_free(tcd->tcd_volume);
+ opj_free(tcd);
+ }
+}
+
+/* ----------------------------------------------------------------------- */
+void tcd_malloc_encode(opj_tcd_t *tcd, opj_volume_t * volume, opj_cp_t * cp, int curtileno) {
+ int compno, resno, bandno, precno, cblkno, i, j;//, k;
+
+ opj_tcd_tile_t *tile = NULL; /* pointer to tcd->tile */
+ opj_tcd_tilecomp_t *tilec = NULL; /* pointer to tcd->tilec */
+ opj_tcd_resolution_t *res = NULL; /* pointer to tcd->res */
+ opj_tcd_band_t *band = NULL; /* pointer to tcd->band */
+ opj_tcd_precinct_t *prc = NULL; /* pointer to tcd->prc */
+ opj_tcd_cblk_t *cblk = NULL; /* pointer to tcd->cblk */
+ opj_tcp_t *tcp = &cp->tcps[curtileno];
+ int p,q,r;
+
+ tcd->volume = volume;
+ tcd->cp = cp;
+ tcd->tcd_volume->tw = cp->tw;
+ tcd->tcd_volume->th = cp->th;
+ tcd->tcd_volume->tl = cp->tl;
+ tcd->tcd_volume->tiles = (opj_tcd_tile_t *) opj_malloc(sizeof(opj_tcd_tile_t));
+ tcd->tile = tcd->tcd_volume->tiles;
+ tile = tcd->tile;
+
+
+ /* p61 ISO/IEC IS15444-1 : 2002 */
+ /* curtileno --> raster scanned index of tiles */
+ /* p,q,r --> matricial index of tiles */
+ p = curtileno % cp->tw;
+ q = curtileno / cp->tw;
+ r = curtileno / (cp->tw * cp->th); /* extension to 3-D */
+
+ /* 4 borders of the tile rescale on the volume if necessary (B.3)*/
+ tile->x0 = int_max(cp->tx0 + p * cp->tdx, volume->x0);
+ tile->y0 = int_max(cp->ty0 + q * cp->tdy, volume->y0);
+ tile->z0 = int_max(cp->tz0 + r * cp->tdz, volume->z0);
+ tile->x1 = int_min(cp->tx0 + (p + 1) * cp->tdx, volume->x1);
+ tile->y1 = int_min(cp->ty0 + (q + 1) * cp->tdy, volume->y1);
+ tile->z1 = int_min(cp->tz0 + (r + 1) * cp->tdz, volume->z1);
+ tile->numcomps = volume->numcomps;
+
+ /* Modification of the RATE >> */
+ for (j = 0; j < tcp->numlayers; j++) {
+ if (tcp->rates[j] <= 1) {
+ tcp->rates[j] = 0;
+ } else {
+ float num = (float) (tile->numcomps * (tile->x1 - tile->x0) * (tile->y1 - tile->y0) * (tile->z1 - tile->z0) * volume->comps[0].prec);
+ float den = (float) (8 * volume->comps[0].dx * volume->comps[0].dy * volume->comps[0].dz);
+ den = tcp->rates[j] * den;
+ tcp->rates[j] = (num + den - 1) / den;
+ }
+ /*tcp->rates[j] = tcp->rates[j] ? int_ceildiv(
+ tile->numcomps * (tile->x1 - tile->x0) * (tile->y1 - tile->y0) * (tile->z1 - tile->z0) * volume->comps[0].prec,
+ (tcp->rates[j] * 8 * volume->comps[0].dx * volume->comps[0].dy * volume->comps[0].dz)) : 0;*/
+ if (tcp->rates[j]) {
+ if (j && tcp->rates[j] < tcp->rates[j - 1] + 10) {
+ tcp->rates[j] = tcp->rates[j - 1] + 20;
+ } else if (!j && tcp->rates[j] < 30){
+ tcp->rates[j] = 30;
+ }
+ }
+ }
+ /* << Modification of the RATE */
+
+ tile->comps = (opj_tcd_tilecomp_t *) opj_malloc(volume->numcomps * sizeof(opj_tcd_tilecomp_t));
+ for (compno = 0; compno < tile->numcomps; compno++) {
+ opj_tccp_t *tccp = &tcp->tccps[compno];
+ int res_max;
+ int prevnumbands = 0;
+
+ /* opj_tcd_tilecomp_t *tilec=&tile->comps[compno]; */
+ tcd->tilec = &tile->comps[compno];
+ tilec = tcd->tilec;
+
+ /* border of each tile component (global) (B.3) */
+ tilec->x0 = int_ceildiv(tile->x0, volume->comps[compno].dx);
+ tilec->y0 = int_ceildiv(tile->y0, volume->comps[compno].dy);
+ tilec->z0 = int_ceildiv(tile->z0, volume->comps[compno].dz);
+ tilec->x1 = int_ceildiv(tile->x1, volume->comps[compno].dx);
+ tilec->y1 = int_ceildiv(tile->y1, volume->comps[compno].dy);
+ tilec->z1 = int_ceildiv(tile->z1, volume->comps[compno].dz);
+
+ tilec->data = (int *) opj_malloc((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0) * (tilec->z1 - tilec->z0) * sizeof(int));
+
+ res_max = 0;
+ for (i = 0;i < 3; i++){
+ tilec->numresolution[i] = tccp->numresolution[i];
+ //Greater of 3 resolutions contains all information
+ res_max = (tilec->numresolution[i] > res_max) ? tilec->numresolution[i] : res_max;
+ }
+
+
+ tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(res_max * sizeof(opj_tcd_resolution_t));
+ for (resno = 0; resno < res_max; resno++) {
+
+ int pdx, pdy, pdz;
+ int tlprcxstart, tlprcystart, tlprczstart;
+ int brprcxend, brprcyend, brprczend;
+ int tlcbgxstart, tlcbgystart, tlcbgzstart;
+ int brcbgxend, brcbgyend, brcbgzend;
+ int cbgwidthexpn, cbgheightexpn, cbglengthexpn;
+ int cblkwidthexpn, cblkheightexpn, cblklengthexpn;
+
+ int diff = tccp->numresolution[0] - tccp->numresolution[2];
+ int levelnox = tilec->numresolution[0] - 1 - resno;
+ int levelnoy = tilec->numresolution[1] - 1 - resno;
+ int levelnoz = tilec->numresolution[2] - 1 - ((resno <= diff) ? 0 : (resno - diff));
+ if (levelnoz < 0) levelnoz = 0;
+
+ /* opj_tcd_resolution_t *res=&tilec->resolutions[resno]; */
+ tcd->res = &tilec->resolutions[resno];
+ res = tcd->res;
+
+ /* border for each resolution level (global) (B.14)*/
+ res->x0 = int_ceildivpow2(tilec->x0, levelnox);
+ res->y0 = int_ceildivpow2(tilec->y0, levelnoy);
+ res->z0 = int_ceildivpow2(tilec->z0, levelnoz);
+ res->x1 = int_ceildivpow2(tilec->x1, levelnox);
+ res->y1 = int_ceildivpow2(tilec->y1, levelnoy);
+ res->z1 = int_ceildivpow2(tilec->z1, levelnoz);
+ //if (res->z1 < 0)fprintf(stdout,"Res: %d %d/%d --> %d\n",resno,tilec->z1, levelnoz, int_ceildivpow2(tilec->z1, levelnoz));
+
+ res->numbands = (resno == 0) ? 1 : (resno <= diff) ? 3 : 7; /* --> 3D */
+
+ /* p. 30, table A-13, ISO/IEC IS154444-1 : 2002 */
+ if (tccp->csty & J3D_CCP_CSTY_PRT) {
+ pdx = tccp->prctsiz[0][resno];
+ pdy = tccp->prctsiz[1][resno];
+ pdz = tccp->prctsiz[2][resno];
+ } else {
+ pdx = 15;
+ pdy = 15;
+ pdz = 15;
+ }
+
+ /* p. 66, B.16, ISO/IEC IS15444-1 : 2002 */
+ tlprcxstart = int_floordivpow2(res->x0, pdx) << pdx;
+ tlprcystart = int_floordivpow2(res->y0, pdy) << pdy;
+ tlprczstart = int_floordivpow2(res->z0, pdz) << pdz;
+ brprcxend = int_ceildivpow2(res->x1, pdx) << pdx;
+ brprcyend = int_ceildivpow2(res->y1, pdy) << pdy;
+ brprczend = int_ceildivpow2(res->z1, pdz) << pdz;
+
+ res->prctno[0] = (brprcxend - tlprcxstart) >> pdx;
+ res->prctno[1] = (brprcyend - tlprcystart) >> pdy;
+ res->prctno[2] = (brprczend - tlprczstart) >> pdz;
+ if (res->prctno[2] == 0) res->prctno[2] = 1;
+
+ /* p. 67, B.17 & B.18, ISO/IEC IS15444-1 : 2002 */
+ if (resno == 0) {
+ tlcbgxstart = tlprcxstart;
+ tlcbgystart = tlprcystart;
+ tlcbgzstart = tlprczstart;
+ brcbgxend = brprcxend;
+ brcbgyend = brprcyend;
+ brcbgzend = brprczend;
+ cbgwidthexpn = pdx;
+ cbgheightexpn = pdy;
+ cbglengthexpn = pdz;
+ } else {
+ tlcbgxstart = int_ceildivpow2(tlprcxstart, 1);
+ tlcbgystart = int_ceildivpow2(tlprcystart, 1);
+ tlcbgzstart = int_ceildivpow2(tlprczstart, 1);
+ brcbgxend = int_ceildivpow2(brprcxend, 1);
+ brcbgyend = int_ceildivpow2(brprcyend, 1);
+ brcbgzend = int_ceildivpow2(brprczend, 1);
+ cbgwidthexpn = pdx - 1;
+ cbgheightexpn = pdy - 1;
+ cbglengthexpn = pdz - 1;
+ }
+
+ cblkwidthexpn = int_min(tccp->cblk[0], cbgwidthexpn); //6
+ cblkheightexpn = int_min(tccp->cblk[1], cbgheightexpn); //6
+ cblklengthexpn = int_min(tccp->cblk[2], cbglengthexpn); //6
+
+ res->bands = (opj_tcd_band_t *) opj_malloc(res->numbands * sizeof(opj_tcd_band_t));
+ for (bandno = 0; bandno < res->numbands; bandno++) {
+ int x0b, y0b, z0b, i;
+ int gain, numbps;
+ opj_stepsize_t *ss = NULL;
+
+ tcd->band = &res->bands[bandno];
+ band = tcd->band;
+
+ band->bandno = (resno == 0) ? 0 : bandno + 1;
+ /* Bandno: 0 - LLL 2 - LHL
+ 1 - HLL 3 - HHL
+ 4 - LLH 6 - LHH
+ 5 - HLH 7 - HHH */
+ x0b = (band->bandno == 1) || (band->bandno == 3) || (band->bandno == 5 ) || (band->bandno == 7 ) ? 1 : 0;
+ y0b = (band->bandno == 2) || (band->bandno == 3) || (band->bandno == 6 ) || (band->bandno == 7 ) ? 1 : 0;
+ z0b = (band->bandno == 4) || (band->bandno == 5) || (band->bandno == 6 ) || (band->bandno == 7 ) ? 1 : 0;
+
+ /* p. 65, B.15, ISO/IEC IS15444-1 : 2002 */
+ if (band->bandno == 0) {
+ /* band border (global) */
+ band->x0 = int_ceildivpow2(tilec->x0, levelnox);
+ band->y0 = int_ceildivpow2(tilec->y0, levelnoy);
+ band->z0 = int_ceildivpow2(tilec->z0, levelnoz);
+ band->x1 = int_ceildivpow2(tilec->x1, levelnox);
+ band->y1 = int_ceildivpow2(tilec->y1, levelnoy);
+ band->z1 = int_ceildivpow2(tilec->z1, levelnoz);
+ } else {
+ band->x0 = int_ceildivpow2(tilec->x0 - (1 << levelnox) * x0b, levelnox + 1);
+ band->y0 = int_ceildivpow2(tilec->y0 - (1 << levelnoy) * y0b, levelnoy + 1);
+ band->z0 = int_ceildivpow2(tilec->z0 - (1 << levelnoz) * z0b, (resno <= diff) ? levelnoz : levelnoz + 1);
+ band->x1 = int_ceildivpow2(tilec->x1 - (1 << levelnox) * x0b, levelnox + 1);
+ band->y1 = int_ceildivpow2(tilec->y1 - (1 << levelnoy) * y0b, levelnoy + 1);
+ band->z1 = int_ceildivpow2(tilec->z1 - (1 << levelnoz) * z0b, (resno <= diff) ? levelnoz : levelnoz + 1);
+ }
+
+ ss = &tccp->stepsizes[(resno == 0) ? 0 : (prevnumbands + bandno + 1)];
+ if (bandno == (res->numbands - 1))
+ prevnumbands += (resno == 0) ? 0 : res->numbands;
+ gain = dwt_getgain(band->bandno,tccp->reversible);
+ numbps = volume->comps[compno].prec + gain;
+ band->stepsize = (float)((1.0 + ss->mant / 2048.0) * pow(2.0, numbps - ss->expn));
+ band->numbps = ss->expn + tccp->numgbits - 1; /* WHY -1 ? */
+
+ band->precincts = (opj_tcd_precinct_t *) opj_malloc((res->prctno[0] * res->prctno[1] * res->prctno[2]) * sizeof(opj_tcd_precinct_t));
+
+ for (i = 0; i < (res->prctno[0] * res->prctno[1] * res->prctno[2]); i++) {
+ band->precincts[i].imsbtree = NULL;
+ band->precincts[i].incltree = NULL;
+ }
+
+ for (precno = 0; precno < (res->prctno[0] * res->prctno[1] * res->prctno[2]); precno++) {
+ int tlcblkxstart, tlcblkystart, tlcblkzstart, brcblkxend, brcblkyend, brcblkzend;
+ int cbgxstart, cbgystart, cbgzstart, cbgxend, cbgyend, cbgzend;
+
+ cbgxstart = tlcbgxstart + (precno % res->prctno[0]) * (1 << cbgwidthexpn);
+ cbgystart = tlcbgystart + ((precno % (res->prctno[0] * res->prctno[1])) / res->prctno[0]) * (1 << cbgheightexpn);
+ cbgzstart = tlcbgzstart + (precno / (res->prctno[0] * res->prctno[1])) * (1 << cbglengthexpn);
+ cbgxend = cbgxstart + (1 << cbgwidthexpn);
+ cbgyend = cbgystart + (1 << cbgheightexpn);
+ cbgzend = cbgzstart + (1 << cbglengthexpn);
+
+ tcd->prc = &band->precincts[precno];
+ prc = tcd->prc;
+
+ /* precinct size (global) */
+ prc->x0 = int_max(cbgxstart, band->x0);
+ prc->y0 = int_max(cbgystart, band->y0);
+ prc->z0 = int_max(cbgzstart, band->z0);
+ prc->x1 = int_min(cbgxend, band->x1);
+ prc->y1 = int_min(cbgyend, band->y1);
+ prc->z1 = int_min(cbgzend, band->z1);
+
+ tlcblkxstart = int_floordivpow2(prc->x0, cblkwidthexpn) << cblkwidthexpn;
+ tlcblkystart = int_floordivpow2(prc->y0, cblkheightexpn) << cblkheightexpn;
+ tlcblkzstart = int_floordivpow2(prc->z0, cblklengthexpn) << cblklengthexpn;
+ brcblkxend = int_ceildivpow2(prc->x1, cblkwidthexpn) << cblkwidthexpn;
+ brcblkyend = int_ceildivpow2(prc->y1, cblkheightexpn) << cblkheightexpn;
+ brcblkzend = int_ceildivpow2(prc->z1, cblklengthexpn) << cblklengthexpn;
+ prc->cblkno[0] = (brcblkxend - tlcblkxstart) >> cblkwidthexpn;
+ prc->cblkno[1] = (brcblkyend - tlcblkystart) >> cblkheightexpn;
+ prc->cblkno[2] = (brcblkzend - tlcblkzstart) >> cblklengthexpn;
+ prc->cblkno[2] = (prc->cblkno[2] == 0) ? 1 : prc->cblkno[2];
+
+ prc->cblks = (opj_tcd_cblk_t *) opj_malloc((prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]) * sizeof(opj_tcd_cblk_t));
+ prc->incltree = tgt_create(prc->cblkno[0], prc->cblkno[1], prc->cblkno[2]);
+ prc->imsbtree = tgt_create(prc->cblkno[0], prc->cblkno[1], prc->cblkno[2]);
+ //tgt_tree_dump(stdout,prc->incltree);
+ for (cblkno = 0; cblkno < (prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]); cblkno++) {
+ int cblkxstart = tlcblkxstart + (cblkno % prc->cblkno[0]) * (1 << cblkwidthexpn);
+ int cblkystart = tlcblkystart + ((cblkno % (prc->cblkno[0] * prc->cblkno[1])) / prc->cblkno[0]) * (1 << cblkheightexpn);
+ int cblkzstart = tlcblkzstart + (cblkno / (prc->cblkno[0] * prc->cblkno[1])) * (1 << cblklengthexpn);
+ int cblkxend = cblkxstart + (1 << cblkwidthexpn);
+ int cblkyend = cblkystart + (1 << cblkheightexpn);
+ int cblkzend = cblkzstart + (1 << cblklengthexpn);
+ int prec = ((tilec->bpp > 16) ? 3 : ((tilec->bpp > 8) ? 2 : 1));
+
+ tcd->cblk = &prc->cblks[cblkno];
+ cblk = tcd->cblk;
+
+ /* code-block size (global) */
+ cblk->x0 = int_max(cblkxstart, prc->x0);
+ cblk->y0 = int_max(cblkystart, prc->y0);
+ cblk->z0 = int_max(cblkzstart, prc->z0);
+ cblk->x1 = int_min(cblkxend, prc->x1);
+ cblk->y1 = int_min(cblkyend, prc->y1);
+ cblk->z1 = int_min(cblkzend, prc->z1);
+ }
+ }
+ }
+ }
+ }
+ //tcd_dump(stdout, tcd, tcd->tcd_volume);
+
+}
+void tcd_init_encode(opj_tcd_t *tcd, opj_volume_t * volume, opj_cp_t * cp, int curtileno) {
+ int compno, resno, bandno, precno, cblkno;
+ int j, p, q, r;
+
+ opj_tcd_tile_t *tile = NULL; /* pointer to tcd->tile */
+ opj_tcd_tilecomp_t *tilec = NULL; /* pointer to tcd->tilec */
+ opj_tcd_resolution_t *res = NULL; /* pointer to tcd->res */
+ opj_tcd_band_t *band = NULL; /* pointer to tcd->band */
+ opj_tcd_precinct_t *prc = NULL; /* pointer to tcd->prc */
+ opj_tcd_cblk_t *cblk = NULL; /* pointer to tcd->cblk */
+ opj_tcp_t *tcp = &cp->tcps[curtileno];
+
+ tcd->tile = tcd->tcd_volume->tiles;
+ tile = tcd->tile;
+
+ /* p61 ISO/IEC IS15444-1 : 2002 */
+ /* curtileno --> raster scanned index of tiles */
+ /* p,q,r --> matricial index of tiles */
+ p = curtileno % cp->tw;
+ q = curtileno / cp->tw;
+ r = curtileno / (cp->tw * cp->th); /* extension to 3-D */
+
+ /* 4 borders of the tile rescale on the volume if necessary (B.3)*/
+ tile->x0 = int_max(cp->tx0 + p * cp->tdx, volume->x0);
+ tile->y0 = int_max(cp->ty0 + q * cp->tdy, volume->y0);
+ tile->z0 = int_max(cp->tz0 + r * cp->tdz, volume->z0);
+ tile->x1 = int_min(cp->tx0 + (p + 1) * cp->tdx, volume->x1);
+ tile->y1 = int_min(cp->ty0 + (q + 1) * cp->tdy, volume->y1);
+ tile->z1 = int_min(cp->tz0 + (r + 1) * cp->tdz, volume->z1);
+ tile->numcomps = volume->numcomps;
+
+ /* Modification of the RATE >> */
+ for (j = 0; j < tcp->numlayers; j++) {
+ if (tcp->rates[j] <= 1) {
+ tcp->rates[j] = 0;
+ } else {
+ float num = (float) (tile->numcomps * (tile->x1 - tile->x0) * (tile->y1 - tile->y0) * (tile->z1 - tile->z0) * volume->comps[0].prec);
+ float den = (float) (8 * volume->comps[0].dx * volume->comps[0].dy * volume->comps[0].dz);
+ den = tcp->rates[j] * den;
+ tcp->rates[j] = (num + den - 1) / den;
+ }
+ /*tcp->rates[j] = tcp->rates[j] ? int_ceildiv(
+ tile->numcomps * (tile->x1 - tile->x0) * (tile->y1 - tile->y0) * (tile->z1 - tile->z0) * volume->comps[0].prec,
+ (tcp->rates[j] * 8 * volume->comps[0].dx * volume->comps[0].dy * volume->comps[0].dz)) : 0;*/
+ if (tcp->rates[j]) {
+ if (j && tcp->rates[j] < tcp->rates[j - 1] + 10) {
+ tcp->rates[j] = tcp->rates[j - 1] + 20;
+ } else if (!j && tcp->rates[j] < 30){
+ tcp->rates[j] = 30;
+ }
+ }
+ }
+ /* << Modification of the RATE */
+
+ for (compno = 0; compno < tile->numcomps; compno++) {
+ opj_tccp_t *tccp = &tcp->tccps[compno];
+ int res_max, i;
+ int prevnumbands = 0;
+
+ /* opj_tcd_tilecomp_t *tilec=&tile->comps[compno]; */
+ tcd->tilec = &tile->comps[compno];
+ tilec = tcd->tilec;
+
+ /* border of each tile component (global) (B.3) */
+ tilec->x0 = int_ceildiv(tile->x0, volume->comps[compno].dx);
+ tilec->y0 = int_ceildiv(tile->y0, volume->comps[compno].dy);
+ tilec->z0 = int_ceildiv(tile->z0, volume->comps[compno].dz);
+ tilec->x1 = int_ceildiv(tile->x1, volume->comps[compno].dx);
+ tilec->y1 = int_ceildiv(tile->y1, volume->comps[compno].dy);
+ tilec->z1 = int_ceildiv(tile->z1, volume->comps[compno].dz);
+
+ tilec->data = (int *) opj_malloc((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0) * (tilec->z1 - tilec->z0) * sizeof(int));
+
+ res_max = 0;
+ for (i = 0;i < 3; i++){
+ tilec->numresolution[i] = tccp->numresolution[i];
+ //Greater of 3 resolutions contains all information
+ res_max = (tilec->numresolution[i] > res_max) ? tilec->numresolution[i] : res_max;
+ }
+
+ tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(res_max * sizeof(opj_tcd_resolution_t));
+ for (resno = 0; resno < res_max; resno++) {
+ int pdx, pdy, pdz;
+ int tlprcxstart, tlprcystart, tlprczstart, brprcxend, brprcyend, brprczend;
+ int tlcbgxstart, tlcbgystart, tlcbgzstart, brcbgxend, brcbgyend, brcbgzend;
+ int cbgwidthexpn, cbgheightexpn, cbglengthexpn;
+ int cblkwidthexpn, cblkheightexpn, cblklengthexpn;
+
+ int levelnox = tilec->numresolution[0] - 1 - resno;
+ int levelnoy = tilec->numresolution[1] - 1 - resno;
+ int diff = tccp->numresolution[0] - tccp->numresolution[2];
+ int levelnoz = tilec->numresolution[2] - 1 - ((resno <= diff) ? 0 : (resno - diff));
+ if (levelnoz < 0) levelnoz = 0;
+
+ tcd->res = &tilec->resolutions[resno];
+ res = tcd->res;
+
+ /* border for each resolution level (global) (B.14)*/
+ res->x0 = int_ceildivpow2(tilec->x0, levelnox);
+ res->y0 = int_ceildivpow2(tilec->y0, levelnoy);
+ res->z0 = int_ceildivpow2(tilec->z0, levelnoz);
+ res->x1 = int_ceildivpow2(tilec->x1, levelnox);
+ res->y1 = int_ceildivpow2(tilec->y1, levelnoy);
+ res->z1 = int_ceildivpow2(tilec->z1, levelnoz);
+
+ // res->numbands = resno == 0 ? 1 : 3; /* --> 2D */
+ res->numbands = (resno == 0) ? 1 : (resno <= diff) ? 3 : 7; /* --> 3D */
+
+ /* p. 30, table A-13, ISO/IEC IS154444-1 : 2002 */
+ if (tccp->csty & J3D_CCP_CSTY_PRT) {
+ pdx = tccp->prctsiz[0][resno];
+ pdy = tccp->prctsiz[1][resno];
+ pdz = tccp->prctsiz[2][resno];
+ } else {
+ pdx = 15;
+ pdy = 15;
+ pdz = 15;
+ }
+ /* p. 66, B.16, ISO/IEC IS15444-1 : 2002 */
+ tlprcxstart = int_floordivpow2(res->x0, pdx) << pdx;
+ tlprcystart = int_floordivpow2(res->y0, pdy) << pdy;
+ tlprczstart = int_floordivpow2(res->z0, pdz) << pdz;
+ brprcxend = int_ceildivpow2(res->x1, pdx) << pdx;
+ brprcyend = int_ceildivpow2(res->y1, pdy) << pdy;
+ brprczend = int_ceildivpow2(res->z1, pdz) << pdz;
+
+ res->prctno[0] = (brprcxend - tlprcxstart) >> pdx;
+ res->prctno[1] = (brprcyend - tlprcystart) >> pdy;
+ res->prctno[2] = (brprczend - tlprczstart) >> pdz;
+ if (res->prctno[2] == 0) res->prctno[2] = 1;
+
+ /* p. 67, B.17 & B.18, ISO/IEC IS15444-1 : 2002 */
+ if (resno == 0) {
+ tlcbgxstart = tlprcxstart;
+ tlcbgystart = tlprcystart;
+ tlcbgzstart = tlprczstart;
+ brcbgxend = brprcxend;
+ brcbgyend = brprcyend;
+ brcbgzend = brprczend;
+ cbgwidthexpn = pdx;
+ cbgheightexpn = pdy;
+ cbglengthexpn = pdz;
+ } else {
+ tlcbgxstart = int_ceildivpow2(tlprcxstart, 1);
+ tlcbgystart = int_ceildivpow2(tlprcystart, 1);
+ tlcbgzstart = int_ceildivpow2(tlprczstart, 1);
+ brcbgxend = int_ceildivpow2(brprcxend, 1);
+ brcbgyend = int_ceildivpow2(brprcyend, 1);
+ brcbgzend = int_ceildivpow2(brprczend, 1);
+ cbgwidthexpn = pdx - 1;
+ cbgheightexpn = pdy - 1;
+ cbglengthexpn = pdz - 1;
+ }
+
+ cblkwidthexpn = int_min(tccp->cblk[0], cbgwidthexpn);
+ cblkheightexpn = int_min(tccp->cblk[1], cbgheightexpn);
+ cblklengthexpn = int_min(tccp->cblk[2], cbglengthexpn);
+
+ res->bands = (opj_tcd_band_t *) opj_malloc(res->numbands * sizeof(opj_tcd_band_t));
+ for (bandno = 0; bandno < res->numbands; bandno++) {
+ int x0b, y0b, z0b;
+ int gain, numbps;
+ opj_stepsize_t *ss = NULL;
+
+ tcd->band = &res->bands[bandno];
+ band = tcd->band;
+
+ band->bandno = resno == 0 ? 0 : bandno + 1;
+ /* Bandno: 0 - LLL 2 - LHL
+ 1 - HLL 3 - HHL
+ 4 - LLH 6 - LHH
+ 5 - HLH 7 - HHH */
+ x0b = (band->bandno == 1) || (band->bandno == 3) || (band->bandno == 5 ) || (band->bandno == 7 ) ? 1 : 0;
+ y0b = (band->bandno == 2) || (band->bandno == 3) || (band->bandno == 6 ) || (band->bandno == 7 ) ? 1 : 0;
+ z0b = (band->bandno == 4) || (band->bandno == 5) || (band->bandno == 6 ) || (band->bandno == 7 ) ? 1 : 0;
+
+ /* p. 65, B.15, ISO/IEC IS15444-1 : 2002 */
+ if (band->bandno == 0) {
+ /* band border (global) */
+ band->x0 = int_ceildivpow2(tilec->x0, levelnox);
+ band->y0 = int_ceildivpow2(tilec->y0, levelnoy);
+ band->z0 = int_ceildivpow2(tilec->z0, levelnoz);
+ band->x1 = int_ceildivpow2(tilec->x1, levelnox);
+ band->y1 = int_ceildivpow2(tilec->y1, levelnoy);
+ band->z1 = int_ceildivpow2(tilec->z1, levelnoz);
+ } else {
+ band->x0 = int_ceildivpow2(tilec->x0 - (1 << levelnox) * x0b, levelnox + 1);
+ band->y0 = int_ceildivpow2(tilec->y0 - (1 << levelnoy) * y0b, levelnoy + 1);
+ band->z0 = int_ceildivpow2(tilec->z0 - (1 << levelnoz) * z0b, (resno <= diff) ? levelnoz : levelnoz + 1);
+ band->x1 = int_ceildivpow2(tilec->x1 - (1 << levelnox) * x0b, levelnox + 1);
+ band->y1 = int_ceildivpow2(tilec->y1 - (1 << levelnoy) * y0b, levelnoy + 1);
+ band->z1 = int_ceildivpow2(tilec->z1 - (1 << levelnoz) * z0b, (resno <= diff) ? levelnoz : levelnoz + 1);
+ }
+
+ ss = &tccp->stepsizes[(resno == 0) ? 0 : (prevnumbands + bandno + 1)];
+ if (bandno == (res->numbands - 1))
+ prevnumbands += (resno == 0) ? 0 : res->numbands;
+ gain = dwt_getgain(band->bandno,tccp->reversible);
+ numbps = volume->comps[compno].prec + gain;
+
+ band->stepsize = (float)((1.0 + ss->mant / 2048.0) * pow(2.0, numbps - ss->expn));
+ band->numbps = ss->expn + tccp->numgbits - 1; /* WHY -1 ? */
+
+ for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) {
+ int tlcblkxstart, tlcblkystart, tlcblkzstart, brcblkxend, brcblkyend, brcblkzend;
+
+ int cbgxstart = tlcbgxstart + (precno % res->prctno[0]) * (1 << cbgwidthexpn);
+ int cbgystart = tlcbgystart + ((precno / (res->prctno[0] * res->prctno[1])) / res->prctno[0]) * (1 << cbgheightexpn);
+ int cbgzstart = tlcbgzstart + (precno / (res->prctno[0] * res->prctno[1])) * (1 << cbglengthexpn);
+ int cbgxend = cbgxstart + (1 << cbgwidthexpn);
+ int cbgyend = cbgystart + (1 << cbgheightexpn);
+ int cbgzend = cbgzstart + (1 << cbglengthexpn);
+
+ /* opj_tcd_precinct_t *prc=&band->precincts[precno]; */
+ tcd->prc = &band->precincts[precno];
+ prc = tcd->prc;
+
+ /* precinct size (global) */
+ prc->x0 = int_max(cbgxstart, band->x0);
+ prc->y0 = int_max(cbgystart, band->y0);
+ prc->z0 = int_max(cbgzstart, band->z0);
+ prc->x1 = int_min(cbgxend, band->x1);
+ prc->y1 = int_min(cbgyend, band->y1);
+ prc->z1 = int_min(cbgzend, band->z1);
+
+ tlcblkxstart = int_floordivpow2(prc->x0, cblkwidthexpn) << cblkwidthexpn;
+ tlcblkystart = int_floordivpow2(prc->y0, cblkheightexpn) << cblkheightexpn;
+ tlcblkzstart = int_floordivpow2(prc->z0, cblklengthexpn) << cblklengthexpn;
+ brcblkxend = int_ceildivpow2(prc->x1, cblkwidthexpn) << cblkwidthexpn;
+ brcblkyend = int_ceildivpow2(prc->y1, cblkheightexpn) << cblkheightexpn;
+ brcblkzend = int_ceildivpow2(prc->z1, cblklengthexpn) << cblklengthexpn;
+ prc->cblkno[0] = (brcblkxend - tlcblkxstart) >> cblkwidthexpn;
+ prc->cblkno[1] = (brcblkyend - tlcblkystart) >> cblkheightexpn;
+ prc->cblkno[2] = (brcblkzend - tlcblkzstart) >> cblklengthexpn;
+ prc->cblkno[2] = (prc->cblkno[2] == 0) ? 1 : prc->cblkno[2];
+
+ opj_free(prc->cblks);
+ prc->cblks = (opj_tcd_cblk_t *) opj_malloc((prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]) * sizeof(opj_tcd_cblk_t));
+ prc->incltree = tgt_create(prc->cblkno[0], prc->cblkno[1], prc->cblkno[2]);
+ prc->imsbtree = tgt_create(prc->cblkno[0], prc->cblkno[1], prc->cblkno[2]);
+
+ for (cblkno = 0; cblkno < (prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]); cblkno++) {
+ int cblkxstart = tlcblkxstart + (cblkno % prc->cblkno[0]) * (1 << cblkwidthexpn);
+ int cblkystart = tlcblkystart + ((cblkno % (prc->cblkno[0] * prc->cblkno[1])) / prc->cblkno[0]) * (1 << cblkheightexpn);
+ int cblkzstart = tlcblkzstart + (cblkno / (prc->cblkno[0] * prc->cblkno[1])) * (1 << cblklengthexpn);
+ int cblkxend = cblkxstart + (1 << cblkwidthexpn);
+ int cblkyend = cblkystart + (1 << cblkheightexpn);
+ int cblkzend = cblkzstart + (1 << cblklengthexpn);
+ int prec = ((tilec->bpp > 16) ? 3 : ((tilec->bpp > 8) ? 2 : 1));
+
+ tcd->cblk = &prc->cblks[cblkno];
+ cblk = tcd->cblk;
+
+ /* code-block size (global) */
+ cblk->x0 = int_max(cblkxstart, prc->x0);
+ cblk->y0 = int_max(cblkystart, prc->y0);
+ cblk->z0 = int_max(cblkzstart, prc->z0);
+ cblk->x1 = int_min(cblkxend, prc->x1);
+ cblk->y1 = int_min(cblkyend, prc->y1);
+ cblk->z1 = int_min(cblkzend, prc->z1);
+ }
+ } /* precno */
+ } /* bandno */
+ } /* resno */
+ } /* compno */
+ //tcd_dump(stdout, tcd, tcd->tcd_volume);
+}
+
+
+void tcd_free_encode(opj_tcd_t *tcd) {
+ int tileno, compno, resno, bandno, precno;
+
+ opj_tcd_tile_t *tile = NULL; /* pointer to tcd->tile */
+// opj_tcd_slice_t *slice = NULL; /* pointer to tcd->slice */
+ opj_tcd_tilecomp_t *tilec = NULL; /* pointer to tcd->tilec */
+ opj_tcd_resolution_t *res = NULL; /* pointer to tcd->res */
+ opj_tcd_band_t *band = NULL; /* pointer to tcd->band */
+ opj_tcd_precinct_t *prc = NULL; /* pointer to tcd->prc */
+
+ for (tileno = 0; tileno < 1; tileno++) {
+ tcd->tile = tcd->tcd_volume->tiles;
+ tile = tcd->tile;
+
+ for (compno = 0; compno < tile->numcomps; compno++) {
+ tcd->tilec = &tile->comps[compno];
+ tilec = tcd->tilec;
+
+ for (resno = 0; resno < tilec->numresolution[0]; resno++) {
+ tcd->res = &tilec->resolutions[resno];
+ res = tcd->res;
+
+ for (bandno = 0; bandno < res->numbands; bandno++) {
+ tcd->band = &res->bands[bandno];
+ band = tcd->band;
+
+ for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) {
+ tcd->prc = &band->precincts[precno];
+ prc = tcd->prc;
+
+ if (prc->incltree != NULL) {
+ tgt_destroy(prc->incltree);
+ prc->incltree = NULL;
+ }
+ if (prc->imsbtree != NULL) {
+ tgt_destroy(prc->imsbtree);
+ prc->imsbtree = NULL;
+ }
+ opj_free(prc->cblks);
+ prc->cblks = NULL;
+ } /* for (precno */
+ opj_free(band->precincts);
+ band->precincts = NULL;
+ } /* for (bandno */
+ } /* for (resno */
+ opj_free(tilec->resolutions);
+ tilec->resolutions = NULL;
+ } /* for (compno */
+ opj_free(tile->comps);
+ tile->comps = NULL;
+ } /* for (tileno */
+ opj_free(tcd->tcd_volume->tiles);
+ tcd->tcd_volume->tiles = NULL;
+}
+
+/* ----------------------------------------------------------------------- */
+void tcd_malloc_decode(opj_tcd_t *tcd, opj_volume_t * volume, opj_cp_t * cp) {
+ int tileno, compno, resno, bandno, precno, cblkno, res_max,
+ i, j, p, q, r;
+ unsigned int x0 = 0, y0 = 0, z0 = 0,
+ x1 = 0, y1 = 0, z1 = 0,
+ w, h, l;
+
+ tcd->volume = volume;
+ tcd->cp = cp;
+ tcd->tcd_volume->tw = cp->tw;
+ tcd->tcd_volume->th = cp->th;
+ tcd->tcd_volume->tl = cp->tl;
+ tcd->tcd_volume->tiles = (opj_tcd_tile_t *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(opj_tcd_tile_t));
+
+ for (i = 0; i < cp->tileno_size; i++) {
+ opj_tcp_t *tcp = &(cp->tcps[cp->tileno[i]]);
+ opj_tcd_tile_t *tile = &(tcd->tcd_volume->tiles[cp->tileno[i]]);
+
+ /* p61 ISO/IEC IS15444-1 : 2002 */
+ /* curtileno --> raster scanned index of tiles */
+ /* p,q,r --> matricial index of tiles */
+ tileno = cp->tileno[i];
+ p = tileno % cp->tw;
+ q = tileno / cp->tw;
+ r = tileno / (cp->tw * cp->th); /* extension to 3-D */
+
+ /* 4 borders of the tile rescale on the volume if necessary (B.3)*/
+ tile->x0 = int_max(cp->tx0 + p * cp->tdx, volume->x0);
+ tile->y0 = int_max(cp->ty0 + q * cp->tdy, volume->y0);
+ tile->z0 = int_max(cp->tz0 + r * cp->tdz, volume->z0);
+ tile->x1 = int_min(cp->tx0 + (p + 1) * cp->tdx, volume->x1);
+ tile->y1 = int_min(cp->ty0 + (q + 1) * cp->tdy, volume->y1);
+ tile->z1 = int_min(cp->tz0 + (r + 1) * cp->tdz, volume->z1);
+ tile->numcomps = volume->numcomps;
+
+ tile->comps = (opj_tcd_tilecomp_t *) opj_malloc(volume->numcomps * sizeof(opj_tcd_tilecomp_t));
+ for (compno = 0; compno < tile->numcomps; compno++) {
+ opj_tccp_t *tccp = &tcp->tccps[compno];
+ opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
+ int prevnumbands = 0;
+
+ /* border of each tile component (global) */
+ tilec->x0 = int_ceildiv(tile->x0, volume->comps[compno].dx);
+ tilec->y0 = int_ceildiv(tile->y0, volume->comps[compno].dy);
+ tilec->z0 = int_ceildiv(tile->z0, volume->comps[compno].dz);
+ tilec->x1 = int_ceildiv(tile->x1, volume->comps[compno].dx);
+ tilec->y1 = int_ceildiv(tile->y1, volume->comps[compno].dy);
+ tilec->z1 = int_ceildiv(tile->z1, volume->comps[compno].dz);
+
+ tilec->data = (int *) opj_malloc((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0) * (tilec->z1 - tilec->z0) * sizeof(int));
+
+ res_max = 0;
+ for (i = 0;i < 3; i++){
+ tilec->numresolution[i] = tccp->numresolution[i];
+ //Greater of 3 resolutions contains all information
+ res_max = (tilec->numresolution[i] > res_max) ? tilec->numresolution[i] : res_max;
+ }
+
+ tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(res_max * sizeof(opj_tcd_resolution_t));
+
+ for (resno = 0; resno < res_max; resno++) {
+ opj_tcd_resolution_t *res = &tilec->resolutions[resno];
+ int pdx, pdy, pdz;
+ int tlprcxstart, tlprcystart, tlprczstart, brprcxend, brprcyend, brprczend;
+ int tlcbgxstart, tlcbgystart, tlcbgzstart, brcbgxend, brcbgyend, brcbgzend;
+ int cbgwidthexpn, cbgheightexpn, cbglengthexpn;
+ int cblkwidthexpn, cblkheightexpn, cblklengthexpn;
+ int levelnox = tilec->numresolution[0] - 1 - resno;
+ int levelnoy = tilec->numresolution[1] - 1 - resno;
+ int diff = tccp->numresolution[0] - tccp->numresolution[2];
+ int levelnoz = tilec->numresolution[2] - 1 - ((resno <= diff) ? 0 : (resno - diff));
+ if (levelnoz < 0) levelnoz = 0;
+
+ /* border for each resolution level (global) */
+ res->x0 = int_ceildivpow2(tilec->x0, levelnox);
+ res->y0 = int_ceildivpow2(tilec->y0, levelnoy);
+ res->z0 = int_ceildivpow2(tilec->z0, levelnoz);
+ res->x1 = int_ceildivpow2(tilec->x1, levelnox);
+ res->y1 = int_ceildivpow2(tilec->y1, levelnoy);
+ res->z1 = int_ceildivpow2(tilec->z1, levelnoz);
+ res->numbands = (resno == 0) ? 1 : (resno <= diff) ? 3 : 7; /* --> 3D */
+
+ /* p. 30, table A-13, ISO/IEC IS154444-1 : 2002 */
+ if (tccp->csty & J3D_CCP_CSTY_PRT) {
+ pdx = tccp->prctsiz[0][resno];
+ pdy = tccp->prctsiz[1][resno];
+ pdz = tccp->prctsiz[2][resno];
+ } else {
+ pdx = 15;
+ pdy = 15;
+ pdz = 15;
+ }
+
+ /* p. 66, B.16, ISO/IEC IS15444-1 : 2002 */
+ tlprcxstart = int_floordivpow2(res->x0, pdx) << pdx;
+ tlprcystart = int_floordivpow2(res->y0, pdy) << pdy;
+ tlprczstart = int_floordivpow2(res->z0, pdz) << pdz;
+ brprcxend = int_ceildivpow2(res->x1, pdx) << pdx;
+ brprcyend = int_ceildivpow2(res->y1, pdy) << pdy;
+ brprczend = int_ceildivpow2(res->z1, pdz) << pdz;
+
+ res->prctno[0] = (brprcxend - tlprcxstart) >> pdx;
+ res->prctno[1] = (brprcyend - tlprcystart) >> pdy;
+ res->prctno[2] = (brprczend - tlprczstart) >> pdz;
+
+ /* p. 67, B.17 & B.18, ISO/IEC IS15444-1 : 2002 */
+ if (resno == 0) {
+ tlcbgxstart = tlprcxstart;//0
+ tlcbgystart = tlprcystart;
+ tlcbgzstart = tlprczstart;
+ brcbgxend = brprcxend;//1
+ brcbgyend = brprcyend;
+ brcbgzend = brprczend;
+ cbgwidthexpn = pdx; //15
+ cbgheightexpn = pdy;
+ cbglengthexpn = pdz;
+ } else {
+ tlcbgxstart = int_ceildivpow2(tlprcxstart, 1);
+ tlcbgystart = int_ceildivpow2(tlprcystart, 1);
+ tlcbgzstart = int_ceildivpow2(tlprczstart, 1);
+ brcbgxend = int_ceildivpow2(brprcxend, 1);
+ brcbgyend = int_ceildivpow2(brprcyend, 1);
+ brcbgzend = int_ceildivpow2(brprczend, 1);
+ cbgwidthexpn = pdx - 1;
+ cbgheightexpn = pdy - 1;
+ cbglengthexpn = pdz - 1;
+ }
+
+ cblkwidthexpn = int_min(tccp->cblk[0], cbgwidthexpn); //6
+ cblkheightexpn = int_min(tccp->cblk[1], cbgheightexpn); //6
+ cblklengthexpn = int_min(tccp->cblk[2], cbglengthexpn); //6
+
+ res->bands = (opj_tcd_band_t *) opj_malloc(res->numbands * sizeof(opj_tcd_band_t));
+ for (bandno = 0; bandno < res->numbands; bandno++) {
+ int x0b, y0b, z0b;
+ int gain, numbps;
+ opj_stepsize_t *ss = NULL;
+
+ opj_tcd_band_t *band = &res->bands[bandno];
+ band->bandno = resno == 0 ? 0 : bandno + 1;
+ /* Bandno: 0 - LLL 2 - LHL
+ 1 - HLL 3 - HHL
+ 4 - LLH 6 - LHH
+ 5 - HLH 7 - HHH */
+ x0b = (band->bandno == 1) || (band->bandno == 3) || (band->bandno == 5 ) || (band->bandno == 7 ) ? 1 : 0;
+ y0b = (band->bandno == 2) || (band->bandno == 3) || (band->bandno == 6 ) || (band->bandno == 7 ) ? 1 : 0;
+ z0b = (band->bandno == 4) || (band->bandno == 5) || (band->bandno == 6 ) || (band->bandno == 7 ) ? 1 : 0;
+
+ /* p. 65, B.15, ISO/IEC IS15444-1 : 2002 */
+ if (band->bandno == 0) {
+ /* band border (global) */
+ band->x0 = int_ceildivpow2(tilec->x0, levelnox);
+ band->y0 = int_ceildivpow2(tilec->y0, levelnoy);
+ band->z0 = int_ceildivpow2(tilec->z0, levelnoz);
+ band->x1 = int_ceildivpow2(tilec->x1, levelnox);
+ band->y1 = int_ceildivpow2(tilec->y1, levelnoy);
+ band->z1 = int_ceildivpow2(tilec->z1, levelnoz);
+ } else {
+ band->x0 = int_ceildivpow2(tilec->x0 - (1 << levelnox) * x0b, levelnox + 1);
+ band->y0 = int_ceildivpow2(tilec->y0 - (1 << levelnoy) * y0b, levelnoy + 1);
+ band->z0 = int_ceildivpow2(tilec->z0 - (1 << levelnoz) * z0b, (resno <= diff) ? levelnoz : levelnoz + 1);
+ band->x1 = int_ceildivpow2(tilec->x1 - (1 << levelnox) * x0b, levelnox + 1);
+ band->y1 = int_ceildivpow2(tilec->y1 - (1 << levelnoy) * y0b, levelnoy + 1);
+ band->z1 = int_ceildivpow2(tilec->z1 - (1 << levelnoz) * z0b, (resno <= diff) ? levelnoz : levelnoz + 1);
+ }
+
+ ss = &tccp->stepsizes[(resno == 0) ? 0 : (prevnumbands + bandno + 1)];
+ if (bandno == (res->numbands - 1))
+ prevnumbands += (resno == 0) ? 0 : res->numbands;
+ gain = dwt_getgain(band->bandno,tccp->reversible);
+ numbps = volume->comps[compno].prec + gain;
+
+ band->stepsize = (float)((1.0 + ss->mant / 2048.0) * pow(2.0, numbps - ss->expn));
+ band->numbps = ss->expn + tccp->numgbits - 1; /* WHY -1 ? */
+
+ band->precincts = (opj_tcd_precinct_t *) opj_malloc(res->prctno[0] * res->prctno[1] * res->prctno[2] * sizeof(opj_tcd_precinct_t));
+
+ for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) {
+ int tlcblkxstart, tlcblkystart, tlcblkzstart, brcblkxend, brcblkyend, brcblkzend;
+
+ int cbgxstart = tlcbgxstart + (precno % res->prctno[0]) * (1 << cbgwidthexpn);
+ int cbgystart = tlcbgystart + (precno / res->prctno[0]) * (1 << cbgheightexpn);
+ int cbgzstart = tlcbgzstart + (precno / (res->prctno[0] * res->prctno[1])) * (1 << cbglengthexpn);
+ int cbgxend = cbgxstart + (1 << cbgwidthexpn);
+ int cbgyend = cbgystart + (1 << cbgheightexpn);
+ int cbgzend = cbgzstart + (1 << cbglengthexpn);
+
+ opj_tcd_precinct_t *prc = &band->precincts[precno];
+ /* precinct size (global) */
+ prc->x0 = int_max(cbgxstart, band->x0);
+ prc->y0 = int_max(cbgystart, band->y0);
+ prc->z0 = int_max(cbgzstart, band->z0);
+ prc->x1 = int_min(cbgxend, band->x1);
+ prc->y1 = int_min(cbgyend, band->y1);
+ prc->z1 = int_min(cbgzend, band->z1);
+
+ tlcblkxstart = int_floordivpow2(prc->x0, cblkwidthexpn) << cblkwidthexpn;
+ tlcblkystart = int_floordivpow2(prc->y0, cblkheightexpn) << cblkheightexpn;
+ tlcblkzstart = int_floordivpow2(prc->z0, cblklengthexpn) << cblklengthexpn;
+ brcblkxend = int_ceildivpow2(prc->x1, cblkwidthexpn) << cblkwidthexpn;
+ brcblkyend = int_ceildivpow2(prc->y1, cblkheightexpn) << cblkheightexpn;
+ brcblkzend = int_ceildivpow2(prc->z1, cblklengthexpn) << cblklengthexpn;
+ prc->cblkno[0] = (brcblkxend - tlcblkxstart) >> cblkwidthexpn;
+ prc->cblkno[1] = (brcblkyend - tlcblkystart) >> cblkheightexpn;
+ prc->cblkno[2] = (brcblkzend - tlcblkzstart) >> cblklengthexpn;
+ prc->cblkno[2] = (prc->cblkno[2] == 0) ? 1 : prc->cblkno[2];
+
+ prc->cblks = (opj_tcd_cblk_t *) opj_malloc((prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]) * sizeof(opj_tcd_cblk_t));
+ prc->incltree = tgt_create(prc->cblkno[0], prc->cblkno[1], prc->cblkno[2]);
+ prc->imsbtree = tgt_create(prc->cblkno[0], prc->cblkno[1], prc->cblkno[2]);
+
+ for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {
+ int cblkxstart = tlcblkxstart + (cblkno % prc->cblkno[0]) * (1 << cblkwidthexpn);
+ int cblkystart = tlcblkystart + ((cblkno % (prc->cblkno[0] * prc->cblkno[1])) / prc->cblkno[0]) * (1 << cblkheightexpn);
+ int cblkzstart = tlcblkzstart + (cblkno / (prc->cblkno[0] * prc->cblkno[1])) * (1 << cblklengthexpn);
+ int cblkxend = cblkxstart + (1 << cblkwidthexpn);
+ int cblkyend = cblkystart + (1 << cblkheightexpn);
+ int cblkzend = cblkzstart + (1 << cblklengthexpn);
+ int prec = ((tilec->bpp > 16) ? 3 : ((tilec->bpp > 8) ? 2 : 1));
+ /* code-block size (global) */
+ opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];
+
+ /* code-block size (global) */
+ cblk->x0 = int_max(cblkxstart, prc->x0);
+ cblk->y0 = int_max(cblkystart, prc->y0);
+ cblk->z0 = int_max(cblkzstart, prc->z0);
+ cblk->x1 = int_min(cblkxend, prc->x1);
+ cblk->y1 = int_min(cblkyend, prc->y1);
+ cblk->z1 = int_min(cblkzend, prc->z1);
+ }
+ } /* precno */
+ } /* bandno */
+ } /* resno */
+ } /* compno */
+ } /* i = 0..cp->tileno_size */
+
+ //tcd_dump(stdout, tcd, tcd->tcd_volume);
+
+ /*
+ Allocate place to store the decoded data = final volume
+ Place limited by the tile really present in the codestream
+ */
+
+ for (i = 0; i < volume->numcomps; i++) {
+ for (j = 0; j < cp->tileno_size; j++) {
+ tileno = cp->tileno[j];
+ x0 = (j == 0) ? tcd->tcd_volume->tiles[tileno].comps[i].x0 : int_min(x0,(unsigned int) tcd->tcd_volume->tiles[tileno].comps[i].x0);
+ y0 = (j == 0) ? tcd->tcd_volume->tiles[tileno].comps[i].y0 : int_min(y0,(unsigned int) tcd->tcd_volume->tiles[tileno].comps[i].y0);
+ z0 = (j == 0) ? tcd->tcd_volume->tiles[tileno].comps[i].z0 : int_min(z0,(unsigned int) tcd->tcd_volume->tiles[tileno].comps[i].z0);
+ x1 = (j == 0) ? tcd->tcd_volume->tiles[tileno].comps[i].x1 : int_max(x1,(unsigned int) tcd->tcd_volume->tiles[tileno].comps[i].x1);
+ y1 = (j == 0) ? tcd->tcd_volume->tiles[tileno].comps[i].y1 : int_max(y1,(unsigned int) tcd->tcd_volume->tiles[tileno].comps[i].y1);
+ z1 = (j == 0) ? tcd->tcd_volume->tiles[tileno].comps[i].z1 : int_max(z1,(unsigned int) tcd->tcd_volume->tiles[tileno].comps[i].z1);
+ }
+
+ w = x1 - x0;
+ h = y1 - y0;
+ l = z1 - z0;
+
+ volume->comps[i].data = (int *) opj_malloc(w * h * l * sizeof(int));
+ volume->comps[i].w = w;
+ volume->comps[i].h = h;
+ volume->comps[i].l = l;
+ volume->comps[i].x0 = x0;
+ volume->comps[i].y0 = y0;
+ volume->comps[i].z0 = z0;
+ volume->comps[i].bigendian = cp->bigendian;
+ }
+}
+
+void tcd_free_decode(opj_tcd_t *tcd) {
+ int tileno,compno,resno,bandno,precno;
+
+ opj_tcd_volume_t *tcd_volume = tcd->tcd_volume;
+
+ for (tileno = 0; tileno < tcd_volume->tw * tcd_volume->th * tcd_volume->tl; tileno++) {
+ opj_tcd_tile_t *tile = &tcd_volume->tiles[tileno];
+ for (compno = 0; compno < tile->numcomps; compno++) {
+ opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
+ for (resno = 0; resno < tilec->numresolution[0]; resno++) {
+ opj_tcd_resolution_t *res = &tilec->resolutions[resno];
+ for (bandno = 0; bandno < res->numbands; bandno++) {
+ opj_tcd_band_t *band = &res->bands[bandno];
+ for (precno = 0; precno < res->prctno[1] * res->prctno[0] * res->prctno[2]; precno++) {
+ opj_tcd_precinct_t *prec = &band->precincts[precno];
+ if (prec->cblks != NULL) opj_free(prec->cblks);
+ if (prec->imsbtree != NULL) tgt_destroy(prec->imsbtree);
+ if (prec->incltree != NULL) tgt_destroy(prec->incltree);
+ /*for (treeno = 0; treeno < prec->numtrees; treeno++){
+ if (prec->imsbtree[treeno] != NULL) tgt_destroy(prec->imsbtree[treeno]);
+ if (prec->incltree[treeno] != NULL) tgt_destroy(prec->incltree[treeno]);
+ }*/
+ }
+ if (band->precincts != NULL) opj_free(band->precincts);
+ }
+ }
+ if (tilec->resolutions != NULL) opj_free(tilec->resolutions);
+ }
+ if (tile->comps != NULL) opj_free(tile->comps);
+ }
+
+ if (tcd_volume->tiles != NULL) opj_free(tcd_volume->tiles);
+}
+
+
+
+/* ----------------------------------------------------------------------- */
+void tcd_makelayer_fixed(opj_tcd_t *tcd, int layno, int final) {
+ int compno, resno, bandno, precno, cblkno;
+ int value; /*, matrice[tcd_tcp->numlayers][tcd_tile->comps[0].numresolution[0]][3]; */
+ int matrice[10][10][3];
+ int i, j, k;
+
+ opj_cp_t *cp = tcd->cp;
+ opj_tcd_tile_t *tcd_tile = tcd->tcd_tile;
+ opj_tcp_t *tcd_tcp = tcd->tcp;
+
+ /*matrice=(int*)opj_malloc(tcd_tcp->numlayers*tcd_tile->comps[0].numresolution[0]*3*sizeof(int)); */
+
+ for (compno = 0; compno < tcd_tile->numcomps; compno++) {
+ opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno];
+ for (i = 0; i < tcd_tcp->numlayers; i++) {
+ for (j = 0; j < tilec->numresolution[0]; j++) {
+ for (k = 0; k < 3; k++) {
+ matrice[i][j][k] =
+ (int) (cp->matrice[i * tilec->numresolution[0] * 3 + j * 3 + k]
+ * (float) (tcd->volume->comps[compno].prec / 16.0));
+ }
+ }
+ }
+
+ for (resno = 0; resno < tilec->numresolution[0]; resno++) {
+ opj_tcd_resolution_t *res = &tilec->resolutions[resno];
+ for (bandno = 0; bandno < res->numbands; bandno++) {
+ opj_tcd_band_t *band = &res->bands[bandno];
+ for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) {
+ opj_tcd_precinct_t *prc = &band->precincts[precno];
+ for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {
+ opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];
+ opj_tcd_layer_t *layer = &cblk->layers[layno];
+ int n;
+ int imsb = tcd->volume->comps[compno].prec - cblk->numbps; /* number of bit-plan equal to zero */
+ /* Correction of the matrix of coefficient to include the IMSB information */
+ if (layno == 0) {
+ value = matrice[layno][resno][bandno];
+ if (imsb >= value) {
+ value = 0;
+ } else {
+ value -= imsb;
+ }
+ } else {
+ value = matrice[layno][resno][bandno] - matrice[layno - 1][resno][bandno];
+ if (imsb >= matrice[layno - 1][resno][bandno]) {
+ value -= (imsb - matrice[layno - 1][resno][bandno]);
+ if (value < 0) {
+ value = 0;
+ }
+ }
+ }
+
+ if (layno == 0) {
+ cblk->numpassesinlayers = 0;
+ }
+
+ n = cblk->numpassesinlayers;
+ if (cblk->numpassesinlayers == 0) {
+ if (value != 0) {
+ n = 3 * value - 2 + cblk->numpassesinlayers;
+ } else {
+ n = cblk->numpassesinlayers;
+ }
+ } else {
+ n = 3 * value + cblk->numpassesinlayers;
+ }
+
+ layer->numpasses = n - cblk->numpassesinlayers;
+
+ if (!layer->numpasses)
+ continue;
+
+ if (cblk->numpassesinlayers == 0) {
+ layer->len = cblk->passes[n - 1].rate;
+ layer->data = cblk->data;
+ } else {
+ layer->len = cblk->passes[n - 1].rate - cblk->passes[cblk->numpassesinlayers - 1].rate;
+ layer->data = cblk->data + cblk->passes[cblk->numpassesinlayers - 1].rate;
+ }
+ if (final)
+ cblk->numpassesinlayers = n;
+ }
+ }
+ }
+ }
+ }
+}
+
+void tcd_rateallocate_fixed(opj_tcd_t *tcd) {
+ int layno;
+ for (layno = 0; layno < tcd->tcp->numlayers; layno++) {
+ tcd_makelayer_fixed(tcd, layno, 1);
+ }
+}
+
+void tcd_makelayer(opj_tcd_t *tcd, int layno, double thresh, int final) {
+ int compno, resno, bandno, precno, cblkno, passno;
+
+ opj_tcd_tile_t *tcd_tile = tcd->tcd_tile;
+
+ tcd_tile->distolayer[layno] = 0; /* fixed_quality */
+
+ for (compno = 0; compno < tcd_tile->numcomps; compno++) {
+ opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno];
+ for (resno = 0; resno < tilec->numresolution[0]; resno++) {
+ opj_tcd_resolution_t *res = &tilec->resolutions[resno];
+ for (bandno = 0; bandno < res->numbands; bandno++) {
+ opj_tcd_band_t *band = &res->bands[bandno];
+ for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) {
+ opj_tcd_precinct_t *prc = &band->precincts[precno];
+ for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {
+ opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];
+ opj_tcd_layer_t *layer = &cblk->layers[layno];
+
+ int n;
+ if (layno == 0) {
+ cblk->numpassesinlayers = 0;
+ }
+ n = cblk->numpassesinlayers;
+ for (passno = cblk->numpassesinlayers; passno < cblk->totalpasses; passno++) {
+ int dr;
+ double dd;
+ opj_tcd_pass_t *pass = &cblk->passes[passno];
+ if (n == 0) {
+ dr = pass->rate;
+ dd = pass->distortiondec;
+ } else {
+ dr = pass->rate - cblk->passes[n - 1].rate;
+ dd = pass->distortiondec - cblk->passes[n - 1].distortiondec;
+ }
+ if (!dr) {
+ if (dd)
+ n = passno + 1;
+ continue;
+ }
+ if (dd / dr >= thresh){
+ n = passno + 1;
+ }
+ }
+ layer->numpasses = n - cblk->numpassesinlayers;
+
+ if (!layer->numpasses) {
+ layer->disto = 0;
+ continue;
+ }
+ if (cblk->numpassesinlayers == 0) {
+ layer->len = cblk->passes[n - 1].rate;
+ layer->data = cblk->data;
+ layer->disto = cblk->passes[n - 1].distortiondec;
+ } else {
+ layer->len = cblk->passes[n - 1].rate - cblk->passes[cblk->numpassesinlayers - 1].rate;
+ layer->data = cblk->data + cblk->passes[cblk->numpassesinlayers - 1].rate;
+ layer->disto = cblk->passes[n - 1].distortiondec - cblk->passes[cblk->numpassesinlayers - 1].distortiondec;
+ }
+
+ tcd_tile->distolayer[layno] += layer->disto; /* fixed_quality */
+
+ if (final)
+ cblk->numpassesinlayers = n;
+
+ // fprintf(stdout,"MakeLayer : %d %f %d %d \n",layer->len, layer->disto, layer->numpasses, n);
+ }
+ }
+ }
+ }
+ }
+}
+
+bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_volume_info_t * volume_info) {
+ int compno, resno, bandno, precno, cblkno, passno, layno;
+ double min, max;
+ double cumdisto[100]; /* fixed_quality */
+ const double K = 1; /* 1.1; // fixed_quality */
+ double maxSE = 0;
+
+ opj_cp_t *cp = tcd->cp;
+ opj_tcd_tile_t *tcd_tile = tcd->tcd_tile;
+ opj_tcp_t *tcd_tcp = tcd->tcp;
+
+ min = DBL_MAX;
+ max = 0;
+
+ tcd_tile->nbpix = 0; /* fixed_quality */
+
+ for (compno = 0; compno < tcd_tile->numcomps; compno++) {
+ opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno];
+ tilec->nbpix = 0;
+ for (resno = 0; resno < tilec->numresolution[0]; resno++) {
+ opj_tcd_resolution_t *res = &tilec->resolutions[resno];
+ for (bandno = 0; bandno < res->numbands; bandno++) {
+ opj_tcd_band_t *band = &res->bands[bandno];
+ for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) {
+ opj_tcd_precinct_t *prc = &band->precincts[precno];
+ for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {
+ opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];
+ for (passno = 0; passno < cblk->totalpasses; passno++) {
+ opj_tcd_pass_t *pass = &cblk->passes[passno];
+ int dr;
+ double dd, rdslope;
+ if (passno == 0) {
+ dr = pass->rate;
+ dd = pass->distortiondec;
+ } else {
+ dr = pass->rate - cblk->passes[passno - 1].rate;
+ dd = pass->distortiondec - cblk->passes[passno - 1].distortiondec;
+ }
+ if (dr == 0) {
+ continue;
+ }
+ rdslope = dd / dr;
+ if (rdslope < min) {
+ min = rdslope;
+ }
+ if (rdslope > max) {
+ max = rdslope;
+ }
+
+ } /* passno */
+
+ /* fixed_quality */
+ tcd_tile->nbpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0) * (cblk->z1 - cblk->z0));
+ tilec->nbpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0) * (cblk->z1 - cblk->z0));
+ } /* cbklno */
+ } /* precno */
+ } /* bandno */
+ } /* resno */
+
+ maxSE += (((double)(1 << tcd->volume->comps[compno].prec) - 1.0)
+ * ((double)(1 << tcd->volume->comps[compno].prec) -1.0))
+ * ((double)(tilec->nbpix));
+ } /* compno */
+
+ /* add antonin index */
+ if(volume_info && volume_info->index_on) {
+ opj_tile_info_t *info_TL = &volume_info->tile[tcd->tcd_tileno];
+ info_TL->nbpix = tcd_tile->nbpix;
+ info_TL->distotile = tcd_tile->distotile;
+ info_TL->thresh = (double *) opj_malloc(tcd_tcp->numlayers * sizeof(double));
+ }
+ /* dda */
+
+ for (layno = 0; layno < tcd_tcp->numlayers; layno++) {
+ double lo = min;
+ double hi = max;
+ int success = 0;
+ int maxlen = tcd_tcp->rates[layno] ? int_min(((int) tcd_tcp->rates[layno]), len) : len;
+ double goodthresh;
+ double distotarget; /* fixed_quality */
+ int i = 0;
+
+ /* fixed_quality */
+ distotarget = tcd_tile->distotile - ((K * maxSE) / pow((float)10, tcd_tcp->distoratio[layno] / 10));
+
+ if ((tcd_tcp->rates[layno]) || (cp->disto_alloc==0)) {
+ opj_t2_t *t2 = t2_create(tcd->cinfo, tcd->volume, cp);
+ int oldl = 0, oldoldl = 0;
+ for (i = 0; i < 128; i++) {
+ double thresh = (lo + hi) / 2;
+ int l = 0;
+ double distoachieved = 0; /* fixed_quality -q */
+
+ tcd_makelayer(tcd, layno, thresh, 0);
+
+ if (cp->fixed_quality) { /* fixed_quality -q */
+ distoachieved = (layno == 0) ? tcd_tile->distolayer[0] : cumdisto[layno - 1] + tcd_tile->distolayer[layno];
+ if (distoachieved < distotarget) {
+ hi = thresh;
+ continue;
+ }
+ lo = thresh;
+ } else { /* disto_alloc -r, fixed_alloc -f */
+ l = t2_encode_packets(t2, tcd->tcd_tileno, tcd_tile, layno + 1, dest, maxlen, volume_info);
+ //fprintf(stdout, "layno %d i %d len=%d max=%d \n",layno,i,l,maxlen);
+ if (l == -999) {
+ lo = thresh;
+ continue;
+ } else if (l == oldl && oldl == oldoldl && tcd_tile->distolayer[layno] > 0.0 && i>32)
+ break;
+ hi = thresh;
+ oldoldl = oldl;
+ oldl = l;
+ }
+ success = 1;
+ goodthresh = thresh;
+ }
+ t2_destroy(t2);
+ } else {
+ success = 1;
+ goodthresh = min;
+ }
+ if (!success) {
+ return false;
+ }
+
+ if(volume_info && volume_info->index_on) { /* Threshold for Marcela Index */
+ volume_info->tile[tcd->tcd_tileno].thresh[layno] = goodthresh;
+ }
+ tcd_makelayer(tcd, layno, goodthresh, 1);
+
+ /* fixed_quality */
+ cumdisto[layno] = (layno == 0) ? tcd_tile->distolayer[0] : cumdisto[layno - 1] + tcd_tile->distolayer[layno];
+ }
+
+ return true;
+}
+
+/* ----------------------------------------------------------------------- */
+int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, opj_volume_info_t * volume_info) {
+ int compno;
+ int l, i, npck = 0;
+ double encoding_time;
+
+ opj_tcd_tile_t *tile = NULL;
+ opj_tcp_t *tcd_tcp = NULL;
+ opj_cp_t *cp = NULL;
+
+ opj_tcp_t *tcp = &tcd->cp->tcps[0];
+ opj_tccp_t *tccp = &tcp->tccps[0];
+ opj_volume_t *volume = tcd->volume;
+ opj_t2_t *t2 = NULL; /* T2 component */
+
+ tcd->tcd_tileno = tileno; /* current encoded/decoded tile */
+
+ tcd->tcd_tile = tcd->tcd_volume->tiles; /* tile information */
+ tile = tcd->tcd_tile;
+
+ tcd->tcp = &tcd->cp->tcps[tileno]; /* coding/decoding params of tileno */
+ tcd_tcp = tcd->tcp;
+
+ cp = tcd->cp; /* coding parameters */
+
+ /* INDEX >> */
+ if(volume_info && volume_info->index_on) {
+ opj_tcd_tilecomp_t *tilec_idx = &tile->comps[0]; /* based on component 0 */
+ for (i = 0; i < tilec_idx->numresolution[0]; i++) {
+ opj_tcd_resolution_t *res_idx = &tilec_idx->resolutions[i];
+
+ volume_info->tile[tileno].prctno[0][i] = res_idx->prctno[0];
+ volume_info->tile[tileno].prctno[1][i] = res_idx->prctno[1];
+ volume_info->tile[tileno].prctno[2][i] = res_idx->prctno[2];
+
+ npck += res_idx->prctno[0] * res_idx->prctno[1] * res_idx->prctno[2];
+
+ volume_info->tile[tileno].prctsiz[0][i] = tccp->prctsiz[0][i];
+ volume_info->tile[tileno].prctsiz[1][i] = tccp->prctsiz[1][i];
+ volume_info->tile[tileno].prctsiz[2][i] = tccp->prctsiz[2][i];
+ }
+ volume_info->tile[tileno].packet = (opj_packet_info_t *) opj_malloc(volume_info->comp * volume_info->layer * npck * sizeof(opj_packet_info_t));
+ }
+ /* << INDEX */
+
+ /*---------------TILE-------------------*/
+ encoding_time = opj_clock(); /* time needed to encode a tile */
+
+ for (compno = 0; compno < tile->numcomps; compno++) {
+ int x, y, z;
+ opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
+
+ int adjust;
+ int offset_x = int_ceildiv(volume->x0, volume->comps[compno].dx); //ceil(x0 / subsampling_dx)
+ int offset_y = int_ceildiv(volume->y0, volume->comps[compno].dy);
+ int offset_z = int_ceildiv(volume->z0, volume->comps[compno].dz);
+
+ int tw = tilec->x1 - tilec->x0;
+ int w = int_ceildiv(volume->x1 - volume->x0, volume->comps[compno].dx);
+ int th = tilec->y1 - tilec->y0;
+ int h = int_ceildiv(volume->y1 - volume->y0, volume->comps[compno].dy);
+ int tl = tilec->z1 - tilec->z0;
+ int l = int_ceildiv(volume->z1 - volume->z0, volume->comps[compno].dz);
+
+
+
+ /* extract tile data from volume.comps[0].data to tile.comps[0].data */
+ //fprintf(stdout,"[INFO] Extract tile data\n");
+ if (tcd->cp->transform_format == TRF_3D_RLS || tcd->cp->transform_format == TRF_3D_LSE) {
+ adjust = 0;
+ } else {
+ adjust = volume->comps[compno].sgnd ? 0 : 1 << (volume->comps[compno].prec - 1); //sign=='+' --> 2^(prec-1)
+ if (volume->comps[compno].dcoffset != 0){
+ adjust += volume->comps[compno].dcoffset;
+ fprintf(stdout,"[INFO] DC Offset applied: DCO = %d -> adjust = %d\n",volume->comps[compno].dcoffset,adjust);
+ }
+ }
+
+ if (tcd_tcp->tccps[compno].reversible == 1) { //IF perfect reconstruction (DWT.5-3)
+ for (z = tilec->z0; z < tilec->z1; z++) {
+ for (y = tilec->y0; y < tilec->y1; y++) {
+ /* start of the src tile scanline */
+ int *data = &volume->comps[compno].data[(tilec->x0 - offset_x) + (y - offset_y) * w + (z - offset_z) * w * h];
+ /* start of the dst tile scanline */
+ int *tile_data = &tilec->data[(y - tilec->y0) * tw + (z - tilec->z0) * tw * th];
+ for (x = tilec->x0; x < tilec->x1; x++) {
+ *tile_data++ = *data++ - adjust;
+ }
+ }
+ }
+ } else if (tcd_tcp->tccps[compno].reversible == 0) { //IF not (DWT.9-7)
+ for (z = tilec->z0; z < tilec->z1; z++) {
+ for (y = tilec->y0; y < tilec->y1; y++) {
+ /* start of the src tile scanline */
+ int *data = &volume->comps[compno].data[(tilec->x0 - offset_x) + (y - offset_y) * w + (z - offset_z) * w * h];
+ /* start of the dst tile scanline */
+ int *tile_data = &tilec->data[(y - tilec->y0) * tw + (z - tilec->z0) * tw * th];
+ for (x = tilec->x0; x < tilec->x1; x++) {
+ *tile_data++ = (*data++ - adjust) << 13;
+ }
+ }
+ }
+ }
+
+ }
+
+ /*----------------MCT-------------------*/
+ if (tcd_tcp->mct) {
+ int samples = (tile->comps[0].x1 - tile->comps[0].x0) * (tile->comps[0].y1 - tile->comps[0].y0) * (tile->comps[0].z1 - tile->comps[0].z0);
+ fprintf(stdout,"[INFO] Tcd_encode_tile: mct\n");
+ if (tcd_tcp->tccps[0].reversible == 0) {
+ mct_encode_real(tile->comps[0].data, tile->comps[1].data, tile->comps[2].data, samples);
+ } else {
+ mct_encode(tile->comps[0].data, tile->comps[1].data, tile->comps[2].data, samples);
+ }
+ }
+ /*----------------TRANSFORM---------------------------------*/
+ fprintf(stdout,"[INFO] Tcd_encode_tile: Transform\n");
+ for (compno = 0; compno < tile->numcomps; compno++) {
+ opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
+ dwt_encode(tilec, tcd_tcp->tccps[compno].dwtid);
+ }
+
+ /*-------------------ENTROPY CODING-----------------------------*/
+ fprintf(stdout,"[INFO] Tcd_encode_tile: Entropy coding\n");
+ if ((cp->encoding_format == ENCOD_2EB)||(cp->encoding_format == ENCOD_3EB))
+ {
+ if (cp->encoding_format == ENCOD_2EB) {
+ opj_t1_t *t1 = NULL;
+ t1 = t1_create(tcd->cinfo);
+ t1_encode_cblks(t1, tile, tcd_tcp);
+ t1_destroy(t1);
+ } else if (cp->encoding_format == ENCOD_3EB) {
+ opj_t1_3d_t *t1 = NULL;
+ t1 = t1_3d_create(tcd->cinfo);
+ t1_3d_encode_cblks(t1, tile, tcd_tcp);
+ t1_3d_destroy(t1);
+ }
+ /*-----------RATE-ALLOCATE------------------*/
+ /* INDEX */
+ if(volume_info) {
+ volume_info->index_write = 0;
+ }
+ if (cp->disto_alloc || cp->fixed_quality) {
+ fprintf(stdout,"[INFO] Tcd_encode_tile: Rate-allocate\n");
+ tcd_rateallocate(tcd, dest, len, volume_info); /* Normal Rate/distortion allocation */
+ } else {/* fixed_alloc */
+ fprintf(stdout,"[INFO] Tcd_encode_tile: Rate-allocate fixed\n");
+ tcd_rateallocate_fixed(tcd); /* Fixed layer allocation */
+ }
+
+ /*--------------TIER2------------------*/
+ /* INDEX */
+ if(volume_info) {
+ volume_info->index_write = 1;
+ }
+ fprintf(stdout,"[INFO] Tcd_encode_tile: Tier - 2\n");
+ t2 = t2_create(tcd->cinfo, volume, cp);
+ l = t2_encode_packets(t2, tileno, tile, tcd_tcp->numlayers, dest, len, volume_info);
+ t2_destroy(t2);
+ } else if ((cp->encoding_format == ENCOD_2GR)||(cp->encoding_format == ENCOD_3GR)) {
+ /*if(volume_info) {
+ volume_info->index_write = 1;
+ }
+ gr = golomb_create(tcd->cinfo, volume, cp);
+ l = golomb_encode(gr, tileno, tile, dest, len, volume_info);
+ golomb_destroy(gr);*/
+ }
+
+
+ /*---------------CLEAN-------------------*/
+ fprintf(stdout,"[INFO] Tcd_encode_tile: %d bytes coded\n",l);
+ encoding_time = opj_clock() - encoding_time;
+ opj_event_msg(tcd->cinfo, EVT_INFO, "- tile encoded in %f s\n", encoding_time);
+
+ /* cleaning memory */
+ for (compno = 0; compno < tile->numcomps; compno++) {
+ tcd->tilec = &tile->comps[compno];
+ opj_free(tcd->tilec->data);
+ }
+
+ if (l == -999){
+ fprintf(stdout,"[ERROR] Unable to perform T2 tier. Return -999.\n");
+ return 0;
+ }
+
+ return l;
+}
+
+
+bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno) {
+ int l, i;
+ int compno, eof = 0;
+ double tile_time, t1_time, dwt_time;
+
+ opj_tcd_tile_t *tile = NULL;
+ opj_t2_t *t2 = NULL; /* T2 component */
+
+ tcd->tcd_tileno = tileno;
+ tcd->tcd_tile = &(tcd->tcd_volume->tiles[tileno]);
+ tcd->tcp = &(tcd->cp->tcps[tileno]);
+ tile = tcd->tcd_tile;
+
+ tile_time = opj_clock(); /* time needed to decode a tile */
+ opj_event_msg(tcd->cinfo, EVT_INFO, "tile %d / %d\n", tileno + 1, tcd->cp->tw * tcd->cp->th * tcd->cp->tl);
+
+ if ((tcd->cp->encoding_format == ENCOD_2EB) || (tcd->cp->encoding_format == ENCOD_3EB)) {
+ /*--------------TIER2------------------*/
+ t2 = t2_create(tcd->cinfo, tcd->volume, tcd->cp);
+ l = t2_decode_packets(t2, src, len, tileno, tile);
+ t2_destroy(t2);
+ opj_event_msg(tcd->cinfo, EVT_INFO, "Tcd_decode_tile: %d bytes decoded\n",l);
+
+ if (l == -999) {
+ eof = 1;
+ opj_event_msg(tcd->cinfo, EVT_ERROR, "Tcd_decode_tile: incomplete bistream\n");
+ }
+
+ /*------------------TIER1-----------------*/
+ opj_event_msg(tcd->cinfo, EVT_INFO, "Tcd_decode_tile: Entropy decoding %d \n",tcd->cp->encoding_format);
+ t1_time = opj_clock(); /* time needed to decode a tile */
+ if (tcd->cp->encoding_format == ENCOD_2EB) {
+ opj_t1_t *t1 = NULL; /* T1 component */
+ t1 = t1_create(tcd->cinfo);
+ t1_decode_cblks(t1, tile, tcd->tcp);
+ t1_destroy(t1);
+ }else if (tcd->cp->encoding_format == ENCOD_3EB) {
+ opj_t1_3d_t *t1 = NULL; /* T1 component */
+ t1 = t1_3d_create(tcd->cinfo);
+ t1_3d_decode_cblks(t1, tile, tcd->tcp);
+ t1_3d_destroy(t1);
+ }
+
+ t1_time = opj_clock() - t1_time;
+ #ifdef VERBOSE
+ opj_event_msg(tcd->cinfo, EVT_INFO, "- tier-1 took %f s\n", t1_time);
+ #endif
+ } else if ((tcd->cp->encoding_format == ENCOD_2GR)||(tcd->cp->encoding_format == ENCOD_3GR)) {
+ opj_event_msg(tcd->cinfo, EVT_INFO, "Tcd_decode_tile: Entropy decoding -- Does nothing :-D\n");
+ /*
+ gr = golomb_create(tcd->cinfo, tcd->volume, tcd->cp);
+ l = golomb_decode(gr, tileno, tile, src, len);
+ golomb_destroy(gr);
+ if (l == -999) {
+ eof = 1;
+ opj_event_msg(tcd->cinfo, EVT_ERROR, "Tcd_decode_tile: incomplete bistream\n");
+ }
+ */
+ }
+
+ /*----------------DWT---------------------*/
+ fprintf(stdout,"[INFO] Tcd_decode_tile: Inverse DWT\n");
+ dwt_time = opj_clock(); /* time needed to decode a tile */
+ for (compno = 0; compno < tile->numcomps; compno++) {
+ opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
+ int stops[3], dwtid[3];
+
+ for (i = 0; i < 3; i++) {
+ if (tcd->cp->reduce[i] != 0)
+ tcd->volume->comps[compno].resno_decoded[i] = tile->comps[compno].numresolution[i] - tcd->cp->reduce[i] - 1;
+ stops[i] = tilec->numresolution[i] - 1 - tcd->volume->comps[compno].resno_decoded[i];
+ if (stops[i] < 0) stops[i]=0;
+ dwtid[i] = tcd->cp->tcps->tccps[compno].dwtid[i];
+ }
+
+ dwt_decode(tilec, stops, dwtid);
+
+ for (i = 0; i < 3; i++) {
+ if (tile->comps[compno].numresolution[i] > 0) {
+ tcd->volume->comps[compno].factor[i] = tile->comps[compno].numresolution[i] - (tcd->volume->comps[compno].resno_decoded[i] + 1);
+ if ( (tcd->volume->comps[compno].factor[i]) < 0 )
+ tcd->volume->comps[compno].factor[i] = 0;
+ }
+ }
+ }
+ dwt_time = opj_clock() - dwt_time;
+ #ifdef VERBOSE
+ opj_event_msg(tcd->cinfo, EVT_INFO, "- dwt took %f s\n", dwt_time);
+ #endif
+
+ /*----------------MCT-------------------*/
+
+ if (tcd->tcp->mct) {
+ if (tcd->tcp->tccps[0].reversible == 1) {
+ mct_decode(tile->comps[0].data, tile->comps[1].data, tile->comps[2].data,
+ (tile->comps[0].x1 - tile->comps[0].x0) * (tile->comps[0].y1 - tile->comps[0].y0) * (tile->comps[0].z1 - tile->comps[0].z0));
+ } else {
+ mct_decode_real(tile->comps[0].data, tile->comps[1].data, tile->comps[2].data,
+ (tile->comps[0].x1 - tile->comps[0].x0) * (tile->comps[0].y1 - tile->comps[0].y0)* (tile->comps[0].z1 - tile->comps[0].z0));
+ }
+ }
+
+ /*---------------TILE-------------------*/
+
+ for (compno = 0; compno < tile->numcomps; compno++) {
+ opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
+ opj_tcd_resolution_t *res = &tilec->resolutions[tcd->volume->comps[compno].resno_decoded[0]];
+ int adjust;
+ int minval = tcd->volume->comps[compno].sgnd ? -(1 << (tcd->volume->comps[compno].prec - 1)) : 0;
+ int maxval = tcd->volume->comps[compno].sgnd ? (1 << (tcd->volume->comps[compno].prec - 1)) - 1 : (1 << tcd->volume->comps[compno].prec) - 1;
+
+ int tw = tilec->x1 - tilec->x0;
+ int w = tcd->volume->comps[compno].w;
+ int th = tilec->y1 - tilec->y0;
+ int h = tcd->volume->comps[compno].h;
+
+ int i, j, k;
+ int offset_x = int_ceildivpow2(tcd->volume->comps[compno].x0, tcd->volume->comps[compno].factor[0]);
+ int offset_y = int_ceildivpow2(tcd->volume->comps[compno].y0, tcd->volume->comps[compno].factor[1]);
+ int offset_z = int_ceildivpow2(tcd->volume->comps[compno].z0, tcd->volume->comps[compno].factor[2]);
+
+ if (tcd->cp->transform_format == TRF_3D_RLS || tcd->cp->transform_format == TRF_3D_LSE) {
+ adjust = 0;
+ } else {
+ adjust = tcd->volume->comps[compno].sgnd ? 0 : 1 << (tcd->volume->comps[compno].prec - 1); //sign=='+' --> 2^(prec-1)
+ if (tcd->volume->comps[compno].dcoffset != 0){
+ adjust += tcd->volume->comps[compno].dcoffset;
+ fprintf(stdout,"[INFO] DC Offset applied: DCO = %d -> adjust = %d\n",tcd->volume->comps[compno].dcoffset,adjust);
+ }
+ }
+
+ for (k = res->z0; k < res->z1; k++) {
+ for (j = res->y0; j < res->y1; j++) {
+ for (i = res->x0; i < res->x1; i++) {
+ int v;
+ float tmp = (float)((tilec->data[i - res->x0 + (j - res->y0) * tw + (k - res->z0) * tw * th]) / 8192.0);
+
+ if (tcd->tcp->tccps[compno].reversible == 1) {
+ v = tilec->data[i - res->x0 + (j - res->y0) * tw + (k - res->z0) * tw * th];
+ } else {
+ int tmp2 = ((int) (floor(fabs(tmp)))) + ((int) floor(fabs(tmp*2))%2);
+ v = ((tmp < 0) ? -tmp2:tmp2);
+ }
+ v += adjust;
+
+ tcd->volume->comps[compno].data[(i - offset_x) + (j - offset_y) * w + (k - offset_z) * w * h] = int_clamp(v, minval, maxval);
+ }
+ }
+ }
+ }
+
+ tile_time = opj_clock() - tile_time; /* time needed to decode a tile */
+ opj_event_msg(tcd->cinfo, EVT_INFO, "- tile decoded in %f s\n", tile_time);
+
+ for (compno = 0; compno < tile->numcomps; compno++) {
+ opj_free(tcd->tcd_volume->tiles[tileno].comps[compno].data);
+ tcd->tcd_volume->tiles[tileno].comps[compno].data = NULL;
+ }
+
+ if (eof) {
+ return false;
+ }
+
+ return true;
+}
+
diff --git a/libopenjpeg3d/tcd.h b/libopenjpeg3d/tcd.h
new file mode 100755
index 00000000..52504d10
--- /dev/null
+++ b/libopenjpeg3d/tcd.h
@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * Copyright (c) 2006, Mónica Díez García, Image Processing Laboratory, University of Valladolid, Spain
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef __TCD_H
+#define __TCD_H
+/**
+@file tcd.h
+@brief Implementation of a tile coder/decoder (TCD)
+
+The functions in TCD.C have for goal to encode or decode each tile independently from
+each other. The functions in TCD.C are used by some function in JP3D.C.
+*/
+
+/** @defgroup TCD TCD - Implementation of a tile coder/decoder */
+/*@{*/
+
+/**
+Tile coder/decoder: segment instance
+*/
+typedef struct opj_tcd_seg {
+/** Number of passes in the segment */
+ int numpasses;
+/** Length of information */
+ int len;
+/** Data */
+ unsigned char *data;
+/** Number of passes posible for the segment */
+ int maxpasses;
+/** Number of passes added to the segment */
+ int numnewpasses;
+/** New length after inclusion of segments */
+ int newlen;
+} opj_tcd_seg_t;
+
+/**
+Tile coder/decoder: pass instance
+*/
+typedef struct opj_tcd_pass {
+/** Rate obtained in the pass*/
+ int rate;
+/** Distorsion obtained in the pass*/
+ double distortiondec;
+ int term;
+/** Length of information */
+ int len;
+} opj_tcd_pass_t;
+
+/**
+Tile coder/decoder: layer instance
+*/
+typedef struct opj_tcd_layer {
+/** Number of passes in the layer */
+ int numpasses;
+/** Length of information */
+ int len;
+/** Distortion within layer */
+ double disto; /* add for index (Cfr. Marcela) */
+ unsigned char *data; /* data */
+} opj_tcd_layer_t;
+
+/**
+Tile coder/decoder: codeblock instance
+*/
+typedef struct opj_tcd_cblk {
+/** Dimension of the code-blocks : left upper corner (x0, y0, z0) */
+ int x0, y0, z0;
+/** Dimension of the code-blocks : right low corner (x1,y1,z1) */
+ int x1, y1, z1;
+/** Number of bits per simbol in codeblock */
+ int numbps;
+ int numlenbits;
+ int len; /* length */
+/** Number of pass already done for the code-blocks */
+ int numpasses;
+/** number of pass added to the code-blocks */
+ int numnewpasses;
+/** Number of segments */
+ int numsegs;
+/** Segments informations */
+ opj_tcd_seg_t segs[100];
+/** Number of passes in the layer */
+ int numpassesinlayers;
+/** Layer information */
+ opj_tcd_layer_t layers[100];
+/** Total number of passes */
+ int totalpasses;
+/** Information about the passes */
+ opj_tcd_pass_t passes[100];
+/* Data */
+ unsigned char data[524288];
+ //unsigned char *data;
+} opj_tcd_cblk_t;
+
+/**
+Tile coder/decoder: precint instance
+*/
+typedef struct opj_tcd_precinct {
+/** Dimension of the precint : left upper corner (x0, y0, z0) */
+ int x0, y0, z0;
+/** Dimension of the precint : right low corner (x1,y1,z1) */
+ int x1, y1, z1;
+/** Number of codeblocks in precinct in width and heigth and length*/
+ int cblkno[3];
+/** Information about the codeblocks */
+ opj_tcd_cblk_t *cblks;
+/** Inclusion tree */
+ opj_tgt_tree_t *incltree;
+/** Missing MSBs tree */
+ opj_tgt_tree_t *imsbtree;
+} opj_tcd_precinct_t;
+
+/**
+Tile coder/decoder: subband instance
+*/
+typedef struct opj_tcd_band {
+/** Dimension of the subband : left upper corner (x0, y0, z0) */
+ int x0, y0, z0;
+/** Dimension of the subband : right low corner (x1,y1,z1) */
+ int x1, y1, z1;
+/** Information about the precints */
+ opj_tcd_precinct_t *precincts; /* precinct information */
+/** Number of bits per symbol in band */
+ int numbps;
+/** Quantization stepsize associated */
+ float stepsize;
+/** Band orientation (O->LLL,...,7->HHH) */
+ int bandno;
+} opj_tcd_band_t;
+
+/**
+Tile coder/decoder: resolution instance
+*/
+typedef struct opj_tcd_resolution {
+/** Dimension of the resolution level : left upper corner (x0, y0, z0) */
+ int x0, y0, z0;
+/** Dimension of the resolution level : right low corner (x1,y1,z1) */
+ int x1, y1, z1;
+/** Number of precints in each dimension for the resolution level */
+ int prctno[3];
+/** Number of subbands for the resolution level */
+ int numbands;
+/** Subband information */
+ opj_tcd_band_t *bands;
+} opj_tcd_resolution_t;
+
+/**
+Tile coder/decoder: component instance
+*/
+typedef struct opj_tcd_tilecomp {
+/** Dimension of the component : left upper corner (x0, y0, z0) */
+ int x0, y0, z0;
+/** Dimension of the component : right low corner (x1,y1,z1) */
+ int x1, y1, z1;
+/** Number of resolutions level if DWT transform*/
+ int numresolution[3];
+/** Resolution information */
+ opj_tcd_resolution_t *resolutions;
+/** Data of the component */
+ int *data;
+/** Fixed_quality related */
+ int nbpix;
+/** Number of bits per voxel in component */
+ int bpp;
+} opj_tcd_tilecomp_t;
+
+/**
+Tile coder/decoder: tile instance
+*/
+typedef struct opj_tcd_tile {
+/** Dimension of the tile : left upper corner (x0, y0, z0) */
+ int x0, y0, z0;
+/** Dimension of the tile : right low corner (x1,y1,z1) */
+ int x1, y1, z1;
+/** Number of components in tile */
+ int numcomps;
+/** Components information */
+ opj_tcd_tilecomp_t *comps;
+/** Fixed_quality related : no of bytes of data*/
+ int nbpix;
+/** Fixed_quality related : distortion achieved in tile */
+ double distotile;
+/** Fixed_quality related : distortion achieved in each layer */
+ double distolayer[100];
+} opj_tcd_tile_t;
+
+/**
+Tile coder/decoder: volume instance
+*/
+typedef struct opj_tcd_volume {
+/** Number of tiles in width and heigth and length */
+ int tw, th, tl;
+/** Tiles information */
+ opj_tcd_tile_t *tiles;
+} opj_tcd_volume_t;
+
+/**
+Tile coder/decoder
+*/
+typedef struct opj_tcd {
+/** Codec context */
+ opj_common_ptr cinfo;
+/** Volume information */
+ opj_volume_t *volume;
+/** Coding parameters */
+ opj_cp_t *cp;
+/** Coding/decoding parameters common to all tiles */
+ opj_tcp_t *tcp;
+/** Info on each volume tile */
+ opj_tcd_volume_t *tcd_volume;
+/** Pointer to the current encoded/decoded tile */
+ opj_tcd_tile_t *tcd_tile;
+/** Current encoded/decoded tile */
+ int tcd_tileno;
+
+ /**@name working variables */
+ /*@{*/
+ opj_tcd_tile_t *tile;
+ opj_tcd_tilecomp_t *tilec;
+ opj_tcd_resolution_t *res;
+ opj_tcd_band_t *band;
+ opj_tcd_precinct_t *prc;
+ opj_tcd_cblk_t *cblk;
+ /*@}*/
+} opj_tcd_t;
+
+/** @name Funciones generales */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+
+/**
+Dump the content of a tcd structure
+*/
+void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_volume_t *img);
+/**
+Create a new TCD handle
+@param cinfo Codec context info
+@return Returns a new TCD handle if successful returns NULL otherwise
+*/
+opj_tcd_t* tcd_create(opj_common_ptr cinfo);
+/**
+Destroy a previously created TCD handle
+@param tcd TCD handle to destroy
+*/
+void tcd_destroy(opj_tcd_t *tcd);
+/**
+Initialize the tile coder (allocate the memory)
+@param tcd TCD handle
+@param volume Raw volume
+@param cp Coding parameters
+@param curtileno Number that identifies the tile that will be encoded
+*/
+void tcd_malloc_encode(opj_tcd_t *tcd, opj_volume_t * volume, opj_cp_t * cp, int curtileno);
+/**
+Initialize the tile coder (reuses the memory allocated by tcd_malloc_encode)(for 3D-DWT)
+@param tcd TCD handle
+@param volume Raw volume
+@param cp Coding parameters
+@param curtileno Number that identifies the tile that will be encoded
+*/
+void tcd_init_encode(opj_tcd_t *tcd, opj_volume_t * volume, opj_cp_t * cp, int curtileno);
+/**
+Free the memory allocated for encoding
+@param tcd TCD handle
+*/
+void tcd_free_encode(opj_tcd_t *tcd);
+/**
+Initialize the tile decoder
+@param tcd TCD handle
+@param volume Raw volume
+@param cp Coding parameters
+*/
+void tcd_malloc_decode(opj_tcd_t *tcd, opj_volume_t * volume, opj_cp_t * cp);
+
+void tcd_makelayer_fixed(opj_tcd_t *tcd, int layno, int final);
+void tcd_rateallocate_fixed(opj_tcd_t *tcd);
+void tcd_makelayer(opj_tcd_t *tcd, int layno, double thresh, int final);
+bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_volume_info_t * volume_info);
+/**
+Encode a tile from the raw volume into a buffer
+@param tcd TCD handle
+@param tileno Number that identifies one of the tiles to be encoded
+@param dest Destination buffer
+@param len Length of destination buffer
+@param volume_info Creation of index file
+@return
+*/
+int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, opj_volume_info_t * volume_info);
+/**
+Decode a tile from a buffer into a raw volume
+@param tcd TCD handle
+@param src Source buffer
+@param len Length of source buffer
+@param tileno Number that identifies one of the tiles to be decoded
+*/
+bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno);
+/**
+Free the memory allocated for decoding
+@param tcd TCD handle
+*/
+void tcd_free_decode(opj_tcd_t *tcd);
+
+/* ----------------------------------------------------------------------- */
+/*@}*/
+
+/*@}*/
+
+#endif /* __TCD_H */
diff --git a/libopenjpeg3d/tgt.c b/libopenjpeg3d/tgt.c
new file mode 100755
index 00000000..1772afac
--- /dev/null
+++ b/libopenjpeg3d/tgt.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * 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
+==========================================================
+*/
+void tgt_tree_dump (FILE *fd, opj_tgt_tree_t * tree){
+ int nodesno;
+
+ fprintf(fd, "TGT_TREE {\n");
+ fprintf(fd, " numnodes: %d \n", tree->numnodes);
+ fprintf(fd, " numleafsh: %d, numleafsv: %d, numleafsz: %d,\n", tree->numleafsh, tree->numleafsv, tree->numleafsz);
+
+ for (nodesno = 0; nodesno < tree->numnodes; nodesno++) {
+ fprintf(fd, "tgt_node %d {\n", nodesno);
+ fprintf(fd, " value: %d \n", tree->nodes[nodesno].value);
+ fprintf(fd, " low: %d \n", tree->nodes[nodesno].low);
+ fprintf(fd, " known: %d \n", tree->nodes[nodesno].known);
+ if (tree->nodes[nodesno].parent) {
+ fprintf(fd, " parent.value: %d \n", tree->nodes[nodesno].parent->value);
+ fprintf(fd, " parent.low: %d \n", tree->nodes[nodesno].parent->low);
+ fprintf(fd, " parent.known: %d \n", tree->nodes[nodesno].parent->known);
+ }
+ fprintf(fd, "}\n");
+
+ }
+ fprintf(fd, "}\n");
+
+}
+
+
+opj_tgt_tree_t *tgt_create(int numleafsh, int numleafsv, int numleafsz) {
+
+ int nplh[32];
+ int nplv[32];
+ int nplz[32];
+ opj_tgt_node_t *node = NULL;
+ opj_tgt_node_t *parentnode = NULL;
+ opj_tgt_node_t *parentnode0 = NULL;
+ opj_tgt_tree_t *tree = NULL;
+ int i, j, k, p, p0;
+ int numlvls;
+ int n, z = 0;
+
+ tree = (opj_tgt_tree_t *) opj_malloc(sizeof(opj_tgt_tree_t));
+ if(!tree)
+ return NULL;
+ tree->numleafsh = numleafsh;
+ tree->numleafsv = numleafsv;
+ tree->numleafsz = numleafsz;
+
+ numlvls = 0;
+ nplh[0] = numleafsh;
+ nplv[0] = numleafsv;
+ nplz[0] = numleafsz;
+ tree->numnodes = 0;
+ do {
+ n = nplh[numlvls] * nplv[numlvls] * nplz[numlvls];
+ nplh[numlvls + 1] = (nplh[numlvls] + 1) / 2;
+ nplv[numlvls + 1] = (nplv[numlvls] + 1) / 2;
+ nplz[numlvls + 1] = (nplz[numlvls] + 1) / 2;
+ tree->numnodes += n;
+ ++numlvls;
+ } while (n > 1);
+
+ if (tree->numnodes == 0) {
+ opj_free(tree);
+ return NULL;
+ }
+
+ tree->nodes = (opj_tgt_node_t *) opj_malloc(tree->numnodes * sizeof(opj_tgt_node_t));
+ if(!tree->nodes) {
+ opj_free(tree);
+ return NULL;
+ }
+
+ node = tree->nodes;
+ parentnode = &tree->nodes[tree->numleafsh * tree->numleafsv * tree->numleafsz];
+ parentnode0 = parentnode;
+
+ p = tree->numleafsh * tree->numleafsv * tree->numleafsz;
+ p0 = p;
+ n = 0;
+ //fprintf(stdout,"\nH %d V %d Z %d numlvls %d nodes %d\n",tree->numleafsh,tree->numleafsv,tree->numleafsz,numlvls,tree->numnodes);
+ for (i = 0; i < numlvls - 1; ++i) {
+ for (j = 0; j < nplv[i]; ++j) {
+ k = nplh[i]*nplz[i];
+ while (--k >= 0) {
+ node->parent = parentnode; //fprintf(stdout,"node[%d].parent = node[%d]\n",n,p);
+ ++node; ++n;
+ if (--k >= 0 && n < p) {
+ node->parent = parentnode; //fprintf(stdout,"node[%d].parent = node[%d]\n",n,p);
+ ++node; ++n;
+ }
+ if (nplz[i] != 1){ //2D operation vs 3D operation
+ if (--k >= 0 && n < p) {
+ node->parent = parentnode; //fprintf(stdout,"node[%d].parent = node[%d]\n",n,p);
+ ++node; ++n;
+ }
+ if (--k >= 0 && n < p) {
+ node->parent = parentnode; //fprintf(stdout,"node[%d].parent = node[%d]\n",n,p);
+ ++node; ++n;
+ }
+ }
+ ++parentnode; ++p;
+ }
+ if ((j & 1) || j == nplv[i] - 1) {
+ parentnode0 = parentnode; p0 = p; //fprintf(stdout,"parent = node[%d] \n",p);
+ } else {
+ parentnode = parentnode0; p = p0; //fprintf(stdout,"parent = node[%d] \n",p);
+ parentnode0 += nplh[i]*nplz[i]; p0 += nplh[i]*nplz[i];
+ }
+ }
+ }
+ node->parent = 0;
+
+
+ tgt_reset(tree);
+
+ return tree;
+}
+
+void tgt_destroy(opj_tgt_tree_t *tree) {
+ opj_free(tree->nodes);
+ opj_free(tree);
+}
+
+void tgt_reset(opj_tgt_tree_t *tree) {
+ int i;
+
+ if (NULL == tree)
+ return;
+
+ for (i = 0; i < tree->numnodes; i++) {
+ tree->nodes[i].value = 999;
+ tree->nodes[i].low = 0;
+ tree->nodes[i].known = 0;
+ }
+}
+
+void tgt_setvalue(opj_tgt_tree_t *tree, int leafno, int value) {
+ opj_tgt_node_t *node;
+ node = &tree->nodes[leafno];
+ while (node && node->value > value) {
+ node->value = value;
+ node = node->parent;
+ }
+}
+
+void tgt_encode(opj_bio_t *bio, opj_tgt_tree_t *tree, int leafno, int threshold) {
+ opj_tgt_node_t *stk[31];
+ opj_tgt_node_t **stkptr;
+ opj_tgt_node_t *node;
+ int 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) {
+ bio_write(bio, 1, 1);
+ node->known = 1;
+ }
+ break;
+ }
+ bio_write(bio, 0, 1);
+ ++low;
+ }
+
+ node->low = low;
+ if (stkptr == stk)
+ break;
+ node = *--stkptr;
+ }
+}
+
+int tgt_decode(opj_bio_t *bio, opj_tgt_tree_t *tree, int leafno, int threshold) {
+ opj_tgt_node_t *stk[31];
+ opj_tgt_node_t **stkptr;
+ opj_tgt_node_t *node;
+ int 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 (bio_read(bio, 1)) {
+ node->value = low;
+ } else {
+ ++low;
+ }
+ }
+ node->low = low;
+ if (stkptr == stk) {
+ break;
+ }
+ node = *--stkptr;
+ }
+
+ return (node->value < threshold) ? 1 : 0;
+}
diff --git a/libopenjpeg3d/tgt.h b/libopenjpeg3d/tgt.h
new file mode 100755
index 00000000..ad8e88d8
--- /dev/null
+++ b/libopenjpeg3d/tgt.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * 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 __TGT_H
+#define __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 {
+/** Node parent reference */
+ struct opj_tgt_node *parent;
+/** */
+ int value;
+/** */
+ int low;
+/** */
+ int known;
+} opj_tgt_node_t;
+
+/**
+Tag tree
+*/
+typedef struct opj_tgt_tree {
+/** Number of leaves from horizontal axis */
+ int numleafsh;
+/** Number of leaves from vertical axis */
+ int numleafsv;
+/** Number of leaves from axial axis */
+ int numleafsz;
+/** Number of nodes */
+ int numnodes;
+/** Reference to each node instance */
+ opj_tgt_node_t *nodes;
+} opj_tgt_tree_t;
+
+/** @name Funciones generales */
+/*@{*/
+/* ----------------------------------------------------------------------- */
+/**
+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 numleafsz Depth of the array of leafs of the tree
+@return Returns a new tag-tree if successful, returns NULL otherwise
+*/
+opj_tgt_tree_t *tgt_create(int numleafsh, int numleafsv, int numleafsz);
+/**
+Destroy a tag-tree, liberating memory
+@param tree Tag-tree to destroy
+*/
+void tgt_destroy(opj_tgt_tree_t *tree);
+/**
+Reset a tag-tree (set all leaves to 0)
+@param tree Tag-tree to reset
+*/
+void 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 tgt_setvalue(opj_tgt_tree_t *tree, int leafno, int 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 tgt_encode(opj_bio_t *bio, opj_tgt_tree_t *tree, int leafno, int 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
+*/
+int tgt_decode(opj_bio_t *bio, opj_tgt_tree_t *tree, int leafno, int threshold);
+
+/*@}*/
+/* ----------------------------------------------------------------------- */
+void tgt_tree_dump (FILE *fd, opj_tgt_tree_t * tree);
+
+#endif /* __TGT_H */
diff --git a/libopenjpeg3d/volume.c b/libopenjpeg3d/volume.c
new file mode 100755
index 00000000..35728daf
--- /dev/null
+++ b/libopenjpeg3d/volume.c
@@ -0,0 +1,89 @@
+/*
+ * 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_volume_t* OPJ_CALLCONV opj_volume_create(int numcmpts, opj_volume_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc) {
+ int compno;
+ opj_volume_t *volume = NULL;
+
+ volume = (opj_volume_t*)opj_malloc(sizeof(opj_volume_t));
+ if(volume) {
+ volume->color_space = clrspc;
+ volume->numcomps = numcmpts;
+ /* allocate memory for the per-component information */
+ volume->comps = (opj_volume_comp_t*)opj_malloc(volume->numcomps * sizeof(opj_volume_comp_t));
+ if(!volume->comps) {
+ opj_volume_destroy(volume);
+ return NULL;
+ }
+ /* create the individual volume components */
+ for(compno = 0; compno < numcmpts; compno++) {
+ opj_volume_comp_t *comp = &volume->comps[compno];
+ comp->dx = cmptparms[compno].dx;
+ comp->dy = cmptparms[compno].dy;
+ comp->dz = cmptparms[compno].dz;
+ comp->w = cmptparms[compno].w;
+ comp->h = cmptparms[compno].h;
+ comp->l = cmptparms[compno].l;
+ comp->x0 = cmptparms[compno].x0;
+ comp->y0 = cmptparms[compno].y0;
+ comp->z0 = cmptparms[compno].z0;
+ comp->prec = cmptparms[compno].prec;
+ comp->bpp = cmptparms[compno].bpp;
+ comp->sgnd = cmptparms[compno].sgnd;
+ comp->bigendian = cmptparms[compno].bigendian;
+ comp->dcoffset = cmptparms[compno].dcoffset;
+ comp->data = (int*)opj_malloc(comp->w * comp->h * comp->l * sizeof(int));
+ if(!comp->data) {
+ fprintf(stdout,"Unable to malloc comp->data (%d x %d x %d x bytes)",comp->w,comp->h,comp->l);
+ opj_volume_destroy(volume);
+ return NULL;
+ }
+ //fprintf(stdout,"%d %d %d %d %d %d %d %d %d", comp->w,comp->h, comp->l, comp->dx, comp->dy, comp->dz, comp->prec, comp->bpp, comp->sgnd);
+ }
+ }
+
+ return volume;
+}
+
+void OPJ_CALLCONV opj_volume_destroy(opj_volume_t *volume) {
+ int i;
+ if(volume) {
+ if(volume->comps) {
+ /* volume components */
+ for(i = 0; i < volume->numcomps; i++) {
+ opj_volume_comp_t *volume_comp = &volume->comps[i];
+ if(volume_comp->data) {
+ opj_free(volume_comp->data);
+ }
+ }
+ opj_free(volume->comps);
+ }
+ opj_free(volume);
+ }
+}
+
diff --git a/libopenjpeg3d/volume.h b/libopenjpeg3d/volume.h
new file mode 100755
index 00000000..02f28d2a
--- /dev/null
+++ b/libopenjpeg3d/volume.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2006, Mónica Díez García, Image Processing Laboratory, University of Valladolid, Spain
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef __VOLUME_H
+#define __VOLUME_H
+/**
+@file volume.h
+@brief Implementation of operations on volumes (VOLUME)
+
+The functions in VOLUME.C have for goal to realize operations on volumes.
+*/
+
+/** @defgroup VOLUME VOLUME - Implementation of operations on volumes */
+/*@{*/
+
+
+/*@}*/
+
+#endif /* __VOLUME_H */
+