Initial revision
authorSebastien Lugan <slugan@users.noreply.github.com>
Thu, 27 Nov 2003 10:10:17 +0000 (10:10 +0000)
committerSebastien Lugan <slugan@users.noreply.github.com>
Thu, 27 Nov 2003 10:10:17 +0000 (10:10 +0000)
31 files changed:
libopenjpeg/.cvsignore [new file with mode: 0644]
libopenjpeg/Makefile [new file with mode: 0644]
libopenjpeg/bio.c [new file with mode: 0644]
libopenjpeg/bio.h [new file with mode: 0644]
libopenjpeg/cio.c [new file with mode: 0644]
libopenjpeg/cio.h [new file with mode: 0644]
libopenjpeg/dwt.c [new file with mode: 0644]
libopenjpeg/dwt.h [new file with mode: 0644]
libopenjpeg/fix.c [new file with mode: 0644]
libopenjpeg/fix.h [new file with mode: 0644]
libopenjpeg/int.c [new file with mode: 0644]
libopenjpeg/int.h [new file with mode: 0644]
libopenjpeg/j2k.c [new file with mode: 0644]
libopenjpeg/j2k.h [new file with mode: 0644]
libopenjpeg/mct.c [new file with mode: 0644]
libopenjpeg/mct.h [new file with mode: 0644]
libopenjpeg/mqc.c [new file with mode: 0644]
libopenjpeg/mqc.h [new file with mode: 0644]
libopenjpeg/openjpeg.h [new file with mode: 0644]
libopenjpeg/pi.c [new file with mode: 0644]
libopenjpeg/pi.h [new file with mode: 0644]
libopenjpeg/raw.c [new file with mode: 0644]
libopenjpeg/raw.h [new file with mode: 0644]
libopenjpeg/t1.c [new file with mode: 0644]
libopenjpeg/t1.h [new file with mode: 0644]
libopenjpeg/t2.c [new file with mode: 0644]
libopenjpeg/t2.h [new file with mode: 0644]
libopenjpeg/tcd.c [new file with mode: 0644]
libopenjpeg/tcd.h [new file with mode: 0644]
libopenjpeg/tgt.c [new file with mode: 0644]
libopenjpeg/tgt.h [new file with mode: 0644]

diff --git a/libopenjpeg/.cvsignore b/libopenjpeg/.cvsignore
new file mode 100644 (file)
index 0000000..5aca9ad
--- /dev/null
@@ -0,0 +1,6 @@
+obj
+obj.w32
+bin
+bin.w32
+lib
+lib.w32
diff --git a/libopenjpeg/Makefile b/libopenjpeg/Makefile
new file mode 100644 (file)
index 0000000..63a5f32
--- /dev/null
@@ -0,0 +1,67 @@
+# $Id$
+#
+# makefile for OpenJPEG library
+
+CFLAGS  = -Wall -O3 -fno-strength-reduce -fomit-frame-pointer
+
+ifndef DEBUG
+  LDFLAGS = -s -lm
+else
+  LDFLAGS = -lm
+endif
+
+OBJ_DIR_W32 = obj.w32
+LIB_DIR_W32 = lib.w32
+
+ifdef MINGW32
+  CC = i386-mingw32-gcc
+  AR = i386-mingw32-ar
+  OBJ_DIR = $(OBJ_DIR_W32)
+  LIB_DIR = $(LIB_DIR_W32)
+  all: $(LIB_DIR)/libopenjpeg.a $(LIB_DIR)/libopenjpeg.dll
+else
+  CC = gcc
+  AR = ar
+  OBJ_DIR = obj
+  LIB_DIR = lib
+  all: $(LIB_DIR)/libopenjpeg.a $(LIB_DIR)/libopenjpeg.so
+endif
+
+$(OBJ_DIR)/%.o:
+       $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
+
+$(OBJ_DIR)/bio.o:      bio.c bio.h
+$(OBJ_DIR)/cio.o:      cio.c cio.h
+$(OBJ_DIR)/dwt.o:      dwt.c dwt.h int.h fix.h tcd.h
+$(OBJ_DIR)/fix.o:      fix.c fix.h
+$(OBJ_DIR)/int.o:      int.c
+$(OBJ_DIR)/j2k.o:      j2k.c j2k.h cio.h tcd.h dwt.h int.h
+$(OBJ_DIR)/mct.o:      mct.c mct.h fix.h
+$(OBJ_DIR)/mqc.o:      mqc.c mqc.h
+$(OBJ_DIR)/pi.o:       pi.c pi.h int.h
+$(OBJ_DIR)/raw.o:      raw.c raw.h
+$(OBJ_DIR)/t1.o:       t1.c t1.h j2k.h mqc.h raw.h int.h mct.h dwt.h fix.h
+$(OBJ_DIR)/t2.o:       t2.c t2.h tcd.h bio.h j2k.h pi.h tgt.h int.h cio.h
+$(OBJ_DIR)/tcd.o:      tcd.c tcd.h int.h t1.h t2.h dwt.h mct.h
+$(OBJ_DIR)/tgt.o:      tgt.c tgt.h bio.h
+
+COM_OBJS = $(addprefix $(OBJ_DIR)/, j2k.o bio.o cio.o dwt.o fix.o int.o mct.o \
+          mqc.o pi.o t1.o t2.o  tgt.o tcd.o raw.o)
+
+$(LIB_DIR)/libopenjpeg.a: ${COM_OBJS}
+       $(AR) -sr $@ $^
+       
+$(LIB_DIR)/libopenjpeg.dll: ${COM_OBJS}
+       ${CC} -s -shared -Wl,-soname,libopenjpeg.dll -o $@ $^
+
+$(LIB_DIR)/libopenjpeg.so.1.0: ${COM_OBJS}
+       ${CC} -s -shared -Wl,-soname,libopenjpeg.so.1 -o $@ $^
+
+$(LIB_DIR)/libopenjpeg.so.1: $(LIB_DIR)/libopenjpeg.so.1.0
+       ln -s libopenjpeg.so.1.0 $(LIB_DIR)/libopenjpeg.so.1
+
+$(LIB_DIR)/libopenjpeg.so: $(LIB_DIR)/libopenjpeg.so.1
+       ln -s libopenjpeg.so.1 $(LIB_DIR)/libopenjpeg.so
+
+clean:
+       rm -f $(OBJ_DIR_W32)/* $(OBJ_DIR)/* $(LIB_DIR_W32)/* $(LIB_DIR)/*
diff --git a/libopenjpeg/bio.c b/libopenjpeg/bio.c
new file mode 100644 (file)
index 0000000..400523d
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2001-2002, David Janssens
+ * Copyright (c) 2003, Yannick Verschueren
+ * Copyright (c) 2003,  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 "bio.h"
+#include <stdio.h>
+#include <setjmp.h>
+
+static unsigned char *bio_start, *bio_end, *bio_bp;
+static unsigned int bio_buf;
+static int bio_ct;
+
+extern jmp_buf j2k_error;
+
+/* <summary> */
+/* Number of bytes written. */
+/* </summary> */
+int bio_numbytes()
+{
+       return bio_bp - bio_start;
+}
+
+/* <summary> */
+/* Init encoder. */
+/* </summary> */
+/* <param name="bp">Output buffer</param> */
+/* <param name="len">Output buffer length</param> */
+void bio_init_enc(unsigned char *bp, int len)
+{
+       bio_start = bp;
+       bio_end = bp + len;
+       bio_bp = bp;
+       bio_buf = 0;
+       bio_ct = 8;
+}
+
+/* <summary> */
+/* Init decoder. */
+/* </summary> */
+/* <param name="bp">Input buffer</param> */
+/* <param name="len">Input buffer length</param> */
+void bio_init_dec(unsigned char *bp, int len)
+{
+       bio_start = bp;
+       bio_end = bp + len;
+       bio_bp = bp;
+       bio_buf = 0;
+       bio_ct = 0;
+}
+
+/* <summary> */
+/* Write byte. --> function modified to eliminate longjmp !!! */
+/* </summary> */
+int bio_byteout()
+{
+       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;
+}
+
+/* <summary> */
+/* Read byte. --> function modified to eliminate longjmp !!  */
+/* </summary> */
+int bio_bytein()
+{
+       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;
+}
+
+/* <summary> */
+/* Write bit. */
+/* </summary> */
+/* <param name="b">Bit to write (0 or 1)</param> */
+void bio_putbit(int b)
+{
+       if (bio_ct == 0) {
+               bio_byteout();
+       }
+       bio_ct--;
+       bio_buf |= b << bio_ct;
+}
+
+/* <summary> */
+/* Read bit. */
+/* </summary> */
+int bio_getbit()
+{
+       if (bio_ct == 0) {
+               bio_bytein();
+       }
+       bio_ct--;
+       return (bio_buf >> bio_ct) & 1;
+}
+
+/* <summary> */
+/* Write bits. */
+/* </summary> */
+/* <param name="v">Value of bits</param> */
+/* <param name="n">Number of bits to write</param> */
+void bio_write(int v, int n)
+{
+       int i;
+       for (i = n - 1; i >= 0; i--) {
+               bio_putbit((v >> i) & 1);
+       }
+}
+
+/* <summary> */
+/* Read bits. */
+/* </summary> */
+/* <param name="n">Number of bits to read</param> */
+int bio_read(int n)
+{
+       int i, v;
+       v = 0;
+       for (i = n - 1; i >= 0; i--) {
+               v += bio_getbit() << i;
+       }
+       return v;
+}
+
+/* <summary> */
+/* Flush bits. MOdified to eliminate longjmp !! */
+/* </summary> */
+int bio_flush()
+{
+       bio_ct = 0;
+       if (bio_byteout())
+               return 1;
+       if (bio_ct == 7) {
+               bio_ct = 0;
+
+               if (bio_byteout())
+                       return 1;
+       }
+       return 0;
+}
+
+/* <summary> */
+/* </summary> */
+int bio_inalign()
+{
+       bio_ct = 0;
+       if ((bio_buf & 0xff) == 0xff) {
+               if (bio_bytein())
+                       return 1;
+               bio_ct = 0;
+       }
+       return 0;
+}
diff --git a/libopenjpeg/bio.h b/libopenjpeg/bio.h
new file mode 100644 (file)
index 0000000..b081349
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2001-2002, David Janssens
+ * Copyright (c) 2003, Yannick Verschueren
+ * Copyright (c) 2003,  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
+
+int bio_numbytes();
+void bio_init_enc(unsigned char *bp, int len);
+void bio_init_dec(unsigned char *bp, int len);
+void bio_write(int v, int n);
+int bio_read(int n);
+int bio_flush();                                                               /* modified to eliminated longjmp !! */
+int bio_inalign();                                                     /* modified to eliminated longjmp !! */
+
+#endif
diff --git a/libopenjpeg/cio.c b/libopenjpeg/cio.c
new file mode 100644 (file)
index 0000000..bc5adc6
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2001-2002, David Janssens
+ * 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 "cio.h"
+#include <setjmp.h>
+
+static unsigned char *cio_start, *cio_end, *cio_bp;
+
+extern jmp_buf j2k_error;
+
+/* <summary> */
+/* Number of bytes written. */
+/* </summary> */
+int cio_numbytes()
+{
+       return cio_bp - cio_start;
+}
+
+/* <summary> */
+/* Get position in byte stream. */
+/* </summary> */
+int cio_tell()
+{
+       return cio_bp - cio_start;
+}
+
+/* <summary> */
+/* Set position in byte stream. */
+/* </summary> */
+void cio_seek(int pos)
+{
+       cio_bp = cio_start + pos;
+}
+
+/* <summary> */
+/* Number of bytes left before the end of the stream. */
+/* </summary> */
+int cio_numbytesleft()
+{
+       return cio_end - cio_bp;
+}
+
+/* <summary> */
+/* Get pointer to the current position in the stream. */
+/* </summary> */
+unsigned char *cio_getbp()
+{
+       return cio_bp;
+}
+
+/* <summary> */
+/* Initialize byte IO. */
+/* </summary> */
+void cio_init(unsigned char *bp, int len)
+{
+       cio_start = bp;
+       cio_end = bp + len;
+       cio_bp = bp;
+}
+
+/* <summary> */
+/* Write a byte. */
+/* </summary> */
+void cio_byteout(unsigned char v)
+{
+       if (cio_bp >= cio_end)
+               longjmp(j2k_error, 1);
+       *cio_bp++ = v;
+
+}
+
+/* <summary> */
+/* Read a byte. */
+/* </summary> */
+unsigned char cio_bytein()
+{
+       if (cio_bp >= cio_end)
+               longjmp(j2k_error, 1);
+       return *cio_bp++;
+}
+
+/* <summary> */
+/* Write a byte. */
+/* </summary> */
+void cio_write(unsigned int v, int n)
+{
+       int i;
+       for (i = n - 1; i >= 0; i--) {
+               cio_byteout((unsigned char) ((v >> (i << 3)) & 0xff));
+       }
+}
+
+/* <summary> */
+/* Read some bytes. */
+/* </summary> */
+unsigned int cio_read(int n)
+{
+       int i;
+       unsigned int v;
+       v = 0;
+       for (i = n - 1; i >= 0; i--) {
+               v += cio_bytein() << (i << 3);
+       }
+       return v;
+}
+
+/* <summary> */
+/* Write some bytes. */
+/* </summary> */
+void cio_skip(int n)
+{
+       cio_bp += n;
+}
diff --git a/libopenjpeg/cio.h b/libopenjpeg/cio.h
new file mode 100644 (file)
index 0000000..c6945b7
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2001-2002, David Janssens
+ * 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
+
+int cio_tell();
+void cio_seek(int pos);
+int cio_numbytes();
+int cio_numbytesleft();
+unsigned char *cio_getbp();
+void cio_init(unsigned char *bp, int len);
+void cio_write(unsigned int v, int n);
+unsigned int cio_read(int n);
+void cio_skip(int n);
+
+#endif
diff --git a/libopenjpeg/dwt.c b/libopenjpeg/dwt.c
new file mode 100644 (file)
index 0000000..6722d9f
--- /dev/null
@@ -0,0 +1,681 @@
+/*
+ * Copyright (c) 2001-2002, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2002-2003,  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 "dwt.h"
+#include "int.h"
+#include "fix.h"
+#include "tcd.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+#define S(i) a[x*(i)*2]
+#define D(i) a[x*(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> */
+double dwt_norms[4][10] = {
+       {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}
+};
+
+/* <summary> */
+/* This table contains the norms of the 9-7 wavelets for different bands.  */
+/* </summary> */
+double dwt_norms_real[4][10] = {
+       {1.000, 1.965, 4.177, 8.403, 16.90, 33.84, 67.69, 135.3, 270.6, 540.9},
+       {2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0},
+       {2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0},
+       {2.080, 3.865, 8.307, 17.18, 34.71, 69.59, 139.3, 278.6, 557.2}
+};
+
+/* Add Patrick */
+static int *b = NULL;
+static int lastSizeOfB = 0;
+
+
+void dwt_clean()
+{
+       if (b != NULL) {
+               free(b);
+       }
+       b = NULL;
+       lastSizeOfB = 0;
+}
+
+/* \ Add Patrick */
+
+/* <summary> */
+/* Forward lazy transform. */
+/* </summary> */
+void dwt_deinterleave(int *a, int n, int x, int res, int cas)
+{
+       int dn, sn, i;
+       sn = res;
+       dn = n - res;
+       if (lastSizeOfB != n) {
+               if (b != NULL)
+                       free(b);
+               b = (int *) malloc(n * sizeof(int));
+               lastSizeOfB = n;
+       }
+
+       if (cas) {
+               for (i = 0; i < sn; i++)
+                       b[i] = a[(2 * i + 1) * x];
+               for (i = 0; i < dn; i++)
+                       b[sn + i] = a[2 * i * x];
+       } else {
+               for (i = 0; i < sn; i++)
+                       b[i] = a[2 * i * x];
+               for (i = 0; i < dn; i++)
+                       b[sn + i] = a[(2 * i + 1) * x];
+       }
+       for (i = 0; i < n; i++)
+               a[i * x] = b[i];
+}
+
+/* <summary> */
+/* Forward lazy transform. */
+/* </summary> */
+void dwt_deinterleave_real(int *a, int n, int x, int res, int cas)
+{
+       int dn, sn, i;
+       sn = res;
+       dn = n - res;
+
+       if (lastSizeOfB != n) {
+               if (b != NULL)
+                       free(b);
+               b = (int *) malloc(n * sizeof(int));
+               lastSizeOfB = n;
+       }
+
+       if (cas) {
+               for (i = 0; i < sn; i++)
+                       b[i] = a[(2 * i + 1) * x];
+               for (i = 0; i < dn; i++)
+                       b[sn + i] = a[2 * i * x];
+       } else {
+               for (i = 0; i < sn; i++)
+                       b[i] = a[2 * i * x];
+               for (i = 0; i < dn; i++)
+                       b[sn + i] = a[(2 * i + 1) * x];
+       }
+       for (i = 0; i < n; i++)
+               a[i * x] = b[i];
+
+}
+
+/* <summary> */
+/* Inverse lazy transform. */
+/* </summary> */
+void dwt_interleave(int *a, int n, int x, int res, int cas)
+{
+       int dn, sn, i;
+       sn = res;
+       dn = n - res;
+
+       if (lastSizeOfB != n) {
+               if (b != NULL)
+                       free(b);
+               b = (int *) malloc(n * sizeof(int));
+               lastSizeOfB = n;
+       }
+
+       if (cas) {
+               for (i = 0; i < sn; i++)
+                       b[2 * i + 1] = a[i * x];
+               for (i = 0; i < dn; i++)
+                       b[2 * i] = a[(sn + i) * x];
+       } else {
+               for (i = 0; i < sn; i++)
+                       b[2 * i] = a[i * x];
+               for (i = 0; i < dn; i++)
+                       b[2 * i + 1] = a[(sn + i) * x];
+       }
+       for (i = 0; i < n; i++)
+               a[i * x] = b[i];
+}
+
+/* <summary> */
+/* Inverse lazy transform. */
+/* </summary> */
+void dwt_interleave_real(int *a, int n, int x, int res, int cas)
+{
+       int dn, sn, i;
+       sn = res;
+       dn = n - res;
+
+       if (lastSizeOfB != n) {
+               if (b != NULL)
+                       free(b);
+               b = (int *) malloc(n * sizeof(int));
+               lastSizeOfB = n;
+       }
+
+       if (cas) {
+               for (i = 0; i < sn; i++)
+                       b[2 * i + 1] = a[i * x];
+               for (i = 0; i < dn; i++)
+                       b[2 * i] = a[(sn + i) * x];
+       } else {
+               for (i = 0; i < sn; i++)
+                       b[2 * i] = a[i * x];
+               for (i = 0; i < dn; i++)
+                       b[2 * i + 1] = a[(sn + i) * x];
+       }
+       for (i = 0; i < n; i++)
+               a[i * x] = b[i];
+
+}
+
+/* <summary> */
+/* Forward 5-3 wavelet tranform in 1-D. */
+/* </summary> */
+void dwt_encode_1(int *a, int n, int x, int res, int cas)
+{
+       int dn, sn, i = 0;
+       sn = res;
+       dn = n - res;
+
+       if (cas) {
+               if (!sn && dn == 1)                                     /* NEW :  CASE ONE ELEMENT */
+                       S(i) *= 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;
+               }
+       } else {
+               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;
+               }
+       }
+       dwt_deinterleave(a, n, x, res, cas);
+}
+
+/* <summary> */
+/* Inverse 5-3 wavelet tranform in 1-D. */
+/* </summary> */
+void dwt_decode_1(int *a, int n, int x, int res, int cas)
+{
+       int dn, sn, i = 0;
+       /* dn=n/2; */
+       /* sn=(n+1)/2; */
+       sn = res;
+       dn = n - res;
+
+       dwt_interleave(a, n, x, res, cas);
+       if (cas) {
+               if (!sn && dn == 1)                                     /* NEW :  CASE ONE ELEMENT */
+                       S(i) /= 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;
+               }
+       } else {
+               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;
+               }
+       }
+}
+
+/* <summary> */
+/* Forward 5-3 wavelet tranform in 2-D. */
+/* </summary> */
+void dwt_encode(int *a, int w, int h, tcd_tilecomp_t * tilec, int l)
+{
+       int i, j, rw, rh, rw1, rh1;
+       int previous_rw, previous_rh, previous_rw1, previous_rh1;
+
+       for (i = 0; i < l; i++) {
+               int cas_col = 0;
+               int cas_row = 0;
+               rw = tilec->resolutions[l - i].x1 - tilec->resolutions[l - i].x0;
+               rh = tilec->resolutions[l - i].y1 - tilec->resolutions[l - i].y0;
+               rw1 =
+                       tilec->resolutions[l - i - 1].x1 - tilec->resolutions[l - i - 1].x0;
+               rh1 =
+                       tilec->resolutions[l - i - 1].y1 - tilec->resolutions[l - i - 1].y0;
+
+               /* Check the different cases for that it's necessary to invert high pass and low pass filter */
+
+               if (tilec->previous_row) {
+                       previous_rw =
+                               tilec->resolutions[l - i].previous_x1 - tilec->resolutions[l -
+                                                                                                                                                                                                                                                                        i].
+                               previous_x0;
+                       previous_rw1 =
+                               tilec->resolutions[l - i - 1].previous_x1 - tilec->resolutions[l -
+                                                                                                                                                                                                                                                                                        i -
+                                                                                                                                                                                                                                                                                        1].
+                               previous_x0;
+                       /* inversion on the previous and propagation of the inversion on the other tile */
+                       if ((previous_rw1 > previous_rw - previous_rw1 && rw1 == rw - rw1)
+                                       || (tilec->resolutions[l - i - 1].cas_row
+                                                       && previous_rw1 == previous_rw - previous_rw1))
+                               cas_row = 1;
+               }
+
+               if (tilec->previous_col) {
+                       previous_rh =
+                               tilec->resolutions[l - i].previous_y1 - tilec->resolutions[l -
+                                                                                                                                                                                                                                                                        i].
+                               previous_y0;
+                       previous_rh1 =
+                               tilec->resolutions[l - i - 1].previous_y1 - tilec->resolutions[l -
+                                                                                                                                                                                                                                                                                        i -
+                                                                                                                                                                                                                                                                                        1].
+                               previous_y0;
+                       /* inversion on the previous and propagation of the inversion on the other tile */
+                       if ((previous_rh1 > previous_rh - previous_rh1 && rh1 == rh - rh1)
+                                       || (tilec->resolutions[l - i - 1].cas_col
+                                                       && previous_rh1 == previous_rh - previous_rh1))
+                               cas_col = 1;
+               }
+
+               /* subband LL shorter than LH or HL */
+               if (rw1 < rw - rw1)
+                       cas_row = 1;
+               if (rh1 < rh - rh1)
+                       cas_col = 1;
+
+               /* OFFSET IMAGE (If origin of the resolution is odd and first tile on the row or column) */
+               if (!tilec->previous_row && ((tilec->resolutions[l - i].x0 % 2) == 1))
+                       cas_row = 1;
+               if (!tilec->previous_col && ((tilec->resolutions[l - i].y0 % 2) == 1))
+                       cas_col = 1;
+
+               tilec->resolutions[l - i - 1].cas_row = cas_row;
+               tilec->resolutions[l - i - 1].cas_col = cas_col;
+
+               for (j = 0; j < rw; j++)
+                       dwt_encode_1(a + j, rh, w, rh1, cas_col);
+               for (j = 0; j < rh; j++)
+                       dwt_encode_1(a + j * w, rw, 1, rw1, cas_row);
+       }
+
+       dwt_clean();
+}
+
+/* <summary> */
+/* Inverse 5-3 wavelet tranform in 2-D. */
+/* </summary> */
+void dwt_decode(int *a, int w, int h, tcd_tilecomp_t * tilec, int l,
+                                                               tcd_tilecomp_t * row_tilec, tcd_tilecomp_t * col_tilec)
+{
+       int i, j, rw, rh, rw1, rh1;
+       int previous_rw, previous_rh, previous_rw1, previous_rh1;
+       for (i = l - 1; i >= 0; i--) {
+               int cas_col = 0;
+               int cas_row = 0;
+
+               rw = tilec->resolutions[l - i].x1 - tilec->resolutions[l - i].x0;
+               rh = tilec->resolutions[l - i].y1 - tilec->resolutions[l - i].y0;
+               rw1 =
+                       tilec->resolutions[l - i - 1].x1 - tilec->resolutions[l - i - 1].x0;
+               rh1 =
+                       tilec->resolutions[l - i - 1].y1 - tilec->resolutions[l - i - 1].y0;
+
+               if (tilec->previous_row) {
+                       previous_rw =
+                               tilec->resolutions[l - i].previous_x1 - tilec->resolutions[l -
+                                                                                                                                                                                                                                                                        i].
+                               previous_x0;
+                       previous_rw1 =
+                               tilec->resolutions[l - i - 1].previous_x1 - tilec->resolutions[l -
+                                                                                                                                                                                                                                                                                        i -
+                                                                                                                                                                                                                                                                                        1].
+                               previous_x0;
+                       if ((previous_rw1 > previous_rw - previous_rw1 && rw1 == rw - rw1)
+                                       || (row_tilec->resolutions[l - i - 1].cas_row
+                                                       && previous_rw1 == previous_rw - previous_rw1))
+                               cas_row = 1;
+               }
+
+               if (tilec->previous_col) {
+                       previous_rh =
+                               tilec->resolutions[l - i].previous_y1 - tilec->resolutions[l -
+                                                                                                                                                                                                                                                                        i].
+                               previous_y0;
+                       previous_rh1 =
+                               tilec->resolutions[l - i - 1].previous_y1 - tilec->resolutions[l -
+                                                                                                                                                                                                                                                                                        i -
+                                                                                                                                                                                                                                                                                        1].
+                               previous_y0;
+                       if ((previous_rh1 > previous_rh - previous_rh1 && rh1 == rh - rh1)
+                                       || (col_tilec->resolutions[l - i - 1].cas_col
+                                                       && previous_rh1 == previous_rh - previous_rh1))
+                               cas_col = 1;
+               }
+
+               if (rw1 < rw - rw1)
+                       cas_row = 1;
+               if (rh1 < rh - rh1)
+                       cas_col = 1;
+
+               /* OFFSET IMAGE (If origin of the resolution is odd and first tile on the row or column) */
+               if (!tilec->previous_row && ((tilec->resolutions[l - i].x0 % 2) == 1))
+                       cas_row = 1;
+               if (!tilec->previous_col && ((tilec->resolutions[l - i].y0 % 2) == 1))
+                       cas_col = 1;
+
+               tilec->resolutions[l - i - 1].cas_row = cas_row;
+               tilec->resolutions[l - i - 1].cas_col = cas_col;
+
+               for (j = 0; j < rh; j++)
+                       dwt_decode_1(a + j * w, rw, 1, rw1, cas_row);
+               for (j = 0; j < rw; j++)
+                       dwt_decode_1(a + j, rh, w, rh1, cas_col);
+       }
+       dwt_clean();
+}
+
+/* <summary> */
+/* Get gain of 5-3 wavelet transform. */
+/* </summary> */
+int dwt_getgain(int orient)
+{
+       if (orient == 0)
+               return 0;
+       if (orient == 1 || orient == 2)
+               return 1;
+       return 2;
+}
+
+/* <summary> */
+/* Get norm of 5-3 wavelet. */
+/* </summary> */
+double dwt_getnorm(int level, int orient)
+{
+       return dwt_norms[orient][level];
+}
+
+/* <summary> */
+/* Forward 9-7 wavelet transform in 1-D. */
+/* </summary> */
+void dwt_encode_1_real(int *a, int n, int x, int res, int cas)
+{
+       int dn, sn, i = 0;
+       dn = n - res;
+       sn = res;
+
+       if (cas) {
+               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);
+                       for (i = 0; i < sn; i++)
+                               D(i) = fix_mul(D(i), 6660);
+               }
+       } else {
+         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);
+                       for (i = 0; i < sn; i++)
+                               S(i) = fix_mul(S(i), 6660);
+               }
+       }
+       dwt_deinterleave_real(a, n, x, res, cas);
+}
+
+/* <summary> */
+/* Inverse 9-7 wavelet transform in 1-D. */
+/* </summary> */
+void dwt_decode_1_real(int *a, int n, int x, int res, int cas)
+{
+       int dn, sn, i = 0;
+       dn = n - res;
+       sn = res;
+       dwt_interleave_real(a, n, x, res, cas);
+       if (cas) {
+               if ((sn > 0) || (dn > 1)) {  /* NEW :  CASE ONE ELEMENT */
+                       for (i = 0; i < sn; i++)
+                               D(i) = fix_mul(D(i), 10076);
+                       for (i = 0; i < dn; i++)
+                               S(i) = fix_mul(S(i), 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), 12993);
+               }
+       } else {
+               if ((dn > 0) || (sn > 1)) {  /* NEW :  CASE ONE ELEMENT */
+                       for (i = 0; i < sn; i++)
+                               S(i) = fix_mul(S(i), 10076);
+                       for (i = 0; i < dn; i++)
+                               D(i) = fix_mul(D(i), 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), 12993);
+               }
+       }
+}
+
+/* <summary> */
+/* Forward 9-7 wavelet transform in 2-D. */
+/* </summary> */
+
+void dwt_encode_real(int *a, int w, int h, tcd_tilecomp_t * tilec, int l)
+{
+       int i, j, rw, rh, rw1, rh1;
+       int previous_rw, previous_rh, previous_rw1, previous_rh1;
+
+       for (i = 0; i < l; i++) {
+               int cas_col = 0;
+               int cas_row = 0;
+               rw = tilec->resolutions[l - i].x1 - tilec->resolutions[l - i].x0;
+               rh = tilec->resolutions[l - i].y1 - tilec->resolutions[l - i].y0;
+               rw1 =
+                       tilec->resolutions[l - i - 1].x1 - tilec->resolutions[l - i - 1].x0;
+               rh1 =
+                       tilec->resolutions[l - i - 1].y1 - tilec->resolutions[l - i - 1].y0;
+
+               if (tilec->previous_row) {
+                       previous_rw =
+                               tilec->resolutions[l - i].previous_x1 - tilec->resolutions[l -
+                                                                                                                                                                                                                                                                        i].
+                               previous_x0;
+                       previous_rw1 =
+                               tilec->resolutions[l - i - 1].previous_x1 - tilec->resolutions[l -
+                                                                                                                                                                                                                                                                                        i -
+                                                                                                                                                                                                                                                                                        1].
+                               previous_x0;
+                       if ((previous_rw1 > previous_rw - previous_rw1 && rw1 == rw - rw1)
+                                       || (tilec->resolutions[l - i - 1].cas_row
+                                                       && previous_rw1 == previous_rw - previous_rw1))
+                               cas_row = 1;
+               }
+
+               if (tilec->previous_col) {
+                       previous_rh =
+                               tilec->resolutions[l - i].previous_y1 - tilec->resolutions[l -
+                                                                                                                                                                                                                                                                        i].
+                               previous_y0;
+                       previous_rh1 =
+                               tilec->resolutions[l - i - 1].previous_y1 - tilec->resolutions[l -
+                                                                                                                                                                                                                                                                                        i -
+                                                                                                                                                                                                                                                                                        1].
+                               previous_y0;
+                       if ((previous_rh1 > previous_rh - previous_rh1 && rh1 == rh - rh1)
+                                       || (tilec->resolutions[l - i - 1].cas_col
+                                                       && previous_rh1 == previous_rh - previous_rh1))
+                               cas_col = 1;
+               }
+
+               if (rw1 < rw - rw1)
+                       cas_row = 1;
+               if (rh1 < rh - rh1)
+                       cas_col = 1;
+
+               /* OFFSET IMAGE (If origin of the resolution is odd and first tile on the row or column) */
+               if (!tilec->previous_row && ((tilec->resolutions[l - i].x0 % 2) == 1))
+                       cas_row = 1;
+               if (!tilec->previous_col && ((tilec->resolutions[l - i].y0 % 2) == 1))
+                       cas_col = 1;
+
+               tilec->resolutions[l - i - 1].cas_row = cas_row;
+               tilec->resolutions[l - i - 1].cas_col = cas_col;
+
+               for (j = 0; j < rw; j++)
+                       dwt_encode_1_real(a + j, rh, w, rh1, cas_col);
+               for (j = 0; j < rh; j++)
+                       dwt_encode_1_real(a + j * w, rw, 1, rw1, cas_row);
+       }
+}
+
+/* <summary> */
+/* Inverse 9-7 wavelet transform in 2-D. */
+/* </summary> */
+void dwt_decode_real(int *a, int w, int h, tcd_tilecomp_t * tilec, int l,
+                                                                                tcd_tilecomp_t * row_tilec,
+                                                                                tcd_tilecomp_t * col_tilec)
+{
+       int i, j, rw, rh, rw1, rh1;
+       int previous_rw, previous_rh, previous_rw1, previous_rh1;
+
+       for (i = l - 1; i >= 0; i--) {
+               int cas_col = 0;
+               int cas_row = 0;
+
+               rw = tilec->resolutions[l - i].x1 - tilec->resolutions[l - i].x0;
+               rh = tilec->resolutions[l - i].y1 - tilec->resolutions[l - i].y0;
+               rw1 =
+                       tilec->resolutions[l - i - 1].x1 - tilec->resolutions[l - i - 1].x0;
+               rh1 =
+                       tilec->resolutions[l - i - 1].y1 - tilec->resolutions[l - i - 1].y0;
+
+               if (tilec->previous_row) {
+                       previous_rw =
+                               tilec->resolutions[l - i].previous_x1 - tilec->resolutions[l -
+                                                                                                                                                                                                                                                                        i].
+                               previous_x0;
+                       previous_rw1 =
+                               tilec->resolutions[l - i - 1].previous_x1 - tilec->resolutions[l -
+                                                                                                                                                                                                                                                                                        i -
+                                                                                                                                                                                                                                                                                        1].
+                               previous_x0;
+                       if ((previous_rw1 > previous_rw - previous_rw1 && rw1 == rw - rw1)
+                                       || (row_tilec->resolutions[l - i - 1].cas_row
+                                                       && previous_rw1 == previous_rw - previous_rw1))
+                               cas_row = 1;
+               }
+
+               if (tilec->previous_col) {
+                       previous_rh =
+                               tilec->resolutions[l - i].previous_y1 - tilec->resolutions[l -
+                                                                                                                                                                                                                                                                        i].
+                               previous_y0;
+                       previous_rh1 =
+                               tilec->resolutions[l - i - 1].previous_y1 - tilec->resolutions[l -
+                                                                                                                                                                                                                                                                                        i -
+                                                                                                                                                                                                                                                                                        1].
+                               previous_y0;
+                       if ((previous_rh1 > previous_rh - previous_rh1 && rh1 == rh - rh1)
+                                       || (col_tilec->resolutions[l - i - 1].cas_col
+                                                       && previous_rh1 == previous_rh - previous_rh1))
+                               cas_col = 1;
+               }
+
+               if (rw1 < rw - rw1)
+                       cas_row = 1;
+               if (rh1 < rh - rh1)
+                       cas_col = 1;
+
+               /* OFFSET IMAGE (If origin of the resolution is odd and first tile on the row or column) */
+               if (!tilec->previous_row && ((tilec->resolutions[l - i].x0 % 2) == 1))
+                       cas_row = 1;
+               if (!tilec->previous_col && ((tilec->resolutions[l - i].y0 % 2) == 1))
+                       cas_col = 1;
+
+               tilec->resolutions[l - i - 1].cas_row = cas_row;
+               tilec->resolutions[l - i - 1].cas_col = cas_col;
+
+               for (j = 0; j < rh; j++)
+                       dwt_decode_1_real(a + j * w, rw, 1, rw1, cas_row);
+               for (j = 0; j < rw; j++)
+                       dwt_decode_1_real(a + j, rh, w, rh1, cas_col);
+       }
+}
+
+/* <summary> */
+/* Get gain of 9-7 wavelet transform. */
+/* </summary> */
+int dwt_getgain_real(int orient)
+{
+       return 0;
+}
+
+/* <summary> */
+/* Get norm of 9-7 wavelet. */
+/* </summary> */
+double dwt_getnorm_real(int level, int orient)
+{
+       return dwt_norms_real[orient][level];
+}
diff --git a/libopenjpeg/dwt.h b/libopenjpeg/dwt.h
new file mode 100644 (file)
index 0000000..60c671d
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2001-2002, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2002-2003,  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 "tcd.h"
+
+#ifndef __DWT_H
+#define __DWT_H
+
+/*
+ * Apply a reversible DWT transform to a component of an image  
+ * a: samples of the component
+ * w: width of the component
+ * h: height of the component
+ * l: number of decomposition levels in the DWT
+ */
+/* void dwt_encode(int* a, int w, int h, int l); */
+void dwt_encode(int *a, int w, int h, tcd_tilecomp_t * tilec, int l);
+/*
+ * Apply a reversible inverse DWT transform to a component of an image  
+ * a: samples of the component
+ * w: width of the component
+ * h: height of the component
+ * l: number of decomposition levels in the DWT
+ */
+void dwt_decode(int *a, int w, int h, tcd_tilecomp_t * tilec, int l,
+                                                               tcd_tilecomp_t * row_tilec, tcd_tilecomp_t * col_tilec);
+/* void dwt_decode(int* a, int w, int h,tcd_tilecomp_t *tilec, int l); */
+/*
+ * Get the gain of a subband for the reversible DWT
+ * orient: number that identifies the subband (0->LL, 1->HL, 2->LH, 3->HH)
+ */
+int dwt_getgain(int orient);
+
+/*
+ * Get the norm of a wavelet function of a subband at a specified level for the reversible DWT
+ * level: level of the wavelet function
+ * orient: band of the wavelet function
+ */
+double dwt_getnorm(int level, int orient);
+
+/*
+ * Apply an irreversible DWT transform to a component of an image  
+ * a: samples of the component
+ * w: width of the component
+ * h: height of the component
+ * l: number of decomposition levels in the DWT
+ */
+void dwt_encode_real(int *a, int w, int h, tcd_tilecomp_t * tilec, int l);
+
+/*
+ * Apply an irreversible inverse DWT transform to a component of an image  
+ * a: samples of the component
+ * w: width of the component
+ * h: height of the component
+ * l: number of decomposition levels in the DWT
+ */
+void dwt_decode_real(int *a, int w, int h, tcd_tilecomp_t * tilec, int l,
+                                                                                tcd_tilecomp_t * row_tilec,
+                                                                                tcd_tilecomp_t * col_tilec);
+/*
+ * Get the gain of a subband for the irreversible DWT
+ * orient: number that identifies the subband (0->LL, 1->HL, 2->LH, 3->HH)
+ */
+int dwt_getgain_real(int orient);
+
+/*
+ * Get the norm of a wavelet function of a subband at a specified level for the irreversible DWT
+ * level: level of the wavelet function
+ * orient: band of the wavelet function
+ */
+double dwt_getnorm_real(int level, int orient);
+
+#endif
diff --git a/libopenjpeg/fix.c b/libopenjpeg/fix.c
new file mode 100644 (file)
index 0000000..6a8a64b
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2001-2002, David Janssens
+ * 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 "fix.h"
+
+#ifdef DAVID_WIN32
+#define int64 __int64
+#else
+#define int64 long long
+#endif
+
+/* <summary> */
+/* Multiply two fixed-precision rational numbers. */
+/* </summary> */
+int fix_mul(int a, int b)
+{
+       return (int) ((int64) a * (int64) b >> 13);
+}
diff --git a/libopenjpeg/fix.h b/libopenjpeg/fix.h
new file mode 100644 (file)
index 0000000..768cada
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2001-2002, David Janssens
+ * 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
+
+int fix_mul(int a, int b);
+
+#endif
diff --git a/libopenjpeg/int.c b/libopenjpeg/int.c
new file mode 100644 (file)
index 0000000..21d7c47
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2001-2002, David Janssens
+ * 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.
+ */
+
+/* <summary> */
+/* Get the minimum of two integers. */
+/* </summary> */
+int int_min(int a, int b)
+{
+       return a < b ? a : b;
+}
+
+/* <summary> */
+/* Get the maximum of two integers. */
+/* </summary> */
+int int_max(int a, int b)
+{
+       return a > b ? a : b;
+}
+
+/* <summary> */
+/* Clamp an integer inside an interval. */
+/* </summary> */
+int int_clamp(int a, int min, int max)
+{
+       if (a < min)
+               return min;
+       if (a > max)
+               return max;
+       return a;
+}
+
+/* <summary> */
+/* Get absolute value of integer. */
+/* </summary> */
+int int_abs(int a)
+{
+       return a < 0 ? -a : a;
+}
+
+/* <summary> */
+/* Divide an integer and round upwards. */
+/* </summary> */
+int int_ceildiv(int a, int b)
+{
+       return (a + b - 1) / b;
+}
+
+/* <summary> */
+/* Divide an integer by a power of 2 and round upwards. */
+/* </summary> */
+int int_ceildivpow2(int a, int b)
+{
+       return (a + (1 << b) - 1) >> b;
+}
+
+/* <summary> */
+/* Divide an integer by a power of 2 and round downwards. */
+/* </summary> */
+int int_floordivpow2(int a, int b)
+{
+       return a >> b;
+}
+
+/* <summary> */
+/* Get logarithm of an integer and round downwards. */
+/* </summary> */
+int int_floorlog2(int a)
+{
+       int l;
+       for (l = 0; a > 1; l++) {
+               a >>= 1;
+       }
+       return l;
+}
diff --git a/libopenjpeg/int.h b/libopenjpeg/int.h
new file mode 100644 (file)
index 0000000..7b6fb87
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2001-2002, David Janssens
+ * 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
+
+int int_min(int a, int b);
+int int_max(int a, int b);
+int int_clamp(int a, int min, int max);
+int int_abs(int a);
+int int_ceildiv(int a, int b);
+int int_ceildivpow2(int a, int b);
+int int_floordivpow2(int a, int b);
+int int_floorlog2(int a);
+
+#endif
diff --git a/libopenjpeg/j2k.c b/libopenjpeg/j2k.c
new file mode 100644 (file)
index 0000000..830c4fe
--- /dev/null
@@ -0,0 +1,1153 @@
+/*
+ * Copyright (c) 2001-2002, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2002-2003,  Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <setjmp.h>
+#include <math.h>
+
+#include "j2k.h"
+#include "cio.h"
+#include "tcd.h"
+#include "dwt.h"
+#include "int.h"
+
+#define J2K_MS_SOC 0xff4f
+#define J2K_MS_SOT 0xff90
+#define J2K_MS_SOD 0xff93
+#define J2K_MS_EOC 0xffd9
+#define J2K_MS_SIZ 0xff51
+#define J2K_MS_COD 0xff52
+#define J2K_MS_COC 0xff53
+#define J2K_MS_RGN 0xff5e
+#define J2K_MS_QCD 0xff5c
+#define J2K_MS_QCC 0xff5d
+#define J2K_MS_POC 0xff5f
+#define J2K_MS_TLM 0xff55
+#define J2K_MS_PLM 0xff57
+#define J2K_MS_PLT 0xff58
+#define J2K_MS_PPM 0xff60
+#define J2K_MS_PPT 0xff61
+#define J2K_MS_SOP 0xff91
+#define J2K_MS_EPH 0xff92
+#define J2K_MS_CRG 0xff63
+#define J2K_MS_COM 0xff64
+
+#define J2K_STATE_MHSOC 0x0001
+#define J2K_STATE_MHSIZ 0x0002
+#define J2K_STATE_MH 0x0004
+#define J2K_STATE_TPHSOT 0x0008
+#define J2K_STATE_TPH 0x0010
+#define J2K_STATE_MT 0x0020
+#define J2K_STATE_NEOC 0x0040
+
+
+jmp_buf j2k_error;
+
+static int j2k_state;
+static int j2k_curtileno;
+static j2k_tcp_t j2k_default_tcp;
+static unsigned char *j2k_eot;
+static int j2k_sot_start;
+static int pos_correction;
+
+static j2k_image_t *j2k_img;
+static j2k_cp_t *j2k_cp;
+
+static unsigned char **j2k_tile_data;
+static int *j2k_tile_len;
+
+static info_image info_IM;
+
+/* Add Patrick */
+void j2k_clean()
+{
+       int tileno = 0;
+       tcd_free_encode(j2k_img, j2k_cp, j2k_curtileno);
+
+       if (info_IM.index_on) {
+               for (tileno = 0; tileno < j2k_cp->tw * j2k_cp->th; tileno++) {
+                       free(info_IM.tile[tileno].packet);
+               }
+               free(info_IM.tile);
+       }
+}
+
+/* \Add Patrick */
+
+void j2k_dump_image(j2k_image_t * img)
+{
+       int compno;
+       fprintf(stderr, "image {\n");
+       fprintf(stderr, "  x0=%d, y0=%d, x1=%d, y1=%d\n", img->x0, img->y0,
+                                       img->x1, img->y1);
+       fprintf(stderr, "  numcomps=%d\n", img->numcomps);
+       for (compno = 0; compno < img->numcomps; compno++) {
+               j2k_comp_t *comp = &img->comps[compno];
+               fprintf(stderr, "  comp %d {\n", compno);
+               fprintf(stderr, "    dx=%d, dy=%d\n", comp->dx, comp->dy);
+               fprintf(stderr, "    prec=%d\n", comp->prec);
+               fprintf(stderr, "    sgnd=%d\n", comp->sgnd);
+               fprintf(stderr, "  }\n");
+       }
+       fprintf(stderr, "}\n");
+}
+
+void j2k_dump_cp(j2k_image_t * img, j2k_cp_t * cp)
+{
+       int tileno, compno, layno, bandno, resno, numbands;
+       fprintf(stderr, "coding parameters {\n");
+       fprintf(stderr, "  tx0=%d, ty0=%d\n", cp->tx0, cp->ty0);
+       fprintf(stderr, "  tdx=%d, tdy=%d\n", cp->tdx, cp->tdy);
+       fprintf(stderr, "  tw=%d, th=%d\n", cp->tw, cp->th);
+       for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
+               j2k_tcp_t *tcp = &cp->tcps[tileno];
+               fprintf(stderr, "  tile %d {\n", tileno);
+               fprintf(stderr, "    csty=%x\n", tcp->csty);
+               fprintf(stderr, "    prg=%d\n", tcp->prg);
+               fprintf(stderr, "    numlayers=%d\n", tcp->numlayers);
+               fprintf(stderr, "    mct=%d\n", tcp->mct);
+               fprintf(stderr, "    rates=");
+               for (layno = 0; layno < tcp->numlayers; layno++) {
+                       fprintf(stderr, "%d ", tcp->rates[layno]);
+               }
+               fprintf(stderr, "\n");
+               for (compno = 0; compno < img->numcomps; compno++) {
+                       j2k_tccp_t *tccp = &tcp->tccps[compno];
+                       fprintf(stderr, "    comp %d {\n", compno);
+                       fprintf(stderr, "      csty=%x\n", tccp->csty);
+                       fprintf(stderr, "      numresolutions=%d\n", tccp->numresolutions);
+                       fprintf(stderr, "      cblkw=%d\n", tccp->cblkw);
+                       fprintf(stderr, "      cblkh=%d\n", tccp->cblkh);
+                       fprintf(stderr, "      cblksty=%x\n", tccp->cblksty);
+                       fprintf(stderr, "      qmfbid=%d\n", tccp->qmfbid);
+                       fprintf(stderr, "      qntsty=%d\n", tccp->qntsty);
+                       fprintf(stderr, "      numgbits=%d\n", tccp->numgbits);
+                       fprintf(stderr, "      roishift=%d\n", tccp->roishift);
+                       fprintf(stderr, "      stepsizes=");
+                       numbands =
+                               tccp->qntsty ==
+                               J2K_CCP_QNTSTY_SIQNT ? 1 : tccp->numresolutions * 3 - 2;
+                       for (bandno = 0; bandno < numbands; bandno++) {
+                               fprintf(stderr, "(%d,%d) ", tccp->stepsizes[bandno].mant,
+                                                               tccp->stepsizes[bandno].expn);
+                       }
+                       fprintf(stderr, "\n");
+
+                       if (tccp->csty & J2K_CCP_CSTY_PRT) {
+                               fprintf(stderr, "      prcw=");
+                               for (resno = 0; resno < tccp->numresolutions; resno++) {
+                                       fprintf(stderr, "%d ", tccp->prcw[resno]);
+                               }
+                               fprintf(stderr, "\n");
+                               fprintf(stderr, "      prch=");
+                               for (resno = 0; resno < tccp->numresolutions; resno++) {
+                                       fprintf(stderr, "%d ", tccp->prch[resno]);
+                               }
+                               fprintf(stderr, "\n");
+                       }
+                       fprintf(stderr, "    }\n");
+               }
+               fprintf(stderr, "  }\n");
+       }
+       fprintf(stderr, "}\n");
+}
+
+void j2k_write_soc()
+{
+       /* fprintf(stderr, "%.8x: SOC\n", cio_tell()); */
+       cio_write(J2K_MS_SOC, 2);
+}
+
+void j2k_read_soc()
+{
+       /* fprintf(stderr, "%.8x: SOC\n", cio_tell()-2); */
+       j2k_state = J2K_STATE_MHSIZ;
+}
+
+void j2k_write_siz()
+{
+       int i;
+       int lenp, len;
+       /* fprintf(stderr, "%.8x: SIZ\n", cio_tell()); */
+       cio_write(J2K_MS_SIZ, 2);                       /* SIZ */
+       lenp = cio_tell();
+       cio_skip(2);
+       cio_write(0, 2);                                                        /* Rsiz (capabilities) */
+       cio_write(j2k_img->x1, 4);              /* Xsiz */
+       cio_write(j2k_img->y1, 4);              /* Ysiz */
+       cio_write(j2k_img->x0, 4);              /* X0siz */
+       cio_write(j2k_img->y0, 4);              /* Y0siz */
+       cio_write(j2k_cp->tdx, 4);              /* XTsiz */
+       cio_write(j2k_cp->tdy, 4);              /* YTsiz */
+       cio_write(j2k_cp->tx0, 4);              /* XT0siz */
+       cio_write(j2k_cp->ty0, 4);              /* YT0siz */
+       cio_write(j2k_img->numcomps, 2);        /* Csiz */
+       for (i = 0; i < j2k_img->numcomps; i++) {
+               cio_write(j2k_img->comps[i].prec - 1 + (j2k_img->comps[i].sgnd << 7), 1);       /* Ssiz_i */
+               cio_write(j2k_img->comps[i].dx, 1);     /* XRsiz_i */
+               cio_write(j2k_img->comps[i].dy, 1);     /* YRsiz_i */
+       }
+       len = cio_tell() - lenp;
+       cio_seek(lenp);
+       cio_write(len, 2);                                              /* Lsiz  */
+       cio_seek(lenp + len);
+}
+
+void j2k_read_siz()
+{
+       int len, i;
+       /* fprintf(stderr, "%.8x: SIZ\n", cio_tell()); */
+       len = cio_read(2);
+       cio_read(2);
+       j2k_img->x1 = cio_read(4);
+       j2k_img->y1 = cio_read(4);
+       j2k_img->x0 = cio_read(4);
+       j2k_img->y0 = cio_read(4);
+       j2k_cp->tdx = cio_read(4);
+       j2k_cp->tdy = cio_read(4);
+       j2k_cp->tx0 = cio_read(4);
+       j2k_cp->ty0 = cio_read(4);
+
+       j2k_img->numcomps = cio_read(2);
+       j2k_img->comps =
+               (j2k_comp_t *) malloc(j2k_img->numcomps * sizeof(j2k_comp_t));
+       for (i = 0; i < j2k_img->numcomps; i++) {
+               int tmp, w, h;
+               tmp = cio_read(1);
+               j2k_img->comps[i].prec = (tmp & 0x7f) + 1;
+               j2k_img->comps[i].sgnd = tmp >> 7;
+               j2k_img->comps[i].dx = cio_read(1);
+               j2k_img->comps[i].dy = cio_read(1);
+               w = int_ceildiv(j2k_img->x1 - j2k_img->x0, j2k_img->comps[i].dx);
+               h = int_ceildiv(j2k_img->y1 - j2k_img->y0, j2k_img->comps[i].dy);
+               j2k_img->comps[i].data = (int *) malloc(sizeof(int) * w * h);
+       }
+
+       j2k_cp->tw = int_ceildiv(j2k_img->x1 - j2k_cp->tx0, j2k_cp->tdx);
+       j2k_cp->th = int_ceildiv(j2k_img->y1 - j2k_cp->ty0, j2k_cp->tdy);
+       j2k_cp->tcps =
+               (j2k_tcp_t *) calloc(sizeof(j2k_tcp_t), j2k_cp->tw * j2k_cp->th);
+       j2k_default_tcp.tccps =
+               (j2k_tccp_t *) calloc(sizeof(j2k_tccp_t), j2k_img->numcomps);
+       for (i = 0; i < j2k_cp->tw * j2k_cp->th; i++) {
+               j2k_cp->tcps[i].tccps =
+                       (j2k_tccp_t *) calloc(sizeof(j2k_tccp_t), j2k_img->numcomps);
+       }
+       j2k_tile_data =
+               (unsigned char **) calloc(j2k_cp->tw * j2k_cp->th, sizeof(char *));
+       j2k_tile_len = (int *) calloc(j2k_cp->tw * j2k_cp->th, sizeof(int));
+       j2k_state = J2K_STATE_MH;
+}
+
+void j2k_write_com()
+{
+       unsigned int i;
+       int lenp, len;
+       char str[256];
+       sprintf(str, "%s", j2k_cp->comment);
+       /* fprintf(stderr, "%.8x: COM\n", cio_tell()); */
+       cio_write(J2K_MS_COM, 2);
+       lenp = cio_tell();
+       cio_skip(2);
+       cio_write(0, 2);
+       for (i = 0; i < strlen(str); i++) {
+               cio_write(str[i], 1);
+       }
+       len = cio_tell() - lenp;
+       cio_seek(lenp);
+       cio_write(len, 2);
+       cio_seek(lenp + len);
+
+}
+
+void j2k_read_com()
+{
+       int len;
+       /* fprintf(stderr, "%.8x: COM\n", cio_tell()-2); */
+       len = cio_read(2);
+       cio_skip(len - 2);
+}
+
+void j2k_write_cox(int compno)
+{
+       int i;
+       j2k_tcp_t *tcp;
+       j2k_tccp_t *tccp;
+       tcp = &j2k_cp->tcps[j2k_curtileno];
+       tccp = &tcp->tccps[compno];
+       cio_write(tccp->numresolutions - 1, 1); /* SPcox (D) */
+       cio_write(tccp->cblkw - 2, 1);  /* SPcox (E) */
+       cio_write(tccp->cblkh - 2, 1);  /* SPcox (F) */
+       cio_write(tccp->cblksty, 1);    /* SPcox (G) */
+       cio_write(tccp->qmfbid, 1);             /* SPcox (H) */
+       if (tccp->csty & J2K_CCP_CSTY_PRT) {
+               for (i = 0; i < tccp->numresolutions; i++) {
+                       cio_write(tccp->prcw[i] + (tccp->prch[i] << 4), 1);     /* SPcox (I_i) */
+               }
+       }
+}
+
+void j2k_read_cox(int compno)
+{
+       int i;
+       j2k_tcp_t *tcp;
+       j2k_tccp_t *tccp;
+       tcp =
+               j2k_state ==
+               J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp;
+       tccp = &tcp->tccps[compno];
+       tccp->numresolutions = cio_read(1) + 1;
+       tccp->cblkw = cio_read(1) + 2;
+       tccp->cblkh = cio_read(1) + 2;
+       tccp->cblksty = cio_read(1);
+       tccp->qmfbid = cio_read(1);
+       if (tccp->csty & J2K_CP_CSTY_PRT) {
+               for (i = 0; i < tccp->numresolutions; i++) {
+                       int tmp = cio_read(1);
+                       tccp->prcw[i] = tmp & 0xf;
+                       tccp->prch[i] = tmp >> 4;
+               }
+       }
+}
+
+void j2k_write_cod()
+{
+       j2k_tcp_t *tcp;
+       int lenp, len;
+       /* fprintf(stderr, "%.8x: COD\n", cio_tell()+pos_correction); */
+       cio_write(J2K_MS_COD, 2);                       /* COD */
+       lenp = cio_tell();
+       cio_skip(2);
+       tcp = &j2k_cp->tcps[j2k_curtileno];
+       cio_write(tcp->csty, 1);                        /* Scod */
+       cio_write(tcp->prg, 1);                         /* SGcod (A) */
+       cio_write(tcp->numlayers, 2);   /* SGcod (B) */
+       cio_write(tcp->mct, 1);                         /* SGcod (C) */
+       j2k_write_cox(0);
+       len = cio_tell() - lenp;
+       cio_seek(lenp);
+       cio_write(len, 2);                                              /* Lcod */
+       cio_seek(lenp + len);
+}
+
+void j2k_read_cod()
+{
+       int len, i, pos;
+       j2k_tcp_t *tcp;
+       /* fprintf(stderr, "%.8x: COD\n", cio_tell()-2); */
+       tcp =
+               j2k_state ==
+               J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp;
+       len = cio_read(2);
+       tcp->csty = cio_read(1);
+       tcp->prg = cio_read(1);
+       tcp->numlayers = cio_read(2);
+       tcp->mct = cio_read(1);
+       pos = cio_tell();
+       for (i = 0; i < j2k_img->numcomps; i++) {
+               tcp->tccps[i].csty = tcp->csty & J2K_CP_CSTY_PRT;
+               cio_seek(pos);
+               j2k_read_cox(i);
+       }
+}
+
+void j2k_write_coc(int compno)
+{
+       j2k_tcp_t *tcp;
+       int lenp, len;
+       /* fprintf(stderr, "%.8x: COC\n", cio_tell()+pos_correction); */
+       cio_write(J2K_MS_COC, 2);                       /* COC */
+       lenp = cio_tell();
+       cio_skip(2);
+       tcp = &j2k_cp->tcps[j2k_curtileno];
+       cio_write(compno, j2k_img->numcomps <= 256 ? 1 : 2);    /* Ccoc */
+       cio_write(tcp->tccps[compno].csty, 1);  /* Scoc */
+       j2k_write_cox(compno);
+       len = cio_tell() - lenp;
+       cio_seek(lenp);
+       cio_write(len, 2);                                              /* Lcoc */
+       cio_seek(lenp + len);
+}
+
+void j2k_read_coc()
+{
+       int len, compno;
+       j2k_tcp_t *tcp;
+       /* fprintf(stderr, "%.8x: COC\n", cio_tell()); */
+       tcp =
+               j2k_state ==
+               J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp;
+       len = cio_read(2);
+       compno = cio_read(j2k_img->numcomps <= 256 ? 1 : 2);
+       tcp->tccps[compno].csty = cio_read(1);
+       j2k_read_cox(compno);
+}
+
+void j2k_write_qcx(int compno)
+{
+       j2k_tcp_t *tcp;
+       j2k_tccp_t *tccp;
+       int bandno, numbands;
+       int expn, mant;
+       tcp = &j2k_cp->tcps[j2k_curtileno];
+       tccp = &tcp->tccps[compno];
+
+       cio_write(tccp->qntsty + (tccp->numgbits << 5), 1);     /* Sqcx */
+       numbands =
+               tccp->qntsty ==
+               J2K_CCP_QNTSTY_SIQNT ? 1 : tccp->numresolutions * 3 - 2;
+
+       for (bandno = 0; bandno < numbands; bandno++) {
+               expn = tccp->stepsizes[bandno].expn;
+               mant = tccp->stepsizes[bandno].mant;
+
+               if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) {
+                       cio_write(expn << 3, 1);        /* SPqcx_i */
+               } else {
+                       cio_write((expn << 11) + mant, 2);      /* SPqcx_i */
+               }
+       }
+
+}
+
+void j2k_read_qcx(int compno, int len)
+{
+       int tmp;
+       j2k_tcp_t *tcp;
+       j2k_tccp_t *tccp;
+       int bandno, numbands;
+       tcp =
+               j2k_state ==
+               J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp;
+       tccp = &tcp->tccps[compno];
+       tmp = cio_read(1);
+       tccp->qntsty = tmp & 0x1f;
+       tccp->numgbits = tmp >> 5;
+       numbands =
+               tccp->qntsty == J2K_CCP_QNTSTY_SIQNT ? 1 : (tccp->qntsty ==
+                                                                                                                                                                                               J2K_CCP_QNTSTY_NOQNT ? len
+                                                                                                                                                                                               - 1 : (len - 1) / 2);
+       for (bandno = 0; bandno < numbands; bandno++) {
+               int expn, mant;
+               if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) {     /* WHY STEPSIZES WHEN NOQNT ? */
+                       expn = cio_read(1) >> 3;
+                       mant = 0;
+               } else {
+                       tmp = cio_read(2);
+                       expn = tmp >> 11;
+                       mant = tmp & 0x7ff;
+               }
+               tccp->stepsizes[bandno].expn = expn;
+               tccp->stepsizes[bandno].mant = mant;
+       }
+}
+
+void j2k_write_qcd()
+{
+       int lenp, len;
+       /* fprintf(stderr, "%.8x: QCD\n", cio_tell()+pos_correction); */
+       cio_write(J2K_MS_QCD, 2);                       /* QCD */
+       lenp = cio_tell();
+       cio_skip(2);
+       j2k_write_qcx(0);
+       len = cio_tell() - lenp;
+       cio_seek(lenp);
+       cio_write(len, 2);                                              /* Lqcd */
+       cio_seek(lenp + len);
+}
+
+void j2k_read_qcd()
+{
+       int len, i, pos;
+       /* fprintf(stderr, "%.8x: QCD\n", cio_tell()-2); */
+       len = cio_read(2);
+       pos = cio_tell();
+       for (i = 0; i < j2k_img->numcomps; i++) {
+               cio_seek(pos);
+               j2k_read_qcx(i, len - 2);
+       }
+}
+
+void j2k_write_qcc(int compno)
+{
+       int lenp, len;
+       /* fprintf(stderr, "%.8x: QCC\n", cio_tell()+pos_correction); */
+       cio_write(J2K_MS_QCC, 2);
+       lenp = cio_tell();
+       cio_skip(2);
+       cio_write(compno, j2k_img->numcomps <= 256 ? 1 : 2);
+       j2k_write_qcx(compno);
+       len = cio_tell() - lenp;
+       cio_seek(lenp);
+       cio_write(len, 2);
+       cio_seek(lenp + len);
+}
+
+void j2k_read_qcc()
+{
+       int len, compno;
+       /* fprintf(stderr, "%.8x: QCC\n", cio_tell()-2); */
+       len = cio_read(2);
+       compno = cio_read(j2k_img->numcomps <= 256 ? 1 : 2);
+       j2k_read_qcx(compno, len - 2 - (j2k_img->numcomps <= 256 ? 1 : 2));
+}
+
+void j2k_write_poc()
+{
+       int len, numpchgs, i;
+       j2k_tcp_t *tcp;
+       fprintf(stderr, "%.8x: POC\n", cio_tell() + pos_correction);
+       tcp = &j2k_cp->tcps[j2k_curtileno];
+       numpchgs = tcp->numpocs;
+       cio_write(J2K_MS_POC, 2);
+       len = 2 + (5 + 2 * (j2k_img->numcomps <= 256 ? 1 : 2)) * numpchgs;
+       cio_write(len, 2);
+       for (i = 0; i < numpchgs; i++) {
+               j2k_poc_t *poc;
+               poc = &tcp->pocs[i];
+               cio_write(poc->resno0, 1);
+               cio_write(poc->compno0, (j2k_img->numcomps <= 256 ? 1 : 2));
+               cio_write(poc->layno1, 2);
+               cio_write(poc->resno1, 1);
+               cio_write(poc->compno1, (j2k_img->numcomps <= 256 ? 1 : 2));
+               cio_write(poc->prg, 1);
+       }
+}
+
+void j2k_read_poc()
+{
+       int len, numpchgs, i;
+       j2k_tcp_t *tcp;
+       fprintf(stderr,
+                                       "WARNING: POC marker segment processing not fully implemented %d\n",
+                                       j2k_curtileno);
+       tcp =
+               j2k_state ==
+               J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp;
+       len = cio_read(2);
+       numpchgs = (len - 2) / (5 + 2 * (j2k_img->numcomps <= 256 ? 1 : 2));
+       for (i = 0; i < numpchgs; i++) {
+               j2k_poc_t *poc;
+               poc = &tcp->pocs[i];
+               poc->resno0 = cio_read(1);
+               poc->compno0 = cio_read(j2k_img->numcomps <= 256 ? 1 : 2);
+               poc->layno1 = cio_read(2);
+               poc->resno1 = cio_read(1);
+               poc->compno1 = cio_read(j2k_img->numcomps <= 256 ? 1 : 2);
+               poc->prg = cio_read(1);
+       }
+       tcp->numpocs = numpchgs;
+}
+
+void j2k_read_crg()
+{
+       int len;
+       len = cio_read(2);
+       fprintf(stderr,
+                                       "WARNING: CRG marker segment processing not implemented\n");
+       cio_skip(len - 2);
+}
+
+void j2k_read_tlm()
+{
+       int len;
+       len = cio_read(2);
+       fprintf(stderr,
+                                       "WARNING: TLM marker segment processing not implemented\n");
+       cio_skip(len - 2);
+}
+
+void j2k_read_plm()
+{
+       int len;
+       len = cio_read(2);
+       fprintf(stderr,
+                                       "WARNING: PLM marker segment processing not implemented\n");
+       cio_skip(len - 2);
+}
+
+void j2k_read_plt()
+{
+       int len;
+       len = cio_read(2);
+       fprintf(stderr,
+                                       "WARNING: PLT marker segment processing not implemented\n");
+       cio_skip(len - 2);
+}
+
+void j2k_read_ppm()
+{
+       int len;
+       len = cio_read(2);
+       fprintf(stderr,
+                                       "WARNING: PPM marker segment processing not implemented\n");
+       cio_skip(len - 2);
+}
+
+void j2k_read_ppt()
+{
+       int len;
+       len = cio_read(2);
+       fprintf(stderr,
+                                       "WARNING: PPT marker segment processing not implemented\n");
+       cio_skip(len - 2);
+}
+
+void j2k_write_sot()
+{
+       int lenp, len;
+       /* fprintf(stderr, "%.8x: SOT\n", cio_tell()+pos_correction); */
+       j2k_sot_start = cio_tell();
+       cio_write(J2K_MS_SOT, 2);                       /* SOT */
+       lenp = cio_tell();
+       cio_skip(2);                                                                    /* Lsot (further) */
+       cio_write(j2k_curtileno, 2);    /* Isot */
+       cio_skip(4);                                                                    /* Psot (further in j2k_write_sod) */
+       cio_write(0, 1);                                                        /* TPsot */
+       cio_write(1, 1);                                                        /* TNsot */
+       len = cio_tell() - lenp;
+       cio_seek(lenp);
+       cio_write(len, 2);                                              /* Lsot */
+       cio_seek(lenp + len);
+}
+
+void j2k_read_sot()
+{
+       int len, tileno, totlen, partno, numparts, i;
+       j2k_tcp_t *tcp;
+       j2k_tccp_t *tmp;
+       /* fprintf(stderr, "%.8x: SOT\n", cio_tell()-2); */
+       len = cio_read(2);
+       tileno = cio_read(2);
+       totlen = cio_read(4);
+       if (!totlen)
+               totlen = cio_numbytesleft() + 8;
+
+       partno = cio_read(1);
+       numparts = cio_read(1);
+       j2k_curtileno = tileno;
+       j2k_eot = cio_getbp() - 12 + totlen;
+       j2k_state = J2K_STATE_TPH;
+       tcp = &j2k_cp->tcps[j2k_curtileno];
+       tmp = tcp->tccps;
+       *tcp = j2k_default_tcp;
+       tcp->tccps = tmp;
+       for (i = 0; i < j2k_img->numcomps; i++) {
+               tcp->tccps[i] = j2k_default_tcp.tccps[i];
+       }
+}
+
+void j2k_write_sod()
+{
+       int l, layno;
+       int totlen;
+       j2k_tcp_t *tcp;
+       static int j2k_sod_start;
+
+       /* fprintf(stderr, "%.8x: SOD\n", cio_tell()+pos_correction); */
+       cio_write(J2K_MS_SOD, 2);
+       if (j2k_curtileno == 0) {
+               j2k_sod_start = cio_tell() + pos_correction;
+       }
+
+       /* INDEX >> */
+       if (info_IM.index_on) {
+               info_IM.tile[j2k_curtileno].end_header =
+                       cio_tell() + pos_correction - 1;
+               info_IM.tile[j2k_curtileno].packet =
+                       (info_packet *) malloc(info_IM.Comp * info_IM.Layer *
+                                                                                                                (info_IM.Decomposition +
+                                                                                                                       1) * 100 * sizeof(info_packet));
+       }
+       /* << INDEX */
+
+       tcp = &j2k_cp->tcps[j2k_curtileno];
+       for (layno = 0; layno < tcp->numlayers; layno++) {
+               tcp->rates[layno] -= (j2k_sod_start / (j2k_cp->th * j2k_cp->tw));
+               /* fprintf(stderr, "tcp->rates[%d]=%d\n", layno, tcp->rates[layno]); */
+       }
+
+       info_IM.num = 0;
+       if (j2k_cp->image_type)
+               l =
+                       tcd_encode_tile_pxm(j2k_curtileno, cio_getbp(),
+                                                                                                       cio_numbytesleft() - 2, &info_IM);
+       else
+               l =
+                       tcd_encode_tile_pgx(j2k_curtileno, cio_getbp(),
+                                                                                                       cio_numbytesleft() - 2, &info_IM);
+
+       /* Writing Psot in SOT marker */
+       totlen = cio_tell() + l - j2k_sot_start;
+       cio_seek(j2k_sot_start + 6);
+       cio_write(totlen, 4);
+       cio_seek(j2k_sot_start + totlen);
+}
+
+void j2k_read_sod()
+{
+       int len, truncate = 0;
+       unsigned char *data;
+
+       /* fprintf(stderr, "%.8x: SOD\n", cio_tell()-2); */
+       len = int_min(j2k_eot - cio_getbp(), cio_numbytesleft() + 1);
+       if (len == cio_numbytesleft() + 1)
+               truncate = 1;                                                           /* Case of a truncate codestream */
+
+       j2k_tile_len[j2k_curtileno] += len;
+       data =
+               (unsigned char *) realloc(j2k_tile_data[j2k_curtileno],
+                                                                                                                       j2k_tile_len[j2k_curtileno]);
+       memcpy(data, cio_getbp(), len);
+       j2k_tile_data[j2k_curtileno] = data;
+
+       cio_skip(len);
+
+       if (!truncate)
+               j2k_state = J2K_STATE_TPHSOT;
+       else
+               j2k_state = J2K_STATE_NEOC;     /* RAJOUTE !! */
+}
+
+void j2k_write_rgn(int compno, int tileno)
+{
+       j2k_tcp_t *tcp = &j2k_cp->tcps[tileno];
+       /* fprintf(stderr, "%.8x: RGN\n",cio_tell()+pos_correction); */
+       cio_write(J2K_MS_RGN, 2);                       /* RGN */
+       cio_write(j2k_img->numcomps <= 256 ? 5 : 6, 2); /* Lrgn */
+       cio_write(compno, j2k_img->numcomps <= 256 ? 1 : 2);    /* Crgn */
+       cio_write(0, 1);                                                        /* Srgn */
+       cio_write(tcp->tccps[compno].roishift, 1);      /* SPrgn */
+}
+
+void j2k_read_rgn()
+{
+       int len, compno, roisty;
+       j2k_tcp_t *tcp;
+       fprintf(stderr, "%.8x: RGN\n", cio_tell() - 2);
+       tcp =
+               j2k_state ==
+               J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp;
+       len = cio_read(2);
+       compno = cio_read(j2k_img->numcomps <= 256 ? 1 : 2);
+       roisty = cio_read(1);
+       tcp->tccps[compno].roishift = cio_read(1);
+}
+
+void j2k_write_eoc()
+{
+       fprintf(stderr, "%.8x: EOC\n", cio_tell() + pos_correction);
+       cio_write(J2K_MS_EOC, 2);
+}
+
+void j2k_read_eoc()
+{
+       int tileno;
+       /* fprintf(stderr, "%.8x: EOC\n", cio_tell()-2); */
+       /* j2k_dump_image(j2k_img); */
+       /* j2k_dump_cp(j2k_img, j2k_cp); */
+
+       tcd_init(j2k_img, j2k_cp);
+       for (tileno = 0; tileno < j2k_cp->tw * j2k_cp->th; tileno++) {
+               tcd_decode_tile(j2k_tile_data[tileno], j2k_tile_len[tileno], tileno);
+       }
+
+       j2k_state = J2K_STATE_MT;
+       longjmp(j2k_error, 1);
+
+}
+
+void j2k_read_unk()
+{
+       fprintf(stderr, "warning: unknown marker\n");
+}
+
+LIBJ2K_API int j2k_encode(j2k_image_t * img, j2k_cp_t * cp, char *outfile,
+                                                                                                       int len, char *index)
+{
+
+
+       int tileno, compno, layno, resno, precno, pack_nb;
+       char *dest;
+       FILE *INDEX;
+       FILE *f;
+
+       if (setjmp(j2k_error)) {
+               return 0;
+       }
+
+       f = fopen(outfile, "wb");
+
+       if (!f) {
+               fprintf(stderr, "failed to open %s for writing\n", outfile);
+               return 1;
+       }
+
+       dest = (char *) malloc(len);
+       cio_init(dest, len);
+
+       j2k_img = img;
+       j2k_cp = cp;
+       /* j2k_dump_cp(j2k_img, j2k_cp); */
+
+       /* INDEX >> */
+       info_IM.index_on = j2k_img->index_on;
+       if (info_IM.index_on) {
+               info_IM.tile =
+                       (info_tile *) malloc(j2k_cp->tw * j2k_cp->th * sizeof(info_tile));
+               info_IM.Im_w = j2k_img->x1 - j2k_img->x0;
+               info_IM.Im_h = j2k_img->y1 - j2k_img->y0;
+               info_IM.Prog = (&j2k_cp->tcps[0])->prg;
+               /* info_IM.Tile_x=j2k_cp->tw; old version parser */
+               /* info_IM.Tile_y=j2k_cp->th; old version parser */
+               info_IM.Tile_x = j2k_cp->tdx;   /* new version parser */
+               info_IM.Tile_y = j2k_cp->tdy;   /* new version parser */
+               info_IM.Comp = j2k_img->numcomps;
+               info_IM.Layer = (&j2k_cp->tcps[0])->numlayers;
+               info_IM.Decomposition = (&j2k_cp->tcps[0])->tccps->numresolutions - 1;
+               info_IM.D_max = 0;                                      /* ADD Marcela */
+       }
+       /* << INDEX */
+
+       j2k_write_soc();
+       j2k_write_siz();
+       j2k_write_cod();
+       j2k_write_qcd();
+
+       for (compno = 0; compno < j2k_img->numcomps; compno++) {
+               j2k_tcp_t *tcp = &j2k_cp->tcps[0];
+               if (tcp->tccps[compno].roishift)
+                       j2k_write_rgn(compno, 0);
+       }
+       if (j2k_cp->comment != NULL)
+               j2k_write_com();
+
+       /* Writing the main header */
+       pos_correction = cio_tell();
+       fwrite(dest, 1, cio_tell(), f);
+
+       /* INDEX >> */
+       if (info_IM.index_on) {
+               info_IM.Main_head_end = cio_tell() - 1;
+       }
+       /* << INDEX */
+
+       for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
+               fprintf(stderr, "\nTile number %d / %d \n", tileno + 1,
+                                               cp->tw * cp->th);
+
+               /* new dest for each tile  */
+               free(dest);
+               dest = (char *) malloc(len);
+               cio_init(dest, len);
+               j2k_curtileno = tileno;
+               /* initialisation before tile encoding  */
+
+               if (tileno == 0) {
+                       tcd_malloc_encode(j2k_img, j2k_cp, j2k_curtileno);
+               } else {
+                       tcd_init_encode(j2k_img, j2k_cp, j2k_curtileno);
+               }
+
+               /* INDEX >> */
+               if (info_IM.index_on) {
+                       info_IM.tile[j2k_curtileno].num_tile = j2k_curtileno;
+                       info_IM.tile[j2k_curtileno].start_pos = cio_tell() + pos_correction;
+               }
+               /* << INDEX */
+               j2k_write_sot();
+
+               for (compno = 1; compno < img->numcomps; compno++) {
+                       j2k_write_coc(compno);
+                       j2k_write_qcc(compno);
+               }
+
+               if (cp->tcps[tileno].numpocs)
+                       j2k_write_poc();
+               j2k_write_sod();
+
+               /* INDEX >> */
+               if (info_IM.index_on) {
+                       info_IM.tile[j2k_curtileno].end_pos =
+                               cio_tell() + pos_correction - 1;
+               }
+               /* << INDEX */
+
+               /*
+                  if (tile->PPT)  BAD PPT !!!
+                  {
+                  FILE *PPT_file;
+
+                  int i;
+                  PPT_file=fopen("PPT","rb");
+                  fprintf(stderr,"%c%c%c%c",255,97,tile->len_ppt/256,tile->len_ppt%256);
+                  for (i=0;i<tile->len_ppt;i++)
+                  {
+                  unsigned char elmt;
+                  fread(&elmt, 1, 1, PPT_file);
+                  fwrite(&elmt,1,1,f);
+                  }
+                  fclose(PPT_file);
+                  unlink("PPT");
+                  }
+                */
+
+               fwrite(dest, 1, cio_tell(), f);
+               pos_correction = cio_tell() + pos_correction;
+       }
+
+       free(dest);
+       dest = (char *) malloc(len);
+       cio_init(dest, len);
+
+       j2k_write_eoc();
+
+       fwrite(dest, 1, 2, f);
+       free(dest);
+       /* closing file *.j2k */
+       fclose(f);
+
+       /* Creation of the index file     */
+       if (info_IM.index_on) {
+               info_IM.codestream_size = cio_tell() + pos_correction;  /* Correction 14/4/03 suite rmq de Patrick */
+               INDEX = fopen(index, "w");
+
+               if (!INDEX) {
+                       fprintf(stderr, "failed to open %s for writing\n", index);
+                       return 1;
+               }
+
+               fprintf(INDEX, "%d %d\n", info_IM.Im_w, info_IM.Im_h);
+               fprintf(INDEX, "%d\n", info_IM.Prog);
+               fprintf(INDEX, "%d %d\n", info_IM.Tile_x, info_IM.Tile_y);
+               fprintf(INDEX, "%d\n", info_IM.Comp);
+               fprintf(INDEX, "%d\n", info_IM.Layer);
+               fprintf(INDEX, "%d\n", info_IM.Decomposition);
+               fprintf(INDEX, "%d %d\n", info_IM.pdx, info_IM.pdy);
+               fprintf(INDEX, "%d\n", info_IM.Main_head_end);
+               fprintf(INDEX, "%d\n", info_IM.codestream_size);
+
+               for (tileno = 0; tileno < j2k_cp->tw * j2k_cp->th; tileno++) {
+                       fprintf(INDEX, "%d %d %d %d\n", info_IM.tile[tileno].num_tile,
+                                                       info_IM.tile[tileno].start_pos,
+                                                       info_IM.tile[tileno].end_header,
+                                                       info_IM.tile[tileno].end_pos);
+               }
+               for (tileno = 0; tileno < j2k_cp->tw * j2k_cp->th; tileno++) {
+                       pack_nb = 0;
+                       if (info_IM.Prog == 0) {        /* LRCP */
+                               for (layno = 0; layno < info_IM.Layer; layno++) {
+                                       for (resno = 0; resno < info_IM.Decomposition + 1; resno++) {
+                                               for (compno = 0; compno < info_IM.Comp; compno++) {
+                                                       for (precno = 0;
+                                                                        precno <
+                                                                        info_IM.tile[tileno].pw * info_IM.tile[tileno].ph;
+                                                                        precno++) {
+                                                               /* fprintf(INDEX,"%d %d %d %d %d %d %d %d %.04f\n",pack_nb,tileno,layno,resno,compno,precno,info_IM.tile[tileno].packet[pack_nb].start_pos,info_IM.tile[tileno].packet[pack_nb].end_pos,info_IM.tile[tileno].packet[pack_nb].disto/info_IM.D_max); */
+                                                               fprintf(INDEX, "%d %d %d %d %d %d %d %d\n", pack_nb,
+                                                                                               tileno, layno, resno, compno, precno,
+                                                                                               info_IM.tile[tileno].packet[pack_nb].start_pos,
+                                                                                               info_IM.tile[tileno].packet[pack_nb].end_pos);
+                                                               pack_nb++;
+                                                       }
+                                               }
+                                       }
+                               }
+                       } else if (info_IM.Prog == 1) { /* RLCP */
+                               for (resno = 0; resno < info_IM.Decomposition + 1; resno++) {
+                                       for (layno = 0; layno < info_IM.Layer; layno++) {
+                                               for (compno = 0; compno < info_IM.Comp; compno++) {
+                                                       for (precno = 0; precno < info_IM.pw * info_IM.ph; precno++) {
+                                                               /* fprintf(INDEX,"%d %d %d %d %d %d %d %d %.04f\n",pack_nb,tileno,layno,resno,compno,precno,info_IM.tile[tileno].packet[pack_nb].start_pos,info_IM.tile[tileno].packet[pack_nb].end_pos,info_IM.tile[tileno].packet[pack_nb].disto/info_IM.D_max); */
+                                                               fprintf(INDEX, "%d %d %d %d %d %d %d %d\n", pack_nb,
+                                                                                               tileno, layno, resno, compno, precno,
+                                                                                               info_IM.tile[tileno].packet[pack_nb].start_pos,
+                                                                                               info_IM.tile[tileno].packet[pack_nb].end_pos);
+                                                               pack_nb++;
+                                                       }
+                                               }
+                                       }
+                               }
+                       } else if (info_IM.Prog == 2) { /* RPCL */
+                               for (resno = 0; resno < info_IM.Decomposition + 1; resno++) {
+                                       for (precno = 0; precno < info_IM.pw * info_IM.ph; precno++) {
+                                               for (compno = 0; compno < info_IM.Comp; compno++) {
+                                                       for (layno = 0; layno < info_IM.Layer; layno++) {
+                                                               /* fprintf(INDEX,"%d %d %d %d %d %d %d %d %.04f\n",pack_nb,tileno,layno,resno,compno,precno,info_IM.tile[tileno].packet[pack_nb].start_pos,info_IM.tile[tileno].packet[pack_nb].end_pos,info_IM.tile[tileno].packet[pack_nb].disto/info_IM.D_max); */
+                                                               fprintf(INDEX, "%d %d %d %d %d %d %d %d\n", pack_nb,
+                                                                                               tileno, layno, resno, compno, precno,
+                                                                                               info_IM.tile[tileno].packet[pack_nb].start_pos,
+                                                                                               info_IM.tile[tileno].packet[pack_nb].end_pos);
+                                                               pack_nb++;
+                                                       }
+                                               }
+                                       }
+                               }
+                       } else if (info_IM.Prog == 3) { /* PCRL */
+                               for (precno = 0; precno < info_IM.pw * info_IM.ph; precno++) {
+                                       for (compno = 0; compno < info_IM.Comp; compno++) {
+                                               for (resno = 0; resno < info_IM.Decomposition + 1; resno++) {
+                                                       for (layno = 0; layno < info_IM.Layer; layno++) {
+                                                               /* fprintf(INDEX,"%d %d %d %d %d %d %d %d %.04f\n",pack_nb,tileno,layno,resno,compno,precno,info_IM.tile[tileno].packet[pack_nb].start_pos,info_IM.tile[tileno].packet[pack_nb].end_pos,info_IM.tile[tileno].packet[pack_nb].disto/info_IM.D_max); */
+                                                               fprintf(INDEX, "%d %d %d %d %d %d %d %d\n", pack_nb,
+                                                                                               tileno, layno, resno, compno, precno,
+                                                                                               info_IM.tile[tileno].packet[pack_nb].start_pos,
+                                                                                               info_IM.tile[tileno].packet[pack_nb].end_pos);
+                                                               pack_nb++;
+                                                       }
+                                               }
+                                       }
+                               }
+                       } else {                                                                        /* CPRL */
+
+                               for (compno = 0; compno < info_IM.Comp; compno++) {
+                                       for (precno = 0; precno < info_IM.pw * info_IM.ph; precno++) {
+                                               for (resno = 0; resno < info_IM.Decomposition + 1; resno++) {
+                                                       for (layno = 0; layno < info_IM.Layer; layno++) {
+                                                               /* fprintf(INDEX,"%d %d %d %d %d %d %d %d %.04f\n",pack_nb,tileno,layno,resno,compno,precno,info_IM.tile[tileno].packet[pack_nb].start_pos,info_IM.tile[tileno].packet[pack_nb].end_pos,info_IM.tile[tileno].packet[pack_nb].disto/info_IM.D_max); */
+                                                               fprintf(INDEX, "%d %d %d %d %d %d %d %d\n", pack_nb,
+                                                                                               tileno, layno, resno, compno, precno,
+                                                                                               info_IM.tile[tileno].packet[pack_nb].start_pos,
+                                                                                               info_IM.tile[tileno].packet[pack_nb].end_pos);
+                                                               pack_nb++;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+               fclose(INDEX);
+       }
+
+       j2k_clean();
+
+       return cio_tell();
+}
+
+typedef struct {
+       int id;
+       int states;
+       void (*handler) ();
+} j2k_dec_mstabent_t;
+
+j2k_dec_mstabent_t j2k_dec_mstab[] = {
+       {J2K_MS_SOC, J2K_STATE_MHSOC, j2k_read_soc},
+       {J2K_MS_SOT, J2K_STATE_MH | J2K_STATE_TPHSOT, j2k_read_sot},
+       {J2K_MS_SOD, J2K_STATE_TPH, j2k_read_sod},
+       {J2K_MS_EOC, J2K_STATE_TPHSOT, j2k_read_eoc},
+       {J2K_MS_SIZ, J2K_STATE_MHSIZ, j2k_read_siz},
+       {J2K_MS_COD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_cod},
+       {J2K_MS_COC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_coc},
+       {J2K_MS_RGN, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_rgn},
+       {J2K_MS_QCD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_qcd},
+       {J2K_MS_QCC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_qcc},
+       {J2K_MS_POC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_poc},
+       {J2K_MS_TLM, J2K_STATE_MH, j2k_read_tlm},
+       {J2K_MS_PLM, J2K_STATE_MH, j2k_read_plm},
+       {J2K_MS_PLT, J2K_STATE_TPH, j2k_read_plt},
+       {J2K_MS_PPM, J2K_STATE_MH, j2k_read_ppm},
+       {J2K_MS_PPT, J2K_STATE_TPH, j2k_read_ppt},
+       {J2K_MS_SOP, 0, 0},
+       {J2K_MS_CRG, J2K_STATE_MH, j2k_read_crg},
+       {J2K_MS_COM, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_com},
+       {0, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_unk}
+};
+
+j2k_dec_mstabent_t *j2k_dec_mstab_lookup(int id)
+{
+       j2k_dec_mstabent_t *e;
+       for (e = j2k_dec_mstab; e->id != 0; e++) {
+               if (e->id == id) {
+                       break;
+               }
+       }
+       return e;
+}
+
+LIBJ2K_API int j2k_decode(unsigned char *src, int len, j2k_image_t ** img,
+                                                                                                       j2k_cp_t ** cp)
+{
+
+       if (setjmp(j2k_error)) {
+               if (j2k_state != J2K_STATE_MT) {
+                       fprintf(stderr, "WARNING: incomplete bitstream\n");
+                       return 0;
+               }
+               return cio_numbytes();
+       }
+
+       j2k_img = (j2k_image_t *) malloc(sizeof(j2k_image_t));
+       j2k_cp = (j2k_cp_t *) malloc(sizeof(j2k_cp_t));
+       *img = j2k_img;
+       *cp = j2k_cp;
+       j2k_state = J2K_STATE_MHSOC;
+       cio_init(src, len);
+
+       for (;;) {
+               j2k_dec_mstabent_t *e;
+               int id = cio_read(2);
+               if (id >> 8 != 0xff) {
+                       fprintf(stderr, "%.8x: expected a marker instead of %x\n",
+                                                       cio_tell() - 2, id);
+                       return 0;
+               }
+               e = j2k_dec_mstab_lookup(id);
+               if (!(j2k_state & e->states)) {
+                       fprintf(stderr, "%.8x: unexpected marker %x\n", cio_tell() - 2, id);
+                       return 0;
+               }
+               if (e->handler) {
+                       (*e->handler) ();
+               }
+               if (j2k_state == J2K_STATE_NEOC)
+                       break;                                                                          /* RAJOUTE */
+       }
+       if (j2k_state == J2K_STATE_NEOC)
+               j2k_read_eoc();                                                 /* RAJOUTE */
+
+       return 0;
+}
+
+#ifdef WIN32
+#include <windows.h>
+
+BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call,
+                                                                                       LPVOID lpReserved)
+{
+       switch (ul_reason_for_call) {
+       case DLL_PROCESS_ATTACH:
+       case DLL_THREAD_ATTACH:
+       case DLL_THREAD_DETACH:
+       case DLL_PROCESS_DETACH:
+               break;
+       }
+       return TRUE;
+}
+#endif
diff --git a/libopenjpeg/j2k.h b/libopenjpeg/j2k.h
new file mode 100644 (file)
index 0000000..3ad9cb0
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2001-2002, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2002-2003,  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.
+ */
+
+#define VERSION "0.0.8"
+
+#ifdef DAVID_WIN32
+#ifdef LIBJ2K_EXPORTS
+#define LIBJ2K_API __declspec(dllexport)
+#else
+#define LIBJ2K_API __declspec(dllimport)
+#endif
+#else
+#define LIBJ2K_API
+#endif
+
+#ifndef __J2K_H
+#define __J2K_H
+
+#define J2K_MAXRLVLS 33
+#define J2K_MAXBANDS (3*J2K_MAXRLVLS+1)
+
+#define J2K_CP_CSTY_PRT 0x01
+#define J2K_CP_CSTY_SOP 0x02
+#define J2K_CP_CSTY_EPH 0x04
+#define J2K_CCP_CSTY_PRT 0x01
+#define J2K_CCP_CBLKSTY_LAZY 0x01
+#define J2K_CCP_CBLKSTY_RESET 0x02
+#define J2K_CCP_CBLKSTY_TERMALL 0x04
+#define J2K_CCP_CBLKSTY_VSC 0x08
+#define J2K_CCP_CBLKSTY_PTERM 0x10
+#define J2K_CCP_CBLKSTY_SEGSYM 0x20
+#define J2K_CCP_QNTSTY_NOQNT 0
+#define J2K_CCP_QNTSTY_SIQNT 1
+#define J2K_CCP_QNTSTY_SEQNT 2
+
+typedef struct {
+       int dx, dy;                                                                             /* XRsiz, YRsiz */
+       int prec;                                                                                       /* precision */
+       int bpp;                                                                                        /* deapth of image in bits */
+       int sgnd;                                                                                       /* signed */
+       int *data;                                                                              /* image-component data */
+} j2k_comp_t;
+
+typedef struct {
+       int x0, y0;                                                                             /* XOsiz, YOsiz */
+       int x1, y1;                                                                             /* Xsiz, Ysiz  */
+       int numcomps;                                                                   /* number of components */
+       int index_on;                                                                   /* 0 = no index || 1 = index */
+       /* int PPT; */
+       j2k_comp_t *comps;                                              /* image-components */
+} j2k_image_t;
+
+typedef struct {
+       int expn;                                                                                       /* exponent */
+       int mant;                                                                                       /* mantissa */
+} j2k_stepsize_t;
+
+typedef struct {
+       int csty;                                                                                       /* coding style */
+       int numresolutions;                                             /* number of resolutions */
+       int cblkw;                                                                              /* width of code-blocks */
+       int cblkh;                                                                              /* height of code-blocks */
+       int cblksty;                                                                    /* code-block coding style */
+       int qmfbid;                                                                             /* discrete wavelet transform identifier */
+       int qntsty;                                                                             /* quantisation style */
+       j2k_stepsize_t stepsizes[J2K_MAXBANDS]; /* stepsizes used for quantisation */
+       int numgbits;                                                                   /* number of guard bits */
+       int roishift;                                                                   /* Region Of Interest shift */
+       int prcw[J2K_MAXRLVLS];                         /* Precinct width */
+       int prch[J2K_MAXRLVLS];                         /* Precinct height */
+} j2k_tccp_t;
+
+typedef struct {
+       int resno0, compno0;
+       int layno1, resno1, compno1;
+       int prg;
+       int tile;
+       char progorder[4];
+} j2k_poc_t;
+
+typedef struct {
+       int csty;                                                                                       /* coding style   */
+       int prg;                                                                                        /* progression order */
+       int numlayers;                                                          /* number of layers */
+       int mct;                                                                                        /* multi-component transform identifier */
+       int rates[100];                                                         /* rates of layers */
+       int numpocs;                                                                    /* number of progression order changes  */
+       j2k_poc_t pocs[32];                                             /* progression order changes */
+       j2k_tccp_t *tccps;                                              /* tile-component coding parameters */
+} j2k_tcp_t;
+
+typedef struct {
+       int image_type;                                                         /* 0: PNM, PGM, PPM 1: PGX */
+       int disto_alloc;                                                        /* Allocation by rate/distortion */
+       int fixed_alloc;                                                        /* Allocation by fixed layer */
+       int tx0, ty0;                                                                   /* XTOsiz, YTOsiz */
+       int tdx, tdy;                                                                   /* XTsiz, YTsiz */
+       char *comment;                                                          /* comment for coding */
+       int tw, th;
+       j2k_tcp_t *tcps;                                                        /* tile coding parameters */
+} j2k_cp_t;
+
+typedef struct {
+       int start_pos, end_pos;                         /* start and end position */
+       double disto;
+} info_packet;                                                                 /* Index struct */
+
+typedef struct {
+       int num_tile;                                                                   /* Number of Tile */
+       int start_pos;                                                          /* Start position */
+       int end_header;                                                         /* End position of the header */
+       int end_pos;                                                                    /* End position */
+       int pw, ph;                                                                             /* number of precinct by tile */
+       info_packet *packet;                                    /* information concerning packets inside tile */
+} info_tile;                                                                           /* index struct */
+
+typedef struct {
+       int index_on;
+       double D_max;                                                                   /* ADD for Marcela */
+       int num;                                                                                        /* numero of packet */
+       int index_write;                                                        /* writing the packet inthe index with t2_encode_packets */
+       int Im_w, Im_h;                                                         /* Image width and Height */
+       int Prog;                                                                                       /* progression order */
+       int Tile_x, Tile_y;                                             /* Number of Tile in X and Y */
+       int tw, th;
+       int Comp;                                                                                       /* Component numbers */
+       int Layer;                                                                              /* number of layer */
+       int Decomposition;                                              /* number of decomposition */
+       int pw, ph;                                                                             /* nombre precinct in X and Y */
+       int pdx, pdy;                                                                   /* size of precinct in X and Y */
+       int Main_head_end;                                              /* Main header position */
+       int codestream_size;                                    /* codestream's size */
+       info_tile *tile;                                                        /* information concerning tiles inside image */
+} info_image;                                                                          /* index struct */
+
+
+
+/* 
+ * Encode an image into a JPEG-2000 codestream
+ * i: image to encode
+ * cp: coding parameters
+ * dest: destination buffer
+ * len: length of destination buffer
+ * index : index file name
+ */
+LIBJ2K_API int j2k_encode(j2k_image_t * i, j2k_cp_t * cp, char *outfile,
+                                                                                                       int len, char *index);
+
+/* LIBJ2K_API int j2k_encode(j2k_image_t *i, j2k_cp_t *cp,unsigned char *dest, int len); */
+/*
+ * Decode an image from a JPEG-2000 codestream
+ * src: source buffer
+ * len: length of source buffer
+ * i: decode image
+ * cp: coding parameters that were used to encode the image
+ */
+LIBJ2K_API int j2k_decode(unsigned char *src, int len, j2k_image_t ** i,
+                                                                                                       j2k_cp_t ** cp);
+
+#endif
diff --git a/libopenjpeg/mct.c b/libopenjpeg/mct.c
new file mode 100644 (file)
index 0000000..ef371e9
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2001-2002, David Janssens
+ * 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 "mct.h"
+#include "fix.h"
+
+/* <summary> */
+/* This table contains the norms of the basis function of the reversible MCT. */
+/* </summary> */
+double mct_norms[3] = { 1.732, .8292, .8292 };
+
+/* <summary> */
+/* This table contains the norms of the basis function of the irreversible MCT. */
+/* </summary> */
+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/libopenjpeg/mct.h b/libopenjpeg/mct.h
new file mode 100644 (file)
index 0000000..196dc6d
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2001-2002, David Janssens
+ * 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
+
+/*
+ * Apply a reversible multi-component transform to an image
+ * R: samples for red component
+ * G: samples for green component
+ * B: samples blue component
+ * n: number of samples for each component
+ */
+void mct_encode(int *R, int *G, int *B, int n);
+/*
+ * Apply a reversible multi-component inverse transform to an image
+ * Y: samples for luminance component
+ * U: samples for red chrominance component
+ * V: samples for blue chrominance component
+ * n: number of samples for each component
+ */
+void mct_decode(int *V, int *U, int *Y, int n);
+/*
+ * Get norm of the basis function used for the reversible multi-component transform
+ * compno: number of the component (0->Y, 1->U, 2->V)
+ */
+double mct_getnorm(int compno);
+
+/*
+ * Apply an irreversible multi-component transform to an image
+ * R: samples for red component
+ * G: samples for green component
+ * B: samples blue component
+ * 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
+ * Y: samples for luminance component
+ * U: samples for red chrominance component
+ * V: samples for blue chrominance component
+ * 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
+ * compno: number of the component (0->Y, 1->U, 2->V)
+ */
+double mct_getnorm_real(int compno);
+
+#endif
diff --git a/libopenjpeg/mqc.c b/libopenjpeg/mqc.c
new file mode 100644 (file)
index 0000000..3f6eb92
--- /dev/null
@@ -0,0 +1,588 @@
+/*
+ * Copyright (c) 2001-2002, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2002-2003,  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 "mqc.h"
+#include <stdio.h>
+
+/* <summary> */
+/* This struct defines the state of a context. */
+/* </summary> */
+typedef struct mqc_state_s {
+       unsigned int qeval;                                             /* the probability of the Least Probable Symbol (0.75->0x8000, 1.5->0xffff) */
+       int mps;                                                                                        /* the Most Probable Symbol (0 or 1) */
+       struct mqc_state_s *nmps;                       /* next state if the next encoded symbol is the MPS */
+       struct mqc_state_s *nlps;                       /* next state if the next encoded symbol is the LPS */
+} mqc_state_t;
+
+/* <summary> */
+/* This array defines all the possible states for a context. */
+/* </summary> */
+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]},
+};
+
+#define MQC_NUMCTXS 32
+
+unsigned int mqc_c;
+unsigned int mqc_a;
+unsigned int mqc_ct;
+unsigned char *mqc_bp;
+unsigned char *mqc_start;
+unsigned char *mqc_end;
+mqc_state_t *mqc_ctxs[MQC_NUMCTXS];
+mqc_state_t **mqc_curctx;
+
+/* <summary> */
+/* Return the number of bytes already encoded. */
+/* </summary> */
+int mqc_numbytes()
+{
+       return mqc_bp - mqc_start;
+}
+
+/* <summary> */
+/* Output a byte, doing bit-stuffing if necessary. */
+/* After a 0xff byte, the next byte must be smaller than 0x90 */
+/* </summary> */
+void mqc_byteout()
+{
+       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;
+                       }
+               }
+       }
+}
+
+/* <summary> */
+/* Renormalize mqc_a and mqc_c while encoding, so that mqc_a stays between 0x8000 and 0x10000 */
+/* </summary> */
+void mqc_renorme()
+{
+       do {
+               mqc_a <<= 1;
+               mqc_c <<= 1;
+               mqc_ct--;
+               if (mqc_ct == 0) {
+                       mqc_byteout();
+               }
+       } while ((mqc_a & 0x8000) == 0);
+}
+
+/* <summary> */
+/* Encode the most probable symbol. */
+/* </summary> */
+void mqc_codemps()
+{
+       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();
+       } else {
+               mqc_c += (*mqc_curctx)->qeval;
+       }
+}
+
+/* <summary> */
+/* Encode the most least symbol. */
+/* </summary> */
+void mqc_codelps()
+{
+       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();
+}
+
+/* <summary> */
+/* Initialize encoder. */
+/* </summary> */
+/* <param name="bp">Output buffer.</param> */
+void mqc_init_enc(unsigned char *bp)
+{
+       mqc_setcurctx(0);
+       mqc_a = 0x8000;
+       mqc_c = 0;
+       mqc_bp = bp - 1;
+       mqc_ct = 12;
+       if (*mqc_bp == 0xff) {
+               mqc_ct = 13;
+       }
+       mqc_start = bp;
+}
+
+/* <summary> */
+/* Set current context. */
+/* </summary> */
+/* <param name="ctxno">Context number.</param> */
+void mqc_setcurctx(int ctxno)
+{
+       mqc_curctx = &mqc_ctxs[ctxno];
+}
+
+/* <summary> */
+/* Encode a symbol using the MQ-coder. */
+/* </summary> */
+/* <param name="d"> The symbol to be encoded (0 or 1).</param> */
+void mqc_encode(int d)
+{
+       if ((*mqc_curctx)->mps == d) {
+               mqc_codemps();
+       } else {
+               mqc_codelps();
+       }
+}
+
+/* <summary> */
+/* Fill mqc_c with 1's for flushing */
+/* </summary> */
+void mqc_setbits()
+{
+       unsigned int tempc = mqc_c + mqc_a;
+       mqc_c |= 0xffff;
+       if (mqc_c >= tempc) {
+               mqc_c -= 0x8000;
+       }
+}
+
+/* <summary> */
+/* Flush encoded data. */
+/* </summary> */
+void mqc_flush()
+{
+       mqc_setbits();
+       mqc_c <<= mqc_ct;
+       mqc_byteout();
+       mqc_c <<= mqc_ct;
+       mqc_byteout();
+
+       if (*mqc_bp != 0xff) {
+               mqc_bp++;
+       }
+}
+
+/* <summary> */
+/* not fully implemented and tested !! */
+/* BYPASS mode switch, initialization operation */
+/* JPEG 2000 p 505 */
+/* </summary> */
+void mqc_bypass_init_enc()
+{
+       mqc_c = 0;
+       mqc_ct = 8;
+       if (*mqc_bp == 0xff) {
+               mqc_ct = 7;
+       }
+}
+
+/* <summary> */
+/* not fully implemented and tested !! */
+/* BYPASS mode switch, coding operation */
+/* JPEG 2000 p 505 */
+/* </summary> */
+void mqc_bypass_enc(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;
+       }
+}
+
+/* <summary> */
+/* not fully implemented and tested !! */
+/* BYPASS mode switch, flush operation */
+/* </summary> */
+int mqc_bypass_flush_enc()
+{
+       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;
+}
+
+/* <summary> */
+/* RESET mode switch */
+/* </summary> */
+void mqc_reset_enc()
+{
+       mqc_resetstates();
+       mqc_setstate(18, 0, 46);
+       mqc_setstate(0, 0, 3);
+       mqc_setstate(1, 0, 4);
+}
+
+/* <summary> */
+/* mode switch RESTART (TERMALL) */
+/* </summary> */
+int mqc_restart_enc()
+{
+       int correction = 1;
+
+       /* <flush part> */
+       int n = 27 - 15 - mqc_ct;
+       mqc_c <<= mqc_ct;
+       while (n > 0) {
+               mqc_byteout();
+               n -= mqc_ct;
+               mqc_c <<= mqc_ct;
+       }
+       mqc_byteout();
+
+       return correction;
+}
+
+/* <summary> */
+/* mode switch RESTART (TERMALL) reinitialisation */
+/* </summary> */
+void mqc_restart_init_enc()
+{
+       /* <Re-init part> */
+       mqc_a = 0x8000;
+       mqc_c = 0;
+       mqc_ct = 12;
+       mqc_bp--;
+       if (*mqc_bp == 0xff) {
+               mqc_ct = 13;
+       }
+
+}
+
+
+/* <summary> */
+/* ERTERM mode switch  */
+/* </summary> */
+void mqc_erterm_enc()
+{
+       int k = 11 - mqc_ct + 1;
+
+       while (k > 0) {
+               mqc_c <<= mqc_ct;
+               mqc_ct = 0;
+               mqc_byteout();
+               k -= mqc_ct;
+       }
+
+       if (*mqc_bp != 0xff) {
+               mqc_byteout();
+       }
+}
+
+/* <summary> */
+/* SEGMARK mode switch (SEGSYM) */
+/* </summary> */
+void mqc_segmark_enc()
+{
+       int i;
+       mqc_setcurctx(18);
+
+       for (i = 1; i < 5; i++) {
+               mqc_encode(i % 2);
+       }
+}
+
+/* <summary> */
+/* </summary> */
+int mqc_mpsexchange()
+{
+       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;
+}
+
+/* <summary> */
+/* </summary> */
+int mqc_lpsexchange()
+{
+       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;
+}
+
+/* <summary> */
+/* Input a byte. */
+/* </summary> */
+void mqc_bytein()
+{
+       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;
+       }
+}
+
+/* <summary> */
+/* Renormalize mqc_a and mqc_c while decoding. */
+/* </summary> */
+void mqc_renormd()
+{
+       do {
+               if (mqc_ct == 0) {
+                       mqc_bytein();
+               }
+               mqc_a <<= 1;
+               mqc_c <<= 1;
+               mqc_ct--;
+       } while (mqc_a < 0x8000);
+}
+
+/* <summary> */
+/* Initialize decoder. */
+/* </summary> */
+void mqc_init_dec(unsigned char *bp, int len)
+{
+       mqc_setcurctx(0);
+       mqc_start = bp;
+       mqc_end = bp + len;
+       mqc_bp = bp;
+       mqc_c = *mqc_bp << 16;
+       mqc_bytein();
+       mqc_c <<= 7;
+       mqc_ct -= 7;
+       mqc_a = 0x8000;
+}
+
+/* <summary> */
+/* Decode a symbol. */
+/* </summary> */
+int mqc_decode()
+{
+       int d;
+       mqc_a -= (*mqc_curctx)->qeval;
+       if ((mqc_c >> 16) < (*mqc_curctx)->qeval) {
+               d = mqc_lpsexchange();
+               mqc_renormd();
+       } else {
+               mqc_c -= (*mqc_curctx)->qeval << 16;
+               if ((mqc_a & 0x8000) == 0) {
+                       d = mqc_mpsexchange();
+                       mqc_renormd();
+               } else {
+                       d = (*mqc_curctx)->mps;
+               }
+       }
+       return d;
+}
+
+/* <summary> */
+/* Reset states of all contexts. */
+/* </summary> */
+void mqc_resetstates()
+{
+       int i;
+       for (i = 0; i < MQC_NUMCTXS; i++) {
+               mqc_ctxs[i] = mqc_states;
+       }
+}
+
+/* <summary> */
+/* Set the state for a context. */
+/* </summary> */
+/* <param name="ctxno">Context number</param> */
+/* <param name="msb">Most significant bit</param> */
+/* <param name="prob">Index to the probability of symbols</param> */
+void mqc_setstate(int ctxno, int msb, int prob)
+{
+       mqc_ctxs[ctxno] = &mqc_states[msb + (prob << 1)];
+}
diff --git a/libopenjpeg/mqc.h b/libopenjpeg/mqc.h
new file mode 100644 (file)
index 0000000..3d29a6d
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2001-2002, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2002-2003,  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
+
+/*
+ * Return the number of bytes written/read since initialisation
+ */
+int mqc_numbytes();
+
+/*
+ * 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)
+ */
+void mqc_resetstates();
+
+/*
+ * Set the state of a particular context
+ * ctxno: number that identifies the context
+ * msb: the MSB of the new state of the context
+ * prob: number that identifies the probability of the symbols for the new state of the context
+ */
+void mqc_setstate(int ctxno, int msb, int prob);
+
+/*
+ * Initialize the encoder
+ * bp: pointer to the start of the buffer where the bytes will be written
+ */
+void mqc_init_enc(unsigned char *bp);
+
+/*
+ * Set the current context used for coding/decoding
+ * ctxno: number that identifies the context
+ */
+void mqc_setcurctx(int ctxno);
+
+/*
+ * Encode a bit
+ * d: bit to encode (0 or 1)
+ */
+void mqc_encode(int d);
+
+/*
+ * Flush the encoder, so that all remaining data is written
+ */
+void mqc_flush();
+
+/*
+ * BYPASS mode switch
+ */
+void mqc_bypass_init_enc();
+
+/*
+ * BYPASS mode switch
+ */
+void mqc_bypass_enc();
+
+/*
+ * BYPASS mode switch
+ */
+int mqc_bypass_flush_enc();
+
+/*
+ * RESET mode switch
+ */
+void mqc_reset_enc();
+
+/*
+ * RESTART mode switch (TERMALL)
+ */
+int mqc_restart_enc();
+
+/*
+ * RESTART mode switch (TERMALL)
+ */
+void mqc_restart_init_enc();
+
+/*
+ * ERTERM mode switch (PTERM)
+ */
+void mqc_erterm_enc();
+
+/*
+ * SEGMARK mode switch (SEGSYM)
+ */
+void mqc_segmark_enc();
+
+
+/*
+ * Initialize the decoder
+ * bp: pointer to the start of the buffer from which the bytes will be read
+ * len: length of the input buffer
+ */
+void mqc_init_dec(unsigned char *bp, int len);
+
+/*
+ * Decode a bit (returns 0 or 1)
+ */
+int mqc_decode();
+
+#endif
diff --git a/libopenjpeg/openjpeg.h b/libopenjpeg/openjpeg.h
new file mode 100644 (file)
index 0000000..ad49eba
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2001-2002, David Janssens
+ * Copyright (c) 2003, Yannick Verschueren
+ * Copyright (c) 2003,  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 __OPENJPEG_H
+#define __OPENJPEG_H
+
+#include <j2k.h>
+#include <tcd.h>
+
+#include <bio.h>
+#include <cio.h>
+#include <dwt.h>
+#include <fix.h>
+#include <int.h>
+#include <mct.h>
+#include <mqc.h>
+#include <pi.h>
+#include <raw.h>
+#include <t1.h>
+#include <t2.h>
+#include <tgt.h>
+
+#endif
diff --git a/libopenjpeg/pi.c b/libopenjpeg/pi.c
new file mode 100644 (file)
index 0000000..eca2c45
--- /dev/null
@@ -0,0 +1,488 @@
+/*
+ * Copyright (c) 2001-2002, David Janssens
+ * Copyright (c) 2003, Yannick Verschueren
+ * Copyright (c) 2003,  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 "pi.h"
+#include "int.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+
+/* <summary> */
+/* Create a packet iterator.   */
+/* </summary> */
+pi_iterator_t *pi_create(j2k_image_t * img, j2k_cp_t * cp, int tileno)
+{
+       int p, q;
+       int compno, resno, pino, layno, precno;
+       int maxres = 0;
+       pi_iterator_t *pi;
+       j2k_tcp_t *tcp;
+       j2k_tccp_t *tccp;
+
+       tcp = &cp->tcps[tileno];
+       pi =
+               (pi_iterator_t *) malloc((tcp->numpocs + 1) * sizeof(pi_iterator_t));
+
+       for (pino = 0; pino < tcp->numpocs + 1; pino++) {       /* change */
+               p = tileno % cp->tw;
+               q = tileno / cp->tw;
+
+               /*    pi->tx0=int_max(cp->tx0+p*cp->tdx, img->x0);
+                  pi->ty0=int_max(cp->ty0+q*cp->tdy, img->y0);
+                  pi->tx1=int_min(cp->tx0+(p+1)*cp->tdx, img->x1);
+                  pi->ty1=int_min(cp->ty0+(q+1)*cp->tdy, img->y1);
+                  pi->numcomps=img->numcomps;
+                  pi->comps=(pi_comp_t*)malloc(img->numcomps*sizeof(pi_comp_t)); */
+
+               pi[pino].tx0 = int_max(cp->tx0 + p * cp->tdx, img->x0);
+               pi[pino].ty0 = int_max(cp->ty0 + q * cp->tdy, img->y0);
+               pi[pino].tx1 = int_min(cp->tx0 + (p + 1) * cp->tdx, img->x1);
+               pi[pino].ty1 = int_min(cp->ty0 + (q + 1) * cp->tdy, img->y1);
+               pi[pino].numcomps = img->numcomps;
+               pi[pino].comps =
+                       (pi_comp_t *) malloc(img->numcomps * sizeof(pi_comp_t));
+
+               for (compno = 0; compno < pi->numcomps; compno++) {
+                       int tcx0, tcy0, tcx1, tcy1;
+                       /* pi_comp_t *comp=&pi->comps[compno]; */
+                       pi_comp_t *comp = &pi[pino].comps[compno];
+                       tccp = &tcp->tccps[compno];
+                       comp->dx = img->comps[compno].dx;
+                       comp->dy = img->comps[compno].dy;
+                       comp->numresolutions = tccp->numresolutions;
+                       comp->resolutions =
+                               (pi_resolution_t *) malloc(comp->numresolutions *
+                                                                                                                                        sizeof(pi_resolution_t));
+                       tcx0 = int_ceildiv(pi->tx0, comp->dx);
+                       tcy0 = int_ceildiv(pi->ty0, comp->dy);
+                       tcx1 = int_ceildiv(pi->tx1, comp->dx);
+                       tcy1 = int_ceildiv(pi->ty1, comp->dy);
+                       if (comp->numresolutions > maxres) {
+                               maxres = comp->numresolutions;
+                       }
+                       for (resno = 0; resno < comp->numresolutions; resno++) {
+                               int levelno;
+                               int rx0, ry0, rx1, ry1;
+                               int px0, py0, px1, py1;
+                               pi_resolution_t *res = &comp->resolutions[resno];
+                               if (tccp->csty & J2K_CCP_CSTY_PRT) {
+                                       res->pdx = tccp->prcw[resno];
+                                       res->pdy = tccp->prch[resno];
+                               } else {
+                                       res->pdx = 15;
+                                       res->pdy = 15;
+                               }
+                               levelno = comp->numresolutions - 1 - resno;
+                               rx0 = int_ceildivpow2(tcx0, levelno);
+                               ry0 = int_ceildivpow2(tcy0, levelno);
+                               rx1 = int_ceildivpow2(tcx1, levelno);
+                               ry1 = int_ceildivpow2(tcy1, levelno);
+                               px0 = int_floordivpow2(rx0, res->pdx) << res->pdx;
+                               py0 = int_floordivpow2(ry0, res->pdy) << res->pdy;
+                               px1 = int_ceildivpow2(rx1, res->pdx) << res->pdx;
+                               py1 = int_ceildivpow2(ry1, res->pdy) << res->pdy;
+                               res->pw = (px1 - px0) >> res->pdx;
+                               res->ph = (py1 - py0) >> res->pdy;
+                       }
+               }
+
+               /*   pi->first=1;
+                  pi->poc.resno0=0;
+                  pi->poc.compno0=0;
+                  pi->poc.layno1=tcp->numlayers;
+                  pi->poc.resno1=maxres;
+                  pi->poc.compno1=img->numcomps;
+                  pi->poc.prg=tcp->prg; */
+
+               for (layno = 0; layno < 10; layno++) {
+                       /* pi_comp_t *compo; */
+                       /* pi_resolution_t *res; */
+                       for (resno = 0; resno < 10; resno++) {
+                               for (compno = 0; compno < 3; compno++) {
+                                       /* compo=&pi[pino].comps[compno]; */
+                                       /* res=&compo->resolutions[pi->resno]; */
+                                       for (precno = 0; precno < 99; precno++) {
+                                               pi[pino].include[layno][resno][compno][precno] = 0;
+                                       }
+                               }
+                       }
+               }
+
+               if (pino == tcp->numpocs) {
+                       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 = img->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;
+}
+
+/* <summary> */
+/* Get next packet in layer=resolution-component-precinct order.   */
+/* </summary> */
+int pi_next_lrcp(pi_iterator_t * pi)
+{
+       pi_comp_t *comp;
+       pi_resolution_t *res;
+
+       if (!pi->first) {
+               comp = &pi->comps[pi->compno];
+               res = &comp->resolutions[pi->resno];
+               goto 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->numresolutions) {
+
+                                       continue;
+                               }
+                               res = &comp->resolutions[pi->resno];
+                               for (pi->precno = 0; pi->precno < res->pw * res->ph; pi->precno++) {
+                                       if (!pi->include[pi->layno][pi->resno][pi->compno][pi->precno]) {
+                                               pi->include[pi->layno][pi->resno][pi->compno][pi->precno] = 1;
+                                               return 1;
+                                       }
+                               skip:;
+                               }
+                       }
+               }
+       }
+       return 0;
+}
+
+/* <summary> */
+/* Get next packet in resolution-layer-component-precinct order.   */
+/* </summary> */
+int pi_next_rlcp(pi_iterator_t * pi)
+{
+       pi_comp_t *comp;
+       pi_resolution_t *res;
+       if (!pi->first) {
+               comp = &pi->comps[pi->compno];
+               res = &comp->resolutions[pi->resno];
+               goto 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->numresolutions) {
+                                       continue;
+                               }
+                               res = &comp->resolutions[pi->resno];
+                               for (pi->precno = 0; pi->precno < res->pw * res->ph; pi->precno++) {
+                                       if (!pi->include[pi->layno][pi->resno][pi->compno][pi->precno]) {
+                                               pi->include[pi->layno][pi->resno][pi->compno][pi->precno] = 1;
+                                               return 1;
+                                       }
+                               skip:;
+                               }
+                       }
+               }
+       }
+       return 0;
+}
+
+/* <summary> */
+/* Get next packet in resolution-precinct-component-layer order.   */
+/* </summary> */
+int pi_next_rpcl(pi_iterator_t * pi)
+{
+       pi_comp_t *comp;
+       pi_resolution_t *res;
+       if (!pi->first) {
+               goto 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->numresolutions; resno++) {
+                               int dx, dy;
+                               res = &comp->resolutions[resno];
+                               dx =
+                                       comp->dx * (1 << (res->pdx + comp->numresolutions - 1 - resno));
+                               dy =
+                                       comp->dy * (1 << (res->pdy + comp->numresolutions - 1 - resno));
+                               pi->dx = !pi->dx ? dx : int_min(pi->dx, dx);
+                               pi->dy = !pi->dy ? dy : int_min(pi->dy, dy);
+                       }
+               }
+       }
+       for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) {
+               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 levelno;
+                                       int trx0, try0;
+                                       int rpx, rpy;
+                                       int prci, prcj;
+                                       comp = &pi->comps[pi->compno];
+                                       if (pi->resno >= comp->numresolutions) {
+                                               continue;
+                                       }
+                                       res = &comp->resolutions[pi->resno];
+                                       levelno = comp->numresolutions - 1 - pi->resno;
+                                       trx0 = int_ceildiv(pi->tx0, comp->dx << levelno);
+                                       try0 = int_ceildiv(pi->ty0, comp->dy << levelno);
+                                       rpx = res->pdx + levelno;
+                                       rpy = res->pdy + levelno;
+                                       if (!
+                                                       (pi->x % (comp->dx << rpx) == 0
+                                                        || (pi->x == pi->tx0 && (trx0 << levelno) % (1 << rpx)))) {
+                                               continue;
+                                       }
+                                       if (!
+                                                       (pi->y % (comp->dy << rpy) == 0
+                                                        || (pi->y == pi->ty0 && (try0 << levelno) % (1 << rpx)))) {
+                                               continue;
+                                       }
+                                       prci =
+                                               int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelno),
+                                                                                                                res->pdx) - int_floordivpow2(trx0, res->pdx);
+                                       prcj =
+                                               int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelno),
+                                                                                                                res->pdy) - int_floordivpow2(try0, res->pdy);
+                                       pi->precno = prci + prcj * res->pw;
+                                       for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) {
+                                               if (!pi->include[pi->layno][pi->resno][pi->compno][pi->precno]) {
+                                                       pi->include[pi->layno][pi->resno][pi->compno][pi->precno] =
+                                                               1;
+                                                       return 1;
+                                               }
+                                       skip:;
+                                       }
+                               }
+                       }
+               }
+       }
+       return 0;
+}
+
+/* <summary> */
+/* Get next packet in precinct-component-resolution-layer order.   */
+/* </summary> */
+int pi_next_pcrl(pi_iterator_t * pi)
+{
+       pi_comp_t *comp;
+       pi_resolution_t *res;
+       if (!pi->first) {
+               comp = &pi->comps[pi->compno];
+               goto 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->numresolutions; resno++) {
+                               int dx, dy;
+                               res = &comp->resolutions[resno];
+                               dx =
+                                       comp->dx * (1 << (res->pdx + comp->numresolutions - 1 - resno));
+                               dy =
+                                       comp->dy * (1 << (res->pdy + comp->numresolutions - 1 - resno));
+                               pi->dx = !pi->dx ? dx : int_min(pi->dx, dx);
+                               pi->dy = !pi->dy ? dy : int_min(pi->dy, dy);
+                       }
+               }
+       }
+       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->numresolutions);
+                                                pi->resno++) {
+                                       int levelno;
+                                       int trx0, try0;
+                                       int rpx, rpy;
+                                       int prci, prcj;
+                                       res = &comp->resolutions[pi->resno];
+                                       levelno = comp->numresolutions - 1 - pi->resno;
+                                       trx0 = int_ceildiv(pi->tx0, comp->dx << levelno);
+                                       try0 = int_ceildiv(pi->ty0, comp->dy << levelno);
+                                       rpx = res->pdx + levelno;
+                                       rpy = res->pdy + levelno;
+                                       if (!
+                                                       (pi->x % (comp->dx << rpx) == 0
+                                                        || (pi->x == pi->tx0 && (trx0 << levelno) % (1 << rpx)))) {
+                                               continue;
+                                       }
+                                       if (!
+                                                       (pi->y % (comp->dy << rpy) == 0
+                                                        || (pi->y == pi->ty0 && (try0 << levelno) % (1 << rpx)))) {
+                                               continue;
+                                       }
+                                       prci =
+                                               int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelno),
+                                                                                                                res->pdx) - int_floordivpow2(trx0, res->pdx);
+                                       prcj =
+                                               int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelno),
+                                                                                                                res->pdy) - int_floordivpow2(try0, res->pdy);
+                                       pi->precno = prci + prcj * res->pw;
+                                       for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) {
+                                               if (!pi->include[pi->layno][pi->resno][pi->compno][pi->precno]) {
+                                                       pi->include[pi->layno][pi->resno][pi->compno][pi->precno] =
+                                                               1;
+                                                       return 1;
+                                               }
+                                       skip:;
+                                       }
+                               }
+                       }
+               }
+       }
+       return 0;
+}
+
+/* <summary> */
+/* Get next packet in component-precinct-resolution-layer order.   */
+/* </summary> */
+int pi_next_cprl(pi_iterator_t * pi)
+{
+       pi_comp_t *comp;
+       pi_resolution_t *res;
+       if (!pi->first) {
+               comp = &pi->comps[pi->compno];
+               goto 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->numresolutions; resno++) {
+                       int dx, dy;
+                       res = &comp->resolutions[resno];
+                       dx = comp->dx * (1 << (res->pdx + comp->numresolutions - 1 - resno));
+                       dy = comp->dy * (1 << (res->pdy + comp->numresolutions - 1 - resno));
+                       pi->dx = !pi->dx ? dx : int_min(pi->dx, dx);
+                       pi->dy = !pi->dy ? dy : int_min(pi->dy, dy);
+               }
+               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->numresolutions);
+                                                pi->resno++) {
+                                       int levelno;
+                                       int trx0, try0;
+                                       int rpx, rpy;
+                                       int prci, prcj;
+                                       res = &comp->resolutions[pi->resno];
+                                       levelno = comp->numresolutions - 1 - pi->resno;
+                                       trx0 = int_ceildiv(pi->tx0, comp->dx << levelno);
+                                       try0 = int_ceildiv(pi->ty0, comp->dy << levelno);
+                                       rpx = res->pdx + levelno;
+                                       rpy = res->pdy + levelno;
+                                       if (!
+                                                       (pi->x % (comp->dx << rpx) == 0
+                                                        || (pi->x == pi->tx0 && (trx0 << levelno) % (1 << rpx)))) {
+                                               continue;
+                                       }
+                                       if (!
+                                                       (pi->y % (comp->dy << rpy) == 0
+                                                        || (pi->y == pi->ty0 && (try0 << levelno) % (1 << rpx)))) {
+                                               continue;
+                                       }
+                                       prci =
+                                               int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelno),
+                                                                                                                res->pdx) - int_floordivpow2(trx0, res->pdx);
+                                       prcj =
+                                               int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelno),
+                                                                                                                res->pdy) - int_floordivpow2(try0, res->pdy);
+                                       pi->precno = prci + prcj * res->pw;
+                                       for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) {
+                                               if (!pi->include[pi->layno][pi->resno][pi->compno][pi->precno]) {
+                                                       pi->include[pi->layno][pi->resno][pi->compno][pi->precno] =
+                                                               1;
+                                                       return 1;
+                                               }
+                                       skip:;
+                                       }
+                               }
+                       }
+               }
+       }
+       return 0;
+}
+
+/* <summary> */
+/* Get next packet.   */
+/* </summary> */
+int pi_next(pi_iterator_t * pi)
+{
+       switch (pi->poc.prg) {
+       case 0:
+               return pi_next_lrcp(pi);
+       case 1:
+               return pi_next_rlcp(pi);
+       case 2:
+               return pi_next_rpcl(pi);
+       case 3:
+               return pi_next_pcrl(pi);
+       case 4:
+               return pi_next_cprl(pi);
+       }
+       return 0;
+}
diff --git a/libopenjpeg/pi.h b/libopenjpeg/pi.h
new file mode 100644 (file)
index 0000000..5403faf
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2001-2002, David Janssens
+ * 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
+
+#include "j2k.h"
+#include "tcd.h"
+
+typedef struct {
+       int pdx, pdy;
+       int pw, ph;
+} pi_resolution_t;
+
+typedef struct {
+       int dx, dy;
+       int numresolutions;
+       pi_resolution_t *resolutions;
+} pi_comp_t;
+
+typedef struct {
+       int include[10][10][3][99];
+       int compno, resno, precno, layno;       /* component, resolution, precinct and layer that indentify the packet */
+       int first;
+       j2k_poc_t poc;
+       int numcomps;
+       pi_comp_t *comps;
+       int tx0, ty0, tx1, ty1;
+       int x, y, dx, dy;
+} pi_iterator_t;                                                               /* packet iterator */
+
+/*
+ * Create a packet iterator
+ * img: raw image for which the packets will be listed
+ * cp: coding paremeters
+ * tileno: number that identifies the tile for which to list the packets
+ * return value: returns a packet iterator that points to the first packet of the tile
+ */
+pi_iterator_t *pi_create(j2k_image_t * img, j2k_cp_t * cp, int tileno);
+
+/* 
+ * Modify the packet iterator to point to the next packet
+ * pi: packet iterator to modify
+ * return value: returns 0 if pi pointed to the last packet or else returns 1 
+ */
+int pi_next(pi_iterator_t * pi);
+
+#endif
diff --git a/libopenjpeg/raw.c b/libopenjpeg/raw.c
new file mode 100644 (file)
index 0000000..bdfe624
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2002-2003, Antonin Descampe
+ * 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 "raw.h"
+
+
+unsigned char raw_c;
+unsigned int raw_ct, raw_lenmax, raw_len;
+unsigned char *raw_bp;
+unsigned char *raw_start;
+unsigned char *raw_end;
+
+/* <summary> */
+/* Return the number of bytes already encoded. */
+/* </summary> */
+int raw_numbytes()
+{
+       return raw_bp - raw_start;
+}
+
+/* <summary> */
+/* Initialize raw-encoder. */
+/* </summary> */
+/* <param name="bp">Output buffer.</param> */
+void raw_init_enc(unsigned char *bp)
+{
+       raw_bp = bp - 1;
+       raw_c = 0;
+       raw_ct = 7;
+       raw_start = bp;
+}
+
+/* <summary> */
+/* Encode a symbol using the RAW-coder. */
+/* </summary> */
+/* <param name="d"> The symbol to be encoded (0 or 1).</param> */
+void raw_encode(int d)
+{
+       /*  raw_c+=d; */
+
+       raw_ct--;
+       raw_c += (d << raw_ct);
+
+       if (raw_ct == 0) {
+               raw_bp++;
+               *raw_bp = raw_c;
+               raw_ct = 7;
+               if (raw_c == 0xff) {
+                       raw_ct = 6;
+               }
+               raw_c = 0;
+       }
+       /*else 
+          {
+          raw_ct--;
+          raw_c<<=1;
+          } */
+}
+
+/* <summary> */
+/* Flush encoded data. */
+/* </summary> */
+void raw_flush()
+{
+       char first = 1;
+       int prev = 1;
+       while (raw_ct != 7) {
+               raw_encode(first ? 0 : !(prev));
+               prev = first ? 0 : !(prev);
+               first = 0;
+       }
+}
+
+/* <summary> */
+/* Initialize raw-decoder. */
+/* </summary> */
+void raw_init_dec(unsigned char *bp, int len)
+{
+       raw_start = bp;
+       raw_lenmax = len;
+       raw_len = 0;
+       raw_c = 0;
+       raw_ct = 0;
+}
+
+/* <summary> */
+/* Decode a symbol using raw-decoder. Cfr p.506 TAUBMAN */
+/* </summary> */
+int raw_decode()
+{
+       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/libopenjpeg/raw.h b/libopenjpeg/raw.h
new file mode 100644 (file)
index 0000000..eede21a
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2002-2003, Antonin Descampe
+ * Copyright (c) 2002-2003,  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
+       
+/*
+ * Return the number of bytes written/read since initialisation
+ */ 
+int raw_numbytes();
+
+
+/*
+ * Initialize the encoder
+ * bp: pointer to the start of the buffer where the bytes will be written
+ */ 
+void raw_init_enc(unsigned char *bp);
+
+
+/*
+ * Encode a bit
+ * d: bit to encode (0 or 1)
+ */ 
+void raw_encode(int d);
+
+
+/*
+ * Flush the encoder, so that all remaining data is written
+ */ 
+void raw_flush();
+
+
+/*
+ * Initialize the decoder
+ * bp: pointer to the start of the buffer from which the bytes will be read
+ * len: length of the input buffer
+ */ 
+void raw_init_dec(unsigned char *bp, int len);
+
+
+/*
+ * Decode a bit (returns 0 or 1)
+ */ 
+int raw_decode();
+
+
+#endif /* 
+ */
diff --git a/libopenjpeg/t1.c b/libopenjpeg/t1.c
new file mode 100644 (file)
index 0000000..2e78530
--- /dev/null
@@ -0,0 +1,1077 @@
+/*
+ * Copyright (c) 2001-2002, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2002-2003,  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 "t1.h"
+#include "j2k.h"
+#include "mqc.h"
+#include "raw.h"                                                               /* Antonin */
+#include "int.h"
+#include "mct.h"
+#include "dwt.h"
+#include "fix.h"
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+
+#define T1_MAXCBLKW 1024
+#define T1_MAXCBLKH 1024
+
+#define T1_SIG_NE 0x0001
+#define T1_SIG_SE 0x0002
+#define T1_SIG_SW 0x0004
+#define T1_SIG_NW 0x0008
+#define T1_SIG_N 0x0010
+#define T1_SIG_E 0x0020
+#define T1_SIG_S 0x0040
+#define T1_SIG_W 0x0080
+#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_BITS 7
+#define T1_NMSEDEC_FRACBITS (T1_NMSEDEC_BITS-1)
+
+/* add TONY */
+#define T1_TYPE_MQ 0
+#define T1_TYPE_RAW 1
+/* dda */
+
+static int t1_lut_ctxno_zc[1024];
+static int t1_lut_ctxno_sc[256];
+static int t1_lut_ctxno_mag[4096];
+static int t1_lut_spb[256];
+static int t1_lut_nmsedec_sig[1 << T1_NMSEDEC_BITS];
+static int t1_lut_nmsedec_sig0[1 << T1_NMSEDEC_BITS];
+static int t1_lut_nmsedec_ref[1 << T1_NMSEDEC_BITS];
+static int t1_lut_nmsedec_ref0[1 << T1_NMSEDEC_BITS];
+
+static int t1_data[T1_MAXCBLKH][T1_MAXCBLKH];
+static int t1_flags[T1_MAXCBLKH + 2][T1_MAXCBLKH + 2];
+
+int t1_getctxno_zc(int f, int orient)
+{
+       return t1_lut_ctxno_zc[(orient << 8) | (f & T1_SIG_OTH)];
+}
+
+int t1_getctxno_sc(int f)
+{
+       return t1_lut_ctxno_sc[(f & (T1_SIG_PRIM | T1_SGN)) >> 4];
+}
+
+int t1_getctxno_mag(int f)
+{
+       return t1_lut_ctxno_mag[(f & T1_SIG_OTH) |
+                                                                                                       (((f & T1_REFINE) != 0) << 11)];
+}
+
+int t1_getspb(int f)
+{
+       return t1_lut_spb[(f & (T1_SIG_PRIM | T1_SGN)) >> 4];
+}
+
+int t1_getnmsedec_sig(int x, int bitpos)
+{
+       if (bitpos > T1_NMSEDEC_FRACBITS)
+               return t1_lut_nmsedec_sig[(x >> (bitpos - T1_NMSEDEC_FRACBITS)) &
+                                                                                                                       ((1 << T1_NMSEDEC_BITS) - 1)];
+       else
+               return t1_lut_nmsedec_sig0[x & ((1 << T1_NMSEDEC_BITS) - 1)];
+}
+
+int t1_getnmsedec_ref(int x, int bitpos)
+{
+       if (bitpos > T1_NMSEDEC_FRACBITS)
+               return t1_lut_nmsedec_ref[(x >> (bitpos - T1_NMSEDEC_FRACBITS)) &
+                                                                                                                       ((1 << T1_NMSEDEC_BITS) - 1)];
+       else
+               return t1_lut_nmsedec_ref0[x & ((1 << T1_NMSEDEC_BITS) - 1)];
+}
+
+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;
+       }
+}
+
+void t1_enc_sigpass_step(int *fp, int *dp, int orient, int bpno, int one,
+                                                                                                int *nmsedec, char type, int vsc)
+{
+       int v, flag;
+       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(t1_getctxno_zc(flag, orient));    /* ESSAI */
+                       mqc_bypass_enc(v);
+               } else {
+                       mqc_setcurctx(t1_getctxno_zc(flag, orient));
+                       mqc_encode(v);
+               }
+               if (v) {
+                       v = *dp < 0 ? 1 : 0;
+                       *nmsedec +=
+                               t1_getnmsedec_sig(int_abs(*dp), bpno + T1_NMSEDEC_FRACBITS);
+                       if (type == T1_TYPE_RAW) {      /* BYPASS/LAZY MODE */
+                               mqc_setcurctx(t1_getctxno_sc(flag));    /* ESSAI */
+                               mqc_bypass_enc(v);
+                       } else {
+                               mqc_setcurctx(t1_getctxno_sc(flag));
+                               mqc_encode(v ^ t1_getspb(flag));
+                       }
+                       t1_updateflags(fp, v);
+                       *fp |= T1_SIG;
+               }
+               *fp |= T1_VISIT;
+       }
+}
+
+void t1_dec_sigpass_step(int *fp, int *dp, int orient, int oneplushalf,
+                                                                                                char type, int vsc)
+{
+       int v, flag;
+       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()) {
+                               v = raw_decode();                               /* ESSAI */
+                               *dp = v ? -oneplushalf : oneplushalf;
+                               t1_updateflags(fp, v);
+                               *fp |= T1_SIG;
+                       }
+               } else {
+                       mqc_setcurctx(t1_getctxno_zc(flag, orient));
+                       if (mqc_decode()) {
+                               mqc_setcurctx(t1_getctxno_sc(flag));
+                               v = mqc_decode() ^ t1_getspb(flag);
+                               *dp = v ? -oneplushalf : oneplushalf;
+                               t1_updateflags(fp, v);
+                               *fp |= T1_SIG;
+                       }
+               }
+               *fp |= T1_VISIT;
+       }
+}                                                                                                                              /* VSC and  BYPASS by Antonin */
+
+void t1_enc_sigpass(int w, int h, int bpno, int orient, int *nmsedec,
+                                                                               char type, int cblksty)
+{
+       int i, j, k, one, vsc;
+       *nmsedec = 0;
+       one = 1 << (bpno + T1_NMSEDEC_FRACBITS);
+       for (k = 0; k < h; k += 4) {
+               for (i = 0; i < w; i++) {
+                       for (j = k; j < k + 4 && j < h; j++) {
+                               vsc = ((cblksty & J2K_CCP_CBLKSTY_VSC)
+                                                        && (j == k + 3 || j == h - 1)) ? 1 : 0;
+                               t1_enc_sigpass_step(&t1_flags[1 + j][1 + i], &t1_data[j][i],
+                                                                                                               orient, bpno, one, nmsedec, type, vsc);
+                       }
+               }
+       }
+}
+
+void t1_dec_sigpass(int w, int h, int bpno, int orient, char type,
+                                                                               int cblksty)
+{
+       int i, j, k, one, half, oneplushalf, vsc;
+       one = 1 << bpno;
+       half = one >> 1;
+       oneplushalf = one | half;
+       for (k = 0; k < h; k += 4) {
+               for (i = 0; i < w; i++) {
+                       for (j = k; j < k + 4 && j < h; j++) {
+                               vsc = ((cblksty & J2K_CCP_CBLKSTY_VSC)
+                                                        && (j == k + 3 || j == h - 1)) ? 1 : 0;
+                               t1_dec_sigpass_step(&t1_flags[1 + j][1 + i], &t1_data[j][i],
+                                                                                                               orient, oneplushalf, type, vsc);
+                       }
+               }
+       }
+}                                                                                                                              /* VSC and  BYPASS by Antonin */
+
+void t1_enc_refpass_step(int *fp, int *dp, int bpno, int one, int *nmsedec,
+                                                                                                char type, int vsc)
+{
+       int v, flag;
+       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(int_abs(*dp), bpno + T1_NMSEDEC_FRACBITS);
+               v = int_abs(*dp) & one ? 1 : 0;
+               if (type == T1_TYPE_RAW) {      /* BYPASS/LAZY MODE */
+                       mqc_setcurctx(t1_getctxno_mag(flag));   /* ESSAI */
+                       mqc_bypass_enc(v);
+               } else {
+                       mqc_setcurctx(t1_getctxno_mag(flag));
+                       mqc_encode(v);
+               }
+               *fp |= T1_REFINE;
+       }
+}
+
+void t1_dec_refpass_step(int *fp, int *dp, int poshalf, int neghalf,
+                                                                                                char type, int vsc)
+{
+       int v, t, flag;
+       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(t1_getctxno_mag(flag));   /* ESSAI */
+                       v = raw_decode();
+               } else {
+                       mqc_setcurctx(t1_getctxno_mag(flag));
+                       v = mqc_decode();
+               }
+               t = v ? poshalf : neghalf;
+               *dp += *dp < 0 ? -t : t;
+               *fp |= T1_REFINE;
+       }
+}                                                                                                                              /* VSC and  BYPASS by Antonin  */
+
+void t1_enc_refpass(int w, int h, int bpno, int *nmsedec, char type,
+                                                                               int cblksty)
+{
+       int i, j, k, one, vsc;
+       *nmsedec = 0;
+       one = 1 << (bpno + T1_NMSEDEC_FRACBITS);
+       for (k = 0; k < h; k += 4) {
+               for (i = 0; i < w; i++) {
+                       for (j = k; j < k + 4 && j < h; j++) {
+                               vsc = ((cblksty & J2K_CCP_CBLKSTY_VSC)
+                                                        && (j == k + 3 || j == h - 1)) ? 1 : 0;
+                               t1_enc_refpass_step(&t1_flags[1 + j][1 + i], &t1_data[j][i], bpno,
+                                                                                                               one, nmsedec, type, vsc);
+                       }
+               }
+       }
+}
+
+void t1_dec_refpass(int w, int h, int bpno, char type, int cblksty)
+{
+       int i, j, k, one, poshalf, neghalf;
+       int vsc;
+       one = 1 << bpno;
+       poshalf = one >> 1;
+       neghalf = bpno > 0 ? -poshalf : -1;
+       for (k = 0; k < h; k += 4) {
+               for (i = 0; i < w; i++) {
+                       for (j = k; j < k + 4 && j < h; j++) {
+                               vsc = ((cblksty & J2K_CCP_CBLKSTY_VSC)
+                                                        && (j == k + 3 || j == h - 1)) ? 1 : 0;
+                               t1_dec_refpass_step(&t1_flags[1 + j][1 + i], &t1_data[j][i],
+                                                                                                               poshalf, neghalf, type, vsc);
+                       }
+               }
+       }
+}                                                                                                                              /* VSC and  BYPASS by Antonin */
+
+void t1_enc_clnpass_step(int *fp, int *dp, int orient, int bpno, int one,
+                                                                                                int *nmsedec, int partial, int vsc)
+{
+       int v, flag;
+       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(t1_getctxno_zc(flag, orient));
+               v = int_abs(*dp) & one ? 1 : 0;
+               mqc_encode(v);
+               if (v) {
+               label_partial:
+                       *nmsedec +=
+                               t1_getnmsedec_sig(int_abs(*dp), bpno + T1_NMSEDEC_FRACBITS);
+                       mqc_setcurctx(t1_getctxno_sc(flag));
+                       v = *dp < 0 ? 1 : 0;
+                       mqc_encode(v ^ t1_getspb(flag));
+                       t1_updateflags(fp, v);
+                       *fp |= T1_SIG;
+               }
+       }
+       *fp &= ~T1_VISIT;
+}
+
+void t1_dec_clnpass_step(int *fp, int *dp, int orient, int oneplushalf,
+                                                                                                int partial, int vsc)
+{
+       int v, flag;
+       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(t1_getctxno_zc(flag, orient));
+               if (mqc_decode()) {
+               label_partial:
+                       mqc_setcurctx(t1_getctxno_sc(flag));
+                       v = mqc_decode() ^ t1_getspb(flag);
+                       *dp = v ? -oneplushalf : oneplushalf;
+                       t1_updateflags(fp, v);
+                       *fp |= T1_SIG;
+               }
+       }
+       *fp &= ~T1_VISIT;
+}                                                                                                                              /* VSC and  BYPASS by Antonin */
+
+void t1_enc_clnpass(int w, int h, int bpno, int orient, int *nmsedec,
+                                                                               int cblksty)
+{
+       int i, j, k, one, agg, runlen, vsc;
+       *nmsedec = 0;
+       one = 1 << (bpno + T1_NMSEDEC_FRACBITS);
+       for (k = 0; k < h; k += 4) {
+               for (i = 0; i < w; i++) {
+                       if (k + 3 < h) {
+                               if (cblksty & J2K_CCP_CBLKSTY_VSC) {
+                                       agg = !(t1_flags[1 + k][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH)
+                                                                       || t1_flags[1 + k + 1][1 +
+                                                                                                                                                                i] & (T1_SIG | T1_VISIT |
+                                                                                                                                                                                        T1_SIG_OTH)
+                                                                       || t1_flags[1 + k + 2][1 +
+                                                                                                                                                                i] & (T1_SIG | T1_VISIT |
+                                                                                                                                                                                        T1_SIG_OTH)
+                                                                       || (t1_flags[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 + k][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH)
+                                                                       || t1_flags[1 + k + 1][1 +
+                                                                                                                                                                i] & (T1_SIG | T1_VISIT |
+                                                                                                                                                                                        T1_SIG_OTH)
+                                                                       || t1_flags[1 + k + 2][1 +
+                                                                                                                                                                i] & (T1_SIG | T1_VISIT |
+                                                                                                                                                                                        T1_SIG_OTH)
+                                                                       || t1_flags[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[k + runlen][i]) & one)
+                                               break;
+                               }
+                               mqc_setcurctx(T1_CTXNO_AGG);
+                               mqc_encode(runlen != 4);
+                               if (runlen == 4) {
+                                       continue;
+                               }
+                               mqc_setcurctx(T1_CTXNO_UNI);
+                               mqc_encode(runlen >> 1);
+                               mqc_encode(runlen & 1);
+                       } else {
+                               runlen = 0;
+                       }
+                       for (j = k + runlen; j < k + 4 && j < h; j++) {
+                               vsc = ((cblksty & J2K_CCP_CBLKSTY_VSC)
+                                                        && (j == k + 3 || j == h - 1)) ? 1 : 0;
+                               t1_enc_clnpass_step(&t1_flags[1 + j][1 + i], &t1_data[j][i],
+                                                                                                               orient, bpno, one, nmsedec, agg
+                                                                                                               && (j == k + runlen), vsc);
+                       }
+               }
+       }
+}
+
+void t1_dec_clnpass(int w, int h, int bpno, int orient, int cblksty)
+{
+       int i, j, k, one, half, oneplushalf, agg, runlen, vsc;
+       int segsym = cblksty & J2K_CCP_CBLKSTY_SEGSYM;
+       one = 1 << bpno;
+       half = one >> 1;
+       oneplushalf = one | half;
+       for (k = 0; k < h; k += 4) {
+               for (i = 0; i < w; i++) {
+                       if (k + 3 < h) {
+                               if (cblksty & J2K_CCP_CBLKSTY_VSC) {
+                                       agg = !(t1_flags[1 + k][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH)
+                                                                       || t1_flags[1 + k + 1][1 +
+                                                                                                                                                                i] & (T1_SIG | T1_VISIT |
+                                                                                                                                                                                        T1_SIG_OTH)
+                                                                       || t1_flags[1 + k + 2][1 +
+                                                                                                                                                                i] & (T1_SIG | T1_VISIT |
+                                                                                                                                                                                        T1_SIG_OTH)
+                                                                       || (t1_flags[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 + k][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH)
+                                                                       || t1_flags[1 + k + 1][1 +
+                                                                                                                                                                i] & (T1_SIG | T1_VISIT |
+                                                                                                                                                                                        T1_SIG_OTH)
+                                                                       || t1_flags[1 + k + 2][1 +
+                                                                                                                                                                i] & (T1_SIG | T1_VISIT |
+                                                                                                                                                                                        T1_SIG_OTH)
+                                                                       || t1_flags[1 + k + 3][1 +
+                                                                                                                                                                i] & (T1_SIG | T1_VISIT |
+                                                                                                                                                                                        T1_SIG_OTH));
+                               }
+                       } else {
+                               agg = 0;
+                       }
+                       if (agg) {
+                               mqc_setcurctx(T1_CTXNO_AGG);
+                               if (!mqc_decode()) {
+                                       continue;
+                               }
+                               mqc_setcurctx(T1_CTXNO_UNI);
+                               runlen = mqc_decode();
+                               runlen = (runlen << 1) | mqc_decode();
+                       } else {
+                               runlen = 0;
+                       }
+                       for (j = k + runlen; j < k + 4 && j < h; j++) {
+                               vsc = ((cblksty & J2K_CCP_CBLKSTY_VSC)
+                                                        && (j == k + 3 || j == h - 1)) ? 1 : 0;
+                               t1_dec_clnpass_step(&t1_flags[1 + j][1 + i], &t1_data[j][i],
+                                                                                                               orient, oneplushalf, agg
+                                                                                                               && (j == k + runlen), vsc);
+                       }
+               }
+       }
+       if (segsym) {
+               int v = 0;
+               mqc_setcurctx(T1_CTXNO_UNI);
+               v = mqc_decode();
+               v = (v << 1) | mqc_decode();
+               v = (v << 1) | mqc_decode();
+               v = (v << 1) | mqc_decode();
+               /*  if (v!=0xa) 
+                  {
+                  fprintf(stderr, "warning: bad segmentation symbol %x\n",v);
+                  } */
+       }
+}                                                                                                                              /* VSC and  BYPASS by Antonin */
+
+double t1_getwmsedec(int nmsedec, int compno, int level, int orient,
+                                                                                int bpno, int qmfbid, double stepsize)
+{
+       double w1, w2, wmsedec;
+       if (qmfbid == 1) {
+               w1 = mct_getnorm(compno);
+               w2 = dwt_getnorm(level, orient);
+       } else {  /* if (qmfbid == 0) */
+               w1 = mct_getnorm_real(compno);
+               w2 = dwt_getnorm_real(level, orient);
+       }
+       wmsedec = w1 * w2 * stepsize * (1 << bpno);
+       wmsedec *= wmsedec * nmsedec / 8192.0;
+       return wmsedec;
+}
+
+void t1_encode_cblk(tcd_cblk_t * cblk, int orient, int compno, int level,
+                                                                               int qmfbid, double stepsize, int cblksty)
+{
+       int i, j;
+       int w, h;
+       int passno;
+       int bpno, passtype;
+       int max;
+       int nmsedec;
+       double cumwmsedec = 0;
+       char type = T1_TYPE_MQ;
+
+       w = cblk->x1 - cblk->x0;
+       h = cblk->y1 - cblk->y0;
+
+       max = 0;
+       for (j = 0; j < h; j++) {
+               for (i = 0; i < w; i++) {
+                       max = int_max(max, int_abs(t1_data[j][i]));
+               }
+       }
+
+       cblk->numbps = max ? (int_floorlog2(max) + 1) - T1_NMSEDEC_FRACBITS : 0;
+
+       for (i = 0; i < sizeof(t1_flags) / sizeof(int); i++)
+               ((int *) t1_flags)[i] = 0;
+       bpno = cblk->numbps - 1;
+       passtype = 2;
+
+       mqc_resetstates();
+       mqc_setstate(T1_CTXNO_UNI, 0, 46);
+       mqc_setstate(T1_CTXNO_AGG, 0, 3);
+       mqc_setstate(T1_CTXNO_ZC, 0, 4);
+       mqc_init_enc(cblk->data);
+
+       for (passno = 0; bpno >= 0; passno++) {
+               tcd_pass_t *pass = &cblk->passes[passno];
+               int correction = 3;
+               type = ((bpno < (cblk->numbps - 4)) && (passtype < 2)
+                                               && (cblksty & J2K_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW :
+                       T1_TYPE_MQ;
+
+               switch (passtype) {
+               case 0:
+                       t1_enc_sigpass(w, h, bpno, orient, &nmsedec, type, cblksty);
+                       break;
+               case 1:
+                       t1_enc_refpass(w, h, bpno, &nmsedec, type, cblksty);
+                       break;
+               case 2:
+                       t1_enc_clnpass(w, h, bpno, orient, &nmsedec, cblksty);
+                       /* code switch SEGMARK (i.e. SEGSYM) */
+                       if (cblksty & J2K_CCP_CBLKSTY_SEGSYM)
+                               mqc_segmark_enc();
+                       break;
+               }
+
+               cumwmsedec +=
+                       t1_getwmsedec(nmsedec, compno, level, orient, bpno, qmfbid,
+                                                                               stepsize);
+
+               /* Code switch "RESTART" (i.e. TERMALL) */
+               if ((cblksty & J2K_CCP_CBLKSTY_TERMALL)
+                               && !((passtype == 2) && (bpno - 1 < 0))) {
+                       if (type == T1_TYPE_RAW)
+                               correction = mqc_bypass_flush_enc();
+                       else
+                               correction = mqc_restart_enc();
+
+                       pass->term = 1;
+               } else {
+                       if (((bpno < (cblk->numbps - 4) && (passtype > 0))
+                                        || ((bpno == (cblk->numbps - 4)) && (passtype == 2)))
+                                       && (cblksty & J2K_CCP_CBLKSTY_LAZY)) {
+                               if (type == T1_TYPE_RAW)
+                                       correction = mqc_bypass_flush_enc();
+                               else
+                                       correction = mqc_restart_enc();
+
+                               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 & J2K_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW :
+                               T1_TYPE_MQ;
+                       if (type == T1_TYPE_RAW)
+                               mqc_bypass_init_enc();
+                       else
+                               mqc_restart_init_enc();
+               }
+
+               pass->distortiondec = cumwmsedec;
+               pass->rate = mqc_numbytes() + correction;       /* FIXME */
+               pass->len =
+                       pass->rate - (passno == 0 ? 0 : cblk->passes[passno - 1].rate);
+
+               /* Code-switch "RESET" */
+               if (cblksty & J2K_CCP_CBLKSTY_RESET)
+                       mqc_reset_enc();
+       }
+
+       /* Code switch "ERTERM" (i.e. PTERM) */
+       if (cblksty & J2K_CCP_CBLKSTY_PTERM)
+               mqc_erterm_enc();
+       else /* Default coding */ if (!(cblksty & J2K_CCP_CBLKSTY_LAZY))
+               mqc_flush();
+
+       cblk->totalpasses = passno;
+}
+
+void t1_decode_cblk(tcd_cblk_t * cblk, int orient, int roishift,
+                                                                               int cblksty)
+{
+       int i;
+       int w, h;
+       int bpno, passtype;
+       int segno, passno;
+       /* add TONY */
+       char type = T1_TYPE_MQ;
+       /* dda */
+
+       for (i = 0; i < sizeof(t1_data) / sizeof(int); i++)
+               ((int *) t1_data)[i] = 0;
+       for (i = 0; i < sizeof(t1_flags) / sizeof(int); i++)
+               ((int *) t1_flags)[i] = 0;
+
+       w = cblk->x1 - cblk->x0;
+       h = cblk->y1 - cblk->y0;
+       bpno = roishift + cblk->numbps - 1;
+       passtype = 2;
+
+       mqc_resetstates();
+       mqc_setstate(T1_CTXNO_UNI, 0, 46);
+       mqc_setstate(T1_CTXNO_AGG, 0, 3);
+       mqc_setstate(T1_CTXNO_ZC, 0, 4);
+
+       for (segno = 0; segno < cblk->numsegs; segno++) {
+               tcd_seg_t *seg = &cblk->segs[segno];
+
+               /* add TONY */
+               type = ((bpno <= (cblk->numbps - 1) - 4) && (passtype < 2)
+                                               && (cblksty & J2K_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW :
+                       T1_TYPE_MQ;
+               if (type == T1_TYPE_RAW)
+                       raw_init_dec(seg->data, seg->len);
+               else
+                       mqc_init_dec(seg->data, seg->len);
+               /* dda */
+
+               for (passno = 0; passno < seg->numpasses; passno++) {
+                       switch (passtype) {
+                       case 0:
+                               t1_dec_sigpass(w, h, bpno, orient, type, cblksty);
+                               break;
+                       case 1:
+                               t1_dec_refpass(w, h, bpno, type, cblksty);
+                               break;
+                       case 2:
+                               t1_dec_clnpass(w, h, bpno, orient, cblksty);
+                               break;
+                       }
+
+                       if ((cblksty & J2K_CCP_CBLKSTY_RESET) && type == T1_TYPE_MQ)
+                               mqc_reset_enc();
+
+                       if (++passtype == 3) {
+                               passtype = 0;
+                               bpno--;
+                       }
+               }
+       }
+}
+
+void t1_encode_cblks(tcd_tile_t * tile, j2k_tcp_t * tcp)
+{
+       int compno, resno, bandno, precno, cblkno;
+       int x, y, i, j, orient;
+       tcd_tilecomp_t *tilec;
+       tcd_resolution_t *res;
+       tcd_band_t *band;
+       tcd_precinct_t *prc;
+       tcd_cblk_t *cblk;
+
+       for (compno = 0; compno < tile->numcomps; compno++) {
+               tilec = &tile->comps[compno];
+               for (resno = 0; resno < tilec->numresolutions; resno++) {
+                       res = &tilec->resolutions[resno];
+                       for (bandno = 0; bandno < res->numbands; bandno++) {
+                               band = &res->bands[bandno];
+                               for (precno = 0; precno < res->pw * res->ph; precno++) {
+                                       prc = &band->precincts[precno];
+                                       for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
+                                               cblk = &prc->cblks[cblkno];
+
+                                               if (band->bandno == 0) {
+                                                       x = cblk->x0 - band->x0;
+                                                       y = cblk->y0 - band->y0;
+                                               } else if (band->bandno == 1) {
+                                                       tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+                                                       x = pres->x1 - pres->x0 + cblk->x0 - band->x0;
+                                                       y = cblk->y0 - band->y0;
+                                               } else if (band->bandno == 2) {
+                                                       tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+                                                       x = cblk->x0 - band->x0;
+                                                       y = pres->y1 - pres->y0 + cblk->y0 - band->y0;
+                                               } else {  /* if (band->bandno == 3) */
+                                                       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;
+                                               }
+
+                                               if (tcp->tccps[compno].qmfbid == 1) {
+
+                                                       for (j = 0; j < cblk->y1 - cblk->y0; j++) {
+                                                               for (i = 0; i < cblk->x1 - cblk->x0; i++) {
+                                                                       t1_data[j][i] =
+                                                                               tilec->data[(x + i) +
+                                                                                                                               (y + j) * (tilec->x1 -
+                                                                                                                                                                        tilec->
+                                                                                                                                                                        x0)] << T1_NMSEDEC_FRACBITS;
+                                                               }
+                                                       }
+                                               } else if (tcp->tccps[compno].qmfbid == 0) {
+                                                       for (j = 0; j < cblk->y1 - cblk->y0; j++) {
+                                                               for (i = 0; i < cblk->x1 - cblk->x0; i++) {
+                                                                       t1_data[j][i] =
+                                                                               fix_mul(tilec->
+                                                                                                               data[x + i +
+                                                                                                                                (y + j) * (tilec->x1 - tilec->x0)],
+                                                                                                               8192 * 8192 / band->stepsize) >> (13 -
+                                                                                                                                                                                                                                                       T1_NMSEDEC_FRACBITS);
+                                                               }
+                                                       }
+                                               }
+                                               orient = band->bandno;  /* FIXME */
+                                               if (orient == 2) {
+                                                       orient = 1;
+                                               } else if (orient == 1) {
+                                                       orient = 2;
+                                               }
+                                               t1_encode_cblk(cblk, orient, compno,
+                                                                                                        tilec->numresolutions - 1 - resno,
+                                                                                                        tcp->tccps[compno].qmfbid, band->stepsize,
+                                                                                                        tcp->tccps[compno].cblksty);
+                                       }                                                                                       /* cblkno */
+
+                               }                                                                                               /* precno */
+                       }                                                                                                       /* bandno */
+
+               }                                                                                                               /* resno */
+
+       }                                                                                                                       /* compo */
+
+}
+
+
+void t1_decode_cblks(tcd_tile_t * tile, j2k_tcp_t * tcp)
+{
+       int compno, resno, bandno, precno, cblkno;
+
+       for (compno = 0; compno < tile->numcomps; compno++) {
+               tcd_tilecomp_t *tilec = &tile->comps[compno];
+               for (resno = 0; resno < tilec->numresolutions; resno++) {
+                       tcd_resolution_t *res = &tilec->resolutions[resno];
+                       for (bandno = 0; bandno < res->numbands; bandno++) {
+                               tcd_band_t *band = &res->bands[bandno];
+                               for (precno = 0; precno < res->pw * res->ph; precno++) {
+                                       tcd_precinct_t *prc = &band->precincts[precno];
+                                       for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
+                                               int x, y, i, j, orient;
+                                               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(cblk, orient, tcp->tccps[compno].roishift,
+                                                                                                        tcp->tccps[compno].cblksty);
+                                               if (band->bandno == 0) {
+                                                       x = cblk->x0 - band->x0;
+                                                       y = cblk->y0 - band->y0;
+                                               } else if (band->bandno == 1) {
+                                                       tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+                                                       x = pres->x1 - pres->x0 + cblk->x0 - band->x0;
+                                                       y = cblk->y0 - band->y0;
+                                               } else if (band->bandno == 2) {
+                                                       tcd_resolution_t *pres = &tilec->resolutions[resno - 1];
+                                                       x = cblk->x0 - band->x0;
+                                                       y = pres->y1 - pres->y0 + cblk->y0 - band->y0;
+                                               } else {  /* if (band->bandno == 3) */
+                                                       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;
+                                               }
+                                               if (tcp->tccps[compno].roishift) {
+                                                       int thresh, val, mag;
+                                                       thresh = 1 << tcp->tccps[compno].roishift;
+                                                       for (j = 0; j < cblk->y1 - cblk->y0; j++) {
+                                                               for (i = 0; i < cblk->x1 - cblk->x0; i++) {
+                                                                       val = t1_data[j][i];
+                                                                       mag = int_abs(val);
+                                                                       if (mag >= thresh) {
+                                                                               mag >>= tcp->tccps[compno].roishift;
+                                                                               t1_data[j][i] = val < 0 ? -mag : mag;
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+
+                                               if (tcp->tccps[compno].qmfbid == 1) {
+                                                       for (j = 0; j < cblk->y1 - cblk->y0; j++) {
+                                                               for (i = 0; i < cblk->x1 - cblk->x0; i++) {
+                                                                       tilec->data[x + i + (y + j) * (tilec->x1 - tilec->x0)] =
+                                                                               t1_data[j][i];
+                                                               }
+                                                       }
+                                               } else if (tcp->tccps[compno].qmfbid == 0) {
+                                                       for (j = 0; j < cblk->y1 - cblk->y0; j++) {
+                                                               for (i = 0; i < cblk->x1 - cblk->x0; i++) {
+                                                                       if (t1_data[j][i] == 0) {
+                                                                               tilec->data[x + i +
+                                                                                                                               (y + j) * (tilec->x1 - tilec->x0)] = 0;
+                                                                       } else {
+                                                                               tilec->data[x + i +
+                                                                                                                               (y + j) * (tilec->x1 - tilec->x0)] =
+                                                                                       fix_mul(t1_data[j][i] << 13, band->stepsize);
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
+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;
+}
+
+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;
+}
+
+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;
+}
+
+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;
+}
+
+void t1_init_luts()
+{
+       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 */
+       /* printf("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));
+       }
+}
diff --git a/libopenjpeg/t1.h b/libopenjpeg/t1.h
new file mode 100644 (file)
index 0000000..5e98bc0
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001-2002, David Janssens
+ * 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
+
+#include "tcd.h"
+#include "j2k.h"
+
+/*
+ * Initialize the look-up tables of the Tier-1 coder/decoder
+ */
+void t1_init_luts();
+
+/*
+ * Encode the code-blocks of a tile
+ * tile: the tile to encode
+ * tcp: tile coding parameters
+ */
+void t1_encode_cblks(tcd_tile_t * tile, j2k_tcp_t * tcp);
+
+/*
+ * Decode the code-blocks of a tile
+ * tile: the tile to encode
+ * tcp: tile coding parameters
+ */
+void t1_decode_cblks(tcd_tile_t * tile, j2k_tcp_t * tcp);
+
+#endif
diff --git a/libopenjpeg/t2.c b/libopenjpeg/t2.c
new file mode 100644 (file)
index 0000000..9bd3a2b
--- /dev/null
@@ -0,0 +1,505 @@
+/*
+ * Copyright (c) 2001-2002, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2002-2003,  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 "t2.h"
+#include "tcd.h"
+#include "bio.h"
+#include "j2k.h"
+#include "pi.h"
+#include "tgt.h"
+#include "int.h"
+#include "cio.h"
+#include <stdio.h>
+#include <setjmp.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define RESTART 0x04
+
+extern jmp_buf j2k_error;
+
+void t2_putcommacode(int n)
+{
+       while (--n >= 0) {
+               bio_write(1, 1);
+       }
+       bio_write(0, 1);
+}
+
+int t2_getcommacode()
+{
+       int n;
+       for (n = 0; bio_read(1); n++) {
+       }
+       return n;
+}
+
+/* <summary> */
+/* Variable length code for signalling delta Zil (truncation point) */
+/* <val> n : delta Zil */
+/* <\summary> */
+void t2_putnumpasses(int n)
+{
+       if (n == 1) {
+               bio_write(0, 1);
+       } else if (n == 2) {
+               bio_write(2, 2);
+       } else if (n <= 5) {
+               bio_write(0xc | (n - 3), 4);
+       } else if (n <= 36) {
+               bio_write(0x1e0 | (n - 6), 9);
+       } else if (n <= 164) {
+               bio_write(0xff80 | (n - 37), 16);
+       }
+}
+
+int t2_getnumpasses()
+{
+       int n;
+       if (!bio_read(1))
+               return 1;
+       if (!bio_read(1))
+               return 2;
+       if ((n = bio_read(2)) != 3)
+               return 3 + n;
+       if ((n = bio_read(5)) != 31)
+               return 6 + n;
+       return 37 + bio_read(7);
+}
+
+int t2_encode_packet(tcd_tile_t * tile, j2k_tcp_t * tcp, int compno,
+                                                                                int resno, int precno, int layno, unsigned char *dest,
+                                                                                int len, info_image * info_IM, int tileno)
+{
+       int bandno, cblkno;
+       unsigned char *sop = 0, *eph = 0;
+       tcd_tilecomp_t *tilec = &tile->comps[compno];
+       tcd_resolution_t *res = &tilec->resolutions[resno];
+       unsigned char *c = dest;
+
+       /* int PPT=tile->PPT, ppt_len=0; */
+       /* FILE *PPT_file; */
+
+       /* <SOP 0xff91> */
+       if (tcp->csty & J2K_CP_CSTY_SOP) {
+               sop = (unsigned char *) malloc(6 * sizeof(unsigned char));
+               sop[0] = 255;
+               sop[1] = 145;
+               sop[2] = 0;
+               sop[3] = 4;
+               sop[4] = (info_IM->num % 65536) / 256;
+               sop[5] = (info_IM->num % 65536) % 256;
+               memcpy(c, sop, 6);
+               free(sop);
+               c += 6;
+       }
+       /* </SOP> */
+
+       if (!layno) {
+               for (bandno = 0; bandno < res->numbands; bandno++) {
+                       tcd_band_t *band = &res->bands[bandno];
+                       tcd_precinct_t *prc = &band->precincts[precno];
+                       tgt_reset(prc->incltree);
+                       tgt_reset(prc->imsbtree);
+                       for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
+                               tcd_cblk_t *cblk = &prc->cblks[cblkno];
+                               cblk->numpasses = 0;
+                               tgt_setvalue(prc->imsbtree, cblkno, band->numbps - cblk->numbps);
+                       }
+               }
+       }
+
+       bio_init_enc(c, len);
+       bio_write(1, 1);                                                        /* Empty header bit */
+
+       /* Writing Packet header */
+       for (bandno = 0; bandno < res->numbands; bandno++) {
+               tcd_band_t *band = &res->bands[bandno];
+               tcd_precinct_t *prc = &band->precincts[precno];
+               for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
+                       tcd_cblk_t *cblk = &prc->cblks[cblkno];
+                       tcd_layer_t *layer = &cblk->layers[layno];
+                       if (!cblk->numpasses && layer->numpasses) {
+                               tgt_setvalue(prc->incltree, cblkno, layno);
+                       }
+               }
+               for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
+                       tcd_cblk_t *cblk = &prc->cblks[cblkno];
+                       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(prc->incltree, cblkno, layno + 1);
+                       } else {
+                               bio_write(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(prc->imsbtree, cblkno, 999);
+                       }
+                       /* number of coding passes included */
+                       t2_putnumpasses(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++) {
+                               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(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++) {
+                               tcd_pass_t *pass = &cblk->passes[passno];
+                               nump++;
+                               len += pass->len;
+                               if (pass->term
+                                               || passno == (cblk->numpasses + layer->numpasses) - 1) {
+                                       bio_write(len, cblk->numlenbits + int_floorlog2(nump));
+                                       len = 0;
+                                       nump = 0;
+                               }
+                       }
+               }
+       }
+
+       if (bio_flush())
+               return -999;                                                            /* modified to eliminate longjmp !! */
+
+       c += bio_numbytes();
+
+       /* <EPH 0xff92> */
+       if (tcp->csty & J2K_CP_CSTY_EPH) {
+               eph = (unsigned char *) malloc(2 * sizeof(unsigned char));
+               eph[0] = 255;
+               eph[1] = 146;
+               memcpy(c, eph, 2);
+               free(eph);
+               c += 2;
+       }
+       /* </EPH> */
+       /*   } */
+       /* Writing the packet body */
+
+       for (bandno = 0; bandno < res->numbands; bandno++) {
+               tcd_band_t *band = &res->bands[bandno];
+               tcd_precinct_t *prc = &band->precincts[precno];
+               for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
+                       tcd_cblk_t *cblk = &prc->cblks[cblkno];
+                       tcd_layer_t *layer = &cblk->layers[layno];
+                       if (!layer->numpasses) {        /* ADD for index Cfr. Marcela --> delta disto by packet */
+                               if (info_IM->index_write && info_IM->index_on) {
+                                       info_tile *info_TL = &info_IM->tile[tileno];
+                                       info_packet *info_PK = &info_TL->packet[info_IM->num];
+                                       info_PK->disto = layer->disto;
+                                       if (info_IM->D_max < info_PK->disto)
+                                               info_IM->D_max = info_PK->disto;
+                               }                                                                                               /* </ADD> */
+                               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 (info_IM->index_write && info_IM->index_on) {
+                               info_tile *info_TL = &info_IM->tile[tileno];
+                               info_packet *info_PK = &info_TL->packet[info_IM->num];
+                               info_PK->disto = layer->disto;
+                               if (info_IM->D_max < info_PK->disto)
+                                       info_IM->D_max = info_PK->disto;
+                       }                                                                                                       /* </ADD> */
+               }
+       }
+       return c - dest;
+}
+
+void t2_init_seg(tcd_seg_t * seg, int cblksty, int first)
+{
+       seg->numpasses = 0;
+       seg->len = 0;
+       if (cblksty & J2K_CCP_CBLKSTY_TERMALL)
+               seg->maxpasses = 1;
+       else if (cblksty & J2K_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(unsigned char *src, int len, tcd_tile_t * tile,
+                                                                                j2k_tcp_t * tcp, int compno, int resno, int precno,
+                                                                                int layno)
+{
+       int bandno, cblkno;
+       tcd_tilecomp_t *tilec = &tile->comps[compno];
+       tcd_resolution_t *res = &tilec->resolutions[resno];
+       unsigned char *c = src;
+       int present;
+
+       if (layno == 0) {
+               for (bandno = 0; bandno < res->numbands; bandno++) {
+                       tcd_band_t *band = &res->bands[bandno];
+                       tcd_precinct_t *prc = &band->precincts[precno];
+                       tgt_reset(prc->incltree);
+                       tgt_reset(prc->imsbtree);
+                       for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
+                               tcd_cblk_t *cblk = &prc->cblks[cblkno];
+                               cblk->numsegs = 0;
+                       }
+               }
+       }
+
+       if (tcp->csty & J2K_CP_CSTY_SOP) {
+               c += 6;
+       }
+       bio_init_dec(c, src + len - c);
+       present = bio_read(1);
+       if (!present) {
+               bio_inalign();
+               c += bio_numbytes();
+               return c - src;
+       }
+       for (bandno = 0; bandno < res->numbands; bandno++) {
+               tcd_band_t *band = &res->bands[bandno];
+               tcd_precinct_t *prc = &band->precincts[precno];
+               for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
+                       int included, increment, n;
+                       tcd_cblk_t *cblk = &prc->cblks[cblkno];
+                       tcd_seg_t *seg;
+                       /* if cblk not yet included before --> inclusion tagtree */
+                       if (!cblk->numsegs) {
+                               included = tgt_decode(prc->incltree, cblkno, layno + 1);
+                               /* else one bit */
+                       } else {
+                               included = bio_read(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(prc->imsbtree, cblkno, i); i++) {
+                               }
+                               numimsbs = i - 1;
+                               cblk->numbps = band->numbps - numimsbs;
+                               cblk->numlenbits = 3;
+                       }
+                       /* number of coding passes */
+                       cblk->numnewpasses = t2_getnumpasses();
+                       increment = t2_getcommacode();
+                       /* 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(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())
+               return -999;
+       c += bio_numbytes();
+       if (tcp->csty & J2K_CP_CSTY_EPH) {
+               c += 2;
+       }
+       for (bandno = 0; bandno < res->numbands; bandno++) {
+               tcd_band_t *band = &res->bands[bandno];
+               tcd_precinct_t *prc = &band->precincts[precno];
+               for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
+                       tcd_cblk_t *cblk = &prc->cblks[cblkno];
+                       tcd_seg_t *seg;
+                       if (!cblk->numnewpasses)
+                               continue;
+                       if (!cblk->numsegs) {
+                               seg = &cblk->segs[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(j2k_image_t * img, j2k_cp_t * cp, int tileno,
+                                                                                       tcd_tile_t * tile, int maxlayers,
+                                                                                       unsigned char *dest, int len, info_image * info_IM)
+{
+       unsigned char *c = dest;
+       int e = 0;
+       pi_iterator_t *pi;
+       int pino, compno;
+
+       pi = pi_create(img, cp, tileno);
+
+       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].compno,
+                                                                                                        pi[pino].resno, pi[pino].precno, pi[pino].layno,
+                                                                                                        c, dest + len - c, info_IM, tileno);
+                               if (e == -999) {
+                                       break;
+                               } else
+                                       c += e;
+                               /* INDEX >> */
+                               if (info_IM->index_write && info_IM->index_on) {
+                                       info_tile *info_TL = &info_IM->tile[tileno];
+                                       info_packet *info_PK = &info_TL->packet[info_IM->num];
+                                       if (!info_IM->num) {
+                                               info_PK->start_pos = info_TL->end_header + 1;
+                                       } else {
+                                               info_PK->start_pos =
+                                                       info_TL->packet[info_IM->num - 1].end_pos + 1;
+                                       }
+                                       info_PK->end_pos = info_PK->start_pos + e - 1;
+
+                               }
+                               /* << INDEX */
+                               if ((info_IM->index_write
+                                                && cp->tcps[tileno].csty & J2K_CP_CSTY_SOP)
+                                               || (info_IM->index_write && info_IM->index_on)) {
+                                       info_IM->num++;
+                               }
+                       }
+
+               }
+
+               /* FREE space memory taken by pi */
+               for (compno = 0; compno < pi[pino].numcomps; compno++) {
+                       free(pi[pino].comps[compno].resolutions);
+               }
+               free(pi[pino].comps);
+       }
+       free(pi);
+       if (e == -999)
+               return e;
+       else
+               return c - dest;
+}
+
+int t2_decode_packets(unsigned char *src, int len, j2k_image_t * img,
+                                                                                       j2k_cp_t * cp, int tileno, tcd_tile_t * tile)
+{
+       unsigned char *c = src;
+       pi_iterator_t *pi;
+       int pino, compno, e = 0;
+
+       pi = pi_create(img, cp, tileno);
+
+       for (pino = 0; pino <= cp->tcps[tileno].numpocs; pino++) {
+               while (pi_next(&pi[pino])) {
+                       e =
+                               t2_decode_packet(c, src + len - c, tile, &cp->tcps[tileno],
+                                                                                                pi[pino].compno, pi[pino].resno, pi[pino].precno,
+                                                                                                pi[pino].layno);
+                       if (e == -999) {                                        /* ADD */
+                               break;
+                       } else
+                               c += e;
+               }
+               /* FREE space memory taken by pi */
+               for (compno = 0; compno < pi[pino].numcomps; compno++) {
+                       free(pi[pino].comps[compno].resolutions);
+               }
+               free(pi[pino].comps);
+       }
+       free(pi);
+       if (e == -999)
+               return e;
+       else
+               return c - src;
+}
diff --git a/libopenjpeg/t2.h b/libopenjpeg/t2.h
new file mode 100644 (file)
index 0000000..4d7757a
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2001-2002, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2002-2003,  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 __T2_H
+#define __T2_H
+
+#include "tcd.h"
+#include "j2k.h"
+
+/*
+ * Encode the packets of a tile to a destination buffer
+ * img: the source image
+ * cp: the image coding parameters
+ * tile: the tile for which to write the packets
+ * dest: the destination buffer
+ * len: the length of the destination buffer
+ */
+int t2_encode_packets(j2k_image_t * img, j2k_cp_t * cp, int tileno,
+                                                                                       tcd_tile_t * tile, int maxlayers,
+                                                                                       unsigned char *dest, int len, info_image * info_IM);
+
+/*
+ * Decode the packets of a tile from a source buffer
+ * src: the source buffer
+ * len: length of the source buffer
+ * img: destination image
+ * cp: image coding parameters
+ * tileno: number that identifies the tile for which to decode the packets
+ * tile: tile for which to decode the packets
+ */
+int t2_decode_packets(unsigned char *src, int len, j2k_image_t * img,
+                                                                                       j2k_cp_t * cp, int tileno, tcd_tile_t * tile);
+
+#endif
diff --git a/libopenjpeg/tcd.c b/libopenjpeg/tcd.c
new file mode 100644 (file)
index 0000000..8b53da0
--- /dev/null
@@ -0,0 +1,1637 @@
+/*
+ * Copyright (c) 2001-2002, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2002-2003,  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 "tcd.h"
+#include "int.h"
+#include "t1.h"
+#include "t2.h"
+#include "dwt.h"
+#include "mct.h"
+#include <setjmp.h>
+#include <float.h>
+#include <stdio.h>
+#include <time.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+static tcd_image_t tcd_image;
+
+static j2k_image_t *tcd_img;
+static j2k_cp_t *tcd_cp;
+
+static tcd_tile_t *tcd_tile;
+static j2k_tcp_t *tcd_tcp;
+static int tcd_tileno;
+
+static tcd_tile_t *tile;
+static tcd_tilecomp_t *tilec;
+static tcd_resolution_t *res;
+static tcd_band_t *band;
+static tcd_precinct_t *prc;
+static tcd_cblk_t *cblk;
+
+extern jmp_buf j2k_error;
+
+void tcd_dump(tcd_image_t * img, int curtileno)
+{
+       int tileno, compno, resno, bandno, precno, cblkno;
+       /* fprintf(stderr, "image {\n"); */
+       fprintf(stderr, "  tw=%d, th=%d x0 %d x1 %d\n", img->tw, img->th,
+                                       tcd_img->x0, tcd_img->x1);
+       for (tileno = 0; tileno < 1; tileno++) {
+               tcd_tile_t *tile = &tcd_image.tiles[curtileno];
+               /* fprintf(stderr, "  tile {\n"); */
+               /* fprintf(stderr, "    x0=%d, y0=%d, x1=%d, y1=%d, numcomps=%d\n", tile->x0, tile->y0, tile->x1, tile->y1, tile->numcomps); */
+               for (compno = 0; compno < tile->numcomps; compno++) {
+                       tcd_tilecomp_t *tilec = &tile->comps[compno];
+                       /* fprintf(stderr, "    tilec {\n"); */
+                       /* fprintf(stderr, "      x0=%d, y0=%d, x1=%d, y1=%d, numresolutions=%d\n", tilec->x0, tilec->y0, tilec->x1, tilec->y1, tilec->numresolutions); */
+                       for (resno = 0; resno < tilec->numresolutions; resno++) {
+                               tcd_resolution_t *res = &tilec->resolutions[resno];
+                               /* fprintf(stderr, "\n   res {\n"); */
+                               /* fprintf(stderr, "          x0=%d, y0=%d, x1=%d, y1=%d, pw=%d, ph=%d, numbands=%d\n", res->x0, res->y0, res->x1, res->y1, res->pw, res->ph, res->numbands); */
+                               for (bandno = 0; bandno < res->numbands; bandno++) {
+                                       tcd_band_t *band = &res->bands[bandno];
+                                       /* fprintf(stderr, "        band {\n"); */
+                                       /* fprintf(stderr, "          x0=%d, y0=%d, x1=%d, y1=%d, stepsize=%d, numbps=%d\n", band->x0, band->y0, band->x1, band->y1, band->stepsize, band->numbps); */
+                                       for (precno = 0; precno < res->pw * res->ph; precno++) {
+                                               tcd_precinct_t *prec = &band->precincts[precno];
+                                               /* fprintf(stderr, "          prec {\n"); */
+                                               /* fprintf(stderr, "            x0=%d, y0=%d, x1=%d, y1=%d, cw=%d, ch=%d\n", prec->x0, prec->y0, prec->x1, prec->y1, prec->cw, prec->ch); */
+                                               for (cblkno = 0; cblkno < prec->cw * prec->ch; cblkno++) {
+                                                       /* tcd_cblk_t *cblk=&prec->cblks[cblkno]; */
+                                                       /* fprintf(stderr, "            cblk {\n"); */
+                                                       /* fprintf(stderr, "              x0=%d, y0=%d, x1=%d, y1=%d\n", cblk->x0, cblk->y0, cblk->x1, cblk->y1); */
+                                                       /* fprintf(stderr, "            }\n"); */
+                                               }
+                                               /* fprintf(stderr, "          }\n"); */
+                                       }
+                                       /* fprintf(stderr, "        }\n"); */
+                               }
+                               /* fprintf(stderr, "      }\n"); */
+                       }
+                       /* fprintf(stderr, "    }\n"); */
+               }
+               /* fprintf(stderr, "  }\n"); */
+       }
+       /* fprintf(stderr, "}\n"); */
+}
+
+void tcd_malloc_encode(j2k_image_t * img, j2k_cp_t * cp, int curtileno)
+{
+       int tileno, compno, resno, bandno, precno, cblkno;
+       tcd_img = img;
+       tcd_cp = cp;
+       tcd_image.tw = cp->tw;
+       tcd_image.th = cp->th;
+       tcd_image.tiles = (tcd_tile_t *) malloc(sizeof(tcd_tile_t));
+
+       for (tileno = 0; tileno < 1; tileno++) {
+               j2k_tcp_t *tcp = &cp->tcps[curtileno];
+               int j;
+               /* cfr p59 ISO/IEC FDIS15444-1 : 2000 (18 august 2000) */
+               int p = curtileno % cp->tw;     /* si numerotation matricielle .. */
+               int q = curtileno / cp->tw;     /* .. coordonnees de la tile (q,p) q pour ligne et p pour colonne */
+               /* tcd_tile_t *tile=&tcd_image.tiles[tileno]; */
+               tile = tcd_image.tiles;
+               /* 4 borders of the tile rescale on the image if necessary */
+               tile->x0 = int_max(cp->tx0 + p * cp->tdx, img->x0);
+               tile->y0 = int_max(cp->ty0 + q * cp->tdy, img->y0);
+               tile->x1 = int_min(cp->tx0 + (p + 1) * cp->tdx, img->x1);
+               tile->y1 = int_min(cp->ty0 + (q + 1) * cp->tdy, img->y1);
+               tile->numcomps = img->numcomps;
+               /* tile->PPT=img->PPT;  */
+               /* Modification of the RATE >> */
+               for (j = 0; j < tcp->numlayers; j++) {
+                       tcp->rates[j] =
+                               ceil(tile->numcomps * (tile->x1 - tile->x0) *
+                                                (tile->y1 -
+                                                       tile->y0) * img->comps[0].prec / (tcp->rates[j] * 8 *
+                                                                                                                                                                                               img->comps[0].dx *
+                                                                                                                                                                                               img->comps[0].dy));
+                       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 =
+                       (tcd_tilecomp_t *) malloc(img->numcomps * sizeof(tcd_tilecomp_t));
+               for (compno = 0; compno < tile->numcomps; compno++) {
+                       j2k_tccp_t *tccp = &tcp->tccps[compno];
+                       /* tcd_tilecomp_t *tilec=&tile->comps[compno]; */
+                       tilec = &tile->comps[compno];
+                       /* border of each tile component (global) */
+                       tilec->x0 = int_ceildiv(tile->x0, img->comps[compno].dx);
+
+                       tilec->y0 = int_ceildiv(tile->y0, img->comps[compno].dy);
+                       tilec->x1 = int_ceildiv(tile->x1, img->comps[compno].dx);
+                       tilec->y1 = int_ceildiv(tile->y1, img->comps[compno].dy);
+
+                       /* Special DWT (always this case) */
+                       tilec->previous_row = 0;
+                       tilec->previous_col = 0;
+
+                       tilec->data =
+                               (int *) malloc(sizeof(int) * (tilec->x1 - tilec->x0) *
+                                                                                        (tilec->y1 - tilec->y0));
+                       tilec->numresolutions = tccp->numresolutions;
+
+                       tilec->resolutions =
+                               (tcd_resolution_t *) malloc(tilec->numresolutions *
+                                                                                                                                               sizeof(tcd_resolution_t));
+
+                       for (resno = 0; resno < tilec->numresolutions; resno++) {
+                               int pdx, pdy;
+                               int levelno = tilec->numresolutions - 1 - resno;
+                               int tlprcxstart, tlprcystart, brprcxend, brprcyend;
+                               int tlcbgxstart, tlcbgystart, brcbgxend, brcbgyend;
+                               int cbgwidthexpn, cbgheightexpn;
+                               int cblkwidthexpn, cblkheightexpn;
+                               /* tcd_resolution_t *res=&tilec->resolutions[resno]; */
+
+                               res = &tilec->resolutions[resno];
+
+                               /* border for each resolution level (global) */
+                               res->x0 = int_ceildivpow2(tilec->x0, levelno);
+                               res->y0 = int_ceildivpow2(tilec->y0, levelno);
+                               res->x1 = int_ceildivpow2(tilec->x1, levelno);
+                               res->y1 = int_ceildivpow2(tilec->y1, levelno);
+
+                               /* Special DWT (always this case) */
+                               res->previous_x0 = 0;
+                               res->previous_y0 = 0;
+                               res->previous_x1 = 0;
+                               res->previous_y1 = 0;
+                               res->cas_row = 0;
+                               res->cas_col = 0;
+                               /* << DWT */
+                               res->numbands = resno == 0 ? 1 : 3;
+                               /* p. 35, table A-23, ISO/IEC FDIS154444-1 : 2000 (18 august 2000) */
+                               if (tccp->csty & J2K_CCP_CSTY_PRT) {
+                                       pdx = tccp->prcw[resno];
+                                       pdy = tccp->prch[resno];
+                               } else {
+                                       pdx = 15;
+                                       pdy = 15;
+                               }
+                               /* p. 64, B.6, ISO/IEC FDIS15444-1 : 2000 (18 august 2000)  */
+                               tlprcxstart = int_floordivpow2(res->x0, pdx) << pdx;
+                               tlprcystart = int_floordivpow2(res->y0, pdy) << pdy;
+                               brprcxend = int_ceildivpow2(res->x1, pdx) << pdx;
+                               brprcyend = int_ceildivpow2(res->y1, pdy) << pdy;
+
+                               res->pw = (brprcxend - tlprcxstart) >> pdx;
+                               res->ph = (brprcyend - tlprcystart) >> pdy;
+
+                               if (resno == 0) {
+                                       tlcbgxstart = tlprcxstart;
+                                       tlcbgystart = tlprcystart;
+                                       brcbgxend = brprcxend;
+                                       brcbgyend = brprcyend;
+                                       cbgwidthexpn = pdx;
+                                       cbgheightexpn = pdy;
+                               } else {
+                                       tlcbgxstart = int_ceildivpow2(tlprcxstart, 1);
+                                       tlcbgystart = int_ceildivpow2(tlprcystart, 1);
+                                       brcbgxend = int_ceildivpow2(brprcxend, 1);
+                                       brcbgyend = int_ceildivpow2(brprcyend, 1);
+                                       cbgwidthexpn = pdx - 1;
+                                       cbgheightexpn = pdy - 1;
+                               }
+
+                               cblkwidthexpn = int_min(tccp->cblkw, cbgwidthexpn);
+                               cblkheightexpn = int_min(tccp->cblkh, cbgheightexpn);
+
+                               for (bandno = 0; bandno < res->numbands; bandno++) {
+                                       int x0b, y0b, i;
+                                       int gain, numbps;
+                                       j2k_stepsize_t *ss;
+                                       band = &res->bands[bandno];
+                                       band->bandno = resno == 0 ? 0 : bandno + 1;
+                                       x0b = (band->bandno == 1) || (band->bandno == 3) ? 1 : 0;
+                                       y0b = (band->bandno == 2) || (band->bandno == 3) ? 1 : 0;
+
+                                       if (band->bandno == 0) {
+                                               /* band border (global) */
+                                               band->x0 = int_ceildivpow2(tilec->x0, levelno);
+                                               band->y0 = int_ceildivpow2(tilec->y0, levelno);
+                                               band->x1 = int_ceildivpow2(tilec->x1, levelno);
+                                               band->y1 = int_ceildivpow2(tilec->y1, levelno);
+                                       } else {
+                                               /* band border (global) */
+                                               band->x0 =
+                                                       int_ceildivpow2(tilec->x0 - (1 << levelno) * x0b,
+                                                                                                                       levelno + 1);
+                                               band->y0 =
+                                                       int_ceildivpow2(tilec->y0 - (1 << levelno) * y0b,
+                                                                                                                       levelno + 1);
+                                               band->x1 =
+                                                       int_ceildivpow2(tilec->x1 - (1 << levelno) * x0b,
+                                                                                                                       levelno + 1);
+                                               band->y1 =
+                                                       int_ceildivpow2(tilec->y1 - (1 << levelno) * y0b,
+                                                                                                                       levelno + 1);
+
+                                       }
+
+                                       ss =
+                                               &tccp->stepsizes[resno ==
+                                                                                                                0 ? 0 : 3 * (resno - 1) + bandno + 1];
+                                       gain =
+                                               tccp->qmfbid ==
+                                               0 ? dwt_getgain_real(band->bandno) : dwt_getgain(band->bandno);
+                                       numbps = img->comps[compno].prec + gain;
+                                       band->stepsize =
+                                               (int) floor((1.0 + ss->mant / 2048.0) *
+                                                                                               pow(2.0, numbps - ss->expn) * 8192.0);
+                                       band->numbps = ss->expn + tccp->numgbits - 1;   /* WHY -1 ? */
+
+                                       band->precincts =
+                                               (tcd_precinct_t *) malloc(3 * res->pw * res->ph *
+                                                                                                                                                       sizeof(tcd_precinct_t));
+
+                                       for (i = 0; i < res->pw * res->ph * 3; i++) {
+                                               band->precincts[i].imsbtree = NULL;
+                                               band->precincts[i].incltree = NULL;
+                                       }
+
+                                       for (precno = 0; precno < res->pw * res->ph; precno++) {
+                                               int tlcblkxstart, tlcblkystart, brcblkxend, brcblkyend;
+                                               int cbgxstart =
+                                                       tlcbgxstart + (precno % res->pw) * (1 << cbgwidthexpn);
+                                               int cbgystart =
+                                                       tlcbgystart + (precno / res->pw) * (1 << cbgheightexpn);
+                                               int cbgxend = cbgxstart + (1 << cbgwidthexpn);
+                                               int cbgyend = cbgystart + (1 << cbgheightexpn);
+                                               /* tcd_precinct_t *prc=&band->precincts[precno]; */
+                                               prc = &band->precincts[precno];
+                                               /* precinct size (global) */
+                                               prc->x0 = int_max(cbgxstart, band->x0);
+                                               prc->y0 = int_max(cbgystart, band->y0);
+                                               prc->x1 = int_min(cbgxend, band->x1);
+                                               prc->y1 = int_min(cbgyend, band->y1);
+
+                                               tlcblkxstart =
+                                                       int_floordivpow2(prc->x0, cblkwidthexpn) << cblkwidthexpn;
+                                               tlcblkystart =
+                                                       int_floordivpow2(prc->y0, cblkheightexpn) << cblkheightexpn;
+                                               brcblkxend =
+                                                       int_ceildivpow2(prc->x1, cblkwidthexpn) << cblkwidthexpn;
+                                               brcblkyend =
+                                                       int_ceildivpow2(prc->y1, cblkheightexpn) << cblkheightexpn;
+                                               prc->cw = (brcblkxend - tlcblkxstart) >> cblkwidthexpn;
+                                               prc->ch = (brcblkyend - tlcblkystart) >> cblkheightexpn;
+
+                                               prc->cblks =
+                                                       (tcd_cblk_t *) malloc((prc->cw * prc->ch) *
+                                                                                                                                               sizeof(tcd_cblk_t));
+                                               prc->incltree = tgt_create(prc->cw, prc->ch);
+                                               prc->imsbtree = tgt_create(prc->cw, prc->ch);
+
+                                               for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
+                                                       int cblkxstart =
+                                                               tlcblkxstart + (cblkno % prc->cw) * (1 << cblkwidthexpn);
+                                                       int cblkystart =
+                                                               tlcblkystart + (cblkno / prc->cw) * (1 << cblkheightexpn);
+                                                       int cblkxend = cblkxstart + (1 << cblkwidthexpn);
+                                                       int cblkyend = cblkystart + (1 << cblkheightexpn);
+
+                                                       cblk = &prc->cblks[cblkno];
+                                                       /* code-block size (global) */
+                                                       cblk->x0 = int_max(cblkxstart, prc->x0);
+                                                       cblk->y0 = int_max(cblkystart, prc->y0);
+                                                       cblk->x1 = int_min(cblkxend, prc->x1);
+                                                       cblk->y1 = int_min(cblkyend, prc->y1);
+
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+       /* tcd_dump(&tcd_image,curtileno); */
+}
+
+void tcd_free_encode(j2k_image_t * img, j2k_cp_t * cp, int curtileno)
+{
+       int tileno, compno, resno, bandno, precno;
+       tcd_img = img;
+       tcd_cp = cp;
+       tcd_image.tw = cp->tw;
+       tcd_image.th = cp->th;
+       for (tileno = 0; tileno < 1; tileno++) {
+               /* j2k_tcp_t *tcp=&cp->tcps[curtileno]; */
+               tile = tcd_image.tiles;
+               for (compno = 0; compno < tile->numcomps; compno++) {
+                       tilec = &tile->comps[compno];
+                       for (resno = 0; resno < tilec->numresolutions; resno++) {
+                               res = &tilec->resolutions[resno];
+                               for (bandno = 0; bandno < res->numbands; bandno++) {
+                                       band = &res->bands[bandno];
+                                       for (precno = 0; precno < res->pw * res->ph; precno++) {
+                                               prc = &band->precincts[precno];
+
+                                               if (prc->incltree != NULL)
+                                                       tgt_destroy(prc->incltree);
+                                               if (prc->imsbtree != NULL)
+                                                       tgt_destroy(prc->imsbtree);
+                                               free(prc->cblks);
+                                       }                                                                                       /* for (precno */
+                                       free(band->precincts);
+                               }                                                                                               /* for (bandno */
+                       }                                                                                                       /* for (resno */
+                       free(tilec->resolutions);
+               }                                                                                                               /* for (compno */
+               free(tile->comps);
+       }                                                                                                                       /* for (tileno */
+       free(tcd_image.tiles);
+}
+
+void tcd_init_encode(j2k_image_t * img, j2k_cp_t * cp, int curtileno)
+{
+       int tileno, compno, resno, bandno, precno, cblkno;
+
+       for (tileno = 0; tileno < 1; tileno++) {
+               j2k_tcp_t *tcp = &cp->tcps[curtileno];
+               int j;
+               int previous_x0, previous_x1, previous_y0, previous_y1;
+               /* cfr p59 ISO/IEC FDIS15444-1 : 2000 (18 august 2000) */
+               int p = curtileno % cp->tw;
+               int q = curtileno / cp->tw;
+               tile = tcd_image.tiles;
+
+               /* 4 borders of the tile rescale on the image if necessary */
+               tile->x0 = int_max(cp->tx0 + p * cp->tdx, img->x0);
+               tile->y0 = int_max(cp->ty0 + q * cp->tdy, img->y0);
+               tile->x1 = int_min(cp->tx0 + (p + 1) * cp->tdx, img->x1);
+               tile->y1 = int_min(cp->ty0 + (q + 1) * cp->tdy, img->y1);
+               /* Special DWT */
+               if (p) {
+                       previous_x0 = int_max(cp->tx0 + (p - 1) * cp->tdx, img->x0);
+                       previous_x1 = int_min(cp->tx0 + p * cp->tdx, img->x1);
+               } else {
+                       previous_x0 = 0;
+                       previous_x1 = 0;
+               }
+
+               if (q) {
+                       previous_y0 = int_max(cp->ty0 + (q - 1) * cp->tdy, img->y0);
+                       previous_y1 = int_min(cp->ty0 + q * cp->tdy, img->y1);
+               } else {
+                       previous_y0 = 0;
+                       previous_y1 = 0;
+               }
+               /* << DWT */
+
+               tile->numcomps = img->numcomps;
+               /* tile->PPT=img->PPT; */
+               /* Modification of the RATE >> */
+               for (j = 0; j < tcp->numlayers; j++) {
+                       tcp->rates[j] =
+                               ceil(tile->numcomps * (tile->x1 - tile->x0) *
+                                                (tile->y1 -
+                                                       tile->y0) * img->comps[0].prec / (tcp->rates[j] * 8 *
+                                                                                                                                                                                               img->comps[0].dx *
+                                                                                                                                                                                               img->comps[0].dy));
+                       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=(tcd_tilecomp_t*)realloc(tile->comps,img->numcomps*sizeof(tcd_tilecomp_t)); */
+               for (compno = 0; compno < tile->numcomps; compno++) {
+                       j2k_tccp_t *tccp = &tcp->tccps[compno];
+                       /* int realloc_op; */
+
+                       tilec = &tile->comps[compno];
+                       /* border of each tile component (global) */
+                       tilec->x0 = int_ceildiv(tile->x0, img->comps[compno].dx);
+                       tilec->y0 = int_ceildiv(tile->y0, img->comps[compno].dy);
+                       tilec->x1 = int_ceildiv(tile->x1, img->comps[compno].dx);
+                       tilec->y1 = int_ceildiv(tile->y1, img->comps[compno].dy);
+
+                       /* special for DWT */
+                       if (p) {
+                               previous_x0 = int_ceildiv(previous_x0, img->comps[compno].dx);
+                               previous_x1 = int_ceildiv(previous_x1, img->comps[compno].dx);
+
+                               tilec->previous_row = 1;
+                       } else {
+                               previous_x0 = 0;
+                               previous_x1 = 0;
+                               tilec->previous_row = 0;
+                       }
+
+                       if (q) {
+                               previous_y0 = int_ceildiv(previous_y0, img->comps[compno].dx);
+                               previous_y1 = int_ceildiv(previous_y1, img->comps[compno].dx);
+                               tilec->previous_col = 1;
+                       } else {
+                               previous_y0 = 0;
+                               previous_y1 = 0;
+                               tilec->previous_col = 0;
+                       }
+                       /* << DWT */
+                       tilec->data =
+                               (int *) malloc(sizeof(int) * (tilec->x1 - tilec->x0) *
+                                                                                        (tilec->y1 - tilec->y0));
+                       tilec->numresolutions = tccp->numresolutions;
+                       /* tilec->resolutions=(tcd_resolution_t*)realloc(tilec->resolutions,tilec->numresolutions*sizeof(tcd_resolution_t)); */
+                       for (resno = 0; resno < tilec->numresolutions; resno++) {
+                               int pdx, pdy;
+                               int levelno = tilec->numresolutions - 1 - resno;
+                               int tlprcxstart, tlprcystart, brprcxend, brprcyend;
+                               int tlcbgxstart, tlcbgystart, brcbgxend, brcbgyend;
+                               int cbgwidthexpn, cbgheightexpn;
+                               int cblkwidthexpn, cblkheightexpn;
+
+                               res = &tilec->resolutions[resno];
+                               /* border for each resolution level (global) */
+                               res->x0 = int_ceildivpow2(tilec->x0, levelno);
+                               res->y0 = int_ceildivpow2(tilec->y0, levelno);
+                               res->x1 = int_ceildivpow2(tilec->x1, levelno);
+                               res->y1 = int_ceildivpow2(tilec->y1, levelno);
+
+                               /* special for DWT */
+                               res->previous_x0 = int_ceildivpow2(previous_x0, levelno);
+                               res->previous_y0 = int_ceildivpow2(previous_y0, levelno);
+                               res->previous_x1 = int_ceildivpow2(previous_x1, levelno);
+                               res->previous_y1 = int_ceildivpow2(previous_y1, levelno);
+
+                               res->numbands = resno == 0 ? 1 : 3;
+                               /* p. 35, table A-23, ISO/IEC FDIS154444-1 : 2000 (18 august 2000) */
+                               if (tccp->csty & J2K_CCP_CSTY_PRT) {
+                                       pdx = tccp->prcw[resno];
+                                       pdy = tccp->prch[resno];
+                               } else {
+                                       pdx = 15;
+                                       pdy = 15;
+                               }
+                               /* p. 64, B.6, ISO/IEC FDIS15444-1 : 2000 (18 august 2000)  */
+                               tlprcxstart = int_floordivpow2(res->x0, pdx) << pdx;
+                               tlprcystart = int_floordivpow2(res->y0, pdy) << pdy;
+                               brprcxend = int_ceildivpow2(res->x1, pdx) << pdx;
+                               brprcyend = int_ceildivpow2(res->y1, pdy) << pdy;
+
+                               res->pw = (brprcxend - tlprcxstart) >> pdx;
+                               res->ph = (brprcyend - tlprcystart) >> pdy;
+
+                               if (resno == 0) {
+                                       tlcbgxstart = tlprcxstart;
+                                       tlcbgystart = tlprcystart;
+                                       brcbgxend = brprcxend;
+                                       brcbgyend = brprcyend;
+                                       cbgwidthexpn = pdx;
+                                       cbgheightexpn = pdy;
+                               } else {
+                                       tlcbgxstart = int_ceildivpow2(tlprcxstart, 1);
+                                       tlcbgystart = int_ceildivpow2(tlprcystart, 1);
+                                       brcbgxend = int_ceildivpow2(brprcxend, 1);
+                                       brcbgyend = int_ceildivpow2(brprcyend, 1);
+                                       cbgwidthexpn = pdx - 1;
+                                       cbgheightexpn = pdy - 1;
+                               }
+
+                               cblkwidthexpn = int_min(tccp->cblkw, cbgwidthexpn);
+                               cblkheightexpn = int_min(tccp->cblkh, cbgheightexpn);
+
+                               for (bandno = 0; bandno < res->numbands; bandno++) {
+                                       int x0b, y0b;
+                                       int gain, numbps;
+                                       j2k_stepsize_t *ss;
+                                       band = &res->bands[bandno];
+                                       band->bandno = resno == 0 ? 0 : bandno + 1;
+                                       x0b = (band->bandno == 1) || (band->bandno == 3) ? 1 : 0;
+                                       y0b = (band->bandno == 2) || (band->bandno == 3) ? 1 : 0;
+
+                                       if (band->bandno == 0) {
+                                               /* band border */
+                                               band->x0 = int_ceildivpow2(tilec->x0, levelno);
+                                               band->y0 = int_ceildivpow2(tilec->y0, levelno);
+                                               band->x1 = int_ceildivpow2(tilec->x1, levelno);
+                                               band->y1 = int_ceildivpow2(tilec->y1, levelno);
+                                       } else {
+                                               band->x0 =
+                                                       int_ceildivpow2(tilec->x0 - (1 << levelno) * x0b,
+                                                                                                                       levelno + 1);
+                                               band->y0 =
+                                                       int_ceildivpow2(tilec->y0 - (1 << levelno) * y0b,
+                                                                                                                       levelno + 1);
+                                               band->x1 =
+                                                       int_ceildivpow2(tilec->x1 - (1 << levelno) * x0b,
+                                                                                                                       levelno + 1);
+                                               band->y1 =
+                                                       int_ceildivpow2(tilec->y1 - (1 << levelno) * y0b,
+                                                                                                                       levelno + 1);
+                                       }
+
+                                       ss =
+                                               &tccp->stepsizes[resno ==
+                                                                                                                0 ? 0 : 3 * (resno - 1) + bandno + 1];
+                                       gain =
+                                               tccp->qmfbid ==
+                                               0 ? dwt_getgain_real(band->bandno) : dwt_getgain(band->bandno);
+                                       numbps = img->comps[compno].prec + gain;
+                                       band->stepsize =
+                                               (int) floor((1.0 + ss->mant / 2048.0) *
+                                                                                               pow(2.0, numbps - ss->expn) * 8192.0);
+                                       band->numbps = ss->expn + tccp->numgbits - 1;   /* WHY -1 ? */
+
+                                       for (precno = 0; precno < res->pw * res->ph; precno++) {
+                                               int tlcblkxstart, tlcblkystart, brcblkxend, brcblkyend;
+                                               int cbgxstart =
+                                                       tlcbgxstart + (precno % res->pw) * (1 << cbgwidthexpn);
+                                               int cbgystart =
+                                                       tlcbgystart + (precno / res->pw) * (1 << cbgheightexpn);
+                                               int cbgxend = cbgxstart + (1 << cbgwidthexpn);
+                                               int cbgyend = cbgystart + (1 << cbgheightexpn);
+
+                                               prc = &band->precincts[precno];
+                                               /* precinct size (global) */
+                                               prc->x0 = int_max(cbgxstart, band->x0);
+                                               prc->y0 = int_max(cbgystart, band->y0);
+                                               prc->x1 = int_min(cbgxend, band->x1);
+                                               prc->y1 = int_min(cbgyend, band->y1);
+
+                                               tlcblkxstart =
+                                                       int_floordivpow2(prc->x0, cblkwidthexpn) << cblkwidthexpn;
+                                               tlcblkystart =
+                                                       int_floordivpow2(prc->y0, cblkheightexpn) << cblkheightexpn;
+                                               brcblkxend =
+                                                       int_ceildivpow2(prc->x1, cblkwidthexpn) << cblkwidthexpn;
+                                               brcblkyend =
+                                                       int_ceildivpow2(prc->y1, cblkheightexpn) << cblkheightexpn;
+                                               prc->cw = (brcblkxend - tlcblkxstart) >> cblkwidthexpn;
+                                               prc->ch = (brcblkyend - tlcblkystart) >> cblkheightexpn;
+
+                                               free(prc->cblks);
+                                               prc->cblks =
+                                                       (tcd_cblk_t *) malloc(prc->cw * prc->ch *
+                                                                                                                                               sizeof(tcd_cblk_t));
+
+                                               if (prc->incltree != NULL)
+                                                       tgt_destroy(prc->incltree);
+                                               if (prc->imsbtree != NULL)
+                                                       tgt_destroy(prc->imsbtree);
+
+                                               prc->incltree = tgt_create(prc->cw, prc->ch);
+                                               prc->imsbtree = tgt_create(prc->cw, prc->ch);
+
+                                               for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
+                                                       int cblkxstart =
+                                                               tlcblkxstart + (cblkno % prc->cw) * (1 << cblkwidthexpn);
+                                                       int cblkystart =
+                                                               tlcblkystart + (cblkno / prc->cw) * (1 << cblkheightexpn);
+                                                       int cblkxend = cblkxstart + (1 << cblkwidthexpn);
+                                                       int cblkyend = cblkystart + (1 << cblkheightexpn);
+                                                       cblk = &prc->cblks[cblkno];
+
+                                                       /* code-block size (global) */
+                                                       cblk->x0 = int_max(cblkxstart, prc->x0);
+                                                       cblk->y0 = int_max(cblkystart, prc->y0);
+                                                       cblk->x1 = int_min(cblkxend, prc->x1);
+                                                       cblk->y1 = int_min(cblkyend, prc->y1);
+
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+       /* tcd_dump(&tcd_image,0); */
+}
+
+void tcd_init(j2k_image_t * img, j2k_cp_t * cp)
+{
+       int tileno, compno, resno, bandno, precno, cblkno;
+       tcd_img = img;
+       tcd_cp = cp;
+       tcd_image.tw = cp->tw;
+       tcd_image.th = cp->th;
+       tcd_image.tiles =
+               (tcd_tile_t *) malloc(cp->tw * cp->th * sizeof(tcd_tile_t));
+       for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
+               j2k_tcp_t *tcp = &cp->tcps[tileno];
+               tcd_tile_t *tile = &tcd_image.tiles[tileno];
+               int previous_x0, previous_x1, previous_y0, previous_y1;
+               /* cfr p59 ISO/IEC FDIS15444-1 : 2000 (18 august 2000) */
+               int p = tileno % cp->tw;                /* si numerotation matricielle .. */
+               int q = tileno / cp->tw;                /* .. coordonnees de la tile (q,p) q pour ligne et p pour colonne */
+
+               /* 4 borders of the tile rescale on the image if necessary */
+               tile->x0 = int_max(cp->tx0 + p * cp->tdx, img->x0);
+               tile->y0 = int_max(cp->ty0 + q * cp->tdy, img->y0);
+               tile->x1 = int_min(cp->tx0 + (p + 1) * cp->tdx, img->x1);
+               tile->y1 = int_min(cp->ty0 + (q + 1) * cp->tdy, img->y1);
+               /* Special DWT */
+               if (p) {
+                       previous_x0 = int_max(cp->tx0 + (p - 1) * cp->tdx, img->x0);
+                       previous_x1 = int_min(cp->tx0 + p * cp->tdx, img->x1);
+               } else {
+                       previous_x0 = 0;
+                       previous_x1 = 0;
+               }
+
+               if (q) {
+                       previous_y0 = int_max(cp->ty0 + (q - 1) * cp->tdy, img->y0);
+                       previous_y1 = int_min(cp->ty0 + q * cp->tdy, img->y1);
+               } else {
+                       previous_y0 = 0;
+                       previous_y1 = 0;
+               }
+               /* << DWT */
+
+               tile->numcomps = img->numcomps;
+               tile->comps =
+                       (tcd_tilecomp_t *) malloc(img->numcomps * sizeof(tcd_tilecomp_t));
+               for (compno = 0; compno < tile->numcomps; compno++) {
+                       j2k_tccp_t *tccp = &tcp->tccps[compno];
+                       tcd_tilecomp_t *tilec = &tile->comps[compno];
+                       /* border of each tile component (global) */
+                       tilec->x0 = int_ceildiv(tile->x0, img->comps[compno].dx);
+                       tilec->y0 = int_ceildiv(tile->y0, img->comps[compno].dy);
+                       tilec->x1 = int_ceildiv(tile->x1, img->comps[compno].dx);
+                       tilec->y1 = int_ceildiv(tile->y1, img->comps[compno].dy);
+                       /* special for DWT */
+                       if (p) {
+                               previous_x0 = int_ceildiv(previous_x0, img->comps[compno].dx);
+                               previous_x1 = int_ceildiv(previous_x1, img->comps[compno].dx);
+
+                               tilec->previous_row = 1;
+                       } else {
+                               previous_x0 = 0;
+                               previous_x1 = 0;
+                               tilec->previous_row = 0;
+                       }
+
+                       if (q) {
+                               previous_y0 = int_ceildiv(previous_y0, img->comps[compno].dx);
+                               previous_y1 = int_ceildiv(previous_y1, img->comps[compno].dx);
+                               tilec->previous_col = 1;
+                       } else {
+                               previous_y0 = 0;
+                               previous_y1 = 0;
+                               tilec->previous_col = 0;
+                       }
+                       /* << DWT */
+                       tilec->data =
+                               (int *) malloc(sizeof(int) * (tilec->x1 - tilec->x0) *
+                                                                                        (tilec->y1 - tilec->y0));
+                       tilec->numresolutions = tccp->numresolutions;
+                       tilec->resolutions =
+                               (tcd_resolution_t *) malloc(tilec->numresolutions *
+                                                                                                                                               sizeof(tcd_resolution_t));
+                       for (resno = 0; resno < tilec->numresolutions; resno++) {
+                               int pdx, pdy;
+                               int levelno = tilec->numresolutions - 1 - resno;
+                               int tlprcxstart, tlprcystart, brprcxend, brprcyend;
+                               int tlcbgxstart, tlcbgystart, brcbgxend, brcbgyend;
+                               int cbgwidthexpn, cbgheightexpn;
+                               int cblkwidthexpn, cblkheightexpn;
+                               tcd_resolution_t *res = &tilec->resolutions[resno];
+
+                               /* border for each resolution level (global) */
+                               res->x0 = int_ceildivpow2(tilec->x0, levelno);
+                               res->y0 = int_ceildivpow2(tilec->y0, levelno);
+                               res->x1 = int_ceildivpow2(tilec->x1, levelno);
+                               res->y1 = int_ceildivpow2(tilec->y1, levelno);
+                               /* special for DWT */
+                               res->previous_x0 = int_ceildivpow2(previous_x0, levelno);
+                               res->previous_y0 = int_ceildivpow2(previous_y0, levelno);
+                               res->previous_x1 = int_ceildivpow2(previous_x1, levelno);
+                               res->previous_y1 = int_ceildivpow2(previous_y1, levelno);
+                               if (!p)
+                                       res->cas_row = 0;
+                               if (!q)
+                                       res->cas_col = 0;
+
+                               res->numbands = resno == 0 ? 1 : 3;
+                               /* p. 35, table A-23, ISO/IEC FDIS154444-1 : 2000 (18 august 2000) */
+                               if (tccp->csty & J2K_CCP_CSTY_PRT) {
+                                       pdx = tccp->prcw[resno];
+                                       pdy = tccp->prch[resno];
+                               } else {
+                                       pdx = 15;
+                                       pdy = 15;
+                               }
+                               /* p. 64, B.6, ISO/IEC FDIS15444-1 : 2000 (18 august 2000)  */
+                               tlprcxstart = int_floordivpow2(res->x0, pdx) << pdx;
+                               tlprcystart = int_floordivpow2(res->y0, pdy) << pdy;
+                               brprcxend = int_ceildivpow2(res->x1, pdx) << pdx;
+                               brprcyend = int_ceildivpow2(res->y1, pdy) << pdy;
+                               res->pw = (brprcxend - tlprcxstart) >> pdx;
+                               res->ph = (brprcyend - tlprcystart) >> pdy;
+
+                               if (resno == 0) {
+                                       tlcbgxstart = tlprcxstart;
+                                       tlcbgystart = tlprcystart;
+                                       brcbgxend = brprcxend;
+                                       brcbgyend = brprcyend;
+                                       cbgwidthexpn = pdx;
+                                       cbgheightexpn = pdy;
+                               } else {
+                                       tlcbgxstart = int_ceildivpow2(tlprcxstart, 1);
+                                       tlcbgystart = int_ceildivpow2(tlprcystart, 1);
+                                       brcbgxend = int_ceildivpow2(brprcxend, 1);
+                                       brcbgyend = int_ceildivpow2(brprcyend, 1);
+                                       cbgwidthexpn = pdx - 1;
+                                       cbgheightexpn = pdy - 1;
+                               }
+
+                               cblkwidthexpn = int_min(tccp->cblkw, cbgwidthexpn);
+                               cblkheightexpn = int_min(tccp->cblkh, cbgheightexpn);
+
+                               for (bandno = 0; bandno < res->numbands; bandno++) {
+                                       int x0b, y0b;
+                                       int gain, numbps;
+                                       j2k_stepsize_t *ss;
+                                       tcd_band_t *band = &res->bands[bandno];
+                                       band->bandno = resno == 0 ? 0 : bandno + 1;
+                                       x0b = (band->bandno == 1) || (band->bandno == 3) ? 1 : 0;
+                                       y0b = (band->bandno == 2) || (band->bandno == 3) ? 1 : 0;
+
+                                       if (band->bandno == 0) {
+                                               /* band border (global) */
+                                               band->x0 = int_ceildivpow2(tilec->x0, levelno);
+                                               band->y0 = int_ceildivpow2(tilec->y0, levelno);
+                                               band->x1 = int_ceildivpow2(tilec->x1, levelno);
+                                               band->y1 = int_ceildivpow2(tilec->y1, levelno);
+                                       } else {
+                                               /* band border (global) */
+                                               band->x0 =
+                                                       int_ceildivpow2(tilec->x0 - (1 << levelno) * x0b,
+                                                                                                                       levelno + 1);
+                                               band->y0 =
+                                                       int_ceildivpow2(tilec->y0 - (1 << levelno) * y0b,
+                                                                                                                       levelno + 1);
+                                               band->x1 =
+                                                       int_ceildivpow2(tilec->x1 - (1 << levelno) * x0b,
+                                                                                                                       levelno + 1);
+                                               band->y1 =
+                                                       int_ceildivpow2(tilec->y1 - (1 << levelno) * y0b,
+                                                                                                                       levelno + 1);
+                                       }
+
+                                       ss =
+                                               &tccp->stepsizes[resno ==
+                                                                                                                0 ? 0 : 3 * (resno - 1) + bandno + 1];
+                                       gain =
+                                               tccp->qmfbid ==
+                                               0 ? dwt_getgain_real(band->bandno) : dwt_getgain(band->bandno);
+                                       numbps = img->comps[compno].prec + gain;
+                                       band->stepsize =
+                                               (int) floor((1.0 + ss->mant / 2048.0) *
+                                                                                               pow(2.0, numbps - ss->expn) * 8192.0);
+                                       band->numbps = ss->expn + tccp->numgbits - 1;   /* WHY -1 ? */
+
+                                       band->precincts =
+                                               (tcd_precinct_t *) malloc(res->pw * res->ph *
+                                                                                                                                                       sizeof(tcd_precinct_t));
+
+                                       for (precno = 0; precno < res->pw * res->ph; precno++) {
+                                               int tlcblkxstart, tlcblkystart, brcblkxend, brcblkyend;
+                                               int cbgxstart =
+                                                       tlcbgxstart + (precno % res->pw) * (1 << cbgwidthexpn);
+                                               int cbgystart =
+                                                       tlcbgystart + (precno / res->pw) * (1 << cbgheightexpn);
+                                               int cbgxend = cbgxstart + (1 << cbgwidthexpn);
+                                               int cbgyend = cbgystart + (1 << cbgheightexpn);
+                                               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->x1 = int_min(cbgxend, band->x1);
+                                               prc->y1 = int_min(cbgyend, band->y1);
+
+                                               tlcblkxstart =
+                                                       int_floordivpow2(prc->x0, cblkwidthexpn) << cblkwidthexpn;
+                                               tlcblkystart =
+                                                       int_floordivpow2(prc->y0, cblkheightexpn) << cblkheightexpn;
+                                               brcblkxend =
+                                                       int_ceildivpow2(prc->x1, cblkwidthexpn) << cblkwidthexpn;
+                                               brcblkyend =
+                                                       int_ceildivpow2(prc->y1, cblkheightexpn) << cblkheightexpn;
+                                               prc->cw = (brcblkxend - tlcblkxstart) >> cblkwidthexpn;
+                                               prc->ch = (brcblkyend - tlcblkystart) >> cblkheightexpn;
+
+                                               prc->cblks =
+                                                       (tcd_cblk_t *) malloc(prc->cw * prc->ch *
+                                                                                                                                               sizeof(tcd_cblk_t));
+
+                                               prc->incltree = tgt_create(prc->cw, prc->ch);
+                                               prc->imsbtree = tgt_create(prc->cw, prc->ch);
+
+                                               for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
+                                                       int cblkxstart =
+                                                               tlcblkxstart + (cblkno % prc->cw) * (1 << cblkwidthexpn);
+                                                       int cblkystart =
+                                                               tlcblkystart + (cblkno / prc->cw) * (1 << cblkheightexpn);
+                                                       int cblkxend = cblkxstart + (1 << cblkwidthexpn);
+                                                       int cblkyend = cblkystart + (1 << cblkheightexpn);
+                                                       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->x1 = int_min(cblkxend, prc->x1);
+                                                       cblk->y1 = int_min(cblkyend, prc->y1);
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+       /* tcd_dump(&tcd_image,0); */
+}
+
+void tcd_makelayer_fixed(int layno, int matrice_data[2][5][3], int final)
+{
+       int compno, resno, bandno, precno, cblkno;
+       int vector[3], matrice[2][5][3];
+       int sum_mat, i, j, k;
+       for (compno = 0; compno < tcd_tile->numcomps; compno++) {
+               tcd_tilecomp_t *tilec = &tcd_tile->comps[compno];
+               for (i = 0; i < 2; i++) {
+                       for (j = 0; j < 5; j++) {
+                               for (k = 0; k < 3; k++) {
+                                       matrice[i][j][k] =
+                                               (int) (matrice_data[i][j][k] *
+                                                                        (float) (tcd_img->comps[compno].prec / 16.0));
+                               }
+                       }
+               }
+               for (resno = 0; resno < tilec->numresolutions; resno++) {
+                       tcd_resolution_t *res = &tilec->resolutions[resno];
+                       for (bandno = 0; bandno < res->numbands; bandno++) {
+                               tcd_band_t *band = &res->bands[bandno];
+                               for (precno = 0; precno < res->pw * res->ph; precno++) {
+                                       tcd_precinct_t *prc = &band->precincts[precno];
+                                       for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
+                                               tcd_cblk_t *cblk = &prc->cblks[cblkno];
+                                               tcd_layer_t *layer = &cblk->layers[layno];
+                                               int i, n;
+                                               int imsb = tcd_img->comps[compno].prec - cblk->numbps;  /* number of bit-plan equal to zero */
+                                               /* Correction of the matrix of coefficient to include the IMSB information */
+                                               sum_mat = 0;
+
+                                               for (i = 0; i < layno + 1; i++) {
+                                                       int mat_old;
+                                                       if (i != tcd_tcp->numlayers) {  /* -1  must add to have a lossless last quality layer */
+                                                               /* different quality (layer) */
+                                                               vector[bandno] = matrice[i][resno][bandno];
+                                                               sum_mat += vector[bandno];
+                                                       } else {
+                                                               /* Full quality (layer) */
+                                                               vector[bandno] = tcd_img->comps[compno].prec - sum_mat;
+                                                       }
+
+                                                       mat_old = vector[bandno];
+                                                       if (imsb > 0) {
+                                                               if (imsb >= vector[bandno]) {
+                                                                       vector[bandno] = 0;
+                                                               } else {
+                                                                       vector[bandno] -= imsb;
+                                                               }
+                                                               imsb -= mat_old;
+                                                       }
+                                               }
+                                               if (layno == 0) {
+                                                       cblk->numpassesinlayers = 0;
+                                               }
+                                               n = cblk->numpassesinlayers;
+                                               if (cblk->numpassesinlayers == 0) {
+                                                       if (vector[bandno] != 0) {
+                                                               n = 3 * vector[bandno] - 2 + cblk->numpassesinlayers;
+                                                       } else {
+                                                               n = cblk->numpassesinlayers;
+                                                       }
+
+                                               } else {
+                                                       n = 3 * vector[bandno] + 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(unsigned char *dest, int len,
+                                                                                                               info_image * info_IM)
+{
+       int layno;
+       int matrice[2][5][3] = { {{16, 0, 0},
+                                                                                                               {16, 16, 16},
+                                                                                                               {16, 16, 16},
+                                                                                                               {0, 0, 0},
+                                                                                                               {0, 0, 0}},
+
+       {{1, 0, 0},
+        {1, 1, 1},
+        {1, 1, 1},
+        {1, 1, 1},
+        {0, 0, 0}}
+       };
+
+       for (layno = 0; layno < tcd_tcp->numlayers; layno++) {
+               tcd_makelayer_fixed(layno, matrice, 1);
+       }
+}
+
+void tcd_makelayer(int layno, double thresh, int final)
+{
+       int compno, resno, bandno, precno, cblkno, passno;
+       for (compno = 0; compno < tcd_tile->numcomps; compno++) {
+               tcd_tilecomp_t *tilec = &tcd_tile->comps[compno];
+               for (resno = 0; resno < tilec->numresolutions; resno++) {
+                       tcd_resolution_t *res = &tilec->resolutions[resno];
+                       for (bandno = 0; bandno < res->numbands; bandno++) {
+                               tcd_band_t *band = &res->bands[bandno];
+                               for (precno = 0; precno < res->pw * res->ph; precno++) {
+                                       tcd_precinct_t *prc = &band->precincts[precno];
+                                       for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
+                                               tcd_cblk_t *cblk = &prc->cblks[cblkno];
+                                               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;
+                                                       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 == 0) {
+                                                               if (dd != 0)
+                                                                       n = passno + 1;
+                                                               continue;
+                                                       }
+                                                       if (dd / dr > thresh)
+                                                               n = passno + 1;
+                                               }
+                                               layer->numpasses = n - cblk->numpassesinlayers;
+                                               if (!layer->numpasses)
+                                                       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;
+                                               }
+
+                                               if (final)
+                                                       cblk->numpassesinlayers = n;
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
+void tcd_rateallocate(unsigned char *dest, int len, info_image * info_IM)
+{
+       int compno, resno, bandno, precno, cblkno, passno, layno;
+       double min, max;
+       min = DBL_MAX;
+       max = 0;
+
+       for (compno = 0; compno < tcd_tile->numcomps; compno++) {
+               tcd_tilecomp_t *tilec = &tcd_tile->comps[compno];
+               for (resno = 0; resno < tilec->numresolutions; resno++) {
+                       tcd_resolution_t *res = &tilec->resolutions[resno];
+                       for (bandno = 0; bandno < res->numbands; bandno++) {
+                               tcd_band_t *band = &res->bands[bandno];
+                               for (precno = 0; precno < res->pw * res->ph; precno++) {
+                                       tcd_precinct_t *prc = &band->precincts[precno];
+                                       for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
+                                               tcd_cblk_t *cblk = &prc->cblks[cblkno];
+                                               for (passno = 0; passno < cblk->totalpasses; passno++) {
+                                                       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 */
+                                       }                                                                                       /* cbklno */
+                               }                                                                                               /* precno */
+                       }                                                                                                       /* bandno */
+               }                                                                                                               /* resno */
+       }                                                                                                                       /* compno */
+
+       for (layno = 0; layno < tcd_tcp->numlayers; layno++) {
+               volatile double lo = min;
+               volatile double hi = max;
+               volatile int success = 0;
+               volatile int maxlen = int_min(tcd_tcp->rates[layno], len);
+               volatile double goodthresh;
+               volatile int goodlen;
+               volatile int i;
+
+               for (i = 0; i < 32; i++) {
+                       volatile double thresh = (lo + hi) / 2;
+                       int l;
+
+                       tcd_makelayer(layno, thresh, 0);
+
+                       l =
+                               t2_encode_packets(tcd_img, tcd_cp, tcd_tileno, tcd_tile, layno + 1,
+                                                                                                       dest, maxlen, info_IM);
+                       /* fprintf(stderr, "rate alloc: len=%d, max=%d\n", l, maxlen); */
+                       if (l == -999) {
+                               lo = thresh;
+                               continue;
+                       }
+
+                       hi = thresh;
+                       success = 1;
+                       goodthresh = thresh;
+                       goodlen = l;
+               }
+
+               if (!success) {
+                       longjmp(j2k_error, 1);
+               }
+               tcd_makelayer(layno, goodthresh, 1);
+       }
+}
+
+int tcd_encode_tile_pxm(int tileno, unsigned char *dest, int len,
+                                                                                               info_image * info_IM)
+{
+       int compno;
+       int l;
+       clock_t time7;                                                          /* , time2, time3, time4, time5, time6, time1; */
+       tcd_tile_t *tile;
+       j2k_tcp_t *tcp = &tcd_cp->tcps[0];
+       j2k_tccp_t *tccp = &tcp->tccps[0];
+
+       tcd_tileno = tileno;
+       tcd_tile = tcd_image.tiles;
+       tcd_tcp = &tcd_cp->tcps[tileno];
+       tile = tcd_tile;
+       /* INDEX >> "Precinct_nb_X et Precinct_nb_Y" */
+       if (info_IM->index_on) {
+               tcd_tilecomp_t *tilec_idx = &tile->comps[0];    /* old parser version */
+               tcd_resolution_t *res_idx = &tilec_idx->resolutions[0]; /* old parser version */
+
+               info_IM->tile[tileno].pw = res_idx->pw;
+               info_IM->tile[tileno].ph = res_idx->ph;
+
+               info_IM->pw = res_idx->pw;      /* old parser version */
+               info_IM->ph = res_idx->ph;      /* old parser version */
+               info_IM->pdx = 1 << tccp->prcw[tccp->numresolutions - 1];
+               info_IM->pdy = 1 << tccp->prch[tccp->numresolutions - 1];
+       }
+       /* << INDEX */
+
+/*---------------TILE-------------------*/
+
+       time7 = clock();
+       /* time1=clock(); */
+
+       for (compno = 0; compno < tile->numcomps; compno++) {
+               FILE *src;
+               char tmp[256];
+               int k;
+               unsigned char elmt;
+               int i, j;
+               int tw, w;
+               tcd_tilecomp_t *tilec = &tile->comps[compno];
+               int adjust =
+                       tcd_img->comps[compno].sgnd ? 0 : 1 << (tcd_img->comps[compno].prec -
+                                                                                                                                                                                       1);
+               int offset_x, offset_y;
+
+               offset_x = int_ceildiv(tcd_img->x0, tcd_img->comps[compno].dx);
+               offset_y = int_ceildiv(tcd_img->y0, tcd_img->comps[compno].dy);
+               tw = tilec->x1 - tilec->x0;
+               w = int_ceildiv(tcd_img->x1 - tcd_img->x0, tcd_img->comps[compno].dx);
+               sprintf(tmp, "Compo%d", compno);        /* component file */
+               src = fopen(tmp, "rb");
+               if (!src) {
+                       fprintf(stderr, "failed to open %s for reading\n", tmp);
+                       return 1;
+               }
+
+               /* read the Compo file to extract data of the tile */
+               k = 0;
+               fseek(src, (tilec->x0 - offset_x) + (tilec->y0 - offset_y) * w,
+                                       SEEK_SET);
+               k = (tilec->x0 - offset_x) + (tilec->y0 - offset_y) * w;
+               for (j = tilec->y0; j < tilec->y1; j++) {
+                       for (i = tilec->x0; i < tilec->x1; i++) {
+                               if (tcd_tcp->tccps[compno].qmfbid == 1) {
+                                       elmt = fgetc(src);
+                                       tilec->data[i - tilec->x0 + (j - tilec->y0) * tw] =
+                                               elmt - adjust;
+                                       k++;
+                               } else if (tcd_tcp->tccps[compno].qmfbid == 0) {
+                                       elmt = fgetc(src);
+                                       tilec->data[i - tilec->x0 + (j - tilec->y0) * tw] =
+                                               (elmt - adjust) << 13;
+                                       k++;
+                               }
+                       }
+                       fseek(src, (tilec->x0 - offset_x) + (j + 1 - offset_y) * w - k,
+                                               SEEK_CUR);
+                       k = tilec->x0 - offset_x + (j + 1 - offset_y) * w;
+
+               }
+               fclose(src);
+       }
+
+       /* time1=clock()-time1;   */
+       /* printf("tile encoding times:\n"); */
+       /* printf("img->tile: %d.%.3d s\n", time1/CLOCKS_PER_SEC, (time1%CLOCKS_PER_SEC)*1000/CLOCKS_PER_SEC); */
+
+/*----------------MCT-------------------*/
+
+       /* time2=clock(); */
+       if (tcd_tcp->mct) {
+               if (tcd_tcp->tccps[0].qmfbid == 0) {
+                       mct_encode_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));
+               } else {
+                       mct_encode(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));
+               }
+       }
+       /* time2=clock()-time2;    */
+       /* printf("mct:       %ld.%.3ld s\n", time2/CLOCKS_PER_SEC, (time2%CLOCKS_PER_SEC)*1000/CLOCKS_PER_SEC); */
+
+/*----------------DWT---------------------*/
+
+       /* time3=clock(); */
+       for (compno = 0; compno < tile->numcomps; compno++) {
+               tcd_tilecomp_t *tilec = &tile->comps[compno];
+               if (tcd_tcp->tccps[compno].qmfbid == 1) {
+                       dwt_encode(tilec->data, tilec->x1 - tilec->x0, tilec->y1 - tilec->y0,
+                                                                tilec, tilec->numresolutions - 1);
+               } else if (tcd_tcp->tccps[compno].qmfbid == 0) {
+                       dwt_encode_real(tilec->data, tilec->x1 - tilec->x0,
+                                                                                       tilec->y1 - tilec->y0, tilec,
+                                                                                       tilec->numresolutions - 1);
+               }
+       }
+       /* time3=clock()-time3; */
+       /* printf("dwt:       %ld.%.3ld s\n", time3/CLOCKS_PER_SEC, (time3%CLOCKS_PER_SEC)*1000/CLOCKS_PER_SEC); */
+
+/*------------------TIER1-----------------*/
+
+       /* time4=clock(); */
+       t1_init_luts();
+       t1_encode_cblks(tile, tcd_tcp);
+       /* time4=clock()-time4; */
+       /* printf("tier 1:    %ld.%.3ld s\n", time4/CLOCKS_PER_SEC, (time4%CLOCKS_PER_SEC)*1000/CLOCKS_PER_SEC); */
+
+/*-----------RATE-ALLOCATE------------------*/
+
+       info_IM->index_write = 0;                       /* INDEX     */
+       /* time5=clock(); */
+       if (tcd_cp->disto_alloc)
+               /* Normal Rate/distortion allocation */
+               tcd_rateallocate(dest, len, info_IM);
+       else
+               /* Fixed layer allocation */
+               tcd_rateallocate_fixed(dest, len, info_IM);
+
+       /* time5=clock()-time5; */
+       /* printf("ratealloc: %ld.%.3ld s\n", time5/CLOCKS_PER_SEC, (time5%CLOCKS_PER_SEC)*1000/CLOCKS_PER_SEC); */
+
+/*--------------TIER2------------------*/
+
+       info_IM->index_write = 1;                       /* INDEX     */
+       /* time6=clock(); */
+       l =
+               t2_encode_packets(tcd_img, tcd_cp, tileno, tile, tcd_tcp->numlayers,
+                                                                                       dest, len, info_IM);
+       /* time6=clock()-time6; */
+       /* printf("tier 2:    %ld.%.3ld s\n", time6/CLOCKS_PER_SEC, (time6%CLOCKS_PER_SEC)*1000/CLOCKS_PER_SEC); */
+
+/*---------------CLEAN-------------------*/
+
+       time7 = clock() - time7;
+       printf("total:     %ld.%.3ld s\n", time7 / CLOCKS_PER_SEC,
+                                (time7 % CLOCKS_PER_SEC) * 1000 / CLOCKS_PER_SEC);
+
+       /* cleaning memory */
+       for (compno = 0; compno < tile->numcomps; compno++) {
+               tilec = &tile->comps[compno];
+               free(tilec->data);
+       }
+
+       return l;
+}
+
+int tcd_encode_tile_pgx(int tileno, unsigned char *dest, int len,
+                                                                                               info_image * info_IM)
+{
+       int compno;
+       int l;
+       clock_t time7;                                                          /* , time2, time3, time4, time5, time6, time1; */
+       tcd_tile_t *tile;
+       j2k_tcp_t *tcp = &tcd_cp->tcps[0];
+       j2k_tccp_t *tccp = &tcp->tccps[0];
+
+       tcd_tileno = tileno;
+       tcd_tile = tcd_image.tiles;
+       tcd_tcp = &tcd_cp->tcps[tileno];
+       tile = tcd_tile;
+       /* INDEX >> "Precinct_nb_X et Precinct_nb_Y" */
+       if (info_IM->index_on) {
+               tcd_tilecomp_t *tilec_idx = &tile->comps[0];
+               tcd_resolution_t *res_idx = &tilec_idx->resolutions[0];
+               info_IM->tile[tileno].pw = res_idx->pw;
+               info_IM->tile[tileno].ph = res_idx->ph;
+               info_IM->pw = res_idx->pw;      /* old parser version */
+               info_IM->ph = res_idx->ph;      /* old parser version */
+               info_IM->pdx = 1 << tccp->prcw[tccp->numresolutions - 1];
+               info_IM->pdy = 1 << tccp->prch[tccp->numresolutions - 1];
+       }
+       /* << INDEX */
+/*---------------TILE-------------------*/
+       time7 = clock();
+       /* time1=clock(); */
+       for (compno = 0; compno < tile->numcomps; compno++) {
+               FILE *src;
+               char tmp[256];
+               int k;
+               int elmt;
+               int i, j;
+               int tw, w;
+               tcd_tilecomp_t *tilec = &tile->comps[compno];
+               int adjust =
+                       tcd_img->comps[compno].sgnd ? 0 : 1 << (tcd_img->comps[compno].prec -
+                                                                                                                                                                                       1);
+               int offset_x, offset_y;
+
+               offset_x = int_ceildiv(tcd_img->x0, tcd_img->comps[compno].dx);
+               offset_y = int_ceildiv(tcd_img->y0, tcd_img->comps[compno].dy);
+               tw = tilec->x1 - tilec->x0;
+               w = int_ceildiv(tcd_img->x1 - tcd_img->x0, tcd_img->comps[compno].dx);
+               sprintf(tmp, "bandtile%d", tileno / tcd_cp->tw + 1);    /* bandtile file opening */
+               src = fopen(tmp, "rb");
+               if (!src) {
+                       fprintf(stderr, "failed to open %s for reading\n", tmp);
+                       return 1;
+               }
+               /* Extract data from bandtile file limited to the current tile */
+               k = 0;
+               while (k < tilec->x0 - offset_x) {
+                       k++;
+                       fscanf(src, "%d", &elmt);
+               }
+
+               for (j = 0; j < tilec->y1 - tilec->y0; j++) {
+                       for (i = tilec->x0; i < tilec->x1; i++) {
+                               if (tcd_tcp->tccps[compno].qmfbid == 1) {
+                                       fscanf(src, "%d", &elmt);
+                                       tilec->data[i - tilec->x0 + (j) * tw] = elmt - adjust;
+                                       k++;
+                               } else if (tcd_tcp->tccps[compno].qmfbid == 0) {
+                                       fscanf(src, "%d", &elmt);
+                                       tilec->data[i - tilec->x0 + (j) * tw] = (elmt - adjust) << 13;
+                                       k++;
+                               }
+                       }
+                       while (k < tilec->x0 - offset_x + (j + 1) * w) {
+                               k++;
+                               fscanf(src, "%d", &elmt);
+                       }
+               }
+               fclose(src);
+       }
+
+       /* time1=clock()-time1;   */
+       /* printf("tile encoding times:\n"); */
+       /* printf("img->tile: %d.%.3d s\n", time1/CLOCKS_PER_SEC, (time1%CLOCKS_PER_SEC)*1000/CLOCKS_PER_SEC); */
+/*----------------MCT-------------------*/
+       /* time2=clock(); */
+       if (tcd_tcp->mct) {
+               if (tcd_tcp->tccps[0].qmfbid == 0) {
+                       mct_encode_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));
+               } else {
+                       mct_encode(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));
+               }
+       }
+
+       /* time2=clock()-time2;    */
+       /* printf("mct:       %d.%.3d s\n", time2/CLOCKS_PER_SEC, (time2%CLOCKS_PER_SEC)*1000/CLOCKS_PER_SEC); */
+
+/*----------------DWT---------------------*/
+       /* time3=clock(); */
+       for (compno = 0; compno < tile->numcomps; compno++) {
+               tcd_tilecomp_t *tilec = &tile->comps[compno];
+               if (tcd_tcp->tccps[compno].qmfbid == 1) {
+                       dwt_encode(tilec->data, tilec->x1 - tilec->x0, tilec->y1 - tilec->y0,
+                                                                tilec, tilec->numresolutions - 1);
+               } else if (tcd_tcp->tccps[compno].qmfbid == 0) {
+                       dwt_encode_real(tilec->data, tilec->x1 - tilec->x0,
+                                                                                       tilec->y1 - tilec->y0, tilec,
+                                                                                       tilec->numresolutions - 1);
+               }
+       }
+       /* time3=clock()-time3; */
+       /* printf("dwt:       %d.%.3d s\n", time3/CLOCKS_PER_SEC, (time3%CLOCKS_PER_SEC)*1000/CLOCKS_PER_SEC); */
+
+/*------------------TIER1-----------------*/
+       /* time4=clock(); */
+       t1_init_luts();
+       t1_encode_cblks(tile, tcd_tcp);
+       /* time4=clock()-time4; */
+       /* printf("tier 1:    %d.%.3d s\n", time4/CLOCKS_PER_SEC, (time4%CLOCKS_PER_SEC)*1000/CLOCKS_PER_SEC); */
+
+/*-----------RATE-ALLOCATE------------------*/
+       info_IM->index_write = 0;                       /* INDEX */
+
+       /* time5=clock(); */
+       tcd_rateallocate(dest, len, info_IM);
+       /* time5=clock()-time5; */
+       /* printf("ratealloc: %d.%.3d s\n", time5/CLOCKS_PER_SEC, (time5%CLOCKS_PER_SEC)*1000/CLOCKS_PER_SEC); */
+
+/*--------------TIER2------------------*/
+       info_IM->index_write = 1;                       /* INDEX */
+
+       /* time6=clock(); */
+       l =
+               t2_encode_packets(tcd_img, tcd_cp, tileno, tile, tcd_tcp->numlayers,
+                                                                                       dest, len, info_IM);
+       /* time6=clock()-time6; */
+       /* printf("tier 2:    %d.%.3d s\n", time6/CLOCKS_PER_SEC, (time6%CLOCKS_PER_SEC)*1000/CLOCKS_PER_SEC); */
+
+ /*---------------CLEAN-------------------*/
+       time7 = clock() - time7;
+       printf("total:     %ld.%.3ld s\n", time7 / CLOCKS_PER_SEC,
+                                (time7 % CLOCKS_PER_SEC) * 1000 / CLOCKS_PER_SEC);
+
+       for (compno = 0; compno < tile->numcomps; compno++) {
+               tilec = &tile->comps[compno];
+               free(tilec->data);
+       }
+
+       return l;
+}
+
+
+int tcd_decode_tile(unsigned char *src, int len, int tileno)
+{
+       int l;
+       int compno;
+       int eof = 0;
+       clock_t time1, time2, time3, time4, time5, time6;
+
+       tcd_tile_t *tile;
+       tcd_tileno = tileno;
+       tcd_tile = &tcd_image.tiles[tileno];
+       tcd_tcp = &tcd_cp->tcps[tileno];
+       tile = tcd_tile;
+
+       time6 = clock();
+
+       time1 = clock();
+
+       l = t2_decode_packets(src, len, tcd_img, tcd_cp, tileno, tile);
+       if (l == -999) {
+               eof = 1;
+               fprintf(stderr, "tcd_decode: incomplete bistream\n");
+       }
+       time1 = clock() - time1;
+       printf("tile decoding time %d/%d:\n", tileno + 1,
+                                tcd_cp->tw * tcd_cp->th);
+       /* printf("tier 2:    %ld.%.3ld s\n", time1/CLOCKS_PER_SEC, (time1%CLOCKS_PER_SEC)*1000/CLOCKS_PER_SEC);    */
+
+       time2 = clock();
+       t1_init_luts();
+       t1_decode_cblks(tile, tcd_tcp);
+       time2 = clock() - time2;
+       /* printf("tier 1:    %ld.%.3ld s\n", time2/CLOCKS_PER_SEC, (time2%CLOCKS_PER_SEC)*1000/CLOCKS_PER_SEC); */
+
+       time3 = clock();
+       for (compno = 0; compno < tile->numcomps; compno++) {
+               tcd_tilecomp_t *tilec = &tile->comps[compno];
+               if (tcd_tcp->tccps[compno].qmfbid == 1) {
+                       if (tileno % tcd_cp->tw) {
+                               tcd_tile_t *tile_row = &tcd_image.tiles[tileno - 1];
+                               tcd_tilecomp_t *tilec_row = &tile_row->comps[compno];
+                               if (tileno / tcd_cp->tw) {
+                                       tcd_tile_t *tile_col = &tcd_image.tiles[tileno - 1];
+                                       tcd_tilecomp_t *tilec_col = &tile_col->comps[compno];
+                                       dwt_decode(tilec->data, tilec->x1 - tilec->x0,
+                                                                                tilec->y1 - tilec->y0, tilec,
+                                                                                tilec->numresolutions - 1, tilec_row, tilec_col);
+                               } else
+                                       dwt_decode(tilec->data, tilec->x1 - tilec->x0,
+                                                                                tilec->y1 - tilec->y0, tilec,
+                                                                                tilec->numresolutions - 1, tilec_row, tilec);
+                       } else {
+                               if (tileno / tcd_cp->tw) {
+                                       tcd_tile_t *tile_col = &tcd_image.tiles[tileno - 1];
+                                       tcd_tilecomp_t *tilec_col = &tile_col->comps[compno];
+                                       dwt_decode(tilec->data, tilec->x1 - tilec->x0,
+                                                                                tilec->y1 - tilec->y0, tilec,
+                                                                                tilec->numresolutions - 1, tilec, tilec_col);
+                               } else
+                                       dwt_decode(tilec->data, tilec->x1 - tilec->x0,
+                                                                                tilec->y1 - tilec->y0, tilec,
+                                                                                tilec->numresolutions - 1, tilec, tilec);
+                       }
+               } else if (tcd_tcp->tccps[compno].qmfbid == 0) {
+                       if (tileno % tcd_cp->tw) {
+                               tcd_tile_t *tile_row = &tcd_image.tiles[tileno - 1];
+                               tcd_tilecomp_t *tilec_row = &tile_row->comps[compno];
+                               if (tileno / tcd_cp->tw) {
+                                       tcd_tile_t *tile_col = &tcd_image.tiles[tileno - 1];
+                                       tcd_tilecomp_t *tilec_col = &tile_col->comps[compno];
+                                       dwt_decode_real(tilec->data, tilec->x1 - tilec->x0,
+                                                                                                       tilec->y1 - tilec->y0, tilec,
+                                                                                                       tilec->numresolutions - 1, tilec_row, tilec_col);
+                               } else
+                                       dwt_decode_real(tilec->data, tilec->x1 - tilec->x0,
+                                                                                                       tilec->y1 - tilec->y0, tilec,
+                                                                                                       tilec->numresolutions - 1, tilec_row, tilec);
+                       } else {
+                               if (tileno / tcd_cp->tw) {
+                                       tcd_tile_t *tile_col = &tcd_image.tiles[tileno - 1];
+                                       tcd_tilecomp_t *tilec_col = &tile_col->comps[compno];
+                                       dwt_decode_real(tilec->data, tilec->x1 - tilec->x0,
+                                                                                                       tilec->y1 - tilec->y0, tilec,
+                                                                                                       tilec->numresolutions - 1, tilec, tilec_col);
+                               } else
+                                       dwt_decode_real(tilec->data, tilec->x1 - tilec->x0,
+                                                                                                       tilec->y1 - tilec->y0, tilec,
+                                                                                                       tilec->numresolutions - 1, tilec, tilec);
+                       }
+               }
+       }
+       time3 = clock() - time3;
+       /* printf("dwt:       %ld.%.3ld s\n", time3/CLOCKS_PER_SEC, (time3%CLOCKS_PER_SEC)*1000/CLOCKS_PER_SEC); */
+
+       time4 = clock();
+       if (tcd_tcp->mct) {
+               if (tcd_tcp->tccps[0].qmfbid == 0) {
+                       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));
+               } else {
+                       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));
+               }
+       }
+       time4 = clock() - time4;
+       /* printf("mct:       %ld.%.3ld s\n", time4/CLOCKS_PER_SEC, (time4%CLOCKS_PER_SEC)*1000/CLOCKS_PER_SEC); */
+
+       time5 = clock();
+       for (compno = 0; compno < tile->numcomps; compno++) {
+               tcd_tilecomp_t *tilec = &tile->comps[compno];
+               int adjust =
+                       tcd_img->comps[compno].sgnd ? 0 : 1 << (tcd_img->comps[compno].prec -
+                                                                                                                                                                                       1);
+               int min =
+                       tcd_img->comps[compno].
+                       sgnd ? -(1 << (tcd_img->comps[compno].prec - 1)) : 0;
+               int max =
+                       tcd_img->comps[compno].
+                       sgnd ? (1 << (tcd_img->comps[compno].prec - 1)) - 1
+                                        : (1 << tcd_img->comps[compno].prec) - 1;
+               int tw = tilec->x1 - tilec->x0;
+               int w =
+                       int_ceildiv(tcd_img->x1 - tcd_img->x0, tcd_img->comps[compno].dx);
+               int i, j;
+               int offset_x = int_ceildiv(tcd_img->x0, tcd_img->comps[compno].dx);
+               int offset_y = int_ceildiv(tcd_img->y0, tcd_img->comps[compno].dy);
+
+               for (j = tilec->y0; j < tilec->y1; j++) {
+                       for (i = tilec->x0; i < tilec->x1; i++) {
+                               int v;
+                               if (tcd_tcp->tccps[compno].qmfbid == 1) {
+                                       v = tilec->data[i - tilec->x0 + (j - tilec->y0) * tw];
+                               } else {  /* if (tcd_tcp->tccps[compno].qmfbid == 0) */
+                                       v = tilec->data[i - tilec->x0 + (j - tilec->y0) * tw] >> 13;
+                               }
+                               v += adjust;
+                               /* tcd_img->comps[compno].data[i+j*w]=int_clamp(v, min, max); */
+                               tcd_img->comps[compno].data[(i - offset_x) + (j - offset_y) * w] = int_clamp(v, min, max);      /* change ! */
+                       }
+               }
+       }
+       time5 = clock() - time5;
+       /* printf("tile->img: %ld.%.3ld s\n", time5/CLOCKS_PER_SEC, (time5%CLOCKS_PER_SEC)*1000/CLOCKS_PER_SEC); */
+
+       time6 = clock() - time6;
+       printf("total:     %ld.%.3ld s\n\n", time6 / CLOCKS_PER_SEC,
+                                (time6 % CLOCKS_PER_SEC) * 1000 / CLOCKS_PER_SEC);
+
+       if (eof) {
+               longjmp(j2k_error, 1);
+       }
+
+       return l;
+}
diff --git a/libopenjpeg/tcd.h b/libopenjpeg/tcd.h
new file mode 100644 (file)
index 0000000..e8e8772
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2001-2002, David Janssens 
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2002-2003,  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 __TCD_H
+#define __TCD_H
+
+#include "j2k.h"
+#include "tgt.h"
+
+typedef struct {
+       int numpasses;
+       int len;
+       unsigned char *data;
+       int maxpasses;
+       int numnewpasses;
+       int newlen;
+} tcd_seg_t;
+
+typedef struct {
+       int rate;
+       double distortiondec;
+       int term, len;
+} tcd_pass_t;
+
+typedef struct {
+       int numpasses;
+       int len;
+       double disto;                                                                   /* add for index (Cfr. Marcela) */
+       unsigned char *data;
+} tcd_layer_t;
+
+typedef struct {
+       int x0, y0, x1, y1;
+       int numbps;
+       int numlenbits;
+       int len;
+       int numpasses;
+       int numnewpasses;
+       int numsegs;
+       tcd_seg_t segs[100];
+       unsigned char data[8192];
+       int numpassesinlayers;
+       tcd_layer_t layers[100];
+       int totalpasses;
+       tcd_pass_t passes[100];
+} tcd_cblk_t;
+
+typedef struct {
+       int x0, y0, x1, y1;
+       int cw, ch;
+       tcd_cblk_t *cblks;
+       tgt_tree_t *incltree;
+       tgt_tree_t *imsbtree;
+} tcd_precinct_t;
+
+typedef struct {
+       int x0, y0, x1, y1;
+       int bandno;
+       tcd_precinct_t *precincts;
+       int numbps;
+       int stepsize;
+} tcd_band_t;
+
+typedef struct {
+       int x0, y0, x1, y1;
+       int previous_x0, previous_y0, previous_x1, previous_y1; /* usefull for the DWT */
+       int cas_col, cas_row;                                   /* usefull for the DWT */
+       int pw, ph;                                                                             /* , old_pw,old_ph, old_pw_max,old_ph_max; */
+       int numbands;
+       tcd_band_t bands[3];
+} tcd_resolution_t;
+
+typedef struct {
+       int x0, y0, x1, y1;
+       int previous_row, previous_col; /* usefull for the DWT */
+       int numresolutions;
+       tcd_resolution_t *resolutions;
+       int *data;
+} tcd_tilecomp_t;
+
+typedef struct {
+       int x0, y0, x1, y1;
+       int numcomps;
+       /* int PPT; */
+       /* int len_ppt; */
+       tcd_tilecomp_t *comps;
+} tcd_tile_t;
+
+typedef struct {
+       int tw, th;
+       tcd_tile_t *tiles;
+} tcd_image_t;
+
+/*
+ * Initialize the tile coder/decoder
+ * img: raw image
+ * cp: coding parameters
+ * info_IM: creation of index file
+ */
+void tcd_init_encode(j2k_image_t * img, j2k_cp_t * cp, int curtileno);
+
+void tcd_malloc_encode(j2k_image_t * img, j2k_cp_t * cp, int curtileno);
+
+void tcd_init(j2k_image_t * img, j2k_cp_t * cp);
+
+void tcd_free_encode(j2k_image_t * img, j2k_cp_t * cp, int curtileno);
+
+/*
+ * Encode a tile from the raw image into a buffer, format pnm, pgm or ppm
+ * tileno: number that identifies one of the tiles to be encoded
+ * dest: destination buffer
+ * len: length of destination buffer
+ */
+int tcd_encode_tile_pxm(int tileno, unsigned char *dest, int len,
+                                                                                               info_image * info_IM);
+
+/*
+ * Encode a tile from the raw image into a buffer, format pgx
+ * tileno: number that identifies one of the tiles to be encoded
+ * dest: destination buffer
+ * len: length of destination buffer
+ */
+int tcd_encode_tile_pgx(int tileno, unsigned char *dest, int len,
+                                                                                               info_image * info_IM);
+
+/*
+ * Decode a tile from a buffer into a raw image
+ * src: source buffer
+ * len: length of the source buffer
+ * tileno: number that identifies the tile that will be decoded
+ */
+int tcd_decode_tile(unsigned char *src, int len, int tileno);
+
+#endif
diff --git a/libopenjpeg/tgt.c b/libopenjpeg/tgt.c
new file mode 100644 (file)
index 0000000..4d4e2be
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2001-2002, David Janssens
+ * 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 "tgt.h"
+#include "bio.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+/* <summary> */
+/* Reset tag-tree. */
+/* </summary> */
+void tgt_reset(tgt_tree_t * tree)
+{
+       int i;
+       /* new */
+       if (!tree || tree == NULL)
+               return;
+
+       for (i = 0; i < tree->numnodes; i++) {
+               tree->nodes[i].value = 999;
+               tree->nodes[i].low = 0;
+               tree->nodes[i].known = 0;
+       }
+}
+
+/* <summary> */
+/* Create tag-tree. */
+/* </summary> */
+tgt_tree_t *tgt_create(int numleafsh, int numleafsv)
+{
+       int nplh[32];
+       int nplv[32];
+       tgt_node_t *node;
+       tgt_node_t *parentnode;
+       tgt_node_t *parentnode0;
+       tgt_tree_t *tree;
+       int i, j, k;
+       int numlvls;
+       int n;
+
+       tree = (tgt_tree_t *) malloc(sizeof(tgt_tree_t));
+       tree->numleafsh = numleafsh;
+       tree->numleafsv = numleafsv;
+
+       numlvls = 0;
+       nplh[0] = numleafsh;
+       nplv[0] = numleafsv;
+       tree->numnodes = 0;
+       do {
+               n = nplh[numlvls] * nplv[numlvls];
+               nplh[numlvls + 1] = (nplh[numlvls] + 1) / 2;
+               nplv[numlvls + 1] = (nplv[numlvls] + 1) / 2;
+               tree->numnodes += n;
+               ++numlvls;
+       } while (n > 1);
+
+       /* ADD */
+       if (tree->numnodes == 0) {
+               free(tree);
+               return NULL;
+       }
+
+       tree->nodes = (tgt_node_t *) malloc(tree->numnodes * sizeof(tgt_node_t));
+
+       node = tree->nodes;
+       parentnode = &tree->nodes[tree->numleafsh * tree->numleafsv];
+       parentnode0 = parentnode;
+
+       for (i = 0; i < numlvls - 1; ++i) {
+               for (j = 0; j < nplv[i]; ++j) {
+                       k = nplh[i];
+                       while (--k >= 0) {
+                               node->parent = parentnode;
+                               ++node;
+                               if (--k >= 0) {
+                                       node->parent = parentnode;
+                                       ++node;
+                               }
+                               ++parentnode;
+                       }
+                       if ((j & 1) || j == nplv[i] - 1) {
+                               parentnode0 = parentnode;
+                       } else {
+                               parentnode = parentnode0;
+                               parentnode0 += nplh[i];
+                       }
+               }
+       }
+       node->parent = 0;
+
+       tgt_reset(tree);
+
+       return tree;
+}
+
+/* <summary> */
+/* Destroy tag-tree. */
+/* </summary> */
+void tgt_destroy(tgt_tree_t * t)
+{
+       free(t->nodes);
+       free(t);
+}
+
+/* <summary> */
+/* Set the value of a leaf of the tag-tree. */
+/* </summary> */
+void tgt_setvalue(tgt_tree_t * tree, int leafno, int value)
+{
+       tgt_node_t *node;
+       node = &tree->nodes[leafno];
+       while (node && node->value > value) {
+               node->value = value;
+               node = node->parent;
+       }
+}
+
+/* <summary> */
+/* Encode the value of a leaf of the tag-tree. */
+/* </summary> */
+void tgt_encode(tgt_tree_t * tree, int leafno, int threshold)
+{
+       tgt_node_t *stk[31];
+       tgt_node_t **stkptr;
+       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(1, 1);
+                                       node->known = 1;
+                               }
+                               break;
+                       }
+                       bio_write(0, 1);
+                       ++low;
+               }
+
+               node->low = low;
+               if (stkptr == stk)
+                       break;
+               node = *--stkptr;
+       }
+
+}
+
+/* <summary> */
+/* Decode the value of a leaf of the tag-tree. */
+/* </summary> */
+int tgt_decode(tgt_tree_t * tree, int leafno, int threshold)
+{
+       tgt_node_t *stk[31];
+       tgt_node_t **stkptr;
+       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(1)) {
+                               node->value = low;
+                       } else {
+                               ++low;
+                       }
+               }
+               node->low = low;
+               if (stkptr == stk) {
+                       break;
+               }
+               node = *--stkptr;
+       }
+
+       return (node->value < threshold) ? 1 : 0;
+}
diff --git a/libopenjpeg/tgt.h b/libopenjpeg/tgt.h
new file mode 100644 (file)
index 0000000..3ace397
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2001-2002, David Janssens
+ * 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
+
+typedef struct tgt_node {
+       struct tgt_node *parent;
+       int value;
+       int low;
+       int known;
+} tgt_node_t;
+
+typedef struct {
+       int numleafsh;
+       int numleafsv;
+       int numnodes;
+       tgt_node_t *nodes;
+} tgt_tree_t;
+
+/*
+ * Create a tag-tree
+ * numleafsh: width of the array of leafs of the tree
+ * numleafsv: height of the array of leafs of the tree
+ */
+tgt_tree_t *tgt_create(int numleafsh, int numleafsv);
+
+/*
+ * Reset a tag-tree (set all leafs to 0)
+ * tree: tag-tree to reset
+ */
+void tgt_reset(tgt_tree_t * tree);
+
+/*
+ * Destroy a tag-tree, liberating memory
+ * tree: tag-tree to destroy
+ */
+void tgt_destroy(tgt_tree_t * tree);
+
+/*
+ * Set the value of a leaf of a tag-tree
+ * tree: tag-tree to modify
+ * leafno: number that identifies the leaf to modify
+ * value: new value of the leaf
+ */
+void tgt_setvalue(tgt_tree_t * tree, int leafno, int value);
+
+/*
+ * Encode the value of a leaf of the tag-tree up to a given threshold
+ * leafno: number that identifies the leaf to encode
+ * threshold: threshold to use when encoding value of the leaf
+ */
+void tgt_encode(tgt_tree_t * tree, int leafno, int threshold);
+
+/*
+ * Decode the value of a leaf of the tag-tree up to a given threshold
+ * leafno: number that identifies the leaf to decode
+ * threshold: threshold to use when decoding value of the leaf
+ */
+int tgt_decode(tgt_tree_t * tree, int leafno, int threshold);
+
+#endif