From 2ad6a9770a867ddc3ecc31f61a248152b7c6eeac Mon Sep 17 00:00:00 2001 From: Sebastien Lugan Date: Thu, 27 Nov 2003 10:10:17 +0000 Subject: [PATCH] Initial revision --- libopenjpeg/.cvsignore | 6 + libopenjpeg/Makefile | 67 ++ libopenjpeg/bio.c | 182 +++++ libopenjpeg/bio.h | 40 + libopenjpeg/cio.c | 136 ++++ libopenjpeg/cio.h | 40 + libopenjpeg/dwt.c | 681 +++++++++++++++++ libopenjpeg/dwt.h | 98 +++ libopenjpeg/fix.c | 41 + libopenjpeg/fix.h | 33 + libopenjpeg/int.c | 97 +++ libopenjpeg/int.h | 39 + libopenjpeg/j2k.c | 1153 ++++++++++++++++++++++++++++ libopenjpeg/j2k.h | 185 +++++ libopenjpeg/mct.c | 134 ++++ libopenjpeg/mct.h | 74 ++ libopenjpeg/mqc.c | 588 +++++++++++++++ libopenjpeg/mqc.h | 127 ++++ libopenjpeg/openjpeg.h | 48 ++ libopenjpeg/pi.c | 488 ++++++++++++ libopenjpeg/pi.h | 71 ++ libopenjpeg/raw.c | 129 ++++ libopenjpeg/raw.h | 72 ++ libopenjpeg/t1.c | 1077 ++++++++++++++++++++++++++ libopenjpeg/t1.h | 52 ++ libopenjpeg/t2.c | 505 +++++++++++++ libopenjpeg/t2.h | 59 ++ libopenjpeg/tcd.c | 1637 ++++++++++++++++++++++++++++++++++++++++ libopenjpeg/tcd.h | 159 ++++ libopenjpeg/tgt.c | 225 ++++++ libopenjpeg/tgt.h | 85 +++ 31 files changed, 8328 insertions(+) create mode 100644 libopenjpeg/.cvsignore create mode 100644 libopenjpeg/Makefile create mode 100644 libopenjpeg/bio.c create mode 100644 libopenjpeg/bio.h create mode 100644 libopenjpeg/cio.c create mode 100644 libopenjpeg/cio.h create mode 100644 libopenjpeg/dwt.c create mode 100644 libopenjpeg/dwt.h create mode 100644 libopenjpeg/fix.c create mode 100644 libopenjpeg/fix.h create mode 100644 libopenjpeg/int.c create mode 100644 libopenjpeg/int.h create mode 100644 libopenjpeg/j2k.c create mode 100644 libopenjpeg/j2k.h create mode 100644 libopenjpeg/mct.c create mode 100644 libopenjpeg/mct.h create mode 100644 libopenjpeg/mqc.c create mode 100644 libopenjpeg/mqc.h create mode 100644 libopenjpeg/openjpeg.h create mode 100644 libopenjpeg/pi.c create mode 100644 libopenjpeg/pi.h create mode 100644 libopenjpeg/raw.c create mode 100644 libopenjpeg/raw.h create mode 100644 libopenjpeg/t1.c create mode 100644 libopenjpeg/t1.h create mode 100644 libopenjpeg/t2.c create mode 100644 libopenjpeg/t2.h create mode 100644 libopenjpeg/tcd.c create mode 100644 libopenjpeg/tcd.h create mode 100644 libopenjpeg/tgt.c create mode 100644 libopenjpeg/tgt.h diff --git a/libopenjpeg/.cvsignore b/libopenjpeg/.cvsignore new file mode 100644 index 00000000..5aca9ad5 --- /dev/null +++ b/libopenjpeg/.cvsignore @@ -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 index 00000000..63a5f322 --- /dev/null +++ b/libopenjpeg/Makefile @@ -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 index 00000000..400523d7 --- /dev/null +++ b/libopenjpeg/bio.c @@ -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 +#include + +static unsigned char *bio_start, *bio_end, *bio_bp; +static unsigned int bio_buf; +static int bio_ct; + +extern jmp_buf j2k_error; + +/* */ +/* Number of bytes written. */ +/* */ +int bio_numbytes() +{ + return bio_bp - bio_start; +} + +/* */ +/* Init encoder. */ +/* */ +/* Output buffer */ +/* Output buffer length */ +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; +} + +/* */ +/* Init decoder. */ +/* */ +/* Input buffer */ +/* Input buffer length */ +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; +} + +/* */ +/* Write byte. --> function modified to eliminate longjmp !!! */ +/* */ +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; +} + +/* */ +/* Read byte. --> function modified to eliminate longjmp !! */ +/* */ +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; +} + +/* */ +/* Write bit. */ +/* */ +/* Bit to write (0 or 1) */ +void bio_putbit(int b) +{ + if (bio_ct == 0) { + bio_byteout(); + } + bio_ct--; + bio_buf |= b << bio_ct; +} + +/* */ +/* Read bit. */ +/* */ +int bio_getbit() +{ + if (bio_ct == 0) { + bio_bytein(); + } + bio_ct--; + return (bio_buf >> bio_ct) & 1; +} + +/* */ +/* Write bits. */ +/* */ +/* Value of bits */ +/* Number of bits to write */ +void bio_write(int v, int n) +{ + int i; + for (i = n - 1; i >= 0; i--) { + bio_putbit((v >> i) & 1); + } +} + +/* */ +/* Read bits. */ +/* */ +/* Number of bits to read */ +int bio_read(int n) +{ + int i, v; + v = 0; + for (i = n - 1; i >= 0; i--) { + v += bio_getbit() << i; + } + return v; +} + +/* */ +/* Flush bits. MOdified to eliminate longjmp !! */ +/* */ +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; +} + +/* */ +/* */ +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 index 00000000..b0813498 --- /dev/null +++ b/libopenjpeg/bio.h @@ -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 index 00000000..bc5adc60 --- /dev/null +++ b/libopenjpeg/cio.c @@ -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 + +static unsigned char *cio_start, *cio_end, *cio_bp; + +extern jmp_buf j2k_error; + +/* */ +/* Number of bytes written. */ +/* */ +int cio_numbytes() +{ + return cio_bp - cio_start; +} + +/* */ +/* Get position in byte stream. */ +/* */ +int cio_tell() +{ + return cio_bp - cio_start; +} + +/* */ +/* Set position in byte stream. */ +/* */ +void cio_seek(int pos) +{ + cio_bp = cio_start + pos; +} + +/* */ +/* Number of bytes left before the end of the stream. */ +/* */ +int cio_numbytesleft() +{ + return cio_end - cio_bp; +} + +/* */ +/* Get pointer to the current position in the stream. */ +/* */ +unsigned char *cio_getbp() +{ + return cio_bp; +} + +/* */ +/* Initialize byte IO. */ +/* */ +void cio_init(unsigned char *bp, int len) +{ + cio_start = bp; + cio_end = bp + len; + cio_bp = bp; +} + +/* */ +/* Write a byte. */ +/* */ +void cio_byteout(unsigned char v) +{ + if (cio_bp >= cio_end) + longjmp(j2k_error, 1); + *cio_bp++ = v; + +} + +/* */ +/* Read a byte. */ +/* */ +unsigned char cio_bytein() +{ + if (cio_bp >= cio_end) + longjmp(j2k_error, 1); + return *cio_bp++; +} + +/* */ +/* Write a byte. */ +/* */ +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)); + } +} + +/* */ +/* Read some bytes. */ +/* */ +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; +} + +/* */ +/* Write some bytes. */ +/* */ +void cio_skip(int n) +{ + cio_bp += n; +} diff --git a/libopenjpeg/cio.h b/libopenjpeg/cio.h new file mode 100644 index 00000000..c6945b7e --- /dev/null +++ b/libopenjpeg/cio.h @@ -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 index 00000000..6722d9f5 --- /dev/null +++ b/libopenjpeg/dwt.c @@ -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 +#include + +#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))) + +/* */ +/* This table contains the norms of the 5-3 wavelets for different bands. */ +/* */ +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} +}; + +/* */ +/* This table contains the norms of the 9-7 wavelets for different bands. */ +/* */ +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 */ + +/* */ +/* Forward lazy transform. */ +/* */ +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]; +} + +/* */ +/* Forward lazy transform. */ +/* */ +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]; + +} + +/* */ +/* Inverse lazy transform. */ +/* */ +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]; +} + +/* */ +/* Inverse lazy transform. */ +/* */ +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]; + +} + +/* */ +/* Forward 5-3 wavelet tranform in 1-D. */ +/* */ +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); +} + +/* */ +/* Inverse 5-3 wavelet tranform in 1-D. */ +/* */ +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; + } + } +} + +/* */ +/* Forward 5-3 wavelet tranform in 2-D. */ +/* */ +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(); +} + +/* */ +/* Inverse 5-3 wavelet tranform in 2-D. */ +/* */ +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(); +} + +/* */ +/* Get gain of 5-3 wavelet transform. */ +/* */ +int dwt_getgain(int orient) +{ + if (orient == 0) + return 0; + if (orient == 1 || orient == 2) + return 1; + return 2; +} + +/* */ +/* Get norm of 5-3 wavelet. */ +/* */ +double dwt_getnorm(int level, int orient) +{ + return dwt_norms[orient][level]; +} + +/* */ +/* Forward 9-7 wavelet transform in 1-D. */ +/* */ +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); +} + +/* */ +/* Inverse 9-7 wavelet transform in 1-D. */ +/* */ +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); + } + } +} + +/* */ +/* Forward 9-7 wavelet transform in 2-D. */ +/* */ + +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); + } +} + +/* */ +/* Inverse 9-7 wavelet transform in 2-D. */ +/* */ +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); + } +} + +/* */ +/* Get gain of 9-7 wavelet transform. */ +/* */ +int dwt_getgain_real(int orient) +{ + return 0; +} + +/* */ +/* Get norm of 9-7 wavelet. */ +/* */ +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 index 00000000..60c671da --- /dev/null +++ b/libopenjpeg/dwt.h @@ -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 index 00000000..6a8a64b4 --- /dev/null +++ b/libopenjpeg/fix.c @@ -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 + +/* */ +/* Multiply two fixed-precision rational numbers. */ +/* */ +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 index 00000000..768cada2 --- /dev/null +++ b/libopenjpeg/fix.h @@ -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 index 00000000..21d7c479 --- /dev/null +++ b/libopenjpeg/int.c @@ -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. + */ + +/* */ +/* Get the minimum of two integers. */ +/* */ +int int_min(int a, int b) +{ + return a < b ? a : b; +} + +/* */ +/* Get the maximum of two integers. */ +/* */ +int int_max(int a, int b) +{ + return a > b ? a : b; +} + +/* */ +/* Clamp an integer inside an interval. */ +/* */ +int int_clamp(int a, int min, int max) +{ + if (a < min) + return min; + if (a > max) + return max; + return a; +} + +/* */ +/* Get absolute value of integer. */ +/* */ +int int_abs(int a) +{ + return a < 0 ? -a : a; +} + +/* */ +/* Divide an integer and round upwards. */ +/* */ +int int_ceildiv(int a, int b) +{ + return (a + b - 1) / b; +} + +/* */ +/* Divide an integer by a power of 2 and round upwards. */ +/* */ +int int_ceildivpow2(int a, int b) +{ + return (a + (1 << b) - 1) >> b; +} + +/* */ +/* Divide an integer by a power of 2 and round downwards. */ +/* */ +int int_floordivpow2(int a, int b) +{ + return a >> b; +} + +/* */ +/* Get logarithm of an integer and round downwards. */ +/* */ +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 index 00000000..7b6fb875 --- /dev/null +++ b/libopenjpeg/int.h @@ -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 index 00000000..830c4fe6 --- /dev/null +++ b/libopenjpeg/j2k.c @@ -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 +#include +#include +#include +#include + +#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;ilen_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 + +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 index 00000000..3ad9cb00 --- /dev/null +++ b/libopenjpeg/j2k.h @@ -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 index 00000000..ef371e92 --- /dev/null +++ b/libopenjpeg/mct.c @@ -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" + +/* */ +/* This table contains the norms of the basis function of the reversible MCT. */ +/* */ +double mct_norms[3] = { 1.732, .8292, .8292 }; + +/* */ +/* This table contains the norms of the basis function of the irreversible MCT. */ +/* */ +double mct_norms_real[3] = { 1.732, 1.805, 1.573 }; + +/* */ +/* Foward reversible MCT. */ +/* */ +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; + } +} + +/* */ +/* Inverse reversible MCT. */ +/* */ +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; + } +} + +/* */ +/* Get norm of basis function of reversible MCT. */ +/* */ +double mct_getnorm(int compno) +{ + return mct_norms[compno]; +} + +/* */ +/* Foward irreversible MCT. */ +/* */ +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; + } +} + +/* */ +/* Inverse irreversible MCT. */ +/* */ +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; + } +} + +/* */ +/* Get norm of basis function of irreversible MCT. */ +/* */ +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 index 00000000..196dc6d3 --- /dev/null +++ b/libopenjpeg/mct.h @@ -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 index 00000000..3f6eb921 --- /dev/null +++ b/libopenjpeg/mqc.c @@ -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 + +/* */ +/* This struct defines the state of a context. */ +/* */ +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; + +/* */ +/* This array defines all the possible states for a context. */ +/* */ +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; + +/* */ +/* Return the number of bytes already encoded. */ +/* */ +int mqc_numbytes() +{ + return mqc_bp - mqc_start; +} + +/* */ +/* Output a byte, doing bit-stuffing if necessary. */ +/* After a 0xff byte, the next byte must be smaller than 0x90 */ +/* */ +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; + } + } + } +} + +/* */ +/* Renormalize mqc_a and mqc_c while encoding, so that mqc_a stays between 0x8000 and 0x10000 */ +/* */ +void mqc_renorme() +{ + do { + mqc_a <<= 1; + mqc_c <<= 1; + mqc_ct--; + if (mqc_ct == 0) { + mqc_byteout(); + } + } while ((mqc_a & 0x8000) == 0); +} + +/* */ +/* Encode the most probable symbol. */ +/* */ +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; + } +} + +/* */ +/* Encode the most least symbol. */ +/* */ +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(); +} + +/* */ +/* Initialize encoder. */ +/* */ +/* Output buffer. */ +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; +} + +/* */ +/* Set current context. */ +/* */ +/* Context number. */ +void mqc_setcurctx(int ctxno) +{ + mqc_curctx = &mqc_ctxs[ctxno]; +} + +/* */ +/* Encode a symbol using the MQ-coder. */ +/* */ +/* The symbol to be encoded (0 or 1). */ +void mqc_encode(int d) +{ + if ((*mqc_curctx)->mps == d) { + mqc_codemps(); + } else { + mqc_codelps(); + } +} + +/* */ +/* Fill mqc_c with 1's for flushing */ +/* */ +void mqc_setbits() +{ + unsigned int tempc = mqc_c + mqc_a; + mqc_c |= 0xffff; + if (mqc_c >= tempc) { + mqc_c -= 0x8000; + } +} + +/* */ +/* Flush encoded data. */ +/* */ +void mqc_flush() +{ + mqc_setbits(); + mqc_c <<= mqc_ct; + mqc_byteout(); + mqc_c <<= mqc_ct; + mqc_byteout(); + + if (*mqc_bp != 0xff) { + mqc_bp++; + } +} + +/* */ +/* not fully implemented and tested !! */ +/* BYPASS mode switch, initialization operation */ +/* JPEG 2000 p 505 */ +/* */ +void mqc_bypass_init_enc() +{ + mqc_c = 0; + mqc_ct = 8; + if (*mqc_bp == 0xff) { + mqc_ct = 7; + } +} + +/* */ +/* not fully implemented and tested !! */ +/* BYPASS mode switch, coding operation */ +/* JPEG 2000 p 505 */ +/* */ +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; + } +} + +/* */ +/* not fully implemented and tested !! */ +/* BYPASS mode switch, flush operation */ +/* */ +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; +} + +/* */ +/* RESET mode switch */ +/* */ +void mqc_reset_enc() +{ + mqc_resetstates(); + mqc_setstate(18, 0, 46); + mqc_setstate(0, 0, 3); + mqc_setstate(1, 0, 4); +} + +/* */ +/* mode switch RESTART (TERMALL) */ +/* */ +int mqc_restart_enc() +{ + int correction = 1; + + /* */ + 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; +} + +/* */ +/* mode switch RESTART (TERMALL) reinitialisation */ +/* */ +void mqc_restart_init_enc() +{ + /* */ + mqc_a = 0x8000; + mqc_c = 0; + mqc_ct = 12; + mqc_bp--; + if (*mqc_bp == 0xff) { + mqc_ct = 13; + } + +} + + +/* */ +/* ERTERM mode switch */ +/* */ +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(); + } +} + +/* */ +/* SEGMARK mode switch (SEGSYM) */ +/* */ +void mqc_segmark_enc() +{ + int i; + mqc_setcurctx(18); + + for (i = 1; i < 5; i++) { + mqc_encode(i % 2); + } +} + +/* */ +/* */ +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; +} + +/* */ +/* */ +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; +} + +/* */ +/* Input a byte. */ +/* */ +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; + } +} + +/* */ +/* Renormalize mqc_a and mqc_c while decoding. */ +/* */ +void mqc_renormd() +{ + do { + if (mqc_ct == 0) { + mqc_bytein(); + } + mqc_a <<= 1; + mqc_c <<= 1; + mqc_ct--; + } while (mqc_a < 0x8000); +} + +/* */ +/* Initialize decoder. */ +/* */ +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; +} + +/* */ +/* Decode a symbol. */ +/* */ +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; +} + +/* */ +/* Reset states of all contexts. */ +/* */ +void mqc_resetstates() +{ + int i; + for (i = 0; i < MQC_NUMCTXS; i++) { + mqc_ctxs[i] = mqc_states; + } +} + +/* */ +/* Set the state for a context. */ +/* */ +/* Context number */ +/* Most significant bit */ +/* Index to the probability of symbols */ +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 index 00000000..3d29a6d2 --- /dev/null +++ b/libopenjpeg/mqc.h @@ -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 index 00000000..ad49ebaf --- /dev/null +++ b/libopenjpeg/openjpeg.h @@ -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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/libopenjpeg/pi.c b/libopenjpeg/pi.c new file mode 100644 index 00000000..eca2c451 --- /dev/null +++ b/libopenjpeg/pi.c @@ -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 +#include + + +/* */ +/* Create a packet iterator. */ +/* */ +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; +} + +/* */ +/* Get next packet in layer=resolution-component-precinct order. */ +/* */ +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; +} + +/* */ +/* Get next packet in resolution-layer-component-precinct order. */ +/* */ +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; +} + +/* */ +/* Get next packet in resolution-precinct-component-layer order. */ +/* */ +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; +} + +/* */ +/* Get next packet in precinct-component-resolution-layer order. */ +/* */ +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; +} + +/* */ +/* Get next packet in component-precinct-resolution-layer order. */ +/* */ +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; +} + +/* */ +/* Get next packet. */ +/* */ +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 index 00000000..5403faf4 --- /dev/null +++ b/libopenjpeg/pi.h @@ -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 index 00000000..bdfe6242 --- /dev/null +++ b/libopenjpeg/raw.c @@ -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; + +/* */ +/* Return the number of bytes already encoded. */ +/* */ +int raw_numbytes() +{ + return raw_bp - raw_start; +} + +/* */ +/* Initialize raw-encoder. */ +/* */ +/* Output buffer. */ +void raw_init_enc(unsigned char *bp) +{ + raw_bp = bp - 1; + raw_c = 0; + raw_ct = 7; + raw_start = bp; +} + +/* */ +/* Encode a symbol using the RAW-coder. */ +/* */ +/* The symbol to be encoded (0 or 1). */ +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; + } */ +} + +/* */ +/* Flush encoded data. */ +/* */ +void raw_flush() +{ + char first = 1; + int prev = 1; + while (raw_ct != 7) { + raw_encode(first ? 0 : !(prev)); + prev = first ? 0 : !(prev); + first = 0; + } +} + +/* */ +/* Initialize raw-decoder. */ +/* */ +void raw_init_dec(unsigned char *bp, int len) +{ + raw_start = bp; + raw_lenmax = len; + raw_len = 0; + raw_c = 0; + raw_ct = 0; +} + +/* */ +/* Decode a symbol using raw-decoder. Cfr p.506 TAUBMAN */ +/* */ +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 index 00000000..eede21a5 --- /dev/null +++ b/libopenjpeg/raw.h @@ -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 index 00000000..2e785304 --- /dev/null +++ b/libopenjpeg/t1.c @@ -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 +#include +#include + +#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 index 00000000..5e98bc09 --- /dev/null +++ b/libopenjpeg/t1.h @@ -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 index 00000000..9bd3a2b0 --- /dev/null +++ b/libopenjpeg/t2.c @@ -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 +#include +#include +#include + +#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; +} + +/* */ +/* Variable length code for signalling delta Zil (truncation point) */ +/* 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; */ + + /* */ + 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; + } + /* */ + + 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(); + + /* */ + 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; + } + /* */ + /* } */ + /* 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; + } /* */ + 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; + } /* */ + } + } + 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 index 00000000..4d7757a6 --- /dev/null +++ b/libopenjpeg/t2.h @@ -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 index 00000000..8b53da0d --- /dev/null +++ b/libopenjpeg/tcd.c @@ -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 +#include +#include +#include +#include +#include +#include + +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 index 00000000..e8e87727 --- /dev/null +++ b/libopenjpeg/tcd.h @@ -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 index 00000000..4d4e2beb --- /dev/null +++ b/libopenjpeg/tgt.c @@ -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 +#include + +/* */ +/* Reset tag-tree. */ +/* */ +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; + } +} + +/* */ +/* Create tag-tree. */ +/* */ +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; +} + +/* */ +/* Destroy tag-tree. */ +/* */ +void tgt_destroy(tgt_tree_t * t) +{ + free(t->nodes); + free(t); +} + +/* */ +/* Set the value of a leaf of the tag-tree. */ +/* */ +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; + } +} + +/* */ +/* Encode the value of a leaf of the tag-tree. */ +/* */ +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; + } + +} + +/* */ +/* Decode the value of a leaf of the tag-tree. */ +/* */ +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 index 00000000..3ace397a --- /dev/null +++ b/libopenjpeg/tgt.h @@ -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