diff --git a/jpwl/decoder/ReadmeJPWLdec.txt b/jpwl/decoder/ReadmeJPWLdec.txt new file mode 100644 index 00000000..5b4f2988 --- /dev/null +++ b/jpwl/decoder/ReadmeJPWLdec.txt @@ -0,0 +1,20 @@ +Version ****JPWLcorrect**** + +This version realizes a JPWL decoder based on OpenJPEG library. +Realized decoder accepts an input JPWL codestream, corrects errors sgnalling eventual +residual errors and finally outputs the corrected JPWL codestream. This codestream shall +be used by a JPEG2000 Part-1 decoder to decode the image. + +How to use decoder from prompt line: + +"jpwl_correct input.j2k o.bmp" + +where, + + - "input.j2k" is the input corrupted JPWL codestream + - "o.bmp" this file is necessary as parameter but the decoder doesn't create + that as output. + +Decoder create output file "output.j2c", that is the corrected JPWL codestream. + +Note that .j2c is the extension accepted by "kakadu" decoder. \ No newline at end of file diff --git a/jpwl/decoder/jpwldec/.cvsignore b/jpwl/decoder/jpwldec/.cvsignore new file mode 100644 index 00000000..5aca9ad5 --- /dev/null +++ b/jpwl/decoder/jpwldec/.cvsignore @@ -0,0 +1,6 @@ +obj +obj.w32 +bin +bin.w32 +lib +lib.w32 diff --git a/jpwl/decoder/jpwldec/Makefile b/jpwl/decoder/jpwldec/Makefile new file mode 100644 index 00000000..27dc9a5c --- /dev/null +++ b/jpwl/decoder/jpwldec/Makefile @@ -0,0 +1,94 @@ +# $Id$ +# +# makefile for OpenJPEG codec + +OPENJPEG_DIR = ../libopenjpeg + +ifndef DEBUG + LDFLAGS = -s -lm +else + LDFLAGS = -lm +endif + +CFLAGS = -Wall -O3 -fno-strength-reduce -fomit-frame-pointer -I$(OPENJPEG_DIR) + +OBJ_DIR_W32 = obj.w32 +BIN_DIR_W32 = bin.w32 +LIB_DIR_W32 = $(OPENJPEG_DIR)/lib.w32 + +ifdef MINGW32 + CC = i386-mingw32-gcc + CFLAGS += -DDONT_HAVE_GETOPT + OBJ_DIR = $(OBJ_DIR_W32) + BIN_DIR = $(BIN_DIR_W32) + LIB_DIR = lib.w32 + all: $(BIN_DIR) $(OBJ_DIR) $(LIB_DIR) \ + $(addprefix $(BIN_DIR)/,j2k_to_image.exe image_to_j2k.exe) +else + CC = gcc + OBJ_DIR = obj + BIN_DIR = bin + LIB_DIR = lib + all: $(BIN_DIR) $(OBJ_DIR) $(LIB_DIR) \ + $(addprefix $(BIN_DIR)/,j2k_to_image image_to_j2k) +endif + +ifdef DYNAMIC + ifdef MINGW32 + LIB_OPENJPEG = $(LIB_DIR)/libopenjpeg.dll + LDFLAGS += -L$(LIB_DIR) -lopenjpeg + else + LIB_OPENJPEG = $(OPENJPEG_DIR)/$(LIB_DIR)/libopenjpeg.so + LDFLAGS += -L$(OPENJPEG_DIR)/$(LIB_DIR) -lopenjpeg + endif +else + LIB_OPENJPEG = $(OPENJPEG_DIR)/$(LIB_DIR)/libopenjpeg.a + LDFLAGS += $(LIB_OPENJPEG) +endif + +$(BIN_DIR): + mkdir $(BIN_DIR) + +$(OBJ_DIR): + mkdir $(OBJ_DIR) + +$(LIB_DIR): + mkdir $(LIB_DIR) + +$(LIB_DIR)/libopenjpeg.dll: $(OPENJPEG_DIR)/$(LIB_DIR)/libopenjpeg.dll + ln -sf ../$< $@ +$(OPENJPEG_DIR)/$(LIB_DIR)/libopenjpeg.dll: + cd $(OPENJPEG_DIR) && \ + $(MAKE) $(OBJ_DIR) $(LIB_DIR) $(LIB_DIR)/libopenjpeg.dll +$(OPENJPEG_DIR)/$(LIB_DIR)/libopenjpeg.a: + cd $(OPENJPEG_DIR) && \ + $(MAKE) $(OBJ_DIR) $(LIB_DIR) $(LIB_DIR)/libopenjpeg.a +$(OPENJPEG_DIR)/$(LIB_DIR)/libopenjpeg.so: + cd $(OPENJPEG_DIR) && \ + $(MAKE) $(LIB_DIR) $(LIB_DIR)/libopenjpeg.so + +$(OBJ_DIR)/%.o: + $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $< + +$(OBJ_DIR)/getopt.o: compat/getopt.c +$(OBJ_DIR)/convert.o: convert.c +$(OBJ_DIR)/j2k_to_image.o: j2k_to_image.c +$(OBJ_DIR)/image_to_j2k.o: image_to_j2k.c convert.h + +J2I_OBJS = $(addprefix $(OBJ_DIR)/,j2k_to_image.o) +I2J_OBJS = $(addprefix $(OBJ_DIR)/,image_to_j2k.o convert.o) + +$(BIN_DIR)/j2k_to_image: $(J2I_OBJS) $(LIB_OPENJPEG) + ${CC} -o $@ $(J2I_OBJS) ${LDFLAGS} + +$(BIN_DIR)/image_to_j2k: $(I2J_OBJS) $(LIB_OPENJPEG) + ${CC} -o $@ $(I2J_OBJS) ${LDFLAGS} + +$(BIN_DIR)/j2k_to_image.exe: $(J2I_OBJS) $(LIB_OPENJPEG) + ${CC} -o $@ $(J2I_OBJS) ${LDFLAGS} + +$(BIN_DIR)/image_to_j2k.exe: $(I2J_OBJS) $(LIB_OPENJPEG) $(OBJ_DIR)/getopt.o + ${CC} -o $@ $(I2J_OBJS) ${LDFLAGS} $(OBJ_DIR)/getopt.o + +clean: + rm -f $(BIN_DIR_W32)/* $(BIN_DIR)/* $(OBJ_DIR_W32)/* $(OBJ_DIR)/* diff --git a/jpwl/decoder/jpwldec/compat/getopt.c b/jpwl/decoder/jpwldec/compat/getopt.c new file mode 100644 index 00000000..d0082c51 --- /dev/null +++ b/jpwl/decoder/jpwldec/compat/getopt.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 1987, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* last review : october 29th, 2002 */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include + +int opterr = 1, /* if error message should be printed */ + optind = 1, /* index into parent argv vector */ + optopt, /* character checked for validity */ + optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ + +#define BADCH (int)'?' +#define BADARG (int)':' +#define EMSG "" + +/* + * getopt -- + * Parse argc/argv argument vector. + */ +int getopt(nargc, nargv, ostr) +int nargc; +char *const *nargv; +const char *ostr; +{ +# define __progname nargv[0] + static char *place = EMSG; /* option letter processing */ + char *oli; /* option letter list index */ + + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc || *(place = nargv[optind]) != '-') { + place = EMSG; + return (-1); + } + if (place[1] && *++place == '-') { /* found "--" */ + ++optind; + place = EMSG; + return (-1); + } + } /* option letter okay? */ + if ((optopt = (int) *place++) == (int) ':' || + !(oli = strchr(ostr, optopt))) { + /* + * if the user didn't specify '-' as an option, + * assume it means -1. + */ + if (optopt == (int) '-') + return (-1); + if (!*place) + ++optind; + if (opterr && *ostr != ':') + (void) fprintf(stderr, + "%s: illegal option -- %c\n", __progname, optopt); + return (BADCH); + } + if (*++oli != ':') { /* don't need argument */ + optarg = NULL; + if (!*place) + ++optind; + } else { /* need an argument */ + if (*place) /* no white space */ + optarg = place; + else if (nargc <= ++optind) { /* no arg */ + place = EMSG; + if (*ostr == ':') + return (BADARG); + if (opterr) + (void) fprintf(stderr, + "%s: option requires an argument -- %c\n", + __progname, optopt); + return (BADCH); + } else /* white space */ + optarg = nargv[optind]; + place = EMSG; + ++optind; + } + return (optopt); /* dump back option letter */ +} diff --git a/jpwl/decoder/jpwldec/compat/getopt.h b/jpwl/decoder/jpwldec/compat/getopt.h new file mode 100644 index 00000000..ab9c1a7b --- /dev/null +++ b/jpwl/decoder/jpwldec/compat/getopt.h @@ -0,0 +1,14 @@ +/* last review : october 29th, 2002 */ + +#ifndef _GETOPT_H_ +#define _GETOPT_H_ + +extern int opterr; +extern int optind; +extern int optopt; +extern int optreset; +extern char *optarg; + +extern int getopt(int nargc, char *const *nargv, const char *ostr); + +#endif /* _GETOPT_H_ */ diff --git a/jpwl/decoder/jpwldec/convert.c b/jpwl/decoder/jpwldec/convert.c new file mode 100644 index 00000000..0bbb022a --- /dev/null +++ b/jpwl/decoder/jpwldec/convert.c @@ -0,0 +1,913 @@ +/* + * Copyright (c) 2001-2003, 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 + +/* -->> -->> -->> -->> + + BMP IMAGE FORMAT + + <<-- <<-- <<-- <<-- */ + +/* UINT2 defines a two byte word */ +typedef unsigned short int UINT2; + +/* UINT4 defines a four byte word */ +typedef unsigned long int UINT4; + +typedef struct { + UINT2 bfType; /* 'BM' for Bitmap (19776) */ + UINT4 bfSize; /* Size of the file */ + UINT2 bfReserved1; /* Reserved : 0 */ + UINT2 bfReserved2; /* Reserved : 0 */ + UINT4 bfOffBits; /* Offset */ +} BITMAPFILEHEADER_t; + +typedef struct { + UINT4 biSize; /* Size of the structure in bytes */ + UINT4 biWidth; /* Width of the image in pixels */ + UINT4 biHeight; /* Heigth of the image in pixels */ + UINT2 biPlanes; /* 1 */ + UINT2 biBitCount; /* Number of color bits by pixels */ + UINT4 biCompression; /* Type of encoding 0: none 1: RLE8 2: RLE4 */ + UINT4 biSizeImage; /* Size of the image in bytes */ + UINT4 biXpelsPerMeter; /* Horizontal (X) resolution in pixels/meter */ + UINT4 biYpelsPerMeter; /* Vertical (Y) resolution in pixels/meter */ + UINT4 biClrUsed; /* Number of color used in the image (0: ALL) */ + UINT4 biClrImportant; /* Number of important color (0: ALL) */ +} BITMAPINFOHEADER_t; + +int bmptoimage(char *filename, j2k_image_t * img, int subsampling_dx, + int subsampling_dy, int Dim[2]) +{ + FILE *IN; + FILE *Compo0 = NULL, *Compo1 = NULL, *Compo2 = NULL; + BITMAPFILEHEADER_t File_h; + BITMAPINFOHEADER_t Info_h; + unsigned char *RGB; + unsigned char *table_R, *table_G, *table_B; + unsigned int j, w, h, PAD, type = 0; + + int i; + int gray_scale = 1, not_end_file = 1; + + unsigned int line = 0, col = 0; + unsigned char v, v2; + UINT4 W, H; + + IN = fopen(filename, "rb"); + if (!IN) { + fprintf(stderr, + "\033[0;33mFailed to open %s for reading !!\033[0;39m\n", + filename); + return 0; + } + + File_h.bfType = getc(IN); + File_h.bfType = (getc(IN) << 8) + File_h.bfType; + + if (File_h.bfType != 19778) { + printf("Error, not a BMP file!\n"); + return 0; + } else { + /* FILE HEADER */ + /* ------------- */ + File_h.bfSize = getc(IN); + File_h.bfSize = (getc(IN) << 8) + File_h.bfSize; + File_h.bfSize = (getc(IN) << 16) + File_h.bfSize; + File_h.bfSize = (getc(IN) << 24) + File_h.bfSize; + + File_h.bfReserved1 = getc(IN); + File_h.bfReserved1 = (getc(IN) << 8) + File_h.bfReserved1; + + File_h.bfReserved2 = getc(IN); + File_h.bfReserved2 = (getc(IN) << 8) + File_h.bfReserved2; + + File_h.bfOffBits = getc(IN); + File_h.bfOffBits = (getc(IN) << 8) + File_h.bfOffBits; + File_h.bfOffBits = (getc(IN) << 16) + File_h.bfOffBits; + File_h.bfOffBits = (getc(IN) << 24) + File_h.bfOffBits; + + /* INFO HEADER */ + /* ------------- */ + + Info_h.biSize = getc(IN); + Info_h.biSize = (getc(IN) << 8) + Info_h.biSize; + Info_h.biSize = (getc(IN) << 16) + Info_h.biSize; + Info_h.biSize = (getc(IN) << 24) + Info_h.biSize; + + Info_h.biWidth = getc(IN); + Info_h.biWidth = (getc(IN) << 8) + Info_h.biWidth; + Info_h.biWidth = (getc(IN) << 16) + Info_h.biWidth; + Info_h.biWidth = (getc(IN) << 24) + Info_h.biWidth; + w = Info_h.biWidth; + + Info_h.biHeight = getc(IN); + Info_h.biHeight = (getc(IN) << 8) + Info_h.biHeight; + Info_h.biHeight = (getc(IN) << 16) + Info_h.biHeight; + Info_h.biHeight = (getc(IN) << 24) + Info_h.biHeight; + h = Info_h.biHeight; + + Info_h.biPlanes = getc(IN); + Info_h.biPlanes = (getc(IN) << 8) + Info_h.biPlanes; + + Info_h.biBitCount = getc(IN); + Info_h.biBitCount = (getc(IN) << 8) + Info_h.biBitCount; + + Info_h.biCompression = getc(IN); + Info_h.biCompression = (getc(IN) << 8) + Info_h.biCompression; + Info_h.biCompression = (getc(IN) << 16) + Info_h.biCompression; + Info_h.biCompression = (getc(IN) << 24) + Info_h.biCompression; + + Info_h.biSizeImage = getc(IN); + Info_h.biSizeImage = (getc(IN) << 8) + Info_h.biSizeImage; + Info_h.biSizeImage = (getc(IN) << 16) + Info_h.biSizeImage; + Info_h.biSizeImage = (getc(IN) << 24) + Info_h.biSizeImage; + + Info_h.biXpelsPerMeter = getc(IN); + Info_h.biXpelsPerMeter = (getc(IN) << 8) + Info_h.biXpelsPerMeter; + Info_h.biXpelsPerMeter = (getc(IN) << 16) + Info_h.biXpelsPerMeter; + Info_h.biXpelsPerMeter = (getc(IN) << 24) + Info_h.biXpelsPerMeter; + + Info_h.biYpelsPerMeter = getc(IN); + Info_h.biYpelsPerMeter = (getc(IN) << 8) + Info_h.biYpelsPerMeter; + Info_h.biYpelsPerMeter = (getc(IN) << 16) + Info_h.biYpelsPerMeter; + Info_h.biYpelsPerMeter = (getc(IN) << 24) + Info_h.biYpelsPerMeter; + + Info_h.biClrUsed = getc(IN); + Info_h.biClrUsed = (getc(IN) << 8) + Info_h.biClrUsed; + Info_h.biClrUsed = (getc(IN) << 16) + Info_h.biClrUsed; + Info_h.biClrUsed = (getc(IN) << 24) + Info_h.biClrUsed; + + Info_h.biClrImportant = getc(IN); + Info_h.biClrImportant = (getc(IN) << 8) + Info_h.biClrImportant; + Info_h.biClrImportant = (getc(IN) << 16) + Info_h.biClrImportant; + Info_h.biClrImportant = (getc(IN) << 24) + Info_h.biClrImportant; + + /* Read the data and store them in the OUT file */ + + if (Info_h.biBitCount == 24) { + img->x0 = Dim[0]; + img->y0 = Dim[1]; + img->x1 = + !Dim[0] ? (w - 1) * subsampling_dx + 1 : Dim[0] + (w - + 1) * + subsampling_dx + 1; + img->y1 = + !Dim[1] ? (h - 1) * subsampling_dy + 1 : Dim[1] + (h - + 1) * + subsampling_dy + 1; + img->numcomps = 3; + img->color_space = 1; + img->comps = + (j2k_comp_t *) malloc(img->numcomps * sizeof(j2k_comp_t)); + for (i = 0; i < img->numcomps; i++) { + img->comps[i].prec = 8; + img->comps[i].bpp = 8; + img->comps[i].sgnd = 0; + img->comps[i].dx = subsampling_dx; + img->comps[i].dy = subsampling_dy; + } + Compo0 = fopen("Compo0", "wb"); + if (!Compo0) { + fprintf(stderr, + "\033[0;33mFailed to open Compo0 for writing !\033[0;39m\n"); + } + Compo1 = fopen("Compo1", "wb"); + if (!Compo1) { + fprintf(stderr, + "\033[0;33mFailed to open Compo1 for writing !\033[0;39m\n"); + } + Compo2 = fopen("Compo2", "wb"); + if (!Compo2) { + fprintf(stderr, + "\033[0;33mFailed to open Compo2 for writing !\033[0;39m\n"); + } + + /* Place the cursor at the beginning of the image information */ + fseek(IN, 0, SEEK_SET); + fseek(IN, File_h.bfOffBits, SEEK_SET); + + W = Info_h.biWidth; + H = Info_h.biHeight; + + // PAD = 4 - (3 * W) % 4; + // PAD = (PAD == 4) ? 0 : PAD; + PAD = (3 * W) % 4 ? 4 - (3 * W) % 4 : 0; + + + RGB = + (unsigned char *) malloc((3 * W + PAD) * H * + sizeof(unsigned char)); + + fread(RGB, sizeof(unsigned char), (3 * W + PAD) * H, IN); + + for (j = 0; j < (3 * W + PAD) * H; j++) { + unsigned char elmt; + int Wp = 3 * W + PAD; + + elmt = RGB[(H - (j / Wp + 1)) * Wp + j % Wp]; + if ((j % Wp) < (3 * W)) { + switch (type) { + case 0: + fprintf(Compo2, "%c", elmt); + type = 1; + break; + case 1: + fprintf(Compo1, "%c", elmt); + type = 2; + break; + case 2: + fprintf(Compo0, "%c", elmt); + type = 0; + break; + } + } + } + + fclose(Compo0); + fclose(Compo1); + fclose(Compo2); + free(RGB); + } else if (Info_h.biBitCount == 8 && Info_h.biCompression == 0) { + img->x0 = Dim[0]; + img->y0 = Dim[1]; + img->x1 = + !Dim[0] ? (w - 1) * subsampling_dx + 1 : Dim[0] + (w - + 1) * + subsampling_dx + 1; + img->y1 = + !Dim[1] ? (h - 1) * subsampling_dy + 1 : Dim[1] + (h - + 1) * + subsampling_dy + 1; + + table_R = (unsigned char *) malloc(256 * sizeof(unsigned char)); + table_G = (unsigned char *) malloc(256 * sizeof(unsigned char)); + table_B = (unsigned char *) malloc(256 * sizeof(unsigned char)); + + for (j = 0; j < Info_h.biClrUsed; j++) { + table_B[j] = getc(IN); + table_G[j] = getc(IN); + table_R[j] = getc(IN); + getc(IN); + if (table_R[j] != table_G[j] && table_R[j] != table_B[j] + && table_G[j] != table_B[j]) + gray_scale = 0; + } + + /* Place the cursor at the beginning of the image information */ + fseek(IN, 0, SEEK_SET); + fseek(IN, File_h.bfOffBits, SEEK_SET); + + W = Info_h.biWidth; + H = Info_h.biHeight; + if (Info_h.biWidth % 2) + W++; + + RGB = (unsigned char *) malloc(W * H * sizeof(unsigned char)); + + fread(RGB, sizeof(unsigned char), W * H, IN); + if (gray_scale) { + img->numcomps = 1; + img->comps = + (j2k_comp_t *) malloc(img->numcomps * sizeof(j2k_comp_t)); + img->comps[0].prec = 8; + img->comps[0].bpp = 8; + img->comps[0].sgnd = 0; + img->comps[0].dx = subsampling_dx; + img->comps[0].dy = subsampling_dy; + Compo0 = fopen("Compo0", "wb"); + if (!Compo0) { + fprintf(stderr, + "\033[0;33mFailed to open Compo0 for writing !\033[0;39m\n"); + } + for (j = 0; j < W * H; j++) { + if ((j % W < W - 1 && Info_h.biWidth % 2) + || !(Info_h.biWidth % 2)) + fprintf(Compo0, "%c", + table_R[RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)]]); + } + fclose(Compo0); + } else { + img->numcomps = 3; + img->comps = + (j2k_comp_t *) malloc(img->numcomps * sizeof(j2k_comp_t)); + for (i = 0; i < img->numcomps; i++) { + img->comps[i].prec = 8; + img->comps[i].bpp = 8; + img->comps[i].sgnd = 0; + img->comps[i].dx = subsampling_dx; + img->comps[i].dy = subsampling_dy; + } + + Compo0 = fopen("Compo0", "wb"); + if (!Compo0) { + fprintf(stderr, + "\033[0;33mFailed to open Compo0 for writing !\033[0;39m\n"); + } + Compo1 = fopen("Compo1", "wb"); + if (!Compo1) { + fprintf(stderr, + "\033[0;33mFailed to open Compo1 for writing !\033[0;39m\n"); + } + Compo2 = fopen("Compo2", "wb"); + if (!Compo2) { + fprintf(stderr, + "\033[0;33mFailed to open Compo2 for writing !\033[0;39m\n"); + } + + for (j = 0; j < W * H; j++) { + if ((j % W < W - 1 && Info_h.biWidth % 2) + || !(Info_h.biWidth % 2)) { + fprintf(Compo0, "%c", + table_R[RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)]]); + fprintf(Compo1, "%c", + table_G[RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)]]); + fprintf(Compo2, "%c", + table_B[RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)]]); + } + + } + fclose(Compo0); + fclose(Compo1); + fclose(Compo2); + } + free(RGB); + + } else if (Info_h.biBitCount == 8 && Info_h.biCompression == 1) { + img->x0 = Dim[0]; + img->y0 = Dim[1]; + img->x1 = + !Dim[0] ? (w - 1) * subsampling_dx + 1 : Dim[0] + (w - + 1) * + subsampling_dx + 1; + img->y1 = + !Dim[1] ? (h - 1) * subsampling_dy + 1 : Dim[1] + (h - + 1) * + subsampling_dy + 1; + + table_R = (unsigned char *) malloc(256 * sizeof(unsigned char)); + table_G = (unsigned char *) malloc(256 * sizeof(unsigned char)); + table_B = (unsigned char *) malloc(256 * sizeof(unsigned char)); + + for (j = 0; j < Info_h.biClrUsed; j++) { + table_B[j] = getc(IN); + table_G[j] = getc(IN); + table_R[j] = getc(IN); + getc(IN); + if (table_R[j] != table_G[j] && table_R[j] != table_B[j] + && table_G[j] != table_B[j]) + gray_scale = 0; + } + + /* Place the cursor at the beginning of the image information */ + fseek(IN, 0, SEEK_SET); + fseek(IN, File_h.bfOffBits, SEEK_SET); + + if (gray_scale) { + img->numcomps = 1; + img->comps = (j2k_comp_t *) malloc(sizeof(j2k_comp_t)); + img->comps[0].prec = 8; + img->comps[0].bpp = 8; + img->comps[0].sgnd = 0; + img->comps[0].dx = subsampling_dx; + img->comps[0].dy = subsampling_dy; + Compo0 = fopen("Compo0", "wb"); + if (!Compo0) { + fprintf(stderr, + "\033[0;33mFailed to open Compo0 for writing !\033[0;39m\n"); + } + } else { + img->numcomps = 3; + img->comps = + (j2k_comp_t *) malloc(img->numcomps * sizeof(j2k_comp_t)); + for (i = 0; i < img->numcomps; i++) { + img->comps[i].prec = 8; + img->comps[i].bpp = 8; + img->comps[i].sgnd = 0; + img->comps[i].dx = subsampling_dx; + img->comps[i].dy = subsampling_dy; + } + Compo0 = fopen("Compo0", "wb"); + if (!Compo0) { + fprintf(stderr, + "\033[0;33mFailed to open Compo0 for writing !\033[0;39m\n"); + } + Compo1 = fopen("Compo1", "wb"); + if (!Compo1) { + fprintf(stderr, + "\033[0;33mFailed to open Compo1 for writing !\033[0;39m\n"); + } + Compo2 = fopen("Compo2", "wb"); + if (!Compo2) { + fprintf(stderr, + "\033[0;33mFailed to open Compo2 for writing !\033[0;39m\n"); + } + } + + RGB = + (unsigned char *) malloc(Info_h.biWidth * Info_h.biHeight * + sizeof(unsigned char)); + + while (not_end_file) { + v = getc(IN); + if (v) { + v2 = getc(IN); + for (i = 0; i < (int) v; i++) { + RGB[line * Info_h.biWidth + col] = v2; + col++; + } + } else { + v = getc(IN); + switch (v) { + case 0: + col = 0; + line++; + break; + case 1: + line++; + not_end_file = 0; + break; + case 2: + printf("No Delta supported\n"); + return 1; + break; + default: + for (i = 0; i < v; i++) { + v2 = getc(IN); + RGB[line * Info_h.biWidth + col] = v2; + col++; + } + if (v % 2) + v2 = getc(IN); + } + } + } + if (gray_scale) { + for (line = 0; line < Info_h.biHeight; line++) + for (col = 0; col < Info_h.biWidth; col++) + fprintf(Compo0, "%c", table_R[(int) + RGB[(Info_h.biHeight - line - + 1) * Info_h.biWidth + + col]]); + fclose(Compo0); + } else { + for (line = 0; line < Info_h.biHeight; line++) + for (col = 0; col < Info_h.biWidth; col++) { + fprintf(Compo0, "%c", table_R[(int) + RGB[(Info_h.biHeight - line - + 1) * Info_h.biWidth + + col]]); + fprintf(Compo1, "%c", table_G[(int) + RGB[(Info_h.biHeight - line - + 1) * Info_h.biWidth + + col]]); + fprintf(Compo2, "%c", table_B[(int) + RGB[(Info_h.biHeight - line - + 1) * Info_h.biWidth + + col]]); + } + fclose(Compo0); + fclose(Compo1); + fclose(Compo2); + } + free(RGB); + } else + fprintf(stderr, + "Other system than 24 bits/pixels or 8 bits (no RLE coding) is not yet implemented [%d]\n", + Info_h.biBitCount); + + fclose(IN); + return 1; + } +} + + /* -->> -->> -->> -->> + + PGX IMAGE FORMAT + + <<-- <<-- <<-- <<-- */ + + +unsigned char readuchar(FILE * f) +{ + unsigned char c1; + fread(&c1, 1, 1, f); + return c1; +} + +unsigned short readushort(FILE * f, int bigendian) +{ + unsigned char c1, c2; + fread(&c1, 1, 1, f); + fread(&c2, 1, 1, f); + if (bigendian) + return (c1 << 8) + c2; + else + return (c2 << 8) + c1; +} + +unsigned int readuint(FILE * f, int bigendian) +{ + unsigned char c1, c2, c3, c4; + fread(&c1, 1, 1, f); + fread(&c2, 1, 1, f); + fread(&c3, 1, 1, f); + fread(&c4, 1, 1, f); + if (bigendian) + return (c1 << 24) + (c2 << 16) + (c3 << 8) + c4; + else + return (c4 << 24) + (c3 << 16) + (c2 << 8) + c1; +} + +int pgxtoimage(char *filename, j2k_image_t * img, int tdy, + int subsampling_dx, int subsampling_dy, int Dim[2], + j2k_cp_t cp) +{ + FILE *f; + int w, h, prec; + int i, compno, bandno; + char str[256], endian[16]; + char sign; + int bigendian; + j2k_comp_t *comp; + + img->numcomps = 1; + img->color_space = 2; + img->comps = (j2k_comp_t *) malloc(img->numcomps * sizeof(j2k_comp_t)); + for (compno = 0; compno < img->numcomps; compno++) { + FILE *src; + char tmp[16]; + int max = 0; + int Y1; + comp = &img->comps[compno]; + sprintf(str, "%s", filename); + f = fopen(str, "rb"); + if (!f) { + fprintf(stderr, "Failed to open %s for reading !\n", str); + return 0; + } + if (fscanf(f, "PG %s %c %d %d %d", endian, &sign, &prec, &w, &h) == 5) { + fgetc(f); + if (!strcmp(endian, "ML")) + bigendian = 1; + else + bigendian = 0; + if (compno == 0) { + img->x0 = Dim[0]; + img->y0 = Dim[1]; + img->x1 = + !Dim[0] ? (w - 1) * subsampling_dx + 1 : Dim[0] + (w - + 1) * + subsampling_dx + 1; + img->y1 = + !Dim[1] ? (h - 1) * subsampling_dy + 1 : Dim[1] + (h - + 1) * + subsampling_dy + 1; + } else { + if (w != img->x1 || h != img->y1) + return 0; + } + + if (sign == '-') { + comp->sgnd = 1; + } else { + comp->sgnd = 0; + } + comp->prec = prec; + comp->dx = subsampling_dx; + comp->dy = subsampling_dy; + bandno = 1; + + Y1 = cp.ty0 + bandno * cp.tdy < + img->y1 ? cp.ty0 + bandno * cp.tdy : img->y1; + Y1 -= img->y0; + + sprintf(tmp, "bandtile%d", bandno); /* bandtile file */ + src = fopen(tmp, "wb"); + if (!src) { + fprintf(stderr, "failed to open %s for writing !\n", tmp); + } + for (i = 0; i < w * h; i++) { + int v; + if (i == Y1 * w / subsampling_dy && tdy != -1) { /* bandtile is full */ + fclose(src); + bandno++; + sprintf(tmp, "bandtile%d", bandno); + src = fopen(tmp, "wb"); + if (!src) { + fprintf(stderr, "failed to open %s for writing !\n", tmp); + } + Y1 = cp.ty0 + bandno * cp.tdy < + img->y1 ? cp.ty0 + bandno * cp.tdy : img->y1; + Y1 -= img->y0; + } + if (comp->prec <= 8) { + if (!comp->sgnd) { + v = readuchar(f); + } else { + v = (char) readuchar(f); + } + } else if (comp->prec <= 16) { + if (!comp->sgnd) { + v = readushort(f, bigendian); + } else { + v = (short) readushort(f, bigendian); + } + } else { + if (!comp->sgnd) { + v = readuint(f, bigendian); + } else { + v = (int) readuint(f, bigendian); + } + } + if (v > max) + max = v; + fprintf(src, "%d ", v); + } + } else { + return 0; + } + fclose(f); + fclose(src); + comp->bpp = int_floorlog2(max) + 1; + } + return 1; +} + +/* -->> -->> -->> -->> + + PNM IMAGE FORMAT + + <<-- <<-- <<-- <<-- */ + +int pnmtoimage(char *filename, j2k_image_t * img, int subsampling_dx, + int subsampling_dy, int Dim[2]) +{ + FILE *f; + FILE *Compo0, *Compo1, *Compo2; + int w, h; + int i; + char value; + char comment[256]; + + f = fopen(filename, "rb"); + if (!f) { + fprintf(stderr, + "\033[0;33mFailed to open %s for reading !!\033[0;39m\n", + filename); + return 0; + } + + if (fgetc(f) != 'P') + return 0; + value = fgetc(f); + + if (value == '2') { + fgetc(f); + if (fgetc(f) == '#') { + fseek(f, 0, SEEK_SET); + fscanf(f, "P2\n"); + fgets(comment, 256, f); + fscanf(f, "%d %d\n255", &w, &h); + } else { + fseek(f, 0, SEEK_SET); + fscanf(f, "P2\n%d %d\n255", &w, &h); + } + + fgetc(f); + img->x0 = Dim[0]; + img->y0 = Dim[1]; + img->x1 = + !Dim[0] ? (w - 1) * subsampling_dx + 1 : Dim[0] + (w - + 1) * + subsampling_dx + 1; + img->y1 = + !Dim[1] ? (h - 1) * subsampling_dy + 1 : Dim[1] + (h - + 1) * + subsampling_dy + 1; + + img->numcomps = 1; + img->color_space = 2; + img->comps = (j2k_comp_t *) malloc(sizeof(j2k_comp_t)); + img->comps[0].prec = 8; + img->comps[0].bpp = 8; + img->comps[0].sgnd = 0; + img->comps[0].dx = subsampling_dx; + img->comps[0].dy = subsampling_dy; + + Compo0 = fopen("Compo0", "wb"); + if (!Compo0) { + fprintf(stderr, + "\033[0;33mFailed to open Compo0 for writing !\033[0;39m\n"); + } + for (i = 0; i < w * h; i++) { + unsigned int l; + fscanf(f, "%d", &l); + fprintf(Compo0, "%c", l); + } + fclose(Compo0); + } else if (value == '5') { + fgetc(f); + if (fgetc(f) == '#') { + fseek(f, 0, SEEK_SET); + fscanf(f, "P5\n"); + fgets(comment, 256, f); + fscanf(f, "%d %d\n255", &w, &h); + } else { + fseek(f, 0, SEEK_SET); + fscanf(f, "P5\n%d %d\n255", &w, &h); + } + + fgetc(f); + img->x0 = Dim[0]; + img->y0 = Dim[1]; + img->x1 = + !Dim[0] ? (w - 1) * subsampling_dx + 1 : Dim[0] + (w - + 1) * + subsampling_dx + 1; + img->y1 = + !Dim[1] ? (h - 1) * subsampling_dy + 1 : Dim[1] + (h - + 1) * + subsampling_dy + 1; + + img->numcomps = 1; + img->color_space = 2; + img->comps = (j2k_comp_t *) malloc(sizeof(j2k_comp_t)); + img->comps[0].prec = 8; + img->comps[0].bpp = 8; + img->comps[0].sgnd = 0; + img->comps[0].dx = subsampling_dx; + img->comps[0].dy = subsampling_dy; + Compo0 = fopen("Compo0", "wb"); + if (!Compo0) { + fprintf(stderr, + "\033[0;33mFailed to open Compo0 for writing !\033[0;39m\n"); + } + for (i = 0; i < w * h; i++) { + unsigned char l; + fread(&l, 1, 1, f); + fwrite(&l, 1, 1, Compo0); + } + fclose(Compo0); + } else if (value == '3') { + fgetc(f); + if (fgetc(f) == '#') { + fseek(f, 0, SEEK_SET); + fscanf(f, "P3\n"); + fgets(comment, 256, f); + fscanf(f, "%d %d\n255", &w, &h); + } else { + fseek(f, 0, SEEK_SET); + fscanf(f, "P3\n%d %d\n255", &w, &h); + } + + fgetc(f); + img->x0 = Dim[0]; + img->y0 = Dim[1]; + img->x1 = + !Dim[0] ? (w - 1) * subsampling_dx + 1 : Dim[0] + (w - + 1) * + subsampling_dx + 1; + img->y1 = + !Dim[1] ? (h - 1) * subsampling_dy + 1 : Dim[1] + (h - + 1) * + subsampling_dy + 1; + img->numcomps = 3; + img->color_space = 1; + img->comps = (j2k_comp_t *) malloc(img->numcomps * sizeof(j2k_comp_t)); + for (i = 0; i < img->numcomps; i++) { + img->comps[i].prec = 8; + img->comps[i].bpp = 8; + img->comps[i].sgnd = 0; + img->comps[i].dx = subsampling_dx; + img->comps[i].dy = subsampling_dy; + } + Compo0 = fopen("Compo0", "wb"); + if (!Compo0) { + fprintf(stderr, + "\033[0;33mFailed to open Compo0 for writing !\033[0;39m\n"); + } + + Compo1 = fopen("Compo1", "wb"); + if (!Compo1) { + fprintf(stderr, + "\033[0;33mFailed to open Compo1 for writing !\033[0;39m\n"); + } + + Compo2 = fopen("Compo2", "wb"); + if (!Compo2) { + fprintf(stderr, + "\033[0;33mFailed to open Compo2 for writing !\033[0;39m\n"); + } + + for (i = 0; i < w * h; i++) { + unsigned int r, g, b; + fscanf(f, "%d", &r); + fscanf(f, "%d", &g); + fscanf(f, "%d", &b); + fprintf(Compo0, "%c", r); + fprintf(Compo1, "%c", g); + fprintf(Compo2, "%c", b); + } + fclose(Compo0); + fclose(Compo1); + fclose(Compo2); + } else if (value == '6') { + fgetc(f); + if (fgetc(f) == '#') { + fseek(f, 0, SEEK_SET); + fscanf(f, "P6\n"); + fgets(comment, 256, f); + fscanf(f, "%d %d\n255", &w, &h); + } else { + fseek(f, 0, SEEK_SET); + fscanf(f, "P6\n%d %d\n255", &w, &h); + } + + fgetc(f); + img->x0 = Dim[0]; + img->y0 = Dim[1]; + img->x1 = + !Dim[0] ? (w - 1) * subsampling_dx + 1 : Dim[0] + (w - + 1) * + subsampling_dx + 1; + img->y1 = + !Dim[1] ? (h - 1) * subsampling_dy + 1 : Dim[1] + (h - + 1) * + subsampling_dy + 1; + img->numcomps = 3; + img->color_space = 1; + img->comps = (j2k_comp_t *) malloc(img->numcomps * sizeof(j2k_comp_t)); + for (i = 0; i < img->numcomps; i++) { + img->comps[i].prec = 8; + img->comps[i].bpp = 8; + img->comps[i].sgnd = 0; + img->comps[i].dx = subsampling_dx; + img->comps[i].dy = subsampling_dy; + } + Compo0 = fopen("Compo0", "wb"); + if (!Compo0) { + fprintf(stderr, + "\033[0;33mFailed to open Compo0 for writing !\033[0;39m\n"); + } + + Compo1 = fopen("Compo1", "wb"); + if (!Compo1) { + fprintf(stderr, + "\033[0;33mFailed to open Compo1 for writing !\033[0;39m\n"); + } + + Compo2 = fopen("Compo2", "wb"); + if (!Compo2) { + fprintf(stderr, + "\033[0;33mFailed to open Compo2 for writing !\033[0;39m\n"); + } + + for (i = 0; i < w * h; i++) { + unsigned char r, g, b; + fread(&r, 1, 1, f); + fread(&g, 1, 1, f); + fread(&b, 1, 1, f); + fwrite(&r, 1, 1, Compo0); + fwrite(&g, 1, 1, Compo1); + fwrite(&b, 1, 1, Compo2); + } + fclose(Compo0); + fclose(Compo1); + fclose(Compo2); + } else { + return 0; + } + fclose(f); + return 1; +} diff --git a/jpwl/decoder/jpwldec/convert.h b/jpwl/decoder/jpwldec/convert.h new file mode 100644 index 00000000..337dae76 --- /dev/null +++ b/jpwl/decoder/jpwldec/convert.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2001-2003, 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 "j2k.h" + +int bmptoimage(char *filename, j2k_image_t * img, int subsampling_dx, + int subsampling_dy, int Dim[2]); + +int pgxtoimage(char *filename, j2k_image_t * img, int tdy, + int subsampling_dx, int subsampling_dy, int Dim[2], + j2k_cp_t cp); + +int pnmtoimage(char *filename, j2k_image_t * img, int subsampling_dx, + int subsampling_dy, int Dim[2]); diff --git a/jpwl/decoder/jpwldec/image_to_j2k.c b/jpwl/decoder/jpwldec/image_to_j2k.c new file mode 100644 index 00000000..94d5ac1d --- /dev/null +++ b/jpwl/decoder/jpwldec/image_to_j2k.c @@ -0,0 +1,887 @@ +/* + * Copyright (c) 2001-2003, 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 +#ifndef DONT_HAVE_GETOPT +#include +#else +#include "compat/getopt.h" +#endif +#include "convert.h" + +void help_display() +{ + printf("HELP\n----\n\n"); + printf("- the option -help displays the readme.txt file on screen\n\n"); + + + printf("List of parameters for the coder JPEG 2000 :\n"); + printf("\n"); + printf + ("- The markers COD and QCD are writed both of two in the main_header and never appear in the tile_header. The markers in the main header are : SOC SIZ COD QCD COM.\n"); + printf("\n"); + printf + ("- This coder can encode mega image, a test was made on a 24000x24000 pixels color image. You need enough disk space memory (twice the original) to encode the image. (i.e. for a 1.5 Gb image you need a minimum of 3Gb of disk memory)\n"); + printf("\n"); + printf("REMARKS :\n"); + printf("---------\n"); + printf("\n"); + printf + ("* the value of rate enter in the code line is the compression factor !\n"); + printf("exemple :\n"); + printf("\n"); + printf + ("-r 20,10,1 means quality 1 : compress 20x, quality 2 : compress 10x and quality 3 : compress 1x = lossless\n"); + printf("\n"); + printf("By default :\n"); + printf("------------\n"); + printf("\n"); + printf(" * lossless\n"); + printf(" * 1 tile\n"); + printf(" * size of precinct 2^15 x 2^15 (means 1 precinct)\n"); + printf(" * size of code-block 64 x 64\n"); + printf(" * Number of resolution : 6\n"); + printf(" * No SOP marker in the codestream\n"); + printf(" * No EPH marker in the codestream\n"); + printf(" * No sub-sampling in x and y direction\n"); + printf(" * No mode switch activated\n"); + printf(" * progression order : LRCP\n"); + printf(" * No index file\n"); + printf(" * No ROI upshifted\n"); + printf(" * No offset of the origin of the image\n"); + printf(" * No offset of the origin of the tiles\n"); + printf(" * Reversible DWT 5-3\n"); + printf("\n"); + printf("Parameters :\n"); + printf("------------\n"); + printf("\n"); + printf + ("-i : source file (-i source.pnm also *.pgm, *.ppm) required\n"); + printf("\n"); + printf("-o : destination file (-o dest.j2k or .jp2) required\n"); + printf("\n"); + printf("-help : Display the help information optional\n "); + printf("\n"); + printf("-r : different rates (-r 20,10,5) optional\n "); + printf("\n"); + printf("-n : Number of resolution (-n 3) optional\n"); + printf("\n"); + printf("-b : size of code block (-b 32,32) optional\n"); + printf("\n"); + printf("-c : size of precinct (-c 128,128) optional\n"); + printf("\n"); + printf("-t : size of tile (-t 512,512) optional\n"); + printf("\n"); + printf + ("-p : progression order (-p LRCP) [LRCP, RLCP, RPCL, PCRL, CPRL] optional\n"); + printf("\n"); + printf + ("-s : subsampling factor (-s 2,2) [-s X,Y] optional\n"); + printf("\n"); + printf + ("-SOP : write SOP marker before each packet optional\n"); + printf("\n"); + printf + ("-EPH : write EPH marker after each header packet optional\n"); + printf("\n"); + printf + ("-M : mode switch (-M 3) [1=BYPASS(LAZY) 2=RESET 4=RESTART(TERMALL) 8=VSC 16=ERTERM(SEGTERM) 32=SEGMARK(SEGSYM)] optional\n"); + printf + (" for several mode switch you have to add the value of each mode you want\n"); + printf + (" ex : RESTART(4) + RESET(2) + SEGMARK(32) = -M 38\n"); + printf("\n"); + printf + ("-x : Create an index file *.Idx (-x index_name.Idx) optional\n"); + printf("\n"); + printf + ("-ROI:c=%%d,U=%%d : quantization indices upshifted for component c=%%d [%%d = 0,1,2]\n"); + printf + (" with a value of U=%%d [0 <= %%d <= 37] (i.e. -ROI:c=0,U=25) optional\n"); + printf("\n"); + printf + ("-d : offset of the origin of the image (-d 150,300) optional\n"); + printf("\n"); + printf + ("-T : offset of the origin of the tiles (-T 100,75) optional\n"); + printf("\n"); + printf("-I : Use the irreversible DWT 9-7 (-I) optional\n"); + printf("\n"); + printf("IMPORTANT :\n"); + printf("-----------\n"); + printf("\n"); + printf("* subsampling bigger than 2 can produce error\n"); + printf("\n"); + printf("The index file respect the structure below :\n"); + printf("---------------------------------------------\n"); + printf("\n"); + printf("Image_height Image_width\n"); + printf("progression order\n"); + printf("Tiles_size_X Tiles_size_Y\n"); + printf("Components_nb\n"); + printf("Layers_nb\n"); + printf("decomposition_levels\n"); + printf("Precincts_size_X Precincts_size_Y\n"); + printf("Main_header_end_position\n"); + printf("Codestream_size\n"); + printf("Tile0 start_pos end_Theader end_pos\n"); + printf("Tile1 '' '' ''\n"); + printf("...\n"); + printf("TileN '' '' ''\n"); + printf("Tpacket_0 Tile layer res. comp. prec. start_pos end_pos\n"); + printf("...\n"); + printf("Tpacket_M '' '' '' '' '' '' ''\n"); +} + +int give_progression(char progression[4]) +{ + if (progression[0] == 'L' && progression[1] == 'R' + && progression[2] == 'C' && progression[3] == 'P') { + return 0; + } else { + if (progression[0] == 'R' && progression[1] == 'L' + && progression[2] == 'C' && progression[3] == 'P') { + return 1; + } else { + if (progression[0] == 'R' && progression[1] == 'P' + && progression[2] == 'C' && progression[3] == 'L') { + return 2; + } else { + if (progression[0] == 'P' && progression[1] == 'C' + && progression[2] == 'R' && progression[3] == 'L') { + return 3; + } else { + if (progression[0] == 'C' && progression[1] == 'P' + && progression[2] == 'R' && progression[3] == 'L') { + return 4; + } else { + return -1; + } + } + } + } + } +} + +double dwt_norms_97[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} +}; + +int floorlog2(int a) +{ + int l; + for (l = 0; a > 1; l++) { + a >>= 1; + } + return l; +} + +void encode_stepsize(int stepsize, int numbps, int *expn, int *mant) +{ + int p, n; + p = floorlog2(stepsize) - 13; + n = 11 - floorlog2(stepsize); + *mant = (n < 0 ? stepsize >> -n : stepsize << n) & 0x7ff; + *expn = numbps - p; +} + +void calc_explicit_stepsizes(j2k_tccp_t * tccp, int prec) +{ + int numbands, bandno; + numbands = 3 * tccp->numresolutions - 2; + for (bandno = 0; bandno < numbands; bandno++) { + double stepsize; + + int resno, level, orient, gain; + resno = bandno == 0 ? 0 : (bandno - 1) / 3 + 1; + orient = bandno == 0 ? 0 : (bandno - 1) % 3 + 1; + level = tccp->numresolutions - 1 - resno; + gain = + tccp->qmfbid == 0 ? 0 : (orient == + 0 ? 0 : (orient == 1 + || orient == 2 ? 1 : 2)); + if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) { + stepsize = 1.0; + } else { + double norm = dwt_norms_97[orient][level]; + stepsize = (1 << (gain + 1)) / norm; + } + encode_stepsize((int) floor(stepsize * 8192.0), prec + gain, + &tccp->stepsizes[bandno].expn, + &tccp->stepsizes[bandno].mant); + } +} + +int main(int argc, char **argv) +{ + int len; + int NumResolution, numD_min; /* NumResolution : number of resolution */ + int Tile_arg; /* Tile_arg = 0 (not in argument) ou = 1 (in argument) */ + int CSty; /* CSty : coding style */ + int Prog_order; /* progression order (default LRCP) */ + char progression[4]; + int numpocs, numpocs_tile; /* Number of progression order change (POC) default 0 */ + int prcw_init[J2K_MAXRLVLS]; /* Initialisation Precinct width */ + int prch_init[J2K_MAXRLVLS]; /* Initialisation Precinct height */ + //int prcw_init, prch_init; /* Initialisation precincts' size */ + int cblockw_init, cblockh_init; /* Initialisation codeblocks' size */ + int mode, value; /* Mode switch (cblk_style) */ + int subsampling_dx, subsampling_dy; /* subsampling value for dx and dy */ + int ROI_compno, ROI_shift; /* region of interrest */ + int Dim[2]; /* portion of the image coded */ + int TX0, TY0; /* tile off-set */ + j2k_image_t img; + j2k_cp_t cp, cp_init; /* cp_init is used to initialise in multiple tiles */ + j2k_tcp_t *tcp, *tcp_init; /* tcp_init is used to initialise in multiple tile */ + j2k_poc_t POC[32]; /* POC : used in case of Progression order change */ + j2k_poc_t *tcp_poc; + j2k_tccp_t *tccp; + int i, tileno, j; + char *infile = 0; + char *outfile = 0; + char *index = 0; + char *s, S1, S2, S3; + int ir = 0; + int res_spec = 0; /* For various precinct sizes specification */ + char sep; + char *outbuf; + FILE *f; + + + /* default value */ + /* ------------- */ + NumResolution = 6; + CSty = 0; + cblockw_init = 64; + cblockh_init = 64; + cp.tw = 1; + cp.th = 1; + cp.index_on = 0; + Prog_order = 0; + numpocs = 0; + mode = 0; + subsampling_dx = 1; + subsampling_dy = 1; + ROI_compno = -1; /* no ROI */ + ROI_shift = 0; + Dim[0] = 0; + Dim[1] = 0; + TX0 = 0; + TY0 = 0; + cp.comment = "Created by OpenJPEG version 0.9"; + cp.disto_alloc = 0; + cp.fixed_alloc = 0; + cp.fixed_quality = 0; //add fixed_quality + /* img.PPT=0; */ + + Tile_arg = 0; + cp_init.tcps = (j2k_tcp_t *) malloc(sizeof(j2k_tcp_t)); /* initialisation if only one tile */ + tcp_init = &cp_init.tcps[0]; + tcp_init->numlayers = 0; + + cp.intermed_file=1; + + while (1) { + int c = getopt(argc, argv, + "i:o:r:q:f:t:n:c:b:x:p:s:d:h:P:S:E:M:R:T:C:I"); + if (c == -1) + break; + switch (c) { + case 'i': /* IN fill */ + infile = optarg; + s = optarg; + while (*s) { + s++; + } + s--; + S3 = *s; + s--; + S2 = *s; + s--; + S1 = *s; + + if ((S1 == 'p' && S2 == 'g' && S3 == 'x') + || (S1 == 'P' && S2 == 'G' && S3 == 'X')) { + cp.image_type = 0; + break; + } + + if ((S1 == 'p' && S2 == 'n' && S3 == 'm') + || (S1 == 'P' && S2 == 'N' && S3 == 'M') + || (S1 == 'p' && S2 == 'g' && S3 == 'm') || (S1 == 'P' + && S2 == 'G' + && S3 == 'M') + || (S1 == 'P' && S2 == 'P' && S3 == 'M') || (S1 == 'p' + && S2 == 'p' + && S3 == 'm')) { + cp.image_type = 1; + break; + } + + if ((S1 == 'b' && S2 == 'm' && S3 == 'p') + || (S1 == 'B' && S2 == 'M' && S3 == 'P')) { + cp.image_type = 2; + break; + } + fprintf(stderr, + "!! Unrecognized format for infile : %c%c%c [accept only *.pnm, *.pgm, *.ppm, *.pgx or *.bmp] !!\n\n", + S1, S2, S3); + return 1; + break; + /* ----------------------------------------------------- */ + case 'o': /* OUT fill */ + outfile = optarg; + while (*outfile) { + outfile++; + } + outfile--; + S3 = *outfile; + outfile--; + S2 = *outfile; + outfile--; + S1 = *outfile; + + outfile = optarg; + + if ((S1 == 'j' && S2 == '2' && S3 == 'k') || (S1 == 'J' && S2 == '2' && S3 == 'K')) + cp.JPEG2000_format=0; + else if ((S1 == 'j' && S2 == 'p' && S3 == '2') || (S1 == 'J' && S2 == 'P' && S3 == '2')) + cp.JPEG2000_format=1; + else { + fprintf(stderr,"Unknown output format image *.%c%c%c [only *.j2k, *.jp2]!! \n",S1,S2,S3); + return 1; + } + + + + break; + /* ----------------------------------------------------- */ + case 'r': /* rates rates/distorsion */ + s = optarg; + while (sscanf(s, "%d", &tcp_init->rates[tcp_init->numlayers]) + == 1) { + tcp_init->numlayers++; + while (*s && *s != ',') { + s++; + } + if (!*s) + break; + s++; + } + cp.disto_alloc = 1; + cp.matrice = NULL; + break; + /* ----------------------------------------------------- */ + case 'q': /* add fixed_quality */ + s = optarg; + while (sscanf(s, "%f", &tcp_init->distoratio[tcp_init->numlayers]) == + 1) { + tcp_init->numlayers++; + while (*s && *s != ',') { + s++; + } + if (!*s) + break; + s++; + } + cp.fixed_quality = 1; + cp.matrice = NULL; + break; + /* dda */ + /* ----------------------------------------------------- */ + case 'f': /* mod fixed_quality (before : -q) */ + s = optarg; + sscanf(s, "%d", &tcp_init->numlayers); + s++; + if (tcp_init->numlayers > 9) + s++; + cp.matrice = + (int *) malloc(tcp_init->numlayers * NumResolution * 3 * + sizeof(int)); + s = s + 2; + for (i = 0; i < tcp_init->numlayers; i++) { + tcp_init->rates[i] = 1; + sscanf(s, "%d,", &cp.matrice[i * NumResolution * 3]); + s += 2; + if (cp.matrice[i * NumResolution * 3] > 9) + s++; + cp.matrice[i * NumResolution * 3 + 1] = 0; + cp.matrice[i * NumResolution * 3 + 2] = 0; + for (j = 1; j < NumResolution; j++) { + sscanf(s, "%d,%d,%d", + &cp.matrice[i * NumResolution * 3 + j * 3 + 0], + &cp.matrice[i * NumResolution * 3 + j * 3 + 1], + &cp.matrice[i * NumResolution * 3 + j * 3 + 2]); + s += 6; + if (cp.matrice[i * NumResolution * 3 + j * 3] > 9) + s++; + if (cp.matrice[i * NumResolution * 3 + j * 3 + 1] > 9) + s++; + if (cp.matrice[i * NumResolution * 3 + j * 3 + 2] > 9) + s++; + } + if (i < tcp_init->numlayers - 1) + s++; + } + cp.fixed_alloc = 1; + break; + /* ----------------------------------------------------- */ + case 't': /* tiles */ + sscanf(optarg, "%d,%d", &cp.tdx, &cp.tdy); + Tile_arg = 1; + break; + /* ----------------------------------------------------- */ + case 'n': /* resolution */ + sscanf(optarg, "%d", &NumResolution); + break; + /* ----------------------------------------------------- */ + case 'c': /* precinct dimension */ + s = optarg; + do { + sep = 0; + sscanf(s, "[%d,%d]%c", &prcw_init[res_spec], + &prch_init[res_spec], &sep); + CSty |= 0x01; + res_spec++; + s = strpbrk(s, "]") + 2; + } while (sep == ','); + break; + /* ----------------------------------------------------- */ + case 'b': /* code-block dimension */ + sscanf(optarg, "%d,%d", &cblockw_init, &cblockh_init); + if (cblockw_init * cblockh_init > 4096 || cblockw_init > 1024 + || cblockw_init < 4 || cblockh_init > 1024 || cblockh_init < 4) { + fprintf(stderr, + "!! Size of code_block error (option -b) !!\n\nRestriction :\n * width*height<=4096\n * 4<=width,height<= 1024\n\n"); + return 1; + } + break; + /* ----------------------------------------------------- */ + case 'x': /* creation of index file */ + index = optarg; + cp.index_on = 1; + break; + /* ----------------------------------------------------- */ + case 'p': /* progression order */ + s = optarg; + for (i = 0; i < 4; i++) { + progression[i] = *s; + s++; + } + Prog_order = give_progression(progression); + + if (Prog_order == -1) { + fprintf(stderr, + "Unrecognized progression order [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n"); + return 1; + } + break; + /* ----------------------------------------------------- */ + case 's': /* subsampling factor */ + if (sscanf(optarg, "%d,%d", &subsampling_dx, &subsampling_dy) + != 2) { + fprintf(stderr, + "'-s' sub-sampling argument error ! [-s dx,dy]\n"); + return 1; + } + break; + /* ----------------------------------------------------- */ + case 'd': /* coordonnate of the reference grid */ + if (sscanf(optarg, "%d,%d", &Dim[0], &Dim[1]) != 2) { + fprintf(stderr, + "-d 'coordonnate of the reference grid' argument error !! [-d x0,y0]\n"); + return 1; + } + break; + /* ----------------------------------------------------- */ + case 'h': /* Display an help description */ + help_display(); + return 0; + break; + /* ----------------------------------------------------- */ + case 'P': /* POC */ + fprintf(stderr, "/----------------------------------\\\n"); + fprintf(stderr, "| POC option not fully tested !! |\n"); + fprintf(stderr, "\\----------------------------------/\n"); + + s = optarg; + while (sscanf(s, "T%d=%d,%d,%d,%d,%d,%s", &POC[numpocs].tile, + &POC[numpocs].resno0, &POC[numpocs].compno0, + &POC[numpocs].layno1, &POC[numpocs].resno1, + &POC[numpocs].compno1, POC[numpocs].progorder) == 7) { + POC[numpocs].prg = give_progression(POC[numpocs].progorder); + /* POC[numpocs].tile; */ + numpocs++; + while (*s && *s != '/') { + s++; + } + if (!*s) + break; + s++; + } + break; + /* ------------------------------------------------------ */ + case 'S': /* SOP marker */ + CSty |= 0x02; + break; + /* ------------------------------------------------------ */ + case 'E': /* EPH marker */ + CSty |= 0x04; + break; + /* ------------------------------------------------------ */ + case 'M': /* Mode switch pas tous au point !! */ + if (sscanf(optarg, "%d", &value) == 1) { + for (i = 0; i <= 5; i++) { + int cache = value & (1 << i); + if (cache) + mode |= (1 << i); + } + } + break; + /* ------------------------------------------------------ */ + case 'R': /* ROI */ + if (sscanf(optarg, "OI:c=%d,U=%d", &ROI_compno, &ROI_shift) != 2) { + fprintf(stderr, "ROI error !! [-ROI:c='compno',U='shift']\n"); + return 1; + } + break; + /* ------------------------------------------------------ */ + case 'T': /* Tile offset */ + if (sscanf(optarg, "%d,%d", &TX0, &TY0) != 2) { + fprintf(stderr, "-T 'tile offset' argument error !! [-T X0,Y0]"); + return 1; + } + break; + /* ------------------------------------------------------ */ + case 'C': /* Add a comment */ + cp.comment = optarg; + break; + /* ------------------------------------------------------ */ + case 'I': /* reversible or not */ + ir = 1; + break; + /* ------------------------------------------------------ */ + default: + return 1; + } + } + + cp.tx0 = TX0; + cp.ty0 = TY0; + + /* Error messages */ + /* -------------- */ + if (!infile || !outfile) { + fprintf(stderr, + "usage: image_to_j2k -i image-file -o j2k/jp2-file (+ options)\n"); + return 1; + } + + if ((cp.disto_alloc || cp.fixed_alloc || cp.fixed_quality)&&(!(cp.disto_alloc ^ cp.fixed_alloc ^ cp.fixed_quality))) { + fprintf(stderr, + "Error: options -r -q and -f can not be used together !!\n"); + return 1; + } // mod fixed_quality + + /* if no rate entered, lossless by default */ + if (tcp_init->numlayers == 0) { + tcp_init->rates[tcp_init->numlayers] = 1; + tcp_init->numlayers++; + cp.disto_alloc = 1; + } + + if (TX0 > Dim[0] || TY0 > Dim[1]) { + fprintf(stderr, + "Error: Tile offset dimension is unnappropriate --> TX0(%d)<=IMG_X0(%d) TYO(%d)<=IMG_Y0(%d) \n", + TX0, Dim[0], TY0, Dim[1]); + return 1; + } + + for (i = 0; i < numpocs; i++) { + if (POC[i].prg == -1) { + fprintf(stderr, + "Unrecognized progression order in option -P (POC n %d) [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n", + i + 1); + } + } + + switch (cp.image_type) { + case 0: + if (Tile_arg) { + if (!pgxtoimage + (infile, &img, cp.tdy, subsampling_dx, subsampling_dy, Dim, + cp)) { + fprintf(stderr, "not a pgx file\n"); + return 1; + } + } else { + if (!pgxtoimage + (infile, &img, -1, subsampling_dx, subsampling_dy, Dim, cp)) { + fprintf(stderr, " not a pgx file\n"); + return 1; + } + } + break; + + case 1: + if (!pnmtoimage(infile, &img, subsampling_dx, subsampling_dy, Dim)) { + fprintf(stderr, " not a pnm file\n"); + return 1; + } + break; + + case 2: + if (!bmptoimage(infile, &img, subsampling_dx, subsampling_dy, Dim)) { + fprintf(stderr, " not a bmp file\n"); + return 1; + } + break; + } + /* to respect profile - 0 */ + /* ---------------------- */ + numD_min = 0; + /* while (int_ceildiv(img.x1,(1<120 || int_ceildiv(img.y1,(1<160) numD_min++; + if ((numD_min+1)>NumResolution) + { + fprintf(stderr,"\n********************************************************************************\n\n"); + fprintf(stderr, "In view to respect Profile-0, the number of resolution used is %d in place of %d\n\n",numD_min+1,NumResolution); + fprintf(stderr, "********************************************************************************\n\n"); + NumResolution=numD_min+1; + } */ + + if (Tile_arg == 1) { + cp.tw = int_ceildiv(img.x1 - cp.tx0, cp.tdx); + cp.th = int_ceildiv(img.y1 - cp.ty0, cp.tdy); + } else { + cp.tdx = img.x1 - cp.tx0; + cp.tdy = img.y1 - cp.ty0; + } + + /* Initialization for PPM marker */ + cp.ppm = 0; + cp.ppm_data = NULL; + cp.ppm_previous = 0; + cp.ppm_store = 0; + + /* Init the mutiple tiles */ + /* ---------------------- */ + cp.tcps = (j2k_tcp_t *) malloc(cp.tw * cp.th * sizeof(j2k_tcp_t)); + + for (tileno = 0; tileno < cp.tw * cp.th; tileno++) { + tcp = &cp.tcps[tileno]; + tcp->numlayers = tcp_init->numlayers; + for (j = 0; j < tcp->numlayers; j++) { + if (cp.fixed_quality) // add fixed_quality + tcp->distoratio[j] = tcp_init->distoratio[j]; + else + tcp->rates[j] = tcp_init->rates[j]; + } + tcp->csty = CSty; + tcp->prg = Prog_order; + tcp->mct = img.numcomps == 3 ? 1 : 0; + tcp->ppt = 0; + tcp->ppt_data = NULL; + tcp->ppt_store = 0; + + numpocs_tile = 0; + tcp->POC = 0; + if (numpocs) { + /* intialisation of POC */ + tcp->POC = 1; + for (i = 0; i < numpocs; i++) { + if (tileno == POC[i].tile - 1 || POC[i].tile == -1) { + tcp_poc = &tcp->pocs[numpocs_tile]; + tcp_poc->resno0 = POC[numpocs_tile].resno0; + tcp_poc->compno0 = POC[numpocs_tile].compno0; + tcp_poc->layno1 = POC[numpocs_tile].layno1; + tcp_poc->resno1 = POC[numpocs_tile].resno1; + tcp_poc->compno1 = POC[numpocs_tile].compno1; + tcp_poc->prg = POC[numpocs_tile].prg; + tcp_poc->tile = POC[numpocs_tile].tile; + numpocs_tile++; + } + } + } + tcp->numpocs = numpocs_tile; + tcp->tccps = (j2k_tccp_t *) malloc(img.numcomps * sizeof(j2k_tccp_t)); + + for (i = 0; i < img.numcomps; i++) { + tccp = &tcp->tccps[i]; + tccp->csty = CSty & 0x01; /* 0 => one precinct || 1 => custom precinct */ + tccp->numresolutions = NumResolution; + tccp->cblkw = int_floorlog2(cblockw_init); + tccp->cblkh = int_floorlog2(cblockh_init); + tccp->cblksty = mode; + tccp->qmfbid = ir ? 0 : 1; + tccp->qntsty = ir ? J2K_CCP_QNTSTY_SEQNT : J2K_CCP_QNTSTY_NOQNT; + tccp->numgbits = 2; + if (i == ROI_compno) + tccp->roishift = ROI_shift; + else + tccp->roishift = 0; + if (CSty & J2K_CCP_CSTY_PRT) { + int p = 0; + for (j = tccp->numresolutions - 1; j >= 0; j--) { + if (p < res_spec) { + if (prcw_init[p] < 1) + tccp->prcw[j] = 1; + else + tccp->prcw[j] = int_floorlog2(prcw_init[p]); + + if (prch_init[p] < 1) + tccp->prch[j] = 1; + else + tccp->prch[j] = int_floorlog2(prch_init[p]); + } else { + int size_prcw, size_prch; + size_prcw = prcw_init[res_spec - 1] >> (p - (res_spec - 1)); + size_prch = prch_init[res_spec - 1] >> (p - (res_spec - 1)); + if (size_prcw < 1) + tccp->prcw[j] = 1; + else + tccp->prcw[j] = int_floorlog2(size_prcw); + if (size_prch < 1) + tccp->prch[j] = 1; + else + tccp->prch[j] = int_floorlog2(size_prch); + } + p++; + /*printf("\nsize precinct pour level %d : %d,%d\n", j, + tccp->prcw[j], tccp->prch[j]);*/ + } + } else { + for (j = 0; j < tccp->numresolutions; j++) { + tccp->prcw[j] = 15; + tccp->prch[j] = 15; + } + } + calc_explicit_stepsizes(tccp, img.comps[i].prec); + } + } + + if (cp.JPEG2000_format==0) { /* J2K format output */ + if (cp.intermed_file==1) { /* After the encoding of each tile, j2k_encode + stores the data in the file*/ + len = j2k_encode(&img, &cp, outfile, cp.tdx * cp.tdy * 2, index); + if (len == 0) { + fprintf(stderr, "failed to encode image\n"); + return 1; + } + } + else { + outbuf = (char *) malloc( cp.tdx * cp.tdy * cp.tw * cp.th * 2); /* Allocate memory for all tiles */ + cio_init(outbuf, cp.tdx * cp.tdy * cp.tw * cp.th * 2); + len = j2k_encode(&img, &cp, outbuf, cp.tdx * cp.tdy * cp.tw * cp.th * 2, index); + if (len == 0) { + fprintf(stderr, "failed to encode image\n"); + return 1; + } + f = fopen(outfile, "wb"); + if (!f) { + fprintf(stderr, "failed to open %s for writing\n", outfile); + return 1; + } + fwrite(outbuf, 1, len, f); + free(outbuf); + fclose(f); + } + } + else /* JP2 format output */ + { + jp2_struct_t * jp2_struct; + jp2_struct = (jp2_struct_t *) malloc(sizeof(jp2_struct_t)); + jp2_struct->image = &img; + + /* Initialising the standard JP2 box content*/ + /* If you wish to modify those boxes, you have to modify the jp2_struct content*/ + if (jp2_init_stdjp2(jp2_struct, &img)) + { + fprintf(stderr,"Error with jp2 initialization"); + return 1; + }; + + if (cp.intermed_file==1) { + /*For the moment, JP2 format does not use intermediary files for each tile*/ + cp.intermed_file=0; + } + outbuf = (char *) malloc( cp.tdx * cp.tdy * cp.tw * cp.th * 2); + cio_init(outbuf, cp.tdx * cp.tdy * cp.tw * cp.th * 2); + len = jp2_encode(jp2_struct, &cp, outbuf, index); + if (len == 0) { + fprintf(stderr, "failed to encode image\n"); + return 1; + } + f = fopen(outfile, "wb"); + if (!f) { + fprintf(stderr, "failed to open %s for writing\n", outfile); + return 1; + } + fwrite(outbuf, 1, len, f); + free(outbuf); + fclose(f); + } + + /* Remove the temporary files */ + /* -------------------------- */ + if (cp.image_type) { /* PNM PGM PPM */ + for (i = 0; i < img.numcomps; i++) { + char tmp; + sprintf(&tmp, "Compo%d", i); + if (remove(&tmp) == -1) { + fprintf(stderr, "failed to kill %s file !\n", &tmp); + } + } + } else { /* PGX */ + for (i = 0; i < cp.th; i++) { + char tmp; + sprintf(&tmp, "bandtile%d", i + 1); + + if (remove(&tmp) == -1) { + fprintf(stderr, "failed to kill %s file !\n", &tmp); + } + } + } + + /* Free memory */ + free(img.comps); + free(cp_init.tcps); + if (tcp_init->numlayers > 9) free(cp.matrice); + for (tileno = 0; tileno < cp.tw * cp.th; tileno++) + free(cp.tcps[tileno].tccps); + free(cp.tcps); + + system("pause"); + return 0; +} diff --git a/jpwl/decoder/jpwldec/image_to_j2k.dsp b/jpwl/decoder/jpwldec/image_to_j2k.dsp new file mode 100644 index 00000000..07e5a0a2 --- /dev/null +++ b/jpwl/decoder/jpwldec/image_to_j2k.dsp @@ -0,0 +1,249 @@ +# Microsoft Developer Studio Project File - Name="image_to_j2k" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=image_to_j2k - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "image_to_j2k.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "image_to_j2k.mak" CFG="image_to_j2k - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "image_to_j2k - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "image_to_j2k - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "image_to_j2k - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../libopenjpeg" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "DONT_HAVE_GETOPT" /YX /FD /c +# ADD BASE RSC /l 0x80c /d "NDEBUG" +# ADD RSC /l 0x80c /i "../libopenjpeg" /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "image_to_j2k - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../libopenjpeg" /D "_DEBUG" /D "DONT_HAVE_GETOPT" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c +# ADD BASE RSC /l 0x80c /d "_DEBUG" +# ADD RSC /l 0x80c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "image_to_j2k - Win32 Release" +# Name "image_to_j2k - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\libopenjpeg\bio.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\cio.c +# End Source File +# Begin Source File + +SOURCE=.\convert.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\dwt.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\fix.c +# End Source File +# Begin Source File + +SOURCE=.\compat\getopt.c +# End Source File +# Begin Source File + +SOURCE=.\image_to_j2k.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\int.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\j2k.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\jp2.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\jpt.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\mct.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\mqc.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\pi.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\raw.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\t1.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\t2.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\tcd.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\tgt.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\libopenjpeg\bio.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\cio.h +# End Source File +# Begin Source File + +SOURCE=.\convert.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\dwt.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\fix.h +# End Source File +# Begin Source File + +SOURCE=.\compat\getopt.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\int.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\j2k.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\jp2.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\jpt.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\mct.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\mqc.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\openjpeg.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\pi.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\raw.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\t1.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\t2.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\tcd.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\tgt.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/jpwl/decoder/jpwldec/image_to_j2k.ncb b/jpwl/decoder/jpwldec/image_to_j2k.ncb new file mode 100644 index 00000000..9057ebac --- /dev/null +++ b/jpwl/decoder/jpwldec/image_to_j2k.ncb @@ -0,0 +1 @@ +Microsoft C/C++ MSF 7.00 diff --git a/jpwl/decoder/jpwldec/image_to_j2k.vcproj b/jpwl/decoder/jpwldec/image_to_j2k.vcproj new file mode 100644 index 00000000..7c5dc50a --- /dev/null +++ b/jpwl/decoder/jpwldec/image_to_j2k.vcproj @@ -0,0 +1,254 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jpwl/decoder/jpwldec/j2k_to_image.c b/jpwl/decoder/jpwldec/j2k_to_image.c new file mode 100644 index 00000000..0c61f1cf --- /dev/null +++ b/jpwl/decoder/jpwldec/j2k_to_image.c @@ -0,0 +1,561 @@ +/* Copyright (c) 2001 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 + +extern int cslen; // Aggiunta in JPWL (per gestire l'inserimento di RED nella CS!) + +int ceildiv(int a, int b) +{ + return (a + b - 1) / b; +} + +int main(int argc, char **argv) +{ + FILE *f; + char *src, *src_name; + char *dest, S1, S2, S3; + int len; + + j2k_image_t img; + + j2k_cp_t cp; + int w, wr, wrr, h, hr, hrr, max; + int i, image_type = -1, compno, pad, j; + int adjust; + jp2_struct_t *jp2_struct; + + if (argc < 3) { + fprintf(stderr, + "usage: %s j2k-file image-file [-reduce n]\n", argv[0]); + return 1; + } + + f = fopen(argv[1], "rb"); + if (!f) { + fprintf(stderr, "failed to open %s for reading\n", argv[1]); + return 1; + } + + dest = argv[2]; + + cp.reduce_on = 0; + cp.reduce_value = 0; + + /* OPTION REDUCE IS ACTIVE */ + if (argc == 5) { + if (strcmp(argv[3], "-reduce")) { + fprintf(stderr, + "usage: options " "-reduce n" + " where n is the factor of reduction [%s]\n", argv[3]); + return 1; + } + cp.reduce_on = 1; + sscanf(argv[4], "%d", &cp.reduce_value); + } + + while (*dest) { + dest++; + } + dest--; + S3 = *dest; + dest--; + S2 = *dest; + dest--; + S1 = *dest; + + if ((S1 == 'p' && S2 == 'g' && S3 == 'x') + || (S1 == 'P' && S2 == 'G' && S3 == 'X')) { + image_type = 0; + + dest--; + + *dest = '\0'; + } + + if ((S1 == 'p' && S2 == 'n' && S3 == 'm') + || (S1 == 'P' && S2 == 'N' && S3 == 'M') || (S1 == 'p' && S2 == 'g' + && S3 == 'm') + || (S1 == 'P' && S2 == 'G' && S3 == 'M') || (S1 == 'P' && S2 == 'P' + && S3 == 'M') + || (S1 == 'p' && S2 == 'p' && S3 == 'm')) { + image_type = 1; + } + + if ((S1 == 'b' && S2 == 'm' && S3 == 'p') + || (S1 == 'B' && S2 == 'M' && S3 == 'P')) { + image_type = 2; + } + + if (image_type == -1) { + fprintf(stderr, + "!! Unrecognized format for infile : %c%c%c [accept only *.pnm, *.pgm, *.ppm, *.pgx or *.bmp] !!\n\n", + S1, S2, S3); + return 1; + } + + fseek(f, 0, SEEK_END); + len = ftell(f); + fseek(f, 0, SEEK_SET); + src = (char *) malloc(len); + fread(src, 1, len, f); + fclose(f); + + src_name = argv[1]; + while (*src_name) { + src_name++; + } + src_name--; + S3 = *src_name; + src_name--; + S2 = *src_name; + src_name--; + S1 = *src_name; + + /* J2K format */ + if ((S1 == 'j' && S2 == '2' && S3 == 'k') + || (S1 == 'J' && S2 == '2' && S3 == 'K') || (S1 == 'j' && S2 == '2' + && S3 == 'c') + || (S1 == 'J' && S2 == '2' && S3 == 'C')) { + if (!j2k_decode(src, len, &img, &cp)) { + fprintf(stderr, "j2k_to_image: failed to decode image!\n"); + return 1; + } + } + + /* JP2 format */ + else if ((S1 == 'j' && S2 == 'p' && S3 == '2') + || (S1 == 'J' && S2 == 'P' && S3 == '2')) { + jp2_struct = (jp2_struct_t *) malloc(sizeof(jp2_struct_t)); + + jp2_struct->image = &img; + + if (jp2_decode(src, len, jp2_struct, &cp)) { + fprintf(stderr, "j2k_to_image: failed to decode image!\n"); + return 1; + } + /* Insert code here if you want to create actions on jp2_struct before deleting it */ + free(jp2_struct); + } + + /* JPT format */ + else if ((S1 == 'j' && S2 == 'p' && S3 == 't') + || (S1 == 'J' && S2 == 'P' && S3 == 'T')) { + if (!j2k_decode_jpt_stream(src, len, &img, &cp)) { + fprintf(stderr, "j2k_to_image: failed to decode image!\n"); + return 1; + } + } + + /* otherwise : error */ + else { + fprintf(stderr, + "j2k_to_image : Unknown format image *.%c%c%c [only *.j2k, *.jp2, *.jpc or *.jpt]!! \n", + S1, S2, S3); + return 1; + } + + src = realloc(src, cslen); // Aggiunta in JPWL per evitare errori di free a causa + // della modifica di CS in caso di aggiunta RED! + free(src); + /* ------------------ CREATE OUT IMAGE WITH THE RIGHT FORMAT ----------------------- */ + + /* ---------------------------- / */ + /* / / */ + /* / FORMAT : PNM, PGM or PPM / */ + /* / / */ + /* ---------------------------- / */ + + switch (image_type) { + case 1: /* PNM PGM PPM */ + if (img.numcomps == 3 && img.comps[0].dx == img.comps[1].dx + && img.comps[1].dx == img.comps[2].dx + && img.comps[0].dy == img.comps[1].dy + && img.comps[1].dy == img.comps[2].dy + && img.comps[0].prec == img.comps[1].prec + && img.comps[1].prec == img.comps[2].prec) { + f = fopen(argv[2], "wb"); + w = ceildiv(img.x1 - img.x0, img.comps[0].dx); + // wr = ceildiv(int_ceildivpow2(img.x1 - img.x0,img.factor),img.comps[0].dx); + wr = img.comps[0].w; + wrr = int_ceildivpow2(img.comps[0].w, img.comps[0].factor); + + h = ceildiv(img.y1 - img.y0, img.comps[0].dy); + // hr = ceildiv(int_ceildivpow2(img.y1 - img.y0,img.factor), img.comps[0].dy); + hr = img.comps[0].h; + hrr = int_ceildivpow2(img.comps[0].h, img.comps[0].factor); + + max = img.comps[0].prec > 8 ? 255 : (1 << img.comps[0].prec) - 1; + + img.comps[0].x0 = + int_ceildivpow2(img.comps[0].x0 - + int_ceildiv(img.x0, img.comps[0].dx), + img.comps[0].factor); + img.comps[0].y0 = + int_ceildivpow2(img.comps[0].y0 - + int_ceildiv(img.y0, img.comps[0].dy), + img.comps[0].factor); + + + fprintf(f, "P6\n# %d %d %d %d %d\n%d %d\n%d\n", + cp.tcps[cp.tileno[0]].tccps[0].numresolutions, w, h, + img.comps[0].x0, img.comps[0].y0, wrr, hrr, max); + adjust = img.comps[0].prec > 8 ? img.comps[0].prec - 8 : 0; + for (i = 0; i < wrr * hrr; i++) { + char r, g, b; + r = img.comps[0].data[i / wrr * wr + i % wrr]; + r += (img.comps[0].sgnd ? 1 << (img.comps[0].prec - 1) : 0); + r = r >> adjust; + + g = img.comps[1].data[i / wrr * wr + i % wrr]; + g += (img.comps[1].sgnd ? 1 << (img.comps[1].prec - 1) : 0); + g = g >> adjust; + + b = img.comps[2].data[i / wrr * wr + i % wrr]; + b += (img.comps[2].sgnd ? 1 << (img.comps[2].prec - 1) : 0); + b = b >> adjust; + + fprintf(f, "%c%c%c", r, g, b); + } + free(img.comps[0].data); + free(img.comps[1].data); + free(img.comps[2].data); + fclose(f); + } else { + for (compno = 0; compno < img.numcomps; compno++) { + char name[256]; + if (img.numcomps > 1) { + sprintf(name, "%d.%s", compno, argv[2]); + } else { + sprintf(name, "%s", argv[2]); + } + f = fopen(name, "wb"); + w = ceildiv(img.x1 - img.x0, img.comps[compno].dx); + // wr = ceildiv(int_ceildivpow2(img.x1 - img.x0,img.factor),img.comps[compno].dx); + wr = img.comps[compno].w; + wrr = + int_ceildivpow2(img.comps[compno].w, img.comps[compno].factor); + + h = ceildiv(img.y1 - img.y0, img.comps[compno].dy); + // hr = ceildiv(int_ceildivpow2(img.y1 - img.y0,img.factor), img.comps[compno].dy); + hr = img.comps[compno].h; + hrr = + int_ceildivpow2(img.comps[compno].h, img.comps[compno].factor); + + max = + img.comps[compno].prec > + 8 ? 255 : (1 << img.comps[compno].prec) - 1; + + img.comps[compno].x0 = + int_ceildivpow2(img.comps[compno].x0 - + int_ceildiv(img.x0, + img.comps[compno].dx), + img.comps[compno].factor); + img.comps[compno].y0 = + int_ceildivpow2(img.comps[compno].y0 - + int_ceildiv(img.y0, + img.comps[compno].dy), + img.comps[compno].factor); + + fprintf(f, "P5\n# %d %d %d %d %d\n%d %d\n%d\n", + cp.tcps[cp.tileno[0]].tccps[compno]. + numresolutions, w, h, img.comps[compno].x0, + img.comps[compno].y0, wrr, hrr, max); + adjust = + img.comps[compno].prec > 8 ? img.comps[compno].prec - 8 : 0; + for (i = 0; i < wrr * hrr; i++) { + char l; + l = img.comps[compno].data[i / wrr * wr + i % wrr]; + l += (img.comps[compno]. + sgnd ? 1 << (img.comps[compno].prec - 1) : 0); + l = l >> adjust; + fprintf(f, "%c", l); + } + fclose(f); + free(img.comps[compno].data); + } + } + break; + + /* ------------------------ / */ + /* / / */ + /* / FORMAT : PGX / */ + /* / / */ + /* /----------------------- / */ + case 0: /* PGX */ + for (compno = 0; compno < img.numcomps; compno++) { + j2k_comp_t *comp = &img.comps[compno]; + char name[256]; + + int nbytes = 0; + //if (img.numcomps > 1) + sprintf(name, "%s-%d.pgx", argv[2], compno); + + //else + + //sprintf(name, "%s.pgx", argv[2]); + + f = fopen(name, "wb"); + // w = ceildiv(img.x1 - img.x0, comp->dx); + // wr = ceildiv(int_ceildivpow2(img.x1 - img.x0,img.factor), comp->dx); + w = img.comps[compno].w; + wr = int_ceildivpow2(img.comps[compno].w, img.comps[compno].factor); + + // h = ceildiv(img.y1 - img.y0, comp->dy); + // hr = ceildiv(int_ceildivpow2(img.y1 - img.y0,img.factor), comp->dy); + h = img.comps[compno].h; + hr = int_ceildivpow2(img.comps[compno].h, img.comps[compno].factor); + + fprintf(f, "PG ML %c %d %d %d\n", comp->sgnd ? '-' : '+', + comp->prec, wr, hr); + + if (comp->prec <= 8) + nbytes = 1; + + else if (comp->prec <= 16) + nbytes = 2; + + else + nbytes = 4; + for (i = 0; i < wr * hr; i++) { + int v = img.comps[compno].data[i / wr * w + i % wr]; + + for (j = nbytes - 1; j >= 0; j--) { + + char byte = (char) (v >> (j * 8)); + + fwrite(&byte, 1, 1, f); + + } + } + free(img.comps[compno].data); + fclose(f); + } + break; + + /* ------------------------ / */ + /* / / */ + /* / FORMAT : BMP / */ + /* / / */ + /* /----------------------- / */ + + case 2: /* BMP */ + if (img.numcomps == 3 && img.comps[0].dx == img.comps[1].dx + && img.comps[1].dx == img.comps[2].dx + && img.comps[0].dy == img.comps[1].dy + && img.comps[1].dy == img.comps[2].dy + && img.comps[0].prec == img.comps[1].prec + && img.comps[1].prec == img.comps[2].prec) { + /* -->> -->> -->> -->> + + 24 bits color + + <<-- <<-- <<-- <<-- */ + + f = fopen(argv[2], "wb"); + // w = ceildiv(img.x1 - img.x0, img.comps[0].dx); + // wr = ceildiv(int_ceildivpow2(img.x1 - img.x0,img.factor), img.comps[0].dx); + w = img.comps[0].w; + wr = int_ceildivpow2(img.comps[0].w, img.comps[0].factor); + + // h = ceildiv(img.y1 - img.y0, img.comps[0].dy); + // hr = ceildiv(int_ceildivpow2(img.y1 - img.y0,img.factor), img.comps[0].dy); + h = img.comps[0].h; + hr = int_ceildivpow2(img.comps[0].h, img.comps[0].factor); + + fprintf(f, "BM"); + + /* FILE HEADER */ + /* ------------- */ + fprintf(f, "%c%c%c%c", + (unsigned char) (hr * wr * 3 + 3 * hr * (wr % 2) + + 54) & 0xff, + (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54) + >> 8) & 0xff, + (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54) + >> 16) & 0xff, + (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54) + >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, + ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (54) & 0xff, ((54) >> 8) & 0xff, + ((54) >> 16) & 0xff, ((54) >> 24) & 0xff); + + /* INFO HEADER */ + /* ------------- */ + fprintf(f, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff, + ((40) >> 16) & 0xff, ((40) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (unsigned char) ((wr) & 0xff), + (unsigned char) ((wr) >> 8) & 0xff, + (unsigned char) ((wr) >> 16) & 0xff, + (unsigned char) ((wr) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (unsigned char) ((hr) & 0xff), + (unsigned char) ((hr) >> 8) & 0xff, + (unsigned char) ((hr) >> 16) & 0xff, + (unsigned char) ((hr) >> 24) & 0xff); + fprintf(f, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff); + fprintf(f, "%c%c", (24) & 0xff, ((24) >> 8) & 0xff); + fprintf(f, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, + ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", + (unsigned char) (3 * hr * wr + + 3 * hr * (wr % 2)) & 0xff, + (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >> + 8) & 0xff, + (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >> + 16) & 0xff, + (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >> + 24) & 0xff); + fprintf(f, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, + ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, + ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, + ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, + ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); + + for (i = 0; i < wr * hr; i++) { + unsigned char R, G, B; + /* a modifier */ + // R = img.comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; + R = img.comps[0].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)]; + // G = img.comps[1].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; + G = img.comps[1].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)]; + // B = img.comps[2].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; + B = img.comps[2].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)]; + fprintf(f, "%c%c%c", B, G, R); + + if ((i + 1) % wr == 0) { + for (pad = (3 * wr) % 4 ? 4 - (3 * wr) % 4 : 0; pad > 0; pad--) /* ADD */ + fprintf(f, "%c", 0); + } + } + fclose(f); + free(img.comps[1].data); + free(img.comps[2].data); + } else { /* Gray-scale */ + + /* -->> -->> -->> -->> + + 8 bits non code (Gray scale) + + <<-- <<-- <<-- <<-- */ + f = fopen(argv[2], "wb"); + // w = ceildiv(img.x1 - img.x0, img.comps[0].dx); + // wr = ceildiv(int_ceildivpow2(img.x1 - img.x0,img.factor), img.comps[0].dx); + w = img.comps[0].w; + wr = int_ceildivpow2(img.comps[0].w, img.comps[0].factor); + + // h = ceildiv(img.y1 - img.y0, img.comps[0].dy); + // hr = ceildiv(int_ceildivpow2(img.y1 - img.y0,img.factor), img.comps[0].dy); + h = img.comps[0].h; + hr = int_ceildivpow2(img.comps[0].h, img.comps[0].factor); + + fprintf(f, "BM"); + + /* FILE HEADER */ + /* ------------- */ + fprintf(f, "%c%c%c%c", + (unsigned char) (hr * wr + 54 + 1024 + + hr * (wr % 2)) & 0xff, + (unsigned char) ((hr * wr + 54 + 1024 + hr * (wr % 2)) + >> 8) & 0xff, + (unsigned char) ((hr * wr + 54 + 1024 + hr * (wr % 2)) + >> 16) & 0xff, + (unsigned char) ((hr * wr + 54 + 1024 + wr * (wr % 2)) + >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, + ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (54 + 1024) & 0xff, + ((54 + 1024) >> 8) & 0xff, ((54 + 1024) >> 16) & 0xff, + ((54 + 1024) >> 24) & 0xff); + + /* INFO HEADER */ + /* ------------- */ + fprintf(f, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff, + ((40) >> 16) & 0xff, ((40) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (unsigned char) ((wr) & 0xff), + (unsigned char) ((wr) >> 8) & 0xff, + (unsigned char) ((wr) >> 16) & 0xff, + (unsigned char) ((wr) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (unsigned char) ((hr) & 0xff), + (unsigned char) ((hr) >> 8) & 0xff, + (unsigned char) ((hr) >> 16) & 0xff, + (unsigned char) ((hr) >> 24) & 0xff); + fprintf(f, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff); + fprintf(f, "%c%c", (8) & 0xff, ((8) >> 8) & 0xff); + fprintf(f, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, + ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", + (unsigned char) (hr * wr + hr * (wr % 2)) & 0xff, + (unsigned char) ((hr * wr + hr * (wr % 2)) >> 8) & + 0xff, + (unsigned char) ((hr * wr + hr * (wr % 2)) >> 16) & + 0xff, + (unsigned char) ((hr * wr + hr * (wr % 2)) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, + ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, + ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, + ((256) >> 16) & 0xff, ((256) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, + ((256) >> 16) & 0xff, ((256) >> 24) & 0xff); + } + + for (i = 0; i < 256; i++) { + fprintf(f, "%c%c%c%c", i, i, i, 0); + } + + for (i = 0; i < wr * hr; i++) { + /* a modifier !! */ + // fprintf(f, "%c", img.comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]); + fprintf(f, "%c", + img.comps[0].data[w * hr - ((i) / (wr) + 1) * w + + (i) % (wr)]); + /*if (((i + 1) % w == 0 && w % 2)) + fprintf(f, "%c", 0); */ + if ((i + 1) % wr == 0) { + for (pad = wr % 4 ? 4 - wr % 4 : 0; pad > 0; pad--) /* ADD */ + fprintf(f, "%c", 0); + } + } + fclose(f); + free(img.comps[0].data); + break; + default: + break; + } + + return 0; +} diff --git a/jpwl/decoder/jpwldec/j2k_to_image.dsp b/jpwl/decoder/jpwldec/j2k_to_image.dsp new file mode 100644 index 00000000..6a633191 --- /dev/null +++ b/jpwl/decoder/jpwldec/j2k_to_image.dsp @@ -0,0 +1,240 @@ +# Microsoft Developer Studio Project File - Name="j2k_to_image" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=j2k_to_image - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "j2k_to_image.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "j2k_to_image.mak" CFG="j2k_to_image - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "j2k_to_image - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "j2k_to_image - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "j2k_to_image - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../libopenjpeg" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "DONT_HAVE_GETOPT" /YX /FD /c +# ADD BASE RSC /l 0x80c /d "NDEBUG" +# ADD RSC /l 0x80c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "j2k_to_image - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "j2k_to_image___Win32_Debug" +# PROP BASE Intermediate_Dir "j2k_to_image___Win32_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "j2k_to_image___Win32_Debug" +# PROP Intermediate_Dir "j2k_to_image___Win32_Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../libopenjpeg" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "DONT_HAVE_GETOPT" /YX /FD /GZ /c +# ADD BASE RSC /l 0x80c /d "_DEBUG" +# ADD RSC /l 0x80c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "j2k_to_image - Win32 Release" +# Name "j2k_to_image - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\libopenjpeg\bio.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\cio.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\dwt.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\fix.c +# End Source File +# Begin Source File + +SOURCE=.\compat\getopt.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\int.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\j2k.c +# End Source File +# Begin Source File + +SOURCE=.\j2k_to_image.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\jp2.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\jpt.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\mct.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\mqc.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\pi.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\raw.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\t1.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\t2.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\tcd.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\tgt.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\libopenjpeg\bio.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\cio.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\dwt.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\fix.h +# End Source File +# Begin Source File + +SOURCE=.\compat\getopt.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\int.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\j2k.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\jp2.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\jpt.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\mct.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\mqc.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\openjpeg.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\pi.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\raw.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\t1.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\t2.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\tcd.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\tgt.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/jpwl/decoder/jpwldec/j2k_to_image.ncb b/jpwl/decoder/jpwldec/j2k_to_image.ncb new file mode 100644 index 00000000..9057ebac --- /dev/null +++ b/jpwl/decoder/jpwldec/j2k_to_image.ncb @@ -0,0 +1 @@ +Microsoft C/C++ MSF 7.00 diff --git a/jpwl/decoder/jpwldec/j2k_to_image.sln b/jpwl/decoder/jpwldec/j2k_to_image.sln new file mode 100644 index 00000000..6720e2c3 --- /dev/null +++ b/jpwl/decoder/jpwldec/j2k_to_image.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "j2k_to_image", "j2k_to_image.vcproj", "{3C09E691-8555-47D1-B1E6-D411A6314AC8}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {3C09E691-8555-47D1-B1E6-D411A6314AC8}.Debug.ActiveCfg = Debug|Win32 + {3C09E691-8555-47D1-B1E6-D411A6314AC8}.Debug.Build.0 = Debug|Win32 + {3C09E691-8555-47D1-B1E6-D411A6314AC8}.Release.ActiveCfg = Release|Win32 + {3C09E691-8555-47D1-B1E6-D411A6314AC8}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/jpwl/decoder/jpwldec/j2k_to_image.suo b/jpwl/decoder/jpwldec/j2k_to_image.suo new file mode 100644 index 00000000..3599f1b0 --- /dev/null +++ b/jpwl/decoder/jpwldec/j2k_to_image.suo @@ -0,0 +1 @@ +ÐÏࡱ \ No newline at end of file diff --git a/jpwl/decoder/jpwldec/j2k_to_image.vcproj b/jpwl/decoder/jpwldec/j2k_to_image.vcproj new file mode 100644 index 00000000..63c967ff --- /dev/null +++ b/jpwl/decoder/jpwldec/j2k_to_image.vcproj @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jpwl/decoder/jpwldec/readme.txt b/jpwl/decoder/jpwldec/readme.txt new file mode 100644 index 00000000..972fac4e --- /dev/null +++ b/jpwl/decoder/jpwldec/readme.txt @@ -0,0 +1,105 @@ +List of parameters for the coder JPEG 2000 : + +Date : June the 25th, 2003 +Author : Yannick Verschueren +Contact : verschueren@tele.ucl.ac.be + +- the option -help displays the readme.txt file on screen + +- The markers COD and QCD are writed both of two in the main_header and never appear in the tile_header. The markers in the main header are : SOC SIZ COD QCD COM. + +- This coder can encode mega image, a test was made on a 24000x24000 pixels color image. You need enough disk space memory (twice the original) to encode the image. (i.e. for a 1.5 Gb image you need a minimum of 3Gb of disk memory) + +REMARKS : +--------- + +* the value of rate enter in the code line is the compression factor ! +exemple : + +-r 20,10,1 means quality 1 : compress 20x, quality 2 : compress 10x and quality 3 : compress 1x = lossless + +* The number of resolution can be modified by the program in view to respect profile-0 conditions (Taubman, Marcelin (2002), "JPEG2000, image compression fundamentals, standards and practice", p700) + +By default : +------------ + + * lossless + * 1 tile + * size of precinct 2^15 x 2^15 (means 1 precinct) + * size of code-block 64 x 64 + * Number of resolution : 6 + * No SOP marker in the codestream + * No EPH marker in the codestream + * No sub-sampling in x and y direction + * No mode switch activated + * progression order : LRCP + * No index file + * No ROI upshifted + * No offset of the origin of the image + * No offset of the origin of the tiles + * Reversible DWT 5-3 + +Parameters : +------------ + +-i : source file (-i source.pnm also *.pgm, *.ppm) "required" + +-o : destination file (-o dest.j2k) "required" + +-r : different rates (-r 20,10,5) "optional" + +-n : Number of resolution (-n 3) "optional" + +-b : size of code block (-b 32,32) "optional" + +-c : size of precinct (-c 128,128) "optional" + +-t : size of tile (-t 512,512) "optional" + +-p : progression order (-p LRCP) [LRCP, RLCP, RPCL, PCRL, CPRL] "optional" + +-s : subsampling factor (-s 2,2) [-s X,Y] "optional" + +-SOP : write SOP marker before each packet "optional" + +-EPH : write EPH marker after each header packet "optional" + +-M : mode switch (-M 3) [1= BYPASS(LAZY) 2=RESET 4=RESTART(TERMALL) 8=VSC 16=ERTERM(SEGTERM) 32=SEGMARK(SEGSYM)] "optional" + for several mode switch you have to add the value of each mode you want + ex : RESTART(4) + RESET(2) + SEGMARK(32) = -M 38 + +-x : Create an index file *.Idx (-x index_name.Idx) "optional" + +-ROI:c=%d,U=%d : quantization indices upshifted for component c=%d [%d = 0,1,2] + with a value of U=%d [0 <= %d <= 37] (i.e. -ROI:c=0,U=25) "optional" + +-d : offset of the origin of the image (-d 150,300) "optional" + +-T : offset of the origin of the tiles (-T 100,75) "optional" + +-I : Use the irreversible DWT 9-7 (-I) "optional" + +IMPORTANT : +----------- + +* subsampling bigger than 2 can produce error + +The index file respect the structure below : +--------------------------------------------- + +Image_height Image_width +progression order +Tiles_size_X Tiles_size_Y +Components_nb +Layers_nb +decomposition_levels +Precincts_size_X Precincts_size_Y +Main_header_end_position +Codestream_size +Tile0 start_pos end_Theader end_pos +Tile1 " " " +... +TileN " " " +Tpacket_0 Tile layer res. comp. prec. start_pos end_pos +... +Tpacket_M " " " " " " " diff --git a/jpwl/decoder/libopenjpeg/.cvsignore b/jpwl/decoder/libopenjpeg/.cvsignore new file mode 100644 index 00000000..5aca9ad5 --- /dev/null +++ b/jpwl/decoder/libopenjpeg/.cvsignore @@ -0,0 +1,6 @@ +obj +obj.w32 +bin +bin.w32 +lib +lib.w32 diff --git a/jpwl/decoder/libopenjpeg/Makefile b/jpwl/decoder/libopenjpeg/Makefile new file mode 100644 index 00000000..d5f2727b --- /dev/null +++ b/jpwl/decoder/libopenjpeg/Makefile @@ -0,0 +1,78 @@ +# $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: $(OBJ_DIR) $(LIB_DIR) \ + $(LIB_DIR)/libopenjpeg.a $(LIB_DIR)/libopenjpeg.dll +else + CC = gcc + AR = ar + OBJ_DIR = obj + LIB_DIR = lib + all: $(OBJ_DIR) $(LIB_DIR) \ + $(LIB_DIR)/libopenjpeg.a $(LIB_DIR)/libopenjpeg.so +endif + +$(OBJ_DIR): + mkdir $(OBJ_DIR) + +$(LIB_DIR): + mkdir $(LIB_DIR) + +$(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 +$(OBJ_DIR)/jpt.o: jpt.c jpt.h cio.h +$(OBJ_DIR)/jp2.o: jp2.c jp2.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 jpt.o jp2.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/jpwl/decoder/libopenjpeg/bio.c b/jpwl/decoder/libopenjpeg/bio.c new file mode 100644 index 00000000..ed846fae --- /dev/null +++ b/jpwl/decoder/libopenjpeg/bio.c @@ -0,0 +1,194 @@ +/* + * 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; /* pointer to the start of the buffer */ +static unsigned char *bio_end; /* pointer to the end of the buffer */ +static unsigned char *bio_bp; /* pointer to the present position in the buffer */ +static unsigned int bio_buf; /* temporary place where each byte is read or written */ +static int bio_ct; /* coder : number of bits free to write // decoder : number of bits read */ + +extern jmp_buf j2k_error; + +/* + * Number of bytes written. + */ +int bio_numbytes() +{ + return bio_bp - bio_start; +} + +/* + * Init encoder. + * + * bp : Output buffer + * len : 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. + * + * bp : Input buffer + * len : 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. + * + * b : 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. + * + * v : Value of bits + * n : 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. + * + * n : 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; +} + +/* + * Passes the ending bits (coming from flushing) + */ +int bio_inalign() +{ + bio_ct = 0; + if ((bio_buf & 0xff) == 0xff) { + if (bio_bytein()) + return 1; + bio_ct = 0; + } + return 0; +} diff --git a/jpwl/decoder/libopenjpeg/bio.h b/jpwl/decoder/libopenjpeg/bio.h new file mode 100644 index 00000000..58995b05 --- /dev/null +++ b/jpwl/decoder/libopenjpeg/bio.h @@ -0,0 +1,75 @@ +/* + * 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 + +/* + * Number of bytes written. + */ +int bio_numbytes(); + +/* + * Init encoder. + * + * bp : Output buffer + * len : Output buffer length + */ +void bio_init_enc(unsigned char *bp, int len); + +/* + * Init decoder. + * + * bp : Input buffer + * len : Input buffer length + */ +void bio_init_dec(unsigned char *bp, int len); + +/* + * Write bits. + * + * v : Value of bits + * n : Number of bits to write + */ +void bio_write(int v, int n); + +/* + * Read bits. + * + * n : Number of bits to read + */ +int bio_read(int n); + +/* + * Flush bits. Modified to eliminate longjmp !! + */ +int bio_flush(); + +int bio_inalign(); /* modified to eliminated longjmp !! */ + +#endif diff --git a/jpwl/decoder/libopenjpeg/cio.c b/jpwl/decoder/libopenjpeg/cio.c new file mode 100644 index 00000000..7aecffca --- /dev/null +++ b/jpwl/decoder/libopenjpeg/cio.c @@ -0,0 +1,152 @@ +/* + * 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; /* pointer to the start of the stream */ +static unsigned char *cio_end; /* pointer to the end of the stream */ +static unsigned char *cio_bp; /* pointer to the present position */ + +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. + * + * pos : position, in number of bytes, from the beginning of the 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 + * + * bp : destination/source stream + * len : length of the stream + */ +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 some bytes. + * + * v : value to write + * n : number of bytes to write + */ +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. + * + * n : number of bytes to read + * + * return : value of the n bytes read + */ +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; +} + +/* + * Skip some bytes. + * + * n : number of bytes to skip + */ +void cio_skip(int n) +{ + cio_bp += n; +} diff --git a/jpwl/decoder/libopenjpeg/cio.h b/jpwl/decoder/libopenjpeg/cio.h new file mode 100644 index 00000000..c75a4653 --- /dev/null +++ b/jpwl/decoder/libopenjpeg/cio.h @@ -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. + */ + +#ifndef __CIO_H +#define __CIO_H + +/* + * Number of bytes written. + * + * returns number of bytes written + */ +int cio_numbytes(); + +/* + * Get position in byte stream. + * + * return position in bytes + */ +int cio_tell(); + +/* + * Set position in byte stream. + * + * pos : position, in number of bytes, from the beginning of the stream + */ +void cio_seek(int pos); + +/* + * Number of bytes left before the end of the stream. + * + * Returns the number of bytes before the end of the stream + */ +int cio_numbytesleft(); + +/* + * Get pointer to the current position in the stream. + * + * return : pointer to the position + */ +unsigned char *cio_getbp(); + +/* + * Initialize byte IO + * + * bp : destination/source stream + * len : length of the stream + */ +void cio_init(unsigned char *bp, int len); + +/* + * Write some bytes. + * + * v : value to write + * n : number of bytes to write + */ +void cio_write(unsigned int v, int n); + +/* + * Read some bytes. + * + * n : number of bytes to read + * + * return : value of the n bytes read + */ +unsigned int cio_read(int n); + +/* + * Skip some bytes. + * + * n : number of bytes to skip + */ +void cio_skip(int n); + +#endif diff --git a/jpwl/decoder/libopenjpeg/dwt.c b/jpwl/decoder/libopenjpeg/dwt.c new file mode 100644 index 00000000..92d006ad --- /dev/null +++ b/jpwl/decoder/libopenjpeg/dwt.c @@ -0,0 +1,454 @@ +/* + * Copyright (c) 2001-2002, David Janssens + * Copyright (c) 2002-2004, Yannick Verschueren + * Copyright (c) 2002-2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "dwt.h" +#include "int.h" +#include "fix.h" +#include "tcd.h" +#include +#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; + +/* */ +/* Cleaning memory. */ +/* */ + +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]; +} + +/* */ +/* 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]; +} + +/* */ +/* 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; + 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; + int rw; /* width of the resolution level computed */ + int rh; /* heigth of the resolution level computed */ + int rw1; /* width of the resolution level once lower than computed one */ + int rh1; /* height of the resolution level once lower than computed one */ + + for (i = 0; i < l; i++) { + int cas_col = 0; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ + int cas_row = 0; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ + 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; + + cas_row = tilec->resolutions[l - i].x0 % 2; + cas_col = tilec->resolutions[l - i].y0 % 2; + + 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, + int stop) +{ + int i, j; + int rw; /* width of the resolution level computed */ + int rh; /* heigth of the resolution level computed */ + int rw1; /* width of the resolution level once lower than computed one */ + int rh1; /* height of the resolution level once lower than computed one */ + + for (i = l - 1; i >= stop; i--) { + int cas_col = 0; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ + int cas_row = 0; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ + + 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; + + cas_row = tilec->resolutions[l - i].x0 % 2; + cas_col = tilec->resolutions[l - i].y0 % 2; + + 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); /*5038 */ + for (i = 0; i < sn; i++) + D(i) = fix_mul(D(i), 6659); /*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); /*5038 */ + for (i = 0; i < sn; i++) + S(i) = fix_mul(S(i), 6659); /*6660 */ + } + } + dwt_deinterleave(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(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), 10078); /* 10076 */ + for (i = 0; i < dn; i++) + S(i) = fix_mul(S(i), 13318); /* 13320 */ + for (i = 0; i < sn; i++) + D(i) -= fix_mul(SS_(i) + SS_(i + 1), 3633); + for (i = 0; i < dn; i++) + S(i) -= fix_mul(DD_(i) + DD_(i - 1), 7233); + for (i = 0; i < sn; i++) + D(i) += fix_mul(SS_(i) + SS_(i + 1), 434); + for (i = 0; i < dn; i++) + S(i) += fix_mul(DD_(i) + DD_(i - 1), 12993); + } + } else { + if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */ + for (i = 0; i < sn; i++) + S(i) = fix_mul(S(i), 10078); /* 10076 */ + for (i = 0; i < dn; i++) + D(i) = fix_mul(D(i), 13318); /* 13320 */ + for (i = 0; i < sn; i++) + S(i) -= fix_mul(D_(i - 1) + D_(i), 3633); + for (i = 0; i < dn; i++) + D(i) -= fix_mul(S_(i) + S_(i + 1), 7233); + for (i = 0; i < sn; i++) + S(i) += fix_mul(D_(i - 1) + D_(i), 434); + for (i = 0; i < dn; i++) + D(i) += fix_mul(S_(i) + S_(i + 1), 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; + int rw; /* width of the resolution level computed */ + int rh; /* heigth of the resolution level computed */ + int rw1; /* width of the resolution level once lower than computed one */ + int rh1; /* height of the resolution level once lower than computed one */ + + for (i = 0; i < l; i++) { + int cas_col = 0; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ + int cas_row = 0; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ + 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; + + cas_row = tilec->resolutions[l - i].x0 % 2; + cas_col = tilec->resolutions[l - i].y0 % 2; + + 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, + int stop) +{ + int i, j; + int rw; /* width of the resolution level computed */ + int rh; /* heigth of the resolution level computed */ + int rw1; /* width of the resolution level once lower than computed one */ + int rh1; /* height of the resolution level once lower than computed one */ + + for (i = l - 1; i >= stop; i--) { + int cas_col = 0; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ + int cas_row = 0; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ + + 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; + + cas_row = tilec->resolutions[l - i].x0 % 2; + cas_col = tilec->resolutions[l - i].y0 % 2; + + 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/jpwl/decoder/libopenjpeg/dwt.h b/jpwl/decoder/libopenjpeg/dwt.h new file mode 100644 index 00000000..ec9860b6 --- /dev/null +++ b/jpwl/decoder/libopenjpeg/dwt.h @@ -0,0 +1,101 @@ +/* + * 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 + * tilec : tile component information (present tile) + * 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 + * tilec : tile component information (present tile) + * l: number of decomposition levels in the DWT + * row_tilec : tile component information (previous tile on the same row) + * col_tilec : tile component information (previous tile on the same column) + */ +void dwt_decode(int *a, int w, int h, tcd_tilecomp_t * tilec, int l, + int stop); + +/* + * 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, + int stop); +/* + * 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/jpwl/decoder/libopenjpeg/fix.c b/jpwl/decoder/libopenjpeg/fix.c new file mode 100644 index 00000000..77ca6d63 --- /dev/null +++ b/jpwl/decoder/libopenjpeg/fix.c @@ -0,0 +1,54 @@ +/* + * 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" +#include //Add Antonin : multbug1 + +#ifdef 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); +//} + +//Mod Antonin : multbug1 +int fix_mul(int a, int b) +{ + double tmp= (double) ((int64) a * (int64) b); + int64 v = (int64) ((fabs(tmp/8192.0)>=floor(fabs(tmp/8192.0))+0.5)?fabs(tmp/8192.0)+1.0:fabs(tmp/8192.0)); + v = (tmp<0)?-v:v; + return (int) v; +} +//doM + diff --git a/jpwl/decoder/libopenjpeg/fix.h b/jpwl/decoder/libopenjpeg/fix.h new file mode 100644 index 00000000..768cada2 --- /dev/null +++ b/jpwl/decoder/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/jpwl/decoder/libopenjpeg/int.c b/jpwl/decoder/libopenjpeg/int.c new file mode 100644 index 00000000..7bb5f23d --- /dev/null +++ b/jpwl/decoder/libopenjpeg/int.c @@ -0,0 +1,113 @@ +/* + * 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. + * + * returns a if a < b else b + */ +int int_min(int a, int b) +{ + return a < b ? a : b; +} + +/* + * Get the maximum of two integers. + * + * returns a if a > b else b + */ +int int_max(int a, int b) +{ + return a > b ? a : b; +} + +/* + * Clamp an integer inside an interval. + * + * return a if (min < a < max) + * return max if (a > max) + * return min if (a < min) + */ +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. + * + * a divided by b + */ +int int_ceildiv(int a, int b) +{ + return (a + b - 1) / b; +} + +/* + * Divide an integer by a power of 2 and round upwards. + * + * a divided by 2^b + */ +int int_ceildivpow2(int a, int b) +{ + return (a + (1 << b) - 1) >> b; +} + +/* + * Divide an integer by a power of 2 and round downwards. + * + * a divided by 2^b + */ +int int_floordivpow2(int a, int b) +{ + return a >> b; +} + +/* + * Get logarithm of an integer and round downwards. + * + * log2(a) + */ +int int_floorlog2(int a) +{ + int l; + for (l = 0; a > 1; l++) { + a >>= 1; + } + return l; +} diff --git a/jpwl/decoder/libopenjpeg/int.h b/jpwl/decoder/libopenjpeg/int.h new file mode 100644 index 00000000..a1b590dd --- /dev/null +++ b/jpwl/decoder/libopenjpeg/int.h @@ -0,0 +1,86 @@ +/* + * 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 + +/* + * Get the minimum of two integers. + * + * returns a if a < b else b + */ +int int_min(int a, int b); + +/* + * Get the maximum of two integers. + * + * returns a if a > b else b + */ +int int_max(int a, int b); + +/* + * Clamp an integer inside an interval. + * + * return a if (min < a < max) + * return max if (a > max) + * return min if (a < min) + */ +int int_clamp(int a, int min, int max); + +/* + * Get absolute value of integer. + */ +int int_abs(int a); + +/* + * Divide an integer and round upwards. + * + * a divided by b + */ +int int_ceildiv(int a, int b); + +/* + * Divide an integer by a power of 2 and round upwards. + * + * a divided by 2^b + */ +int int_ceildivpow2(int a, int b); + +/* + * Divide an integer by a power of 2 and round downwards. + * + * a divided by 2^b + */ +int int_floordivpow2(int a, int b); + +/* + * Get logarithm of an integer and round downwards. + * + * log2(a) + */ +int int_floorlog2(int a); + +#endif diff --git a/jpwl/decoder/libopenjpeg/j2k.c b/jpwl/decoder/libopenjpeg/j2k.c new file mode 100644 index 00000000..7360a108 --- /dev/null +++ b/jpwl/decoder/libopenjpeg/j2k.c @@ -0,0 +1,1769 @@ + // Questo file per la versione jpwldec1.6 è modificato con l'aggiunta della funzione per + // lettura del marker segment ESD!!! +/* + * Copyright (c) 2001-2002, David Janssens + * Copyright (c) 2002-2004, Yannick Verschueren + * Copyright (c) 2002-2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include "j2k.h" +#include "cio.h" +#include "tcd.h" +#include "dwt.h" +#include "int.h" +#include "jpt.h" +#include "jpw.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 JPWL_MS_EPB 0xff96 +#define JPWL_MS_EPC 0xff97 +#define JPWL_MS_ESD 0xff98 // marker segment ESD: aggiunto per JPWL +#define JPWL_MS_RED 0xff99 + +#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; + +static int nesd; // Aggiunto per JPWL (gestione ESD!) +extern int cslen; // Aggiunto per JPWL (gestione RED!) + +/* 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() +{ + cio_write(J2K_MS_SOC, 2); +} + +void j2k_read_soc() +{ + j2k_state = J2K_STATE_MHSIZ; +} + +void j2k_write_siz() +{ + int i; + int lenp, len; + + 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; + + len = cio_read(2); /* Lsiz */ + cio_read(2); /* Rsiz (capabilities) */ + j2k_img->x1 = cio_read(4); /* Xsiz */ + j2k_img->y1 = cio_read(4); /* Ysiz */ + j2k_img->x0 = cio_read(4); /* X0siz */ + j2k_img->y0 = cio_read(4); /* Y0siz */ + j2k_cp->tdx = cio_read(4); /* XTsiz */ + j2k_cp->tdy = cio_read(4); /* YTsiz */ + j2k_cp->tx0 = cio_read(4); /* XT0siz */ + j2k_cp->ty0 = cio_read(4); /* YT0siz */ + + j2k_img->numcomps = cio_read(2); /* Csiz */ + 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); /* Ssiz_i */ + j2k_img->comps[i].prec = (tmp & 0x7f) + 1; + j2k_img->comps[i].sgnd = tmp >> 7; + j2k_img->comps[i].dx = cio_read(1); /* XRsiz_i */ + j2k_img->comps[i].dy = cio_read(1); /* YRsiz_i */ + 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].resno_decoded = 0; /* number of resolution decoded */ + j2k_img->comps[i].factor = 0; /* reducing factor by component */ + } + + 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(j2k_cp->tw * j2k_cp->th, sizeof(j2k_tcp_t)); + j2k_cp->tileno = (int *) calloc(j2k_cp->tw * j2k_cp->th, sizeof(int)); + j2k_cp->tileno_size = 0; + + for (i = 0; i < j2k_cp->tw * j2k_cp->th; i++) { + j2k_cp->tcps[i].POC = 0; + j2k_cp->tcps[i].numpocs = 0; + j2k_cp->tcps[i].first = 1; + } + + /* Initialization for PPM marker */ + j2k_cp->ppm = 0; + j2k_cp->ppm_data = NULL; + j2k_cp->ppm_previous = 0; + j2k_cp->ppm_store = 0; + + 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); + + 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; + + 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; /* SPcox (D) */ + tccp->cblkw = cio_read(1) + 2; /* SPcox (E) */ + tccp->cblkh = cio_read(1) + 2; /* SPcox (F) */ + tccp->cblksty = cio_read(1); /* SPcox (G) */ + tccp->qmfbid = cio_read(1); /* SPcox (H) */ + if (tccp->csty & J2K_CP_CSTY_PRT) { + for (i = 0; i < tccp->numresolutions; i++) { + int tmp = cio_read(1); /* SPcox (I_i) */ + tccp->prcw[i] = tmp & 0xf; + tccp->prch[i] = tmp >> 4; + } + } +} + +void j2k_write_cod() +{ + j2k_tcp_t *tcp; + int lenp, len; + + 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; + + tcp = + j2k_state == + J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp; + len = cio_read(2); /* Lcod */ + tcp->csty = cio_read(1); /* Scod */ + tcp->prg = cio_read(1); /* SGcod (A) */ + tcp->numlayers = cio_read(2); /* SGcod (B) */ + tcp->mct = cio_read(1); /* SGcod (C) */ + + 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; + + 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; + + tcp = + j2k_state == + J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp; + len = cio_read(2); /* Lcoc */ + compno = cio_read(j2k_img->numcomps <= 256 ? 1 : 2); /* Ccoc */ + tcp->tccps[compno].csty = cio_read(1); /* Scoc */ + 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); /* Sqcx */ + 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) { + expn = cio_read(1) >> 3; /* SPqcx_i */ + mant = 0; + } else { + tmp = cio_read(2); /* SPqcx_i */ + expn = tmp >> 11; + mant = tmp & 0x7ff; + } + tccp->stepsizes[bandno].expn = expn; + tccp->stepsizes[bandno].mant = mant; + } + + + + /* Add Antonin : if scalar_derived -> compute other stepsizes */ + + + + if (tccp->qntsty==J2K_CCP_QNTSTY_SIQNT) { + + for (bandno=1 ; bandnostepsizes[bandno].expn = ((tccp->stepsizes[0].expn)-((bandno-1)/3)>0)?(tccp->stepsizes[0].expn)-((bandno-1)/3):0; + + tccp->stepsizes[bandno].mant = tccp->stepsizes[0].mant; + + } + + } + + + + /* ddA */ +} + +void j2k_write_qcd() +{ + int lenp, len; + + 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; + + len = cio_read(2); /* Lqcd */ + 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; + + cio_write(J2K_MS_QCC, 2); /* QCC */ + lenp = cio_tell(); + cio_skip(2); + cio_write(compno, j2k_img->numcomps <= 256 ? 1 : 2); /* Cqcc */ + j2k_write_qcx(compno); + len = cio_tell() - lenp; + cio_seek(lenp); + cio_write(len, 2); /* Lqcc */ + cio_seek(lenp + len); +} + +void j2k_read_qcc() +{ + int len, compno; + + len = cio_read(2); /* Lqcc */ + compno = cio_read(j2k_img->numcomps <= 256 ? 1 : 2); /* Cqcc */ + j2k_read_qcx(compno, len - 2 - (j2k_img->numcomps <= 256 ? 1 : 2)); +} + +void j2k_write_poc() +{ + int len, numpchgs, i; + j2k_tcp_t *tcp; + j2k_tccp_t *tccp; + + tcp = &j2k_cp->tcps[j2k_curtileno]; + tccp = &tcp->tccps[0]; + numpchgs = tcp->numpocs; + cio_write(J2K_MS_POC, 2); /* POC */ + len = 2 + (5 + 2 * (j2k_img->numcomps <= 256 ? 1 : 2)) * numpchgs; + cio_write(len, 2); /* Lpoc */ + for (i = 0; i < numpchgs; i++) { + // MODIF + j2k_poc_t *poc; + poc = &tcp->pocs[i]; + cio_write(poc->resno0, 1); /* RSpoc_i */ + cio_write(poc->compno0, (j2k_img->numcomps <= 256 ? 1 : 2)); /* CSpoc_i */ + cio_write(poc->layno1, 2); /* LYEpoc_i */ + poc->layno1 = int_min(poc->layno1, tcp->numlayers); + cio_write(poc->resno1, 1); /* REpoc_i */ + poc->resno1 = int_min(poc->resno1, tccp->numresolutions); + cio_write(poc->compno1, (j2k_img->numcomps <= 256 ? 1 : 2)); /* CEpoc_i */ + poc->compno1 = int_min(poc->compno1, j2k_img->numcomps); + cio_write(poc->prg, 1); /* Ppoc_i */ + } +} + +void j2k_read_poc() +{ + int len, numpchgs, i, old_poc; + j2k_tcp_t *tcp; + j2k_tccp_t *tccp; + + tcp = + j2k_state == + J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp; + + old_poc = tcp->POC ? tcp->numpocs + 1 : 0; + tcp->POC = 1; + tccp = &tcp->tccps[0]; + len = cio_read(2); /* Lpoc */ + numpchgs = (len - 2) / (5 + 2 * (j2k_img->numcomps <= 256 ? 1 : 2)); + + for (i = old_poc; i < numpchgs + old_poc; i++) { + j2k_poc_t *poc; + poc = &tcp->pocs[i]; + poc->resno0 = cio_read(1); /* RSpoc_i */ + poc->compno0 = cio_read(j2k_img->numcomps <= 256 ? 1 : 2); /* CSpoc_i */ + poc->layno1 = int_min(cio_read(2), tcp->numlayers); /* LYEpoc_i */ + poc->resno1 = int_min(cio_read(1), tccp->numresolutions); /* REpoc_i */ + poc->compno1 = int_min(cio_read(j2k_img->numcomps <= 256 ? 1 : 2), j2k_img->numcomps); /* CEpoc_i */ + poc->prg = cio_read(1); /* Ppoc_i */ + } + + tcp->numpocs = numpchgs + old_poc - 1; +} + +void j2k_read_crg() +{ + int len, i, Xcrg_i, Ycrg_i; + + len = cio_read(2); /* Lcrg */ + for (i = 0; i < j2k_img->numcomps; i++) { + Xcrg_i = cio_read(2); /* Xcrg_i */ + Ycrg_i = cio_read(2); /* Ycrg_i */ + } +} + +void j2k_read_tlm() +{ + int len, Ztlm, Stlm, ST, SP, tile_tlm, i; + long int Ttlm_i, Ptlm_i; + + len = cio_read(2); /* Ltlm */ + Ztlm = cio_read(1); /* Ztlm */ + Stlm = cio_read(1); /* Stlm */ + ST = ((Stlm >> 4) & 0x01) + ((Stlm >> 4) & 0x02); + SP = (Stlm >> 6) & 0x01; + tile_tlm = (len - 4) / ((SP + 1) * 2 + ST); + for (i = 0; i < tile_tlm; i++) { + Ttlm_i = cio_read(ST); /* Ttlm_i */ + Ptlm_i = cio_read(SP ? 4 : 2); /* Ptlm_i */ + } +} + +void j2k_read_plm() +{ + int len, i, Zplm, Nplm, add, packet_len = 0; + + len = cio_read(2); /* Lplm */ + Zplm = cio_read(1); /* Zplm */ + len -= 3; + while (len > 0) { + Nplm = cio_read(4); /* Nplm */ + len -= 4; + for (i = Nplm; i > 0; i--) { + add = cio_read(1); + len--; + packet_len = (packet_len << 7) + add; /* Iplm_ij */ + if ((add & 0x80) == 0) { + /* New packet */ + packet_len = 0; + } + if (len <= 0) + break; + } + } +} + +void j2k_read_plt() +{ + int len, i, Zplt, packet_len = 0, add; + + len = cio_read(2); /* Lplt */ + Zplt = cio_read(1); /* Zplt */ + for (i = len - 3; i > 0; i--) { + add = cio_read(1); + packet_len = (packet_len << 7) + add; /* Iplt_i */ + if ((add & 0x80) == 0) { + /* New packet */ + packet_len = 0; + } + } +} + +void j2k_read_ppm() +{ + int len, Z_ppm, i, j; + int N_ppm; + + len = cio_read(2); + j2k_cp->ppm = 1; + + Z_ppm = cio_read(1); /* Z_ppm */ + len -= 3; + while (len > 0) { + if (j2k_cp->ppm_previous == 0) { + N_ppm = cio_read(4); /* N_ppm */ + len -= 4; + } else { + N_ppm = j2k_cp->ppm_previous; + } + + j = j2k_cp->ppm_store; + if (Z_ppm == 0) { /* First PPM marker */ + j2k_cp->ppm_data = + (unsigned char *) calloc(N_ppm, sizeof(unsigned char)); + + j2k_cp->ppm_len = N_ppm; //Add antonin : ppmbug1 + + } else { /* NON-first PPM marker */ + j2k_cp->ppm_data = + (unsigned char *) realloc(j2k_cp->ppm_data, + (N_ppm + + j2k_cp->ppm_store) * + sizeof(unsigned char)); + + j2k_cp->ppm_len = N_ppm + j2k_cp->ppm_store; //Add antonin : ppmbug1 + + } + + for (i = N_ppm; i > 0; i--) { /* Read packet header */ + j2k_cp->ppm_data[j] = cio_read(1); + j++; + len--; + if (len == 0) + break; /* Case of non-finished packet header in present marker but finished in next one */ + } + + j2k_cp->ppm_previous = i - 1; + j2k_cp->ppm_store = j; + } +} + +void j2k_read_ppt() +{ + int len, Z_ppt, i, j = 0; + j2k_tcp_t *tcp; + + len = cio_read(2); + Z_ppt = cio_read(1); + tcp = &j2k_cp->tcps[j2k_curtileno]; + tcp->ppt = 1; + if (Z_ppt == 0) { /* First PPT marker */ + tcp->ppt_data = + (unsigned char *) calloc(len - 3, sizeof(unsigned char)); + tcp->ppt_store = 0; + + tcp->ppt_len = len-3; //Add antonin : ppmbug1 + } else { /* NON-first PPT marker */ + tcp->ppt_data = + (unsigned char *) realloc(tcp->ppt_data, + (len - 3 + + tcp->ppt_store) * sizeof(unsigned char)); + + tcp->ppt_len=len - 3 + tcp->ppt_store; //Add antonin : ppmbug1 + + } + + j = tcp->ppt_store; + for (i = len - 3; i > 0; i--) { + tcp->ppt_data[j] = cio_read(1); + j++; + } + tcp->ppt_store = j; +} + +void j2k_write_sot() +{ + int lenp, len; + + 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; + char status = 0; + + len = cio_read(2); + tileno = cio_read(2); + + if (j2k_cp->tileno_size == 0) { + j2k_cp->tileno[j2k_cp->tileno_size] = tileno; + j2k_cp->tileno_size++; + } else { + i = 0; + while (i < j2k_cp->tileno_size && status == 0) { + status = j2k_cp->tileno[i] == tileno ? 1 : 0; + i++; + } + if (status == 0) { + j2k_cp->tileno[j2k_cp->tileno_size] = tileno; + j2k_cp->tileno_size++; + } + } + + 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]; + + if (tcp->first == 1) { + tmp = tcp->tccps; + *tcp = j2k_default_tcp; + + /* Initialization PPT */ + tcp->ppt = 0; + tcp->ppt_data = NULL; + + tcp->tccps = tmp; + for (i = 0; i < j2k_img->numcomps; i++) { + tcp->tccps[i] = j2k_default_tcp.tccps[i]; + } + j2k_cp->tcps[j2k_curtileno].first = 0; + } +} + +void j2k_write_sod() +{ + int l, layno; + int totlen; + j2k_tcp_t *tcp; + static int j2k_sod_start; + + 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 *) calloc(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)); + } + + 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, i; + unsigned char *data; + + len = int_min(j2k_eot - cio_getbp(), cio_numbytesleft() + 1); + if (len == cio_numbytesleft() + 1) + truncate = 1; /* Case of a truncate codestream */ + + data = + (unsigned char *) malloc((j2k_tile_len[j2k_curtileno] + len) * + sizeof(unsigned char)); + for (i = 0; i < j2k_tile_len[j2k_curtileno]; i++) + data[i] = j2k_tile_data[j2k_curtileno][i]; + for (i = 0; i < len; i++) + data[i + j2k_tile_len[j2k_curtileno]] = cio_read(1); + + j2k_tile_len[j2k_curtileno] += len; + free(j2k_tile_data[j2k_curtileno]); + j2k_tile_data[j2k_curtileno] = data; + data = NULL; + + 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]; + + 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; + + tcp = + j2k_state == + J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp; + len = cio_read(2); /* Lrgn */ + compno = cio_read(j2k_img->numcomps <= 256 ? 1 : 2); /* Crgn */ + roisty = cio_read(1); /* Srgn */ + tcp->tccps[compno].roishift = cio_read(1); /* SPrgn */ +} + +void j2k_write_eoc() +{ + /* fprintf(stderr, "%.8x: EOC\n", cio_tell() + pos_correction); */ + cio_write(J2K_MS_EOC, 2); +} + +void j2k_read_eoc() +{ + int i, tileno; + + tcd_init(j2k_img, j2k_cp); + + for (i = 0; i < j2k_cp->tileno_size; i++) { + tileno = j2k_cp->tileno[i]; + tcd_decode_tile(j2k_tile_data[tileno], j2k_tile_len[tileno], tileno); + free(j2k_tile_data[tileno]); + } + + j2k_state = J2K_STATE_MT; + longjmp(j2k_error, 1); +} + +void j2k_read_unk() +{ + //c'era un bug in questa funzione occorre leggere la lunghezza di un marker sconosciuto per proseguire il parsing + int len; + fprintf(stderr, "warning: unknown marker at %x\n",cio_tell()); + len = cio_read(2); + cio_skip(len - 2); //bug corretto +} + +void j2k_read_jpwlms() +{ + //c'era un bug in questa funzione occorre leggere la lunghezza di un marker sconosciuto per proseguire il parsing + int len; + len = cio_read(2); + cio_skip(len - 2); //bug corretto +} + +LIBJ2K_API int j2k_encode(j2k_image_t * img, j2k_cp_t * cp, char *output, + int len, char *index) +{ + int tileno, compno, layno, resno, precno, pack_nb; + char *dest = NULL; + FILE *INDEX = NULL; + FILE *f = NULL; + + if (setjmp(j2k_error)) { + return 0; + } + + if (cp->intermed_file==1) { + f = fopen(output, "wb"); + if (!f) { + fprintf(stderr, "failed to open %s for writing\n", output); + 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_cp->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.tw=j2k_cp->tw; + info_IM.th=j2k_cp->th; + 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(); + + if (cp->intermed_file==1) { + /* 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, "Tile number %d / %d ", tileno + 1, + cp->tw * cp->th); + + if (cp->intermed_file==1) { + /* 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"); + } + */ + if (cp->intermed_file==1) { + fwrite(dest, 1, cio_tell(), f); + pos_correction = cio_tell() + pos_correction; + } + } + + if (cp->intermed_file==1) { + free(dest); + dest = (char *) malloc(len); + cio_init(dest, len); + } + + j2k_write_eoc(); + + if (cp->intermed_file==1) { + fwrite(dest, 1, 2, f); + free(dest); + /* closing file *.j2k */ + fclose(f); + } + + /* Creation of the index file */ + + if (info_IM.index_on) { + + double DistoTotal = 0; + + 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 %d\n", info_IM.tw, info_IM.th); + + fprintf(INDEX, "%d\n", info_IM.Comp); + + fprintf(INDEX, "%d\n", info_IM.Layer); + + fprintf(INDEX, "%d\n", info_IM.Decomposition); + + for (resno=info_IM.Decomposition;resno>=0;resno--) { + + fprintf(INDEX, "[%d,%d] ", (1<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) +{ + /*int temp; + printf("ciao!\n"); + temp=setjmp(j2k_error); + printf("temp: %d\n");*/ + if (setjmp(j2k_error)) { + //printf("temp: %d\n"); + if (j2k_state != J2K_STATE_MT) { + fprintf(stderr, "WARNING: incomplete bitstream\n"); + return 0; + } + j2k_clean(); + return cio_numbytes(); /* Correct way of ending j2k_decode */ + //return len; + } + + j2k_img = img; + + j2k_cp = cp; + + j2k_state = J2K_STATE_MHSOC; + cio_init(src, len); + + + if (decode_JPWL(src, len)) { + //printf("ciao!\n"); + _exit(-4); + //printf("Sto leggendo una codestream JPWL!\n"); + nesd = 0; + len = cslen; + cio_init(src, len); + } + //printf("ciao!\n"); + //else + //printf("Non ho riconosciuto la codestream come JPWL!\n"); + //cio_init(src, cslen); + // len = cslen; + exit(-5); + //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; +} +void jpwl_read_esd() +{ + unsigned int lesd, cesd2; + unsigned char pesd, cesd1; + unsigned long esdata; + int mode, metric, i, temp; + short int ex, mant; + double value; + FILE *f; + + + //printf("Eccomi qua!\n"); + lesd = cio_read(2); + //esd[nesd].lesd = cio_read(2); + if (j2k_img->numcomps<257) + { + cesd1 = cio_read(1); + //esd[nesd].cesd1 = cio_read(1); + esdata = lesd - 4; + } + else + { + cesd2 = cio_read(2); + //esd[nesd].cesd2 = cio_read(2); + esdata = lesd - 5; + } + pesd = cio_read(1); + //esd[nesd].pesd = cio_read(1); + if (j2k_state==J2K_STATE_MH) + { + if ((f = fopen("esdmap","w"))==NULL) + { + printf("Unable to open file 'esdmap'!\n"); + exit(1); + } + } + else + if ((f = fopen("esdmap","a"))==NULL) + { + printf("Unable to open file 'esdmap'!\n"); + exit(1); + } + mode = (pesd >> 6)&3; // 0:pm, 1:brm, 2:prm, 3:reserved ! + //mode = (esd[nesd].pesd >> 6)&3; // 0:pm, 1:brm, 2:prm, 3:reserved ! + metric = (pesd >> 3) & 7; // 0:relative, 1:MSE, 2:MSEred, 3:PSNR, 4:PSNRincr, 5:MAXERR ! + //metric = (esd[nesd].pesd >> 3) & 7; // 0:relative, 1:MSE, 2:MSEred, 3:PSNR, 4:PSNRincr, 5:MAXERR ! + fprintf(f,"Lesd: %x\n",lesd); + if (j2k_img->numcomps<257) + fprintf(f,"Cesd: %x\n",cesd1); + else + fprintf(f,"Cesd: %x\n",cesd2); + fprintf(f,"Pesd: %x\n",pesd); + //fprintf(f,"mode: %d\n",mode); + //fprintf(f,"metric: %d\n",metric); + switch (mode) { + case 0: // packed mode + //esdata = esdata/(1+((pesd>>2)&1)+2*(1+((pesd>>1)&1))); //numero livelli + esdata = esdata/(1+((pesd>>2)&1)); //numero livelli + fprintf(f,"LEVEL\tVALUE\n"); + for (i=0; i>2)&1))); + temp = cio_read(1+((pesd>>2)&1)); + if (metric!=0) + { + mant = temp & 0x07FF; + ex = (temp >> 11) & 0x001F; + value = pow(2,ex-15)*(1+(mant/pow(2,11))); + //fprintf(f,"%x\n",cio_read(1)); + fprintf(f,"%d\t%f\n",i,value); + } + else // relative error sensivity + { + fprintf(f,"%d\t%d\n",i,temp); + } + } + break; + case 1: // byte range mode + esdata = esdata/(1+((pesd>>2)&1)+2*(2+2*((pesd>>1)&1))); //numero livelli + fprintf(f,"LEVEL\tSTART BYTE\tEND BYTE\tVALUE\n"); + for (i=0; i>2)&1))); + //fprintf(f,"%d\t%d\t%d\t",i,cio_read(2+2*((pesd>>1)&1)), + // cio_read(2+2*((pesd>>1)&1))); + fprintf(f,"%d\t%d\t\t",i,cio_read(2+2*((pesd>>1)&1))); + fprintf(f,"%d\t\t",cio_read(2+2*((pesd>>1)&1))); + temp = cio_read(1+((pesd>>2)&1)); + if (metric!=0) + { + mant = temp & 0x07FF; + ex = (temp >> 11) & 0x001F; + value = pow(2,ex-15)*(1+(mant/pow(2,11))); + //fprintf(f,"%x\n",cio_read(1)); + fprintf(f,"%f\n",value); + } + else // relative error sensivity + { + fprintf(f,"%d\n",temp); + } + } + break; + case 2: // packed range mode + esdata = esdata/(1+((pesd>>2)&1)+2*(2+2*((pesd>>1)&1))); //numero livelli + //printf("esdata: %d\n",esdata); + fprintf(f,"LEVEL\tSTART PCK\tEND PCK\t\tVALUE\n"); + for (i=0; i>1)&1)), + // cio_read(2+2*((pesd>>1)&1))); // Cosi' non funziona bene...mah!!! + fprintf(f,"%d\t%d\t\t",i,cio_read(2+2*((pesd>>1)&1))); + fprintf(f,"%d\t\t",cio_read(2+2*((pesd>>1)&1))); + temp = cio_read(1+((pesd>>2)&1)); + if (metric!=0) + { + mant = temp & 0x07FF; + ex = (temp >> 11) & 0x001F; + value = pow(2,ex-15)*(1+(mant/pow(2,11))); + //fprintf(f,"%x\n",cio_read(1)); + fprintf(f,"%f\n",value); + } + else // relative error sensivity + { + fprintf(f,"%d\n",temp); + } + } + //printf("Ho letto ESD!\n"); + break; + } + + //esdata = esdata/2; + //for (i=0; i> 11) & 0x001F; + // value = pow(2,ex-15)*(1+(mant/pow(2,11))); + //fprintf(f,"%x\n",cio_read(1)); + // fprintf(f,"level %d: %f\n",i,value); + //} + //printf("temp: %x\n",cio_read(2)); + //cio_skip(-2); + fclose(f); +} +/* + * Read a JPT-stream and decode file + * + */ +int j2k_decode_jpt_stream(unsigned char *src, int len, j2k_image_t * img, + j2k_cp_t * cp) +{ + jpt_msg_header_struct_t header; + int position; + + if (setjmp(j2k_error)) { + if (j2k_state != J2K_STATE_MT) { + fprintf(stderr, "WARNING: incomplete bitstream\n"); + return 0; + } + return cio_numbytes(); + } + + j2k_img = img; + + j2k_cp = cp; + + j2k_state = J2K_STATE_MHSOC; + cio_init(src, len); + + /* Initialize the header */ + jpt_init_Msg_Header(&header); + /* Read the first header of the message */ + jpt_read_Msg_Header(&header); + + position = cio_tell(); + if (header.Class_Id != 6) { /* 6 : Main header data-bin message */ + fprintf(stderr, + "[JPT-stream] : Expecting Main header first [class_Id %d] !\n", + header.Class_Id); + return 0; + } + + for (;;) { + j2k_dec_mstabent_t *e; + int id; + + if (!cio_numbytesleft()) { + j2k_read_eoc(); + return 0; + } + /* data-bin read -> need to read a new header */ + if ((unsigned int) (cio_tell() - position) == header.Msg_length) { + jpt_read_Msg_Header(&header); + position = cio_tell(); + if (header.Class_Id != 4) { /* 4 : Tile data-bin message */ + fprintf(stderr, "[JPT-stream] : Expecting Tile info !\n"); + return 0; + } + } + + 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/jpwl/decoder/libopenjpeg/j2k.h b/jpwl/decoder/libopenjpeg/j2k.h new file mode 100644 index 00000000..8ff9fe4d --- /dev/null +++ b/jpwl/decoder/libopenjpeg/j2k.h @@ -0,0 +1,227 @@ +/* + * 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 /* Number of maximum resolution level authorized */ +#define J2K_MAXBANDS (3*J2K_MAXRLVLS-2) /* Number of maximum sub-band linked to number of resolution level */ + +#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 w, h; /* width and height of data */ + int x0, y0; /* offset of the component compare to the whole image */ + int prec; /* precision */ + int bpp; /* deapth of image in bits */ + int sgnd; /* signed */ + int resno_decoded; /* number of decoded resolution */ + int factor; /* number of division by 2 of the out image compare to the original size of image */ + 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 color_space; /* sRGB, Greyscale or YUV */ + 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 quantization */ + 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 first; /* 1 : first part-tile of a tile */ + 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 */ + int POC; /* Precise if a POC marker has been used O:NO, 1:YES */ + j2k_poc_t pocs[32]; /* progression order changes */ + unsigned char *ppt_data; /* packet header store there for futur use in t2_decode_packet */ + int ppt; /* If ppt == 1 --> there was a PPT marker for the present tile */ + int ppt_store; /* Use in case of multiple marker PPT (number of info already store) */ + int ppt_len; /* ppmbug1 */ + float distoratio[100]; /* add fixed_quality */ + j2k_tccp_t *tccps; /* tile-component coding parameters */ +} j2k_tcp_t; + +typedef struct { + int JPEG2000_format; /* 0: J2K 1:JP2 */ + int intermed_file; /* 1: Store each encoded tile one by one in the output file (for mega-Images)*/ + int image_type; /* 0: PNM, PGM, PPM 1: PGX */ + int disto_alloc; /* Allocation by rate/distortion */ + int fixed_alloc; /* Allocation by fixed layer */ + int fixed_quality; /* add fixed_quality */ + int reduce_on; /* option reduce is used if reduce = 1 */ + int reduce_value; /* if option reduce is used -> original dimension divided by 2^value */ + int index_on; /* 0 = no index || 1 = index */ + int tx0, ty0; /* XTOsiz, YTOsiz */ + int tdx, tdy; /* XTsiz, YTsiz */ + char *comment; /* comment for coding */ + int tw, th; /* number of tiles in width and heigth */ + int *tileno; /* ID number of the tiles present in the codestream */ + int tileno_size; /* size of the vector tileno */ + unsigned char *ppm_data; /* packet header store there for futur use in t2_decode_packet */ + int ppm; /* If ppm == 1 --> there was a PPM marker for the present tile */ + int ppm_store; /* Use in case of multiple marker PPM (number of info already store) */ + int ppm_previous; /* Use in case of multiple marker PPM (case on non-finished previous info) */ + int ppm_len; /* ppmbug1 */ + j2k_tcp_t *tcps; /* tile coding parameters */ + int *matrice; /* Fixed layer */ +} j2k_cp_t; + +typedef struct { + int start_pos, end_pos; /* start and end position */ + double disto; /* ADD for Marcela */ +} info_packet; /* Index struct */ + +typedef struct { + double *thresh; /* value of thresh for each layer by tile cfr. Marcela */ + 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[33], ph[33]; /* precinct number for each resolution level */ + + int pdx[33], pdy[33]; /* precinct size (in power of 2), in X and Y for each resolution level */ + info_packet *packet; /* information concerning packets inside tile */ + int nbpix; /* add fixed_quality */ + double distotile; /* add fixed_quality */ +} 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; /* Tile size in x and y */ + int tw, th; /* Number of Tile in X and Y */ + int Comp; /* Component numbers */ + int Layer; /* number of layer */ + int Decomposition; /* number of decomposition */ + 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 + * output: destination buffer or name of the output file when cp->intermed_file==1 + * len: length of destination buffer + * index : index file name + */ +void j2k_read_jpwlms(); + +LIBJ2K_API int j2k_encode(j2k_image_t * i, j2k_cp_t * cp, char *output, + int len, char *index); + +void jpwl_read_esd(); + +/* 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 * img, + j2k_cp_t * cp); + + +/* + * Decode an image form a JPT-stream (JPEG 2000, JPIP) + * src: source buffer + * len: length of source buffer + * i: decode image + * cp: coding parameters that were used to encode the image + * + */ +int j2k_decode_jpt_stream(unsigned char *src, int len, j2k_image_t * img, + j2k_cp_t * cp); + +#endif diff --git a/jpwl/decoder/libopenjpeg/jp2.c b/jpwl/decoder/libopenjpeg/jp2.c new file mode 100644 index 00000000..a7f9fddc --- /dev/null +++ b/jpwl/decoder/libopenjpeg/jp2.c @@ -0,0 +1,539 @@ +/* +* Copyright (c) 2003-2004, Yannick Verschueren +* Copyright (c) 2003-2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include + +#include "j2k.h" +#include "jp2.h" +#include "cio.h" +#include "tcd.h" +#include "int.h" + +#define JPIP_JPIP 0x6a706970 + +#define JP2_JP 0x6a502020 +#define JP2_FTYP 0x66747970 +#define JP2_JP2H 0x6a703268 +#define JP2_IHDR 0x69686472 +#define JP2_COLR 0x636f6c72 +#define JP2_JP2C 0x6a703263 +#define JP2_URL 0x75726c20 +#define JP2_DBTL 0x6474626c +#define JP2_BPCC 0x62706363 +#define JP2_JP2 0x6a703220 + +/* +* +* Read box headers +* +*/ + +int jp2_read_boxhdr(jp2_box_t * box) +{ + box->init_pos = cio_tell(); + box->length = cio_read(4); + box->type = cio_read(4); + if (box->length == 1) { + if (cio_read(4) != 0) { + fprintf(stderr, "Error: Cannot handle box sizes higher than 2^32\n"); + return 1; + }; + box->length = cio_read(4); + } + return 0; +} + +/* +* +* Initialisation of a Standard JP2 structure +*/ + +int jp2_init_stdjp2(jp2_struct_t * jp2_struct, j2k_image_t * img) +{ + int depth_0, sign, depth, i; + + + jp2_struct->h = img->y1 - img->y0; // HEIGHT + jp2_struct->w = img->x1 - img->x0; // WIDTH + jp2_struct->numcomps = img->numcomps; // NC + jp2_struct->comps = (jp2_comps_t *) malloc(jp2_struct->numcomps * sizeof(jp2_comps_t)); + + depth_0 = img->comps[0].prec - 1; + sign = img->comps[0].sgnd; + jp2_struct->bpc = depth_0 + (sign << 7); + + for (i = 1; i < img->numcomps; i++) { + depth = img->comps[i].prec - 1; + sign = img->comps[i].sgnd; + if (depth_0 != depth) + jp2_struct->bpc = 255; + } + + + + jp2_struct->C = 7; // C : Always 7 + jp2_struct->UnkC = 0; // UnkC, colorspace specified in colr box + jp2_struct->IPR = 0; // IPR, no intellectual property + + for (i = 0; i < img->numcomps; i++) + jp2_struct->comps[i].bpcc = + img->comps[i].prec - 1 + (img->comps[i].sgnd << 7); + + jp2_struct->precedence = 0; // PRECEDENCE + jp2_struct->approx = 0; // APPROX + + if ((img->numcomps == 1 || img->numcomps == 3) + && (jp2_struct->bpc != 255)) + jp2_struct->meth = 1; + else + jp2_struct->meth = 2; + + if (jp2_struct->meth == 1) { + if (img->color_space == 1) + jp2_struct->enumcs = 16; + else if (img->color_space == 2) + jp2_struct->enumcs = 17; + else if (img->color_space == 3) + jp2_struct->enumcs = 18; // YUV + } else + jp2_struct->enumcs = 0; // PROFILE (??) + + jp2_struct->brand = JP2_JP2; /* BR */ + jp2_struct->minversion = 0; /* MinV */ + jp2_struct->numcl = 1; + jp2_struct->cl = (int *) malloc(jp2_struct->numcl * sizeof(int)); + jp2_struct->cl[0] = JP2_JP2; /* CL0 : JP2 */ + return 0; +} + + +void jp2_write_url(char *Idx_file) +{ + unsigned int i; + char str[256]; + jp2_box_t box; + + sprintf(str, "%s", Idx_file); + + + box.init_pos = cio_tell(); + cio_skip(4); + cio_write(JP2_URL, 4); // DBTL + cio_write(0, 1); // VERS + cio_write(0, 3); // FLAG + + for (i = 0; i < strlen(str); i++) { + cio_write(str[i], 1); + } + + box.length = cio_tell() - box.init_pos; + cio_seek(box.init_pos); + cio_write(box.length, 4); /* L */ + cio_seek(box.init_pos + box.length); +} + +/* +* Read the IHDR box +* +* Image Header box +* +*/ +int jp2_read_ihdr(jp2_struct_t * jp2_struct) +{ + jp2_box_t box; + + jp2_read_boxhdr(&box); + if (JP2_IHDR != box.type) { + fprintf(stderr, "Error: Expected IHDR Marker\n"); + return 1; + } + + jp2_struct->h = cio_read(4); // HEIGHT + jp2_struct->w = cio_read(4); // WIDTH + jp2_struct->numcomps = cio_read(2); // NC + + jp2_struct->bpc = cio_read(1); // BPC + + jp2_struct->C = cio_read(1); // C + jp2_struct->UnkC = cio_read(1); // UnkC + jp2_struct->IPR = cio_read(1); // IPR + + if (cio_tell() - box.init_pos != box.length) { + fprintf(stderr, "Error with IHDR Box\n"); + return 1; + } + return 0; +} + +void jp2_write_ihdr(jp2_struct_t * jp2_struct) +{ + jp2_box_t box; + + box.init_pos = cio_tell(); + cio_skip(4); + cio_write(JP2_IHDR, 4); // IHDR + + cio_write(jp2_struct->h, 4); // HEIGHT + cio_write(jp2_struct->w, 4); // WIDTH + cio_write(jp2_struct->numcomps, 2); // NC + + cio_write(jp2_struct->bpc, 1); // BPC + + cio_write(jp2_struct->C, 1); // C : Always 7 + cio_write(jp2_struct->UnkC, 1); // UnkC, colorspace unknow + cio_write(jp2_struct->IPR, 1); // IPR, no intellectual property + + box.length = cio_tell() - box.init_pos; + cio_seek(box.init_pos); + cio_write(box.length, 4); /* L */ + cio_seek(box.init_pos + box.length); +} + + +void jp2_write_bpcc(jp2_struct_t * jp2_struct) +{ + unsigned int i; + jp2_box_t box; + + box.init_pos = cio_tell(); + cio_skip(4); + cio_write(JP2_BPCC, 4); // BPCC + + for (i = 0; i < jp2_struct->numcomps; i++) + cio_write(jp2_struct->comps[i].bpcc, 1); + + box.length = cio_tell() - box.init_pos; + cio_seek(box.init_pos); + cio_write(box.length, 4); /* L */ + cio_seek(box.init_pos + box.length); +} + + +int jp2_read_bpcc(jp2_struct_t * jp2_struct) +{ + unsigned int i; + jp2_box_t box; + + jp2_read_boxhdr(&box); + if (JP2_BPCC != box.type) { + fprintf(stderr, "Error: Expected BPCC Marker\n"); + return 1; + } + + for (i = 0; i < jp2_struct->numcomps; i++) + jp2_struct->comps[i].bpcc = cio_read(1); + + if (cio_tell() - box.init_pos != box.length) { + fprintf(stderr, "Error with BPCC Box\n"); + return 1; + } + return 0; +} + +void jp2_write_colr(jp2_struct_t * jp2_struct) +{ + jp2_box_t box; + + box.init_pos = cio_tell(); + cio_skip(4); + cio_write(JP2_COLR, 4); // COLR + + cio_write(jp2_struct->meth, 1); // METH + cio_write(jp2_struct->precedence, 1); // PRECEDENCE + cio_write(jp2_struct->approx, 1); // APPROX + + if (jp2_struct->meth == 1) + cio_write(jp2_struct->enumcs, 4); // EnumCS + else + cio_write(0, 1); // PROFILE (??) + + box.length = cio_tell() - box.init_pos; + cio_seek(box.init_pos); + cio_write(box.length, 4); /* L */ + cio_seek(box.init_pos + box.length); +} + +int jp2_read_colr(jp2_struct_t * jp2_struct) +{ + jp2_box_t box; + + jp2_read_boxhdr(&box); + if (JP2_COLR != box.type) { + fprintf(stderr, "Error: Expected COLR Marker\n"); + return 1; + } + + jp2_struct->meth = cio_read(1); // METH + jp2_struct->precedence = cio_read(1); // PRECEDENCE + jp2_struct->approx = cio_read(1); // APPROX + + if (jp2_struct->meth == 1) + jp2_struct->enumcs = cio_read(4); // EnumCS + else + cio_read(1); // PROFILE + + if (cio_tell() - box.init_pos != box.length) { + fprintf(stderr, "Error with BPCC Box\n"); + return 1; + } + return 0; +} + +/* +* Write the JP2H box +* +* JP2 Header box +* +*/ +void jp2_write_jp2h(jp2_struct_t * jp2_struct) +{ + jp2_box_t box; + + box.init_pos = cio_tell(); + cio_skip(4);; + cio_write(JP2_JP2H, 4); /* JP2H */ + + jp2_write_ihdr(jp2_struct); + + if (jp2_struct->bpc == 255) + jp2_write_bpcc(jp2_struct); + jp2_write_colr(jp2_struct); + + box.length = cio_tell() - box.init_pos; + cio_seek(box.init_pos); + cio_write(box.length, 4); /* L */ + cio_seek(box.init_pos + box.length); +} + + +/* +* Read the JP2H box +* +* JP2 Header box +* +*/ +int jp2_read_jp2h(jp2_struct_t * jp2_struct) +{ + jp2_box_t box; + + jp2_read_boxhdr(&box); + if (JP2_JP2H != box.type) { + fprintf(stderr, "Error: Expected JP2H Marker\n"); + return 1; + } + + if (jp2_read_ihdr(jp2_struct)) + return 1; + + if (jp2_struct->bpc == 255) + if (jp2_read_bpcc(jp2_struct)) + return 1; + if (jp2_read_colr(jp2_struct)) + return 1; + + if (cio_tell() - box.init_pos != box.length) { + fprintf(stderr, "Error with JP2H Box\n"); + return 1; + } + return 0; +} + +/* +* Write the FTYP box +* +* File type box +* +*/ +void jp2_write_ftyp(jp2_struct_t * jp2_struct) +{ + unsigned int i; + jp2_box_t box; + + box.init_pos = cio_tell(); + cio_skip(4); + cio_write(JP2_FTYP, 4); /* FTYP */ + + cio_write(jp2_struct->brand, 4); /* BR */ + cio_write(jp2_struct->minversion, 4); /* MinV */ + + for (i = 0; i < jp2_struct->numcl; i++) + cio_write(jp2_struct->cl[i], 4); /* CL */ + + box.length = cio_tell() - box.init_pos; + cio_seek(box.init_pos); + cio_write(box.length, 4); /* L */ + cio_seek(box.init_pos + box.length); +} + +/* +* Read the FTYP box +* +* File type box +* +*/ +int jp2_read_ftyp(jp2_struct_t * jp2_struct) +{ + int i; + jp2_box_t box; + + jp2_read_boxhdr(&box); + + if (JP2_FTYP != box.type) { + fprintf(stderr, "Error: Excpected FTYP Marker\n"); + return 1; + } + + jp2_struct->brand = cio_read(4); /* BR */ + jp2_struct->minversion = cio_read(4); /* MinV */ + jp2_struct->numcl = (box.length - 16) / 4; + jp2_struct->cl = + (unsigned int *) malloc(jp2_struct->numcl * sizeof(unsigned int)); + + for (i = jp2_struct->numcl; i > 0; i--) + jp2_struct->cl[i] = cio_read(4); /* CLi */ + + if (cio_tell() - box.init_pos != box.length) { + fprintf(stderr, "Error with FTYP Box\n"); + return 1; + } + return 0; +} + +int jp2_write_jp2c(j2k_image_t * img, j2k_cp_t * cp, char *jp2_buffer, + char *index) +{ + int len; + jp2_box_t box; + + box.init_pos = cio_tell(); + cio_skip(4); + cio_write(JP2_JP2C, 4); // JP2C + + len = j2k_encode(img, cp, jp2_buffer, cp->tdx * cp->tdy * cp->th * cp->tw * 2, index); + + box.length = cio_tell() - box.init_pos; + cio_seek(box.init_pos); + cio_write(box.length, 4); /* L */ + cio_seek(box.init_pos + box.length); + return box.length; +} + + +int jp2_read_jp2c(unsigned char *src, int len, jp2_struct_t * jp2_struct, + j2k_cp_t * cp) +{ + jp2_box_t box; + + jp2_read_boxhdr(&box); + if (JP2_JP2C != box.type) { + fprintf(stderr, "Error: Expected JP2C Marker\n"); + return 1; + } + + src += cio_tell(); + + if (j2k_decode(src, len, jp2_struct->image, cp) == 0) { + fprintf(stderr, "JP2F box: failed to decode J2K bitstream image!\n"); + return 1; + } + + return 0; +} + +void jp2_write_jp() +{ + jp2_box_t box; + + box.init_pos = cio_tell(); + cio_skip(4); + cio_write(JP2_JP, 4); // JP + cio_write(0x0d0a870a, 4); + + box.length = cio_tell() - box.init_pos; + cio_seek(box.init_pos); + cio_write(box.length, 4); /* L */ + cio_seek(box.init_pos + box.length); +} + +/* +* Read the JP box +* +* JPEG 2000 signature +* +* return 1 if error else 0 +*/ +int jp2_read_jp() +{ + jp2_box_t box; + + jp2_read_boxhdr(&box); + if (JP2_JP != box.type) { + fprintf(stderr, "Error: Expected JP Marker\n"); + return 1; + } + if (0x0d0a870a != cio_read(4)) { + fprintf(stderr, "Error with JP Marker\n"); + return 1; + } + if (cio_tell() - box.init_pos != box.length) { + fprintf(stderr, "Error with JP Box size\n"); + return 1; + } + return 0; + +} + +int jp2_decode(unsigned char *src, int len, jp2_struct_t * jp2_struct, + j2k_cp_t * cp) +{ + cio_init(src, len); + + if (jp2_read_jp()) + return 1; + if (jp2_read_ftyp(jp2_struct)) + return 1; + if (jp2_read_jp2h(jp2_struct)) + return 1; + if (jp2_read_jp2c(src, len, jp2_struct, cp)) + return 1; + return 0; +} + +int jp2_encode(jp2_struct_t * jp2_struct, j2k_cp_t * cp, char *output, + char *index) +{ + int len; + + jp2_write_jp(); + jp2_write_ftyp(jp2_struct); + jp2_write_jp2h(jp2_struct); + len = jp2_write_jp2c(jp2_struct->image, cp, output, index); + + return cio_tell(); +} diff --git a/jpwl/decoder/libopenjpeg/jp2.h b/jpwl/decoder/libopenjpeg/jp2.h new file mode 100644 index 00000000..21ee133d --- /dev/null +++ b/jpwl/decoder/libopenjpeg/jp2.h @@ -0,0 +1,122 @@ +/* + * 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 __JP2_H +#define __JP2_H + +#include "j2k.h" + +typedef struct { + int depth; + int sgnd; + int bpcc; +} jp2_comps_t; + +typedef struct { + unsigned int w; + unsigned int h; + unsigned int numcomps; + unsigned int bpc; + unsigned int C; + unsigned int UnkC; + unsigned int IPR; + unsigned int meth; + unsigned int approx; + unsigned int enumcs; + unsigned int precedence; + unsigned int brand; + unsigned int minversion; + unsigned int numcl; + unsigned int *cl; + jp2_comps_t *comps; + j2k_image_t *image; +} jp2_struct_t; + +typedef struct { + int length; + int type; + int init_pos; +} jp2_box_t; + +/* int jp2_init_stdjp2(jp2_struct_t * jp2_struct, j2k_image_t * img); + * + * Create a standard jp2_structure + * jp2_struct: the structure you are creating + * img: a j2k_image_t wich will help you to create the jp2_structure + */ +int jp2_init_stdjp2(jp2_struct_t * jp2_struct, j2k_image_t * img); + +/* int jp2_write_jp2c(j2k_image_t * img, j2k_cp_t * cp, char *jp2_buffer, + * char *index); + * + * Write the jp2c codestream box + * img: the j2k_image that will be compressed + * jp2_buffer: the buffer that will recieve the compressed data + * index: the name of the index file + */ +int jp2_write_jp2c(j2k_image_t * img, j2k_cp_t * cp, char *jp2_buffer, + char *index); + + +/* int jp2_write_jp2h(jp2_struct_t * jp2_struct); + * + * Write the jp2h header box + * jp2_struct: the jp2 structure you are working with + */ +void jp2_write_jp2h(jp2_struct_t * jp2_struct); + +/* int jp2_read_jp2h(jp2_struct_t * jp2_struct); + * + * Read the jp2h header box + * jp2_struct: the jp2 structure you are working with + */ +int jp2_read_jp2h(jp2_struct_t * jp2_struct); + +/* int jp2_encode(jp2_struct_t * jp2_struct, j2k_cp_t * cp, char *output, + * char *index); + * + * Encode a JP2 file + * jp2_buffer: the buffer containing the pointer to the image to encode + * cp: coding parameters of the image + * outbuf: pointer to memory where compressed data will be written + * index: the name of the index file + */ +int jp2_encode(jp2_struct_t * jp2_struct, j2k_cp_t * cp, char *output, + char *index); + +/* int jp2_decode(unsigned char *src, int len, jp2_struct_t * jp2_struct, + * j2k_cp_t * cp); + * + * Decode a JP2 file + * src: pointer to memory where compressed data is stored + * len: length of src buffer + * jp2_struct: the jp2 structure that will be created + * cp: coding parameters of the image + */ +int jp2_decode(unsigned char *src, int len, jp2_struct_t * jp2_struct, + j2k_cp_t * cp); + +#endif diff --git a/jpwl/decoder/libopenjpeg/jpt.c b/jpwl/decoder/libopenjpeg/jpt.c new file mode 100644 index 00000000..de0c8746 --- /dev/null +++ b/jpwl/decoder/libopenjpeg/jpt.c @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2004, Yannick Verschueren + * Copyright (c) 2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#include "jpt.h" +#include "j2k.h" +#include "cio.h" + + +/* + * Read the information contains in VBAS [JPP/JPT stream message header] + * Store information (7 bits) in value + * + */ +unsigned int jpt_read_VBAS_info(unsigned int value) +{ + unsigned char elmt; + + elmt = cio_read(1); + while ((elmt >> 7) == 1) { + value = (value << 7); + value |= (elmt & 0x7f); + elmt = cio_read(1); + } + value = (value << 7); + value |= (elmt & 0x7f); + + return value; +} + +/* + * Initialize the value of the message header structure + * + */ +void jpt_init_Msg_Header(jpt_msg_header_struct_t * header) +{ + header->Id = 0; /* In-class Identifier */ + header->last_byte = 0; /* Last byte information */ + header->Class_Id = 0; /* Class Identifier */ + header->CSn_Id = 0; /* CSn : index identifier */ + header->Msg_offset = 0; /* Message offset */ + header->Msg_length = 0; /* Message length */ + header->Layer_nb = 0; /* Auxiliary for JPP case */ +} + +/* + * Re-initialize the value of the message header structure + * + * Only parameters always present in message header + * + */ +void jpt_reinit_Msg_Header(jpt_msg_header_struct_t * header) +{ + header->Id = 0; /* In-class Identifier */ + header->last_byte = 0; /* Last byte information */ + header->Msg_offset = 0; /* Message offset */ + header->Msg_length = 0; /* Message length */ +} + +/* + * Read the message header for a JPP/JPT - stream + * + */ +void jpt_read_Msg_Header(jpt_msg_header_struct_t * header) +{ + unsigned char elmt, Class = 0, CSn = 0; + jpt_reinit_Msg_Header(header); + + /* ------------- */ + /* VBAS : Bin-ID */ + /* ------------- */ + elmt = cio_read(1); + + /* See for Class and CSn */ + switch ((elmt >> 5) & 0x03) { + case 0: + fprintf(stderr, "Forbidden value encounter in message header !!\n"); + break; + case 1: + Class = 0; + CSn = 0; + break; + case 2: + Class = 1; + CSn = 0; + break; + case 3: + Class = 1; + CSn = 1; + break; + default: + break; + } + + /* see information on bits 'c' [p 10 : A.2.1 general, ISO/IEC FCD 15444-9] */ + if (((elmt >> 3) & 0x01) == 1) + header->last_byte = 1; + + /* In-class identifier */ + header->Id |= (elmt & 0x0f); + if ((elmt >> 7) == 1) + header->Id = jpt_read_VBAS_info(header->Id); + + /* ------------ */ + /* VBAS : Class */ + /* ------------ */ + if (Class == 1) { + header->Class_Id = 0; + header->Class_Id = jpt_read_VBAS_info(header->Class_Id); + } + + /* ---------- */ + /* VBAS : CSn */ + /* ---------- */ + if (CSn == 1) { + header->CSn_Id = 0; + header->CSn_Id = jpt_read_VBAS_info(header->CSn_Id); + } + + /* ----------------- */ + /* VBAS : Msg_offset */ + /* ----------------- */ + header->Msg_offset = jpt_read_VBAS_info(header->Msg_offset); + + /* ----------------- */ + /* VBAS : Msg_length */ + /* ----------------- */ + header->Msg_length = jpt_read_VBAS_info(header->Msg_length); + + /* ---------- */ + /* VBAS : Aux */ + /* ---------- */ + if (header->CSn_Id == 1) { + header->Layer_nb = 0; + header->Layer_nb = jpt_read_VBAS_info(header->Layer_nb); + } +} diff --git a/jpwl/decoder/libopenjpeg/jpt.h b/jpwl/decoder/libopenjpeg/jpt.h new file mode 100644 index 00000000..ea784e0e --- /dev/null +++ b/jpwl/decoder/libopenjpeg/jpt.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2004, Yannick Verschueren + * Copyright (c) 2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Message Header JPT_stream Structure + * + */ +typedef struct { + unsigned int Id; /* In-class Identifier */ + unsigned int last_byte; /* Last byte information */ + unsigned int Class_Id; /* Class Identifier */ + unsigned int CSn_Id; /* CSn : index identifier */ + unsigned int Msg_offset; /* Message offset */ + unsigned int Msg_length; /* Message length */ + unsigned int Layer_nb; /* Auxiliary for JPP case */ +} jpt_msg_header_struct_t; + +/* + * Initialize the value of the message header structure + * + * header : Message header structure + * + */ +void jpt_init_Msg_Header(jpt_msg_header_struct_t * header); + +/* + * Read the message header for a JPP/JPT - stream + * + * header : Message header structure + * + */ +void jpt_read_Msg_Header(jpt_msg_header_struct_t * header); diff --git a/jpwl/decoder/libopenjpeg/jpw.c b/jpwl/decoder/libopenjpeg/jpw.c new file mode 100644 index 00000000..6f46c796 --- /dev/null +++ b/jpwl/decoder/libopenjpeg/jpw.c @@ -0,0 +1,3532 @@ +// In questa versione si aggiunge la funzione che inserisce il marker RED + +// Per ora si suppone che venga aggiunto un solo RED, nel main header, e che sia +// utilizzata la modalità byte-range mode. Osserviamo che ci sono problemi realizzativi +// per l'utilizzo delle modalità a pacchetto (non ci sono pacchetti negli header!). +// Decidiamo di aggiungere il marker RED subito prima di SOT (alla fine di MH!!!). +// Per stare sicuri, come address length utilizziamo 4 bytes (b1=1). + +#include +#include +#include +#include +#include +#include "j2k.h" +#include "cio.h" +#include "jpw.h" + +#define J2K_MS_SOC 0xff4f +#define J2K_MS_SIZ 0xff51 +#define J2K_MS_SOT 0xff90 +#define JPWL_MS_EPC 0xff68 +#define JPWL_MS_EPB 0xff66 +#define JPWL_MS_RED 0xff69 +#define J2K_MS_EOC 0xffd9 + +#define J2K_STATE_MHSOC 0x0001 +#define J2K_STATE_TPHSOT 0x0008 +#define J2K_STATE_MH 0x0004 +#define J2K_STATE_TPH 0x0010 +#define J2K_STATE_MT 0x0020 + +#define mm 8 /* RS code over GF(2**4) - change to suit */ + +int pp [mm+1] = { 1, 0, 1, 1, 1, 0, 0, 0, 1 }; + +int *alpha_to, *index_of, *gg; +int *recd, *data, *bb; + + +static long crcSum; + +static int CrcT16[256] = +{0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, +0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, +0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, +0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, +0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, +0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, +0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, +0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, +0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, +0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, +0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, +0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, +0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, +0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, +0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, +0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, +0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, +0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, +0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, +0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, +0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, +0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, +0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, +0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, +0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, +0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, +0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, +0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, +0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, +0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, +0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, +0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0}; + +static long CrcT32[256] = {0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, +0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, +0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, +0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, +0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, +0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, +0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, +0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd, +0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, +0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, +0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, +0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, +0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, +0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, +0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, +0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, +0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, +0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, +0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, +0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, +0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, +0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, +0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, +0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, +0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, +0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692, +0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, +0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, +0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, +0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, +0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, +0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a, +0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, +0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, +0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, +0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, +0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, +0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b, +0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, +0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, +0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, +0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, +0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, +0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, +0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, +0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, +0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, +0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, +0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, +0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, +0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, +0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, +0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, +0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, +0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, +0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, +0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, +0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, +0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, +0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, +0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, +0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c, +0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, +0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4}; + +typedef struct { + unsigned int id; + unsigned int lid; + unsigned char *pid; +} id_tecn; + +typedef struct { + unsigned int lepc; + unsigned int pcrc; + unsigned long cl; + unsigned char pepc; + id_tecn *tecn; // array di strutture di tipo id_tecn!!! +} EPC_par; + +typedef struct { + unsigned int lepb; + unsigned char depb; + unsigned long ldpepb; + unsigned long pepb; + unsigned int ldata; +} EPB_par; +typedef struct //***********Questa struttura non dovrebbe servire effettivamente!!!! +{ + unsigned int lesd; + unsigned char cesd1; + unsigned int cesd2; + unsigned char pesd; +} ESD_MS; +typedef struct +{ + unsigned int lred; + unsigned char pred; + unsigned char *reddata; +} RED; + + +EPC_par epc; +ESD_MS *esd; +RED red; +int lmex, nbckpar, epbpm, next, startsot; +unsigned long psot; + +unsigned char *cssrc;// Queste variabili servono per la gestione della codestream. +unsigned int cslen; // Se voglio utilizzare le funzioni "cio" per gestire un buffer, +int cspos; // queste variabili consentono di reinizializzare cio per la CS!! +unsigned int csread; // Lunghezza della codestream letta...serve per uscire in caso di errori + +int redpos; // Per la gestione del passaggio delle funzioni "cio" al e dal buffer RED +int decodeflag; // Vale 1 se RS è stato decodificato, 0 altrimenti +unsigned long redlen; // Lunghezza del buffer che contiene REDdata +int redmode; // Se vale 0 allora RED in MH, se vale 1 allora RED in MH e nei vari TPH +int redlenok; // Lunghezza del campo dati della RED che non necessita aggiornamento offset +int nepbrd; // Tiene conto del numero di EPB letti +int lastepb; // Se vale 1 l'EPB corrente è l'ultimo dell'header in questione! + + +// La funzione seguente cerca la presenza nella codestream del marker EPC +// in modo da determinare se si tratta di una codestream JPWL +// Ritorna il numero di EPC presenti nella codestream +int decode_JPWL(unsigned char *src, int len) +{ + unsigned int temp, nepb, j2k_state, pos, nepc, posi, mem, rest; + //int flag; // se 0 vuol dire che ha trovato EPC dopo SIZ, se 1 dopo EPB + int err; // se 1 vuol dire che EPC è corretto, se 0 vuol dire che contiene + // ancora errori! + unsigned long psot, i; + FILE *f,*g; + + + cssrc = src; //*********Aggiunta in questa versione 1.7 + cslen = len; //*********Aggiunta in questa versione 1.7 + redpos = 0; //*********Aggiunta in questa versione 1.7 + redlen = 0; //*********Aggiunta in questa versione 1.7 + redlenok = 0; + redmode = 0; //*********Aggiunta in questa versione 1.7 + // Per default si assume che la RED è scritta solo in MH!!! + + csread = 0; + + f = fopen("output.j2c","wb"); + if (f==NULL) + printf("Unable to open file!\n"); + cio_seek(0); + //printf("CL: %d\n",epc.cl); + for (i=0; i> 8 != 0xff) { + // fprintf(stderr, "%.8x: expected a marker instead of %x\n", + // cio_tell() - 2, temp); + // return 0; + //} + //temp = cio_read(2); // qui dovrebbe leggere la lunghezza di SIZ: Lsiz + //cio_skip(temp-2); + + + j2k_state = 0; // inizializza j2k_state ad un valore indefinito + nepc = 0; // inizializza a zero il numero di EPC finora trovati + nepbrd = 0; + lastepb = 0; + + + //while ((j2k_state != J2K_STATE_MT)&&(csread < cslen)) + while (j2k_state != J2K_STATE_MT) + { + + //nepc = find_EPC(nepc,&j2k_state); + temp = cio_read(2); // qui dovrebbe leggere SIZ o SOT + /*if (temp >> 8 != 0xff) { + fprintf(stderr, "%.8x: expected a marker instead of %x\n", + cio_tell() - 2, temp); + return nepc; + }*/ + //csread+=2; + + posi = cio_tell(); // memorizza la posizione a monte della lunghezza di SIZ o SOT + + //ncomp = 3; // di default si assume che l'immagine abbia 3 componenti!!! + if (temp == J2K_MS_SIZ) // Ha letto SIZ!!! + { + temp = cio_read(2); // legge Lsiz + //csread+=2; + //ncomp = (temp - 38)/3; // calcola il numero di componenti dell'immagine + // nbckpar serve per modificare il numero di blocchi di decodifica per la prima + // parte del primo EPB in base al numero di componenti utilizzate!!! + lmex = temp + 17; // lunghezza dei dati da proteggere; + nbckpar = (int)ceil((double)lmex / 96); // 96 è nn-kk per il primo EPB + // temp=Lsiz, 17 tiene conto di EPB,SIZ,SOC + + } + else // sta leggendo SOT oppure sta leggendo SIZ ma ci sono errori nel marker SIZ!!! + { // ...in tal caso il decoder assume che l'immagine sia composta da 3 componenti + nbckpar = 1; + temp = cio_read(2); // qui dovrebbe leggere la lunghezza di SIZ o SOT + } + cio_skip(temp-2); + //csread += (temp - 2); + + + + temp = cio_read(2); // qui dovrebbe leggere EPC o EPB, se ci sono + //if (temp >> 8 != 0xff) { + // fprintf(stderr, "%.8x: expected a marker instead of %x\n", + // cio_tell() - 2, temp); + // return nepc; + //} + //csread += 2; + if (temp != JPWL_MS_EPC) + { + temp = cio_read(2); // qui dovrebbe leggere la lunghezza di EPB, se c'è: Lepb + cio_skip(temp-2); + temp = cio_read(2); // qui dovrebbe leggere EPC, se c'è!! + //if (temp >> 8 != 0xff) { + //fprintf(stderr, "%.8x: expected a marker instead of %x\n", + // cio_tell() - 2, temp); + //return nepc; + //} + //csread += temp + 2; + + pos = cio_tell(); + + if ((temp != JPWL_MS_EPC)&&(nepc == 0)) + { + cio_seek(0); + /*return nepc; */ // non ha trovato EPC => vede la codestream come NON JPWL + _exit(-1); + } + + if ((temp != JPWL_MS_EPC)&&(nepc != 0)) //vuol dire che il TPH in questione non ha EPC + { + cio_seek(posi); // siamo a monte della lunghezza di SOT + cio_skip(4); + psot = cio_read(4); + if (psot == 0) // vuol dire che siamo nell'ultimo TPH + j2k_state = J2K_STATE_MT; // cosi' al passo seguente si esce dal ciclo + cio_seek(posi-2); + cio_skip(psot); // si pone a valle dei dati del tile corrente + if (cio_read(2) == J2K_MS_EOC) + j2k_state = J2K_STATE_MT; + cio_skip(-2); // si pone a valle dei dati del tile corrente + //csread += (psot - pos); + //return nepc; + + } + if (temp == JPWL_MS_EPC) // ha trovato l'EPC non subito dopo SIZ, quindi c'è EPB! + { + if (nepc == 0) + { + j2k_state = J2K_STATE_MHSOC; + cio_seek(posi-4); // si posiziona a monte di SOC + next = cio_tell(); // assegna a next = 0!!!! + } + if (nepc != 0) + { + j2k_state = J2K_STATE_TPHSOT; + cio_seek(posi-2); // si posiziona a monte di SOT + next = cio_tell(); + } + //printf("next: %x\n",next); + red.reddata = (char *) malloc(len * sizeof(char));// Allochiamo lo spazio necessario per RED + // Scegliamo len per "stare larghi" + + // ********Cio' che segue è un'aggiunta in jpwldec1.9!!!!********** + mem = next; + i = 0; + if (!(rest = read_EPB_2(&j2k_state)))// legge il primo EPB(della CS o del tile,caso + EPC!) + return nepc; + i += rest; + temp = cio_tell(); // Memorizza posizione a valle di EPB + cio_seek(pos); // si posiziona a valle del marker EPC + err = read_EPC(); // Legge il primo EPC, o comunque il primo EPC di un tile + //if (err == 1) + // printf("CRC EPC corretto!\n"); + //else + // printf("CRC EPC errato!\n"); + nepc++; // nel caso di più EPC usati nella codestream + nepb = epc.tecn[0].lid / 4; // calcola il numero di EPB presenti + //printf("nepb: %d\n",nepb); + /*********************************************************************** + Qui dovrà essere aggiunta la porzione di codice per la gestione + della scrittura della RED anche nei tile! + *************************************************************************/ + + //while ((i> 8 != 0xff) { + // fprintf(stderr, "%.8x: expected a marker instead of %x\n", + // cio_tell() - 2, temp); + // return nepc; + //} + + //while ((temp != J2K_MS_SOT)&&(csread < cslen)) + while (temp != J2K_MS_SOT) + { + cio_skip(cio_read(2)-2); + temp = cio_read(2); + //if (temp >> 8 != 0xff) { + //fprintf(stderr, "%.8x: expected a marker instead of %x\n", + // cio_tell() - 2, temp); + //return nepc; + //} + //csread += 2; + } + cio_skip(-2); + } + j2k_state = J2K_STATE_TPHSOT; + if (j2k_state == J2K_STATE_TPHSOT) + { + cio_seek(temp); // Si posiziona all'inizio di SOT + pos = cio_tell(); + //printf("pos: %x\n",pos); + //system("pause"); + do + { + if (!(rest = read_EPB_2(&j2k_state))) + return nepc; + i += rest; + //printf("state: %x\n",j2k_state); + } + while (lastepb == 0); + //printf("ciao!\n"); + //while ((lastepb == 0)&&(csread < cslen)); + //printf("state: %x\n",j2k_state); + //system("pause"); + } + temp = cio_read(2); + //printf("mrk: %x\n",temp); + //system("pause"); + //if (temp >> 8 != 0xff) { + //fprintf(stderr, "%.8x: expected a marker instead of %x\n", + // cio_tell() - 2, temp); + //return nepc; + //} + //csread += 2; + if (temp != J2K_MS_EOC) + { + if ((j2k_state == J2K_STATE_TPH)||(temp != J2K_MS_SOT)) + { + cio_seek(pos); + cio_skip(6); + psot = cio_read(4); + cio_seek(pos); + cio_skip(psot); + temp = cio_read(2); + if (temp == J2K_MS_EOC) + j2k_state = J2K_STATE_MT; + else + { + j2k_state = J2K_STATE_TPHSOT; + cio_skip(-2); + temp = cio_tell(); + } + + } + if (temp == J2K_MS_SOT) + { + cio_skip(-2); + temp = cio_tell(); + j2k_state = J2K_STATE_TPHSOT; + } + } + } + // Ora sono stati letti tutti gli EPB associati all'ultimo EPC letto + //printf("temp: %x\n",temp); + + //while ((temp != J2K_MS_EOC)&&(csread < cslen)) + //while (temp != J2K_MS_EOC) + //{ + // cio_seek(pos); + // cio_skip(6); + // psot = cio_read(4); + // cio_seek(pos); + // cio_skip(psot); + // temp = cio_read(2); + // //if (temp >> 8 != 0xff) { + // //fprintf(stderr, "%.8x: expected a marker instead of %x\n", + // // cio_tell() - 2, temp); + // //return nepc; + // //} + // //csread += 2; + //} + //cio_skip(-2); // A questo punto siamo all'inizio di EOC + //j2k_state = J2K_STATE_MT; + + } + } + else // ho trovato EPC dopo SIZ o SOT + { + err = read_EPC(); + //if (err == 1) + // printf("CRC EPC corretto!\n"); + //else + // printf("CRC EPC errato!\n"); + if (nepc == 0) + { + cio_seek(posi); // siamo a monte della lunghezza di SIZ + cio_skip(cio_read(2)-2); // si pone a valle di SIZ + temp = cio_read(2); // legge il marker successivo + //if (temp >> 8 != 0xff) { + // fprintf(stderr, "%.8x: expected a marker instead of %x\n", + // cio_tell() - 2, temp); + // return nepc; + //} + + //while ((temp != J2K_MS_SOT)&&(csread < cslen)) + while (temp != J2K_MS_SOT) + { + cio_skip(cio_read(2)-2); // si pone a valle del MS corrente + temp = cio_read(2); // legge il marker successivo + //if (temp >> 8 != 0xff) { + //fprintf(stderr, "%.8x: expected a marker instead of %x\n", + // cio_tell() - 2, temp); + //return nepc; + //} + //csread += 2; + //printf("MS: %x\n",temp); + } + cio_skip(-2); // si posiziona a valle del main header + } + if (nepc != 0) + { + cio_seek(posi); // siamo a monte della lunghezza di SOT + cio_skip(4); + psot = cio_read(4); + if (psot == 0) // vuol dire che siamo nell'ultimo TPH + j2k_state = J2K_STATE_MT; // cosi' al passo seguente si esce dal cilclo + cio_seek(posi-2); + cio_skip(psot); // si pone a valle dei dati del tile corrente + temp = cio_read(2); + if (temp == J2K_MS_EOC) + { + j2k_state = J2K_STATE_MT; + } + cio_skip(-2); // si pone a valle dei dati del tile corrente + } + //j2k_state = J2K_STATE_MT; + nepc++; + } + } // fine while (j2k_state != J2K_STATE_MT)!! + + //printf("Eccomi!\n"); + //f = fopen("output","wb"); + //if (f==NULL) + // printf("Unable to open file!\n"); + //cio_seek(0); + //printf("CL: %d\n",epc.cl); + //for (i=0; i> 8 != 0xff) { + // fprintf(stderr, "%.8x: expected a marker instead of %x\n", + // cio_tell() - 2, temp); + // return nepc; + //} + cio_skip(-2); + } + //cio_skip(-2); + //printf("sdfpo: %x\n",cio_read(2)); + // A questo punto ci troviamo a valle dell'ultimo marker del MH + // Dobbiamo inserire il marker RED!!! + insert_RED(cio_tell(),red.lred+2,redlenok); + g = fopen("output.j2c","wb"); + if (g==NULL) + printf("Unable to open file!\n"); + cio_seek(0); + for (i=0; i<(epc.cl+redlen+5); i++) + fputc(cio_read(1),g); + fclose(g); + _exit(-1); + cslen = epc.cl + redlen + 5; + //free(red.reddata); + } + else + { + f = fopen("output.j2c","wb"); + if (f==NULL) + printf("Unable to open file!\n"); + cio_seek(0); + //printf("CL: %d\n",epc.cl); + for (i=0; i>4)&1) // E' presente una o più ESD !!! + { + esd = (ESD_MS *) malloc(10 * sizeof(ESD_MS)); // ******Si puo' togliere!!!!! + //printf("La codestream contiene il marker ESD!\n"); + } + ltec = epc.lepc - 9; // lunghezza dell'EPC a partire dalla fine di pepc + count = 0; + nid = 0; // numero di tecniche id usate + while (count> 6)&1)) // quello corrente non è l'ultimo EPB del tile corrente + lastepb = 0; + if ((depb >> 6)&1) // quello corrente è l'ultimo EPB del tile corrente + lastepb = 1; + //printf("lastepb: %d\n",lastepb); + //printf("pack: %d\n",(depb >> 7)&1); + if (!((depb >> 7)&1)) // EPB in modalità unpacked + { + //printf("Unpacked\n"); + //system("pause"); + if ((!((depb >> 6)&1))&&((*j2k_state == J2K_STATE_MHSOC)||(*j2k_state == J2K_STATE_MH))) + *j2k_state = J2K_STATE_MH; // vuol dire che il prossimo EPB è in MH ma non è il primo + //if (((depb >> 6)&1)&&((*j2k_state == J2K_STATE_MH)||(*j2k_state == J2K_STATE_MHSOC))) + // *j2k_state = J2K_STATE_TPHSOT; // vuol dire che il prossimo EPB è il primo di un TPH + //if (((depb >> 6)&1)&&((*j2k_state == J2K_STATE_TPH)||(*j2k_state == J2K_STATE_TPHSOT))) + // *j2k_state = J2K_STATE_TPHSOT; // vuol dire che il prossimo EPB è il primo di un TPH + if ((!((depb >> 6)&1))&&((*j2k_state == J2K_STATE_TPHSOT)||(*j2k_state == J2K_STATE_TPH))) + *j2k_state = J2K_STATE_TPH; // vuol dire che il prossimo EPB è relativo ad un TPH + + nepbrd++; + // Ora leggendo pepb il decoder deve capire quale codice applicare per la porzione di dati + // cui fa riferimento la seconda parte del campo EPBdata + + if (pepb) // se pepb=0 allora si usano i codici di default precedenti + { + if ((pepb>>28)==2) + { + // in questo caso deve effettuare la decodifica RS + /***********/ + // liberiamo gli spazi allocati + free(alpha_to); + free(index_of); + free(gg); + free(recd); + free(data); + free(bb); + /***********/ + kk = (int) pepb & 0x000000ff; + nn = (int) (pepb>>8) & 0x000000ff; + tt = (int) ceil((double)(nn-kk)/2); + nn1 = 255; kk1 = kk + (nn1 - nn); + alpha_to = (int *) malloc((nn1+1)*sizeof(int)); + index_of = (int *) malloc((nn1+1)*sizeof(int)); + gg = (int *) malloc((nn1-kk1+1)*sizeof(int)); + recd = (int *) malloc((nn1)*sizeof(int)); ///forse alcune di queste malloc possono + data = (int *) malloc((kk1)*sizeof(int)); // essere eliminate, inutili per decodifica!!! + bb = (int *) malloc((nn1-kk1)*sizeof(int)); + generate_gf(nn1,kk1) ; + gen_poly(nn1,kk1) ; + } + + if ((pepb>>28)==1) + { + // in questo caso deve effettuare le decodifica CRC + free(buff); + buff = (char *) malloc(ldpepb * sizeof(char)); + write_buff(buff,posdata2+ldata,ldpepb); + if (pepb & 0x00000001) // vuol dire che bisogna decodificare secondo CRC 32 + { + /*per fare il crc32 occorre invertire i byte in ingresso, invertire il crc calcolato + e farne il complemento a 1*/ + ResetCRC(); + for (i=0; i < ldpepb; i++) + UpdateCRC32(reflectByte(buff[i])); + reflectCRC32(); + crcSum ^= 0xffffffff; // effettua il complemento a 1 + cio_seek(posdata2); + datacrc = cio_read(4); + //printf("CRCSUM: %x\n",crcSum); + //if (datacrc == crcSum) + // printf("CRC corretto!\n"); + //else + // printf("CRC errato!\n"); + } + else // vuol dire che bisogna decodificare secondo CRC 16 + { + ResetCRC(); + for (i=0; i < ldpepb; i++) + UpdateCRC16(buff[i]); + cio_seek(posdata2); + datacrc = cio_read(2); + //printf("CRCSUM: %x\n",crcSum); + //if (datacrc == crcSum) + // printf("CRC corretto!\n"); + //else + // printf("CRC errato!\n"); + } + free(buff); + cio_seek(posdata2 + ldata + ldpepb); + next = cio_tell(); + //printf("read: %x\n",cio_read(2)); + //cio_skip(-2); + + temp = cio_read(2); + if (temp == J2K_MS_SOT) + *j2k_state = J2K_STATE_TPHSOT; + if (temp == J2K_MS_EOC) + *j2k_state = J2K_STATE_MT; + cio_skip(-2); + //printf("state: %x\n",*j2k_state); + + return 1; + //return (posdata2 + ldata + ldpepb); // ritorna la posizione a valle dei dati successivi a EPB + //return; + } + + if (pepb>=0x30000000) + { + // tecniche registrate in RA + cio_seek(posdata2); + return 1; + //return (posdata2 + ldata + ldpepb); + // Per adesso prevede la semplice uscita dalla funzione + } + + if (pepb==0xffffffff) + { + // non sono usati metodi per i dati seguenti + cio_seek(posdata2); + return 1; + //return (posdata2 + ldata + ldpepb); + //return; + } + }// Fine if (pepb) + + + + /*******************/ + // qui bisogna aggiungere la parte per la gestione della modalità packed/unpacked + /*******************/ + + + //cio_seek(posdata + (nn-kk)); + //posdata2 = cio_tell(); // posizione inizio seconda parte dati EPB + + /********************/ + // Per adesso si suppone che il primo EPB di un header utilizza lo stesso codice + // di default anche per la seconda parte dei dati...in seguito bisognerà aggiungere + // la funzionalità che gestisce l'uso dei vari codici in base al campo pepb + /********************/ + + // Ora bisogna copiare in buff la seconda parte dei dati di EPB e i dati successivi all'epb + // per una lunghezza pari a ldpepb + + nblock = ldata / (nn-kk); // numero di "blocchi di decodifica" + //printf("nblock = %d\n",nblock); + //*system("pause"); + //cio_seek(posdata2); // si posiziona all'inizio della seconda parte dei dati EPB + free(buff); + buff = (char *) malloc(nn1 * sizeof(char)); + for (i=0; i> 6)&1) // quello corrente è l'ultimo EPB del tile corrente + //{ + // lastepb = 1; // l'epb corrente è l'ultimo del tile + //nepbpm = ((depb << 2) >> 2); // numero di EPB accorpati in modalità packed + // nepbpm = (depb & 0x3f); // numero di EPB accorpati in modalità packed + //printf("nepbpm: %d\n",nepbpm); + //} + if (!((depb >> 6)&1)) // quello corrente non è l'ultimo EPB del tile corrente + nepbpm += 1; + if ((depb >> 6)&1) // quello corrente è l'ultimo EPB del tile corrente + { + nepbpm += 1; + lastepb = 1; + } + + //printf("nepbpm: %d\n",nepbpm); + //printf("lastepb: %d\n",lastepb); + //system("pause"); + + cio_skip(-3); // si posiziona all'inizio del campo lepb + cio_skip(cio_read(2)-2); // si posiziona a valle dell'epb corrente + pos = cio_tell(); // memorizza la posizione all'inizio dell'EPB successivo + //printf("pos: %x\n",pos); + //printf("mrk: %x\n",cio_read(2)); + //cio_skip(-2); + //system("pause"); + cio_skip(2); + + //conta++; + + //csread += lepb; + + } // Fine while (lastepb == 0)!!!! + // A questo punto il decoder ha decodificato le porzioni iniziali di tutti gli EPB + // del tile corrente + + + // Ora dobbiamo decodificare le porzioni finali di tutti gli EPB!!! + + // pos contiene la posizione a valle dell'ultimo degli EPB packed!!! + cio_skip(-2); + posend = cio_tell(); + //printf("posend: %x\n",posend); + //system("pause"); + lpack = posend-posfirst; // lunghezza totale della catena di EPB + epb = (EPB_par *) malloc(nepbpm * sizeof(EPB_par)); + cio_seek(posfirst); + //printf("posfirst: %x\n",posfirst); + + //printf("nepbpm: %d\n",nepbpm); + for (count=0; count> 6)&1))&&((*j2k_state == J2K_STATE_MHSOC)||(*j2k_state == J2K_STATE_MH))) + // *j2k_state = J2K_STATE_MH; // vuol dire che il prossimo EPB è in MH ma non è il primo + //if (((epb[count].depb >> 6)&1)&&((*j2k_state == J2K_STATE_MH)||(*j2k_state == J2K_STATE_MHSOC))) + // *j2k_state = J2K_STATE_TPHSOT; // vuol dire che il prossimo EPB è il primo di un TPH + //if (((epb[count].depb >> 6)&1)&&((*j2k_state == J2K_STATE_TPH)||(*j2k_state == J2K_STATE_TPHSOT))) + // *j2k_state = J2K_STATE_TPHSOT; // vuol dire che il prossimo EPB è il primo di un TPH + //if ((!((epb[count].depb >> 6)&1))&&((*j2k_state == J2K_STATE_TPHSOT)||(*j2k_state == J2K_STATE_TPH))) + // *j2k_state = J2K_STATE_TPH; // vuol dire che il prossimo EPB è relativo ad un TPH + + // Ora leggendo pepb il decoder deve capire quale codice applicare per la porzione di dati + // cui fa riferimento la seconda parte del campo EPBdata + + if (epb[count].pepb) // se pepb=0 allora si usano i codici di default precedenti + { + if ((epb[count].pepb>>28)==2) + { + // in questo caso deve effettuare la decodifica RS + /***********/ + // liberiamo gli spazi allocati + free(alpha_to); + free(index_of); + free(gg); + free(recd); + free(data); + free(bb); + /***********/ + kk = (int) epb[count].pepb & 0x000000ff; + nn = (int) (epb[count].pepb>>8) & 0x000000ff; + tt = (int) ceil((double)(nn-kk)/2); + nn1 = 255; kk1 = kk + (nn1 - nn); + alpha_to = (int *) malloc((nn1+1)*sizeof(int)); + index_of = (int *) malloc((nn1+1)*sizeof(int)); + gg = (int *) malloc((nn1-kk1+1)*sizeof(int)); + recd = (int *) malloc((nn1)*sizeof(int)); ///forse alcune di queste malloc possono + data = (int *) malloc((kk1)*sizeof(int)); // essere eliminate, inutili per decodifica!!! + bb = (int *) malloc((nn1-kk1)*sizeof(int)); + generate_gf(nn1,kk1) ; + gen_poly(nn1,kk1) ; + } + + if ((epb[count].pepb>>28)==1) + { + // in questo caso deve effettuare le decodifica CRC + free(buff); + buff = (char *) malloc(epb[count].ldpepb * sizeof(char)); + write_buff(buff,posdata2+epb[count].ldata,epb[count].ldpepb);//***Correggi!!!!!!!!!!! + if (epb[count].pepb & 0x00000001) // vuol dire che bisogna decodificare secondo CRC 32 + { + /*per fare il crc32 occorre invertire i byte in ingresso, invertire il crc calcolato + e farne il complemento a 1*/ + ResetCRC(); + cio_seek(posend+ldpread); // si posiziona nel blocco dati corrispondente + for (i=0; i < epb[count].ldpepb; i++) + UpdateCRC32(reflectByte(buff[i])); + reflectCRC32(); + if (lastepb==1) + { + cio_seek(startsot); + cio_skip(6); + psot = cio_read(4); + next = startsot + psot; // **************Da correggere!!!! + cio_seek(next); + //printf("%x\n",cio_read(2)); + //cio_skip(-2); + } + if ((cio_read(2) == 0xffd9)||(psot == 0)) + *j2k_state = J2K_STATE_MT; + cio_skip(-2); + //else + //{ + // next = cio_tell(); // posizione alla fine dei dati protetti (ldpepb) + //} + crcSum ^= 0xffffffff; // effettua il complemento a 1 + cio_seek(posdata2); + datacrc = cio_read(4); + //if (datacrc == crcSum) + // printf("CRC corretto!\n"); + //else + // printf("CRC errato!\n"); + + } + else // vuol dire che bisogna decodificare secondo CRC 16 + { + ResetCRC(); + cio_seek(posend+ldpread); // si posiziona nel blocco dati corrispondente + for (i=0; i < epb[count].ldpepb; i++) + UpdateCRC16(buff[i]); + if (lastepb==1) + { + cio_seek(startsot); + cio_skip(6); + psot = cio_read(4); + next = startsot + psot; + cio_seek(next); + } + if ((cio_read(2) == 0xffd9)||(psot == 0)) + *j2k_state = J2K_STATE_MT; + cio_skip(-2); + cio_seek(posdata2); + datacrc = cio_read(2); + //if (datacrc == crcSum) + // printf("CRC corretto!\n"); + //else + // printf("CRC errato!\n"); + } + //free(buff); + } + + if (epb[count].pepb>=0x30000000) + { + next = cio_tell(); + // tecniche registrate in RA + } + + if (epb[count].pepb==0xffffffff) + { + next = cio_tell(); + // non sono usati metodi per i dati seguenti + } + } + + if (((epb[count].pepb>>28)==2)||(epb[count].pepb==0)) // Vuol dire che si usano codici RS + { + // Ora bisogna copiare in buff la seconda parte dei dati di EPB e i dati successivi all'epb + // per una lunghezza pari a ldpepb + + //printf("count: %d\n",count); + //printf("ldpread: %d\n",ldpread); + //system("pause"); + //printf("nn: %d\n",nn); + //printf("kk: %d\n",kk); + //system("pause"); + //printf("posiz: %x\n",posdata2 + epb[count].ldata); + nblock = epb[count].ldata / (nn-kk); // numero di "blocchi di decodifica" + //printf("nblock: %d\n",nblock); + free(buff); + buff = (char *) malloc(nn1 * sizeof(char)); + cio_seek(startsot); + cio_skip(6); + psot = cio_read(4); + //printf("ldata: %d\n",epb[count].ldata); + //printf("nblock: %d\n",nblock); + for (i=0; ipepb)) + + // A questo punto abbiamo corretto anche la parte di dati cui fa riferimento la seconda + // parte del campo EPBdata + + ldpread += epb[count].ldpepb; + cio_seek(pos+2); + cio_skip(epb[count].lepb); + pos = cio_tell(); // posizione a valle dell'EPB corrente + + } // fine for (count=0; count> 6)&1))&&((*j2k_state == J2K_STATE_MHSOC)||(*j2k_state == J2K_STATE_MH))) + *j2k_state = J2K_STATE_MH; // vuol dire che il prossimo EPB è in MH ma non è il primo + if (((depb >> 6)&1)&&((*j2k_state == J2K_STATE_MH)||(*j2k_state == J2K_STATE_MHSOC))) + *j2k_state = J2K_STATE_TPHSOT; // vuol dire che il prossimo EPB è il primo di un TPH + if (((depb >> 6)&1)&&((*j2k_state == J2K_STATE_TPH)||(*j2k_state == J2K_STATE_TPHSOT))) + *j2k_state = J2K_STATE_TPHSOT; // vuol dire che il prossimo EPB è il primo di un TPH + if ((!((depb >> 6)&1))&&((*j2k_state == J2K_STATE_TPHSOT)||(*j2k_state == J2K_STATE_TPH))) + *j2k_state = J2K_STATE_TPH; // vuol dire che il prossimo EPB è relativo ad un TPH + + if (!((depb >> 7)&1)) + epbpm = 1; // Gli EPB sono scritti in modalità unpacked (epbpm=0) + else + epbpm = 0; // Gli EPB sono scritti in modalità packed (epbpm=1) + + + nepbrd++; + + // Ora leggendo pepb il decoder deve capire quale codice applicare per la porzione di dati + // cui fa riferimento la seconda parte del campo EPBdata + + if (pepb) // se pepb=0 allora si usano i codici di default precedenti + { + if ((pepb>>28)==2) + { + // in questo caso deve effettuare la decodifica RS + /***********/ + // liberiamo gli spazi allocati + free(alpha_to); + free(index_of); + free(gg); + free(recd); + free(data); + free(bb); + /***********/ + kk = (int) pepb & 0x000000ff; + nn = (int) (pepb>>8) & 0x000000ff; + tt = (int) ceil((double)(nn-kk)/2); + nn1 = 255; kk1 = kk + (nn1 - nn); + alpha_to = (int *) malloc((nn1+1)*sizeof(int)); + index_of = (int *) malloc((nn1+1)*sizeof(int)); + gg = (int *) malloc((nn1-kk1+1)*sizeof(int)); + recd = (int *) malloc((nn1)*sizeof(int)); ///forse alcune di queste malloc possono + data = (int *) malloc((kk1)*sizeof(int)); // essere eliminate, inutili per decodifica!!! + bb = (int *) malloc((nn1-kk1)*sizeof(int)); + generate_gf(nn1,kk1) ; + gen_poly(nn1,kk1) ; + } + + if ((pepb>>28)==1) + { + // in questo caso deve effettuare le decodifica CRC + free(buff); + buff = (char *) malloc(ldpepb * sizeof(char)); + write_buff(buff,posdata2+ldata,ldpepb); + if (pepb & 0x00000001) // vuol dire che bisogna decodificare secondo CRC 32 + { + /*per fare il crc32 occorre invertire i byte in ingresso, invertire il crc calcolato + e farne il complemento a 1*/ + ResetCRC(); + for (i=0; i < ldpepb; i++) + UpdateCRC32(reflectByte(buff[i])); + reflectCRC32(); + crcSum ^= 0xffffffff; // effettua il complemento a 1 + cio_seek(posdata2); + datacrc = cio_read(4); + if (datacrc == crcSum) + printf("CRC corretto!\n"); + else + printf("CRC errato!\n"); + } + else // vuol dire che bisogna decodificare secondo CRC 16 + { + ResetCRC(); + for (i=0; i < ldpepb; i++) + UpdateCRC16(buff[i]); + cio_seek(posdata2); + datacrc = cio_read(2); + if (datacrc == crcSum) + printf("CRC corretto!\n"); + else + printf("CRC errato!\n"); + } + free(buff); + return (posdata2 + ldata + ldpepb); // ritorna la posizione a valle dei dati successivi a EPB + //return; + } + + if (pepb>=0x30000000) + { + // tecniche registrate in RA + return (posdata2 + ldata + ldpepb); + // Per adesso prevede la semplice uscita dalla funzione + } + + if (pepb==0xffffffff) + { + // non sono usati metodi per i dati seguenti + return (posdata2 + ldata + ldpepb); + //return; + } + } + + + + /*******************/ + // qui bisogna aggiungere la parte per la gestione della modalità packed/unpacked + /*******************/ + + + //cio_seek(posdata + (nn-kk)); + //posdata2 = cio_tell(); // posizione inizio seconda parte dati EPB + + /********************/ + // Per adesso si suppone che il primo EPB di un header utilizza lo stesso codice + // di default anche per la seconda parte dei dati...in seguito bisognerà aggiungere + // la funzionalità che gestisce l'uso dei vari codici in base al campo pepb + /********************/ + + // Ora bisogna copiare in buff la seconda parte dei dati di EPB e i dati successivi all'epb + // per una lunghezza pari a ldpepb + + nblock = ldata / (nn-kk); // numero di "blocchi di decodifica" + //printf("nblock = %d\n",nblock); + //*system("pause"); + //cio_seek(posdata2); // si posiziona all'inizio della seconda parte dei dati EPB + free(buff); + buff = (char *) malloc(nn1 * sizeof(char)); + for (i=0; i> 6)&1) // quello corrente è l'ultimo EPB del tile corrente + //{ + // lastepb = 1; // l'epb corrente è l'ultimo del tile + //nepbpm = ((depb << 2) >> 2); // numero di EPB accorpati in modalità packed + // nepbpm = (depb & 0x3f); // numero di EPB accorpati in modalità packed + //printf("nepbpm: %d\n",nepbpm); + //} + if (!((depb >> 6)&1)) // quello corrente non è l'ultimo EPB del tile corrente + nepbpm += 1; + if ((depb >> 6)&1) // quello corrente è l'ultimo EPB del tile corrente + { + nepbpm += 1; + lastepb = 1; + } + + cio_skip(-3); // si posiziona all'inizio del campo lepb + cio_skip(cio_read(2)-2); // si posiziona a valle dell'epb corrente + pos = cio_tell(); // memorizza la posizione all'inizio dell'EPB successivo + cio_skip(2); + + //conta++; + + } // Fine while (lastepb == 0)!!!! + // A questo punto il decoder ha decodificato le porzioni iniziali di tutti gli EPB + // del tile corrente + + + // Ora dobbiamo decodificare le porzioni finali di tutti gli EPB!!! + + // pos contiene la posizione a valle dell'ultimo degli EPB packed!!! + cio_skip(-2); + posend = cio_tell(); + lpack = posend-posfirst; // lunghezza totale della catena di EPB + epb = (EPB_par *) malloc(nepbpm * sizeof(EPB_par)); + cio_seek(posfirst); + //printf("nepbpm: %d\n",nepbpm); + for (count=0; count> 6)&1))&&((*j2k_state == J2K_STATE_MHSOC)||(*j2k_state == J2K_STATE_MH))) + *j2k_state = J2K_STATE_MH; // vuol dire che il prossimo EPB è in MH ma non è il primo + if (((epb[count].depb >> 6)&1)&&((*j2k_state == J2K_STATE_MH)||(*j2k_state == J2K_STATE_MHSOC))) + *j2k_state = J2K_STATE_TPHSOT; // vuol dire che il prossimo EPB è il primo di un TPH + if (((epb[count].depb >> 6)&1)&&((*j2k_state == J2K_STATE_TPH)||(*j2k_state == J2K_STATE_TPHSOT))) + *j2k_state = J2K_STATE_TPHSOT; // vuol dire che il prossimo EPB è il primo di un TPH + if ((!((epb[count].depb >> 6)&1))&&((*j2k_state == J2K_STATE_TPHSOT)||(*j2k_state == J2K_STATE_TPH))) + *j2k_state = J2K_STATE_TPH; // vuol dire che il prossimo EPB è relativo ad un TPH + + // Ora leggendo pepb il decoder deve capire quale codice applicare per la porzione di dati + // cui fa riferimento la seconda parte del campo EPBdata + + if (epb[count].pepb) // se pepb=0 allora si usano i codici di default precedenti + { + if ((epb[count].pepb>>28)==2) + { + // in questo caso deve effettuare la decodifica RS + /***********/ + // liberiamo gli spazi allocati + free(alpha_to); + free(index_of); + free(gg); + free(recd); + free(data); + free(bb); + /***********/ + kk = (int) epb[count].pepb & 0x000000ff; + nn = (int) (epb[count].pepb>>8) & 0x000000ff; + tt = (int) ceil((double)(nn-kk)/2); + nn1 = 255; kk1 = kk + (nn1 - nn); + alpha_to = (int *) malloc((nn1+1)*sizeof(int)); + index_of = (int *) malloc((nn1+1)*sizeof(int)); + gg = (int *) malloc((nn1-kk1+1)*sizeof(int)); + recd = (int *) malloc((nn1)*sizeof(int)); ///forse alcune di queste malloc possono + data = (int *) malloc((kk1)*sizeof(int)); // essere eliminate, inutili per decodifica!!! + bb = (int *) malloc((nn1-kk1)*sizeof(int)); + generate_gf(nn1,kk1) ; + gen_poly(nn1,kk1) ; + } + + if ((epb[count].pepb>>28)==1) + { + // in questo caso deve effettuare le decodifica CRC + free(buff); + buff = (char *) malloc(epb[count].ldpepb * sizeof(char)); + write_buff(buff,posdata2+epb[count].ldata,epb[count].ldpepb); + if (epb[count].pepb & 0x00000001) // vuol dire che bisogna decodificare secondo CRC 32 + { + /*per fare il crc32 occorre invertire i byte in ingresso, invertire il crc calcolato + e farne il complemento a 1*/ + ResetCRC(); + cio_seek(posend+ldpread); // si posiziona nel blocco dati corrispondente + for (i=0; i < epb[count].ldpepb; i++) + UpdateCRC32(reflectByte(buff[i])); + reflectCRC32(); + if (lastepb==1) + { + next = startsot + psot; + cio_seek(next); + //printf("%x\n",cio_read(2)); + //cio_skip(-2); + } + if ((cio_read(2) == 0xffd9)||(psot == 0)) + *j2k_state = J2K_STATE_MT; + cio_skip(-2); + //else + //{ + // next = cio_tell(); // posizione alla fine dei dati protetti (ldpepb) + //} + crcSum ^= 0xffffffff; // effettua il complemento a 1 + cio_seek(posdata2); + datacrc = cio_read(4); + if (datacrc == crcSum) + printf("CRC corretto!\n"); + else + printf("CRC errato!\n"); + + } + else // vuol dire che bisogna decodificare secondo CRC 16 + { + ResetCRC(); + cio_seek(posend+ldpread); // si posiziona nel blocco dati corrispondente + for (i=0; i < epb[count].ldpepb; i++) + UpdateCRC16(buff[i]); + if (lastepb==1) + { + next = startsot + psot; + cio_seek(next); + } + if ((cio_read(2) == 0xffd9)||(psot == 0)) + *j2k_state = J2K_STATE_MT; + cio_skip(-2); + cio_seek(posdata2); + datacrc = cio_read(2); + if (datacrc == crcSum) + printf("CRC corretto!\n"); + else + printf("CRC errato!\n"); + } + //free(buff); + } + + if (epb[count].pepb>=0x30000000) + { + //if (lastepb==1) + // next = startsot + psot; + // tecniche registrate in RA + } + + if (epb[count].pepb==0xffffffff) + { + //if (lastepb==1) + // next = startsot + psot; + // non sono usati metodi per i dati seguenti + } + } + + if (((epb[count].pepb>>28)==2)||(epb[count].pepb==0)) // Vuol dire che si usano codici RS + { + // Ora bisogna copiare in buff la seconda parte dei dati di EPB e i dati successivi all'epb + // per una lunghezza pari a ldpepb + + //printf("posiz: %x\n",posdata2 + epb[count].ldata); + nblock = epb[count].ldata / (nn-kk); // numero di "blocchi di decodifica" + free(buff); + buff = (char *) malloc(nn1 * sizeof(char)); + //printf("ldata: %d\n",epb[count].ldata); + //printf("nblock: %d\n",nblock); + for (i=0; ipepb)) + + // A questo punto abbiamo corretto anche la parte di dati cui fa riferimento la seconda + // parte del campo EPBdata + + ldpread += epb[count].ldpepb; + cio_seek(pos+2); + cio_skip(epb[count].lepb); + pos = cio_tell(); // posizione a valle dell'EPB corrente + + } // fine for (count=0; count> 8)) & 0xff); + crcSum = ((crcSum << 8) ^ CrcT16[tmp]) & 0xffff; +} + +void UpdateCRC32(char x) +{ + int tmp; + tmp = ((x ^ (crcSum >> 24)) & 0xff); + crcSum = ((crcSum << 8) ^ CrcT32[tmp]); +} +/* funzioni per l'inversione dei byte e del crc32 */ + +char reflectByte(char inbyte) +{ + // reflect one byte + + unsigned char outbyte=0; + unsigned char i=0x01; + unsigned char j; + + for (j=0x080; j; j>>=1) + { + if (inbyte & i) outbyte|=j; + i<<=1; + } + + return outbyte; +} + + +void reflectCRC32() +{ + + + unsigned long outcrc=0; + unsigned long i=0x00000001; + unsigned long j; + + for (j=0x80000000; j; j>>=1) + { + if (crcSum & i) + outcrc|=j; + i=i<<1; + } + crcSum = outcrc; +} + +// Codice relativo alla CODIFICA/DECODIFICA RS + + + +//#define nn 255 /* nn=2**mm -1 length of codeword */ +//#define tt 48 /* number of errors that can be corrected */ +//#define kk 159 /* kk = nn-2*tt */ + +//int pp [mm+1] = { 1, 1, 0, 0, 1} ; /* specify irreducible polynomial coeffts */ + + + +void generate_gf(int nn, int kk) +/* generate GF(2**mm) from the irreducible polynomial p(X) in pp[0]..pp[mm] + lookup tables: index->polynomial form alpha_to[] contains j=alpha**i; + polynomial form -> index form index_of[j=alpha**i] = i + alpha=2 is the primitive element of GF(2**mm) +*/ + { + register int i, mask ; + + mask = 1 ; + alpha_to[mm] = 0 ; + for (i=0; i>= 1 ; + for (i=mm+1; i= mask) + alpha_to[i] = alpha_to[mm] ^ ((alpha_to[i-1]^mask)<<1) ; + else alpha_to[i] = alpha_to[i-1]<<1 ; + index_of[alpha_to[i]] = i ; + } + index_of[0] = -1 ; + } + + +void gen_poly(int nn, int kk) +/* Obtain the generator polynomial of the tt-error correcting, length + nn=(2**mm -1) Reed Solomon code from the product of (X+alpha**i), i=1..2*tt +*/ + { + register int i,j ; + + gg[0] = 2 ; /* primitive element alpha = 2 for GF(2**mm) */ + gg[1] = 1 ; /* g(x) = (X+alpha) initially */ + for (i=2; i<=nn-kk; i++) + { gg[i] = 1 ; + for (j=i-1; j>0; j--) + if (gg[j] != 0) gg[j] = gg[j-1]^ alpha_to[(index_of[gg[j]]+i)%nn] ; + else gg[j] = gg[j-1] ; + gg[0] = alpha_to[(index_of[gg[0]]+i)%nn] ; /* gg[0] can never be zero */ + } + /* convert gg[] to index form for quicker encoding */ + for (i=0; i<=nn-kk; i++) gg[i] = index_of[gg[i]] ; + } + + +void encode_rs(int nn, int kk, int tt) +/* take the string of symbols in data[i], i=0..(k-1) and encode systematically + to produce 2*tt parity symbols in bb[0]..bb[2*tt-1] + data[] is input and bb[] is output in polynomial form. + Encoding is done by using a feedback shift register with appropriate + connections specified by the elements of gg[], which was generated above. + Codeword is c(X) = data(X)*X**(nn-kk)+ b(X) */ + { + register int i,j ; + int feedback ; + + for (i=0; i=0; i--) + { feedback = index_of[data[i]^bb[nn-kk-1]] ; + if (feedback != -1) + { for (j=nn-kk-1; j>0; j--) + if (gg[j] != -1) + bb[j] = bb[j-1]^alpha_to[(gg[j]+feedback)%nn] ; + else + bb[j] = bb[j-1] ; + bb[0] = alpha_to[(gg[0]+feedback)%nn] ; + } + else + { for (j=nn-kk-1; j>0; j--) + bb[j] = bb[j-1] ; + bb[0] = 0 ; + } ; + } ; + } ; + +// La funzione seguente, leggermente modificata rispetto al sorgente in "eccpage", ritorna +// 1 se è riuscita a correggere gli errori o se non ci sono errori, 0 se il processo di +// decodifica RS non è stato portato a termine. + +void decode_rs(int nn, int kk, int tt) +/* assume we have received bits grouped into mm-bit symbols in recd[i], + i=0..(nn-1), and recd[i] is index form (ie as powers of alpha). + We first compute the 2*tt syndromes by substituting alpha**i into rec(X) and + evaluating, storing the syndromes in s[i], i=1..2tt (leave s[0] zero) . + Then we use the Berlekamp iteration to find the error location polynomial + elp[i]. If the degree of the elp is >tt, we cannot correct all the errors + and hence just put out the information symbols uncorrected. If the degree of + elp is <=tt, we substitute alpha**i , i=1..n into the elp to get the roots, + hence the inverse roots, the error location numbers. If the number of errors + located does not equal the degree of the elp, we have more than tt errors + and cannot correct them. Otherwise, we then solve for the error value at + the error location and correct the error. The procedure is that found in + Lin and Costello. For the cases where the number of errors is known to be too + large to correct, the information symbols as received are output (the + advantage of systematic encoding is that hopefully some of the information + symbols will be okay and that if we are in luck, the errors are in the + parity part of the transmitted codeword). Of course, these insoluble cases + can be returned as error flags to the calling routine if desired. */ + { + register int i,j,u,q ; + //int elp[nn-kk+2][nn-kk], d[nn-kk+2], l[nn-kk+2], u_lu[nn-kk+2], s[nn-kk+1] ; + //int count=0, syn_error=0, root[tt], loc[tt], z[tt+1], err[nn], reg[tt+1] ; + + + int **elp, *d, *l, *u_lu, *s; + int count=0, syn_error=0, *root, *loc, *z, *err, *reg; + + + elp = (int **) malloc((nn-kk+2)*sizeof(int)); + for (i=0; i<(nn-kk+2); i++) + elp[i] = (int *) malloc((nn-kk)*sizeof(int)); + d = (int *) malloc((nn-kk+2)*sizeof(int)); + l = (int *) malloc((nn-kk+2)*sizeof(int)); + u_lu = (int *) malloc((nn-kk+2)*sizeof(int)); + s = (int *) malloc((nn-kk+2)*sizeof(int)); + root = (int *) malloc(tt*sizeof(int)); + loc = (int *) malloc(tt*sizeof(int)); + z = (int *) malloc((tt+1)*sizeof(int)); + err = (int *) malloc(nn*sizeof(int)); + reg = (int *) malloc((tt+1)*sizeof(int)); + + +/* first form the syndromes */ + for (i=1; i<=nn-kk; i++) + { s[i] = 0 ; + for (j=0; j error */ + s[i] = index_of[s[i]] ; + } ; + + if (syn_error) /* if errors, try and correct */ + { +/* compute the error location polynomial via the Berlekamp iterative algorithm, + following the terminology of Lin and Costello : d[u] is the 'mu'th + discrepancy, where u='mu'+1 and 'mu' (the Greek letter!) is the step number + ranging from -1 to 2*tt (see L&C), l[u] is the + degree of the elp at that step, and u_l[u] is the difference between the + step number and the degree of the elp. +*/ +/* initialise table entries */ + d[0] = 0 ; /* index form */ + d[1] = s[1] ; /* index form */ + elp[0][0] = 0 ; /* index form */ + elp[1][0] = 1 ; /* polynomial form */ + for (i=1; i0)) q-- ; +/* have found first non-zero d[q] */ + if (q>0) + { j=q ; + do + { j-- ; + if ((d[j]!=-1) && (u_lu[q]0) ; + } ; + +/* have now found q such that d[u]!=0 and u_lu[q] is maximum */ +/* store degree of new elp polynomial */ + if (l[u]>l[q]+u-q) l[u+1] = l[u] ; + else l[u+1] = l[q]+u-q ; + +/* form new elp(x) */ + for (i=0; i >tt errors and cannot solve */ + { for (i=0; itt hence cannot solve */ + { for (i=0; i no errors: output received codeword */ + { for (i=0; i */ +/* 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/jpwl/decoder/libopenjpeg/mct.h b/jpwl/decoder/libopenjpeg/mct.h new file mode 100644 index 00000000..196dc6d3 --- /dev/null +++ b/jpwl/decoder/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/jpwl/decoder/libopenjpeg/mqc.c b/jpwl/decoder/libopenjpeg/mqc.c new file mode 100644 index 00000000..31adc845 --- /dev/null +++ b/jpwl/decoder/libopenjpeg/mqc.c @@ -0,0 +1,591 @@ +/* + * 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_setcurctx(0); + 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; + //add antonin initbug1 + if (len==0) mqc_c = 0xff << 16; + else mqc_c = *mqc_bp << 16; + //dda + 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/jpwl/decoder/libopenjpeg/mqc.h b/jpwl/decoder/libopenjpeg/mqc.h new file mode 100644 index 00000000..ea01d809 --- /dev/null +++ b/jpwl/decoder/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(int d); + +/* + * 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/jpwl/decoder/libopenjpeg/openjpeg.h b/jpwl/decoder/libopenjpeg/openjpeg.h new file mode 100644 index 00000000..a2543e64 --- /dev/null +++ b/jpwl/decoder/libopenjpeg/openjpeg.h @@ -0,0 +1,49 @@ +/* + * 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 +#include + +#endif diff --git a/jpwl/decoder/libopenjpeg/pi.c b/jpwl/decoder/libopenjpeg/pi.c new file mode 100644 index 00000000..cfe5ba00 --- /dev/null +++ b/jpwl/decoder/libopenjpeg/pi.c @@ -0,0 +1,557 @@ +/* + * Copyright (c) 2001-2002, David Janssens + * Copyright (c) 2003-2004, Yannick Verschueren + * Copyright (c) 2003-2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "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, i; + int compno, resno, pino; + 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[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[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 = (rx0==rx1)?0:((px1 - px0) >> res->pdx); //Mod Antonin : sizebug1 + res->ph = (ry0==ry1)?0:((py1 - py0) >> res->pdy); //Mod Antonin : sizebug1 + } + } + + tccp = &tcp->tccps[0]; + pi[pino].step_p = 1; + pi[pino].step_c = 100 * pi[pino].step_p; + pi[pino].step_r = img->numcomps * pi[pino].step_c; + pi[pino].step_l = maxres * pi[pino].step_r; + + if (pino == 0) { + pi[pino].include = + (short int *) malloc(img->numcomps * maxres * + tcp->numlayers * 100 * sizeof(short int)); + for (i = 0; i < img->numcomps * maxres * tcp->numlayers * 100; i++) + pi[pino].include[i] = 0; + } + /* pi[pino].include=(short int*)calloc(img->numcomps*maxres*tcp->numlayers*1000,sizeof(short int)); */ + else + pi[pino].include = pi[pino - 1].include; + + if (tcp->POC == 0) { + pi[pino].first = 1; + pi[pino].poc.resno0 = 0; + pi[pino].poc.compno0 = 0; + pi[pino].poc.layno1 = tcp->numlayers; + pi[pino].poc.resno1 = maxres; + pi[pino].poc.compno1 = 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. + * + * pi: packet iterator to modify + * */ +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->step_l + + pi->resno * pi->step_r + + pi->compno * pi->step_c + pi->precno * pi->step_p]) { + pi->include[pi->layno * pi->step_l + + pi->resno * pi->step_r + + pi->compno * pi->step_c + + pi->precno * pi->step_p] = 1; + return 1; + } + skip:; + } + } + } + } + return 0; +} + +/* + * Get next packet in resolution-layer-component-precinct order. + * + * pi: packet iterator to modify + * */ +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->step_l + + pi->resno * pi->step_r + + pi->compno * pi->step_c + pi->precno * pi->step_p]) { + pi->include[pi->layno * pi->step_l + + pi->resno * pi->step_r + + pi->compno * pi->step_c + + pi->precno * pi->step_p] = 1; + return 1; + } + skip:; + } + } + } + } + return 0; +} + +/* + * Get next packet in resolution-precinct-component-layer order. + * + * pi: packet iterator to modify + * */ +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 trx1, try1;// Add antonin pcrl + 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); + trx1 = int_ceildiv(pi->tx1, comp->dx << levelno);// Add antonin pcrl + try1 = int_ceildiv(pi->ty1, comp->dy << levelno);// Add antonin pcrl + 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; + } + + //Add Antonin : sizebug1 + if ((res->pw==0)||(res->pw==0)) continue; + //ddA + + //Add Antonin : pcrl + if ((trx0==trx1)||(try0==try1)) continue; + //ddA + + 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->step_l + + pi->resno * pi->step_r + + pi->compno * pi->step_c + + pi->precno * pi->step_p]) { + pi->include[pi->layno * pi->step_l + + pi->resno * pi->step_r + + pi->compno * pi->step_c + + pi->precno * pi->step_p] = 1; + return 1; + } + skip:; + } + } + } + } + } + return 0; +} + +/* + * Get next packet in precinct-component-resolution-layer order. + * + * pi: packet iterator to modify + * */ +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 trx1, try1;// Add antonin pcrl + 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); + trx1 = int_ceildiv(pi->tx1, comp->dx << levelno);// Add antonin pcrl + try1 = int_ceildiv(pi->ty1, comp->dy << levelno);// Add antonin pcrl + 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; + } + + //Add Antonin : sizebug1 + if ((res->pw==0)||(res->pw==0)) continue; + //ddA + + //Add Antonin : pcrl + if ((trx0==trx1)||(try0==try1)) continue; + //ddA + + 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->step_l + + pi->resno * pi->step_r + + pi->compno * pi->step_c + + pi->precno * pi->step_p]) { + pi->include[pi->layno * pi->step_l + + pi->resno * pi->step_r + + pi->compno * pi->step_c + + pi->precno * pi->step_p] = 1; + return 1; + } +skip:; + } + } + } + } + } + return 0; +} + +/* + * Get next packet in component-precinct-resolution-layer order. + * + * pi: packet iterator to modify + * */ +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 trx1, try1;// Add antonin pcrl + 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); + trx1 = int_ceildiv(pi->tx1, comp->dx << levelno);// Add antonin pcrl + try1 = int_ceildiv(pi->ty1, comp->dy << levelno);// Add antonin pcrl + 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; + } + + //Add Antonin : sizebug1 + if ((res->pw==0)||(res->pw==0)) continue; + //ddA + + //Add Antonin : pcrl + if ((trx0==trx1)||(try0==try1)) continue; + //ddA + + 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->step_l + + pi->resno * pi->step_r + + pi->compno * pi->step_c + + pi->precno * pi->step_p]) { + pi->include[pi->layno * pi->step_l + + pi->resno * pi->step_r + + pi->compno * pi->step_c + + pi->precno * pi->step_p] = 1; + return 1; + } + skip:; + } + } + } + } + } + return 0; +} + +/* + * Get next packet. + * + * pi: packet iterator to modify + * */ +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/jpwl/decoder/libopenjpeg/pi.h b/jpwl/decoder/libopenjpeg/pi.h new file mode 100644 index 00000000..acfe201a --- /dev/null +++ b/jpwl/decoder/libopenjpeg/pi.h @@ -0,0 +1,72 @@ +/* + * 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 { + short int *include; /* precise if the packet has been already used (usefull for progression order change) */ + int step_l, step_r, step_c, step_p; /* different steps (layer, resolution, component, precinct) to localize the packet in the include vector */ + int compno, resno, precno, layno; /* component, resolution, precinct and layer that indentify the packet */ + int first; /* 0 if the first packet */ + 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/jpwl/decoder/libopenjpeg/raw.c b/jpwl/decoder/libopenjpeg/raw.c new file mode 100644 index 00000000..bae2e899 --- /dev/null +++ b/jpwl/decoder/libopenjpeg/raw.c @@ -0,0 +1,81 @@ +/* + * 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; /* temporary buffer where bits are coded or decoded */ +unsigned int raw_ct; /* number of bits already read or free to write */ +unsigned int raw_lenmax; /* maximum length to decode */ +unsigned int raw_len; /* length decoded */ +unsigned char *raw_bp; /* pointer to the current position in the buffer */ +unsigned char *raw_start; /* pointer to the start of the buffer */ +unsigned char *raw_end; /* pointer to the end of the buffer */ + +/* + * Return the number of bytes already encoded. + */ +int raw_numbytes() +{ + return raw_bp - raw_start; +} + +/* + * Initialize raw-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) +{ + 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/jpwl/decoder/libopenjpeg/raw.h b/jpwl/decoder/libopenjpeg/raw.h new file mode 100644 index 00000000..08b20bc6 --- /dev/null +++ b/jpwl/decoder/libopenjpeg/raw.h @@ -0,0 +1,48 @@ +/* + * 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 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/jpwl/decoder/libopenjpeg/t1.c b/jpwl/decoder/libopenjpeg/t1.c new file mode 100644 index 00000000..4df64799 --- /dev/null +++ b/jpwl/decoder/libopenjpeg/t1.c @@ -0,0 +1,1098 @@ +/* + * 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_MAXCBLKW]; +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, int numcomps) //mod fixed_quality +{ + double w1, w2, wmsedec; + if (qmfbid == 1) { + w1 = (numcomps > 1) ? mct_getnorm(compno) : 1; + w2 = dwt_getnorm(level, orient); + } else { /* if (qmfbid == 0) */ + w1 = (numcomps > 1) ? mct_getnorm_real(compno) : 1; + w2 = dwt_getnorm_real(level, orient); + } + wmsedec = w1 * w2 * (stepsize / 8192.0) * (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 numcomps, tcd_tile_t * tile) //mod fixed_quality +{ + 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, numcomps); //mod fixed_quality + tile->distotile += t1_getwmsedec(nmsedec, compno, level, orient, bpno, qmfbid, stepsize, numcomps); //add antonin quality + + + /* Code switch "RESTART" (i.e. TERMALL) */ + if ((cblksty & J2K_CCP_CBLKSTY_TERMALL) + && !((passtype == 2) && (bpno - 1 < 0))) { + if (type == T1_TYPE_RAW) { + mqc_flush(); + correction = 1; + /* correction = mqc_bypass_flush_enc(); */ + } else { /* correction = mqc_restart_enc(); */ + mqc_flush(); + correction = 1; + } + 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) { + mqc_flush(); + correction = 1; + /* correction = mqc_bypass_flush_enc(); */ + } else { /* correction = mqc_restart_enc(); */ + mqc_flush(); + correction = 1; + } + pass->term = 1; + } else { + pass->term = 0; + } + } + + if (++passtype == 3) { + passtype = 0; + bpno--; + } + + if (pass->term && bpno > 0) { + type = ((bpno < (cblk->numbps - 4)) && (passtype < 2) + && (cblksty & 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; + char type = T1_TYPE_MQ; //BYPASS mode + + 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 BYPASS mode + 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 + + if (bpno==0) cblk->lastbp=1; // Add Antonin : quantizbug1 + + 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_resetstates(); + mqc_setstate(T1_CTXNO_UNI, 0, 46); + mqc_setstate(T1_CTXNO_AGG, 0, 3); + mqc_setstate(T1_CTXNO_ZC, 0, 4); + } + + 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; + + tile->distotile = 0; //add fixed_quality + + 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, tile->numcomps, tile); //mod fixed_quality + } /* 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 { + // Add antonin : quantizbug1 + t1_data[j][i]<<=1; + //if (cblk->lastbp) + t1_data[j][i]+=t1_data[j][i]>0?1:-1; + // ddA + tilec->data[x + i + + (y + j) * (tilec->x1 - + tilec-> + x0)] = + fix_mul(t1_data[j][i] << 12, band->stepsize); //Mod Antonin : quantizbug1 (before : << 13) + } + } + } + } + } + } + } + } + } +} + +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/jpwl/decoder/libopenjpeg/t1.h b/jpwl/decoder/libopenjpeg/t1.h new file mode 100644 index 00000000..5e98bc09 --- /dev/null +++ b/jpwl/decoder/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/jpwl/decoder/libopenjpeg/t2.c b/jpwl/decoder/libopenjpeg/t2.c new file mode 100644 index 00000000..9ccc64c3 --- /dev/null +++ b/jpwl/decoder/libopenjpeg/t2.c @@ -0,0 +1,644 @@ +/* + * Copyright (c) 2001-2002, David Janssens + * Copyright (c) 2002-2004, Yannick Verschueren + * Copyright (c) 2002-2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "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); +} + +/* + * Encode a packet of a tile to a destination buffer + * + * Tile : the tile for which to write the packets + * tcp : the tile coding parameters + * compno : Identity of the packet --> component value + * resno : Identity of the packet --> resolution level value + * precno : Identity of the packet --> precinct value + * layno : Identity of the packet --> quality layer value + * dest : the destination buffer + * len : the length of the destination buffer + * info_IM : structure to create an index file + * tileno : number of the tile encoded +*/ +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; + + /* */ + 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) { + 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; +} + +/* + * Decode a packet of a tile from a source buffer + * + * src : the source buffer + * len : the length of the source buffer + * tile : the tile for which to write the packets + * cp : the image coding parameters + * tcp : the tile coding parameters + * compno : Identity of the packet --> component value + * resno : Identity of the packet --> resolution level value + * precno : Identity of the packet --> precinct value + * layno : Identity of the packet --> quality layer value + */ +int t2_decode_packet(unsigned char *src, int len, tcd_tile_t * tile, + j2k_cp_t * cp, 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; + unsigned char *hd = NULL; + 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]; + + //Add Antonin : sizebug1 + if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)) continue; + //ddA + + 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; + } + } + } + + // SOP markers + if (tcp->csty & J2K_CP_CSTY_SOP) { + if ((*c) != 0xff || (*(c + 1) != 0x91)) { + printf("Warning : expected SOP marker\n"); + } else { + c += 6; + } + //TODO : check the Nsop value + } + + /* When the marker PPT/PPM is used the packet header are store in PPT/PPM marker + This part deal with this caracteristic + step 1: Read packet header in the saved structure + step 2: Return to codestream for decoding */ + + if (cp->ppm == 1) { /* PPM */ + hd = cp->ppm_data; + bio_init_dec(hd, cp->ppm_len); //Mod Antonin : ppmbug1 + } else if (tcp->ppt == 1) { /* PPT */ + hd = tcp->ppt_data; + bio_init_dec(hd, tcp->ppt_len); //Mod Antonin : ppmbug1 + } else { /* Normal Case */ + hd = c; + bio_init_dec(hd, src+len-hd); + } + + present = bio_read(1); + + if (!present) { + bio_inalign(); + hd += bio_numbytes(); + + // EPH markers + if (tcp->csty & J2K_CP_CSTY_EPH) { + if ((*hd) != 0xff || (*(hd + 1) != 0x92)) { + printf("Error : expected EPH marker\n"); + } else { + hd += 2; + } + } + + if (cp->ppm == 1) { /* PPM case */ + cp->ppm_len+=cp->ppm_data-hd; + cp->ppm_data = hd; + return c - src; + } + if (tcp->ppt == 1) { /* PPT case */ + tcp->ppt_len+=tcp->ppt_data-hd; + tcp->ppt_data = hd; + return c - src; + } + + return hd - src; + } + + for (bandno = 0; bandno < res->numbands; bandno++) { + tcd_band_t *band = &res->bands[bandno]; + tcd_precinct_t *prc = &band->precincts[precno]; + + //Add Antonin : sizebug1 + if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)) continue; + //ddA + + 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; + + hd += bio_numbytes(); + + // EPH markers + if (tcp->csty & J2K_CP_CSTY_EPH) { + if ((*hd) != 0xff || (*(hd + 1) != 0x92)) { + printf("Error : expected EPH marker\n"); + } else { + hd += 2; + } + } + + if (cp->ppm==1) { + cp->ppm_len+=cp->ppm_data-hd; + cp->ppm_data = hd; + } else if (tcp->ppt == 1) { + tcp->ppt_len+=tcp->ppt_data-hd; + tcp->ppt_data = hd; + } else { + c=hd; + } + + for (bandno = 0; bandno < res->numbands; bandno++) { + tcd_band_t *band = &res->bands[bandno]; + tcd_precinct_t *prc = &band->precincts[precno]; + + //Add Antonin : sizebug1 + if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)) continue; + //ddA + + 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[0]; + cblk->numsegs++; + cblk->len = 0; + } else { + seg = &cblk->segs[cblk->numsegs - 1]; + if (seg->numpasses == seg->maxpasses) { + seg++; + cblk->numsegs++; + } + } + do { + if (c + seg->newlen > src + len) { + return -999; + } + + memcpy(cblk->data + cblk->len, c, seg->newlen); + if (seg->numpasses == 0) { + seg->data = cblk->data + cblk->len; + } + c += seg->newlen; + cblk->len += seg->newlen; + seg->len += seg->newlen; + seg->numpasses += seg->numnewpasses; + cblk->numnewpasses -= seg->numnewpasses; + if (cblk->numnewpasses > 0) { + seg++; + cblk->numsegs++; + } + } while (cblk->numnewpasses > 0); + } + } + + return c - src; +} + + + +/* + * Encode the packets of a tile to a destination buffer + * + * img : the source image + * cp : the image coding parameters + * tileno : number of the tile encoded + * tile : the tile for which to write the packets + * maxlayers : maximum number of layers + * dest : the destination buffer + * len : the length of the destination buffer + * info_IM : structure to create an index file + */ +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[0].include); + free(pi); + if (e == -999) + return e; + else + return c - dest; +} + + + +/* + * 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) +{ + unsigned char *c = src; + pi_iterator_t *pi; + int pino, compno, e = 0; + int n = 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, + &cp->tcps[tileno], pi[pino].compno, + pi[pino].resno, pi[pino].precno, + pi[pino].layno); + + /* progression in resolution */ + img->comps[pi[pino].compno].resno_decoded = + e > 0 ? int_max(pi[pino].resno, + img->comps[pi[pino].compno]. + resno_decoded) : img->comps[pi[pino]. + compno].resno_decoded; + n++; + + 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[0].include); + free(pi); + + if (e == -999) + return e; + else + return c - src; +} diff --git a/jpwl/decoder/libopenjpeg/t2.h b/jpwl/decoder/libopenjpeg/t2.h new file mode 100644 index 00000000..795fb53f --- /dev/null +++ b/jpwl/decoder/libopenjpeg/t2.h @@ -0,0 +1,64 @@ +/* + * 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 + * tileno : number of the tile encoded + * tile : the tile for which to write the packets + * maxlayers : maximum number of layers + * dest : the destination buffer + * len : the length of the destination buffer + * info_IM : structure to create an index file + */ +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/jpwl/decoder/libopenjpeg/tcd.c b/jpwl/decoder/libopenjpeg/tcd.c new file mode 100644 index 00000000..b3b27dd5 --- /dev/null +++ b/jpwl/decoder/libopenjpeg/tcd.c @@ -0,0 +1,1601 @@ +/* + * Copyright (c) 2001-2002, David Janssens + * Copyright (c) 2002-2004, Yannick Verschueren + * Copyright (c) 2002-2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "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 y0=%d y1=%d\n", img->tw, img->th, + tcd_img->x0, tcd_img->x1, tcd_img->y0, tcd_img->y1); + for (tileno = 0; tileno < img->th*img->tw; tileno++) { + tcd_tile_t *tile = &tcd_image.tiles[tileno]; + 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] = + int_ceildiv(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); + + tilec->data = + (int *) malloc((tilec->x1 - tilec->x0) * + (tilec->y1 - tilec->y0) * sizeof(int)); + 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); + + 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); + + tile->numcomps = img->numcomps; + /* tile->PPT=img->PPT; */ + /* Modification of the RATE >> */ + for (j = 0; j < tcp->numlayers; j++) { + tcp->rates[j] = + int_ceildiv(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); + + tilec->data = + (int *) malloc((tilec->x1 - tilec->x0) * + (tilec->y1 - tilec->y0) * sizeof(int)); + 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); + + 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, i, j; + unsigned int x0 = 0, y0 = 0, x1 = 0, y1 = 0, w, h, p, q; + 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]; */ + + for (i = 0; i < cp->tileno_size; i++) { + j2k_tcp_t *tcp = &cp->tcps[cp->tileno[i]]; + tcd_tile_t *tile = &tcd_image.tiles[cp->tileno[i]]; + tileno = cp->tileno[i]; + + + // int previous_x0, previous_x1, previous_y0, previous_y1; + /* cfr p59 ISO/IEC FDIS15444-1 : 2000 (18 august 2000) */ + p = tileno % cp->tw; /* si numerotation matricielle .. */ + 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); + + 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); + + tilec->data = + (int *) malloc((tilec->x1 - tilec->x0) * + (tilec->y1 - tilec->y0) * sizeof(int)); + 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); + + 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 = (res->x0==res->x1)?0:((brprcxend - tlprcxstart) >> pdx); // Mod Antonin : sizebug1 + res->ph = (res->y0==res->y1)?0:((brprcyend - tlprcystart) >> pdy); // Mod Antonin : sizebug1 + + 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); + + + + cblk->lastbp = 0; // Add Antonin : quantizbug1 + } + } + } + } + } + } + //tcd_dump(&tcd_image,0); + + + /* Allocate place to store the data decoded = final image */ + /* Place limited by the tile really present in the codestream */ + + + for (i = 0; i < img->numcomps; i++) { + for (j = 0; j < cp->tileno_size; j++) { + tileno = cp->tileno[j]; + x0 = j == 0 ? tcd_image.tiles[tileno].comps[i].x0 : int_min(x0, + tcd_image. + tiles[tileno].comps[i].x0); + y0 = j == 0 ? tcd_image.tiles[tileno].comps[i].y0 : int_min(y0, + tcd_image. + tiles[tileno].comps[i].y0); + x1 = j == 0 ? tcd_image.tiles[tileno].comps[i].x1 : int_max(x1, + tcd_image. + tiles[tileno].comps[i].x1); + y1 = j == 0 ? tcd_image.tiles[tileno].comps[i].y1 : int_max(y1, + tcd_image. + tiles[tileno].comps[i].y1); + } + //w = int_ceildiv(x1 - x0, img->comps[i].dx); + //h = int_ceildiv(y1 - y0, img->comps[i].dy); + + w = x1 - x0; + + h = y1 - y0; + img->comps[i].data = (int *) calloc(w * h, sizeof(int)); + img->comps[i].w = w; + img->comps[i].h = h; + img->comps[i].x0 = x0; + img->comps[i].y0 = y0; + } +} + +void tcd_makelayer_fixed(int layno, int final) +{ + int compno, resno, bandno, precno, cblkno; + int value; //, matrice[tcd_tcp->numlayers][tcd_tile->comps[0].numresolutions][3]; + int matrice[10][10][3]; + int i, j, k; + + /*matrice=(int*)malloc(tcd_tcp->numlayers*tcd_tile->comps[0].numresolutions*3*sizeof(int)); */ + + for (compno = 0; compno < tcd_tile->numcomps; compno++) { + tcd_tilecomp_t *tilec = &tcd_tile->comps[compno]; + for (i = 0; i < tcd_tcp->numlayers; i++) { + for (j = 0; j < tilec->numresolutions; j++) { + for (k = 0; k < 3; k++) { + matrice[i][j][k] = + (int) (tcd_cp-> + matrice[i * tilec->numresolutions * 3 + + j * 3 + + 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 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 */ + + if (layno == 0) { + value = matrice[layno][resno][bandno]; + if (imsb >= value) + value = 0; + else + value -= imsb; + } else { + value = + matrice[layno][resno][bandno] - + matrice[layno - 1][resno][bandno]; + if (imsb >= matrice[layno - 1][resno][bandno]) { + value -= (imsb - matrice[layno - 1][resno][bandno]); + if (value < 0) + value = 0; + } + } + + if (layno == 0) + cblk->numpassesinlayers = 0; + + n = cblk->numpassesinlayers; + if (cblk->numpassesinlayers == 0) { + if (value != 0) + n = 3 * value - 2 + cblk->numpassesinlayers; + else + n = cblk->numpassesinlayers; + } else + n = 3 * value + cblk->numpassesinlayers; + + layer->numpasses = n - cblk->numpassesinlayers; + + if (!layer->numpasses) + continue; + + if (cblk->numpassesinlayers == 0) { + layer->len = cblk->passes[n - 1].rate; + layer->data = cblk->data; + } else { + layer->len = + cblk->passes[n - 1].rate - + cblk->passes[cblk->numpassesinlayers - 1].rate; + layer->data = + cblk->data + + cblk->passes[cblk->numpassesinlayers - 1].rate; + } + if (final) + cblk->numpassesinlayers = n; + } + } + } + } + } +} + +void tcd_rateallocate_fixed() +{ + int layno; + + for (layno = 0; layno < tcd_tcp->numlayers; layno++) { + tcd_makelayer_fixed(layno, 1); + } +} + +void tcd_makelayer(int layno, double thresh, int final) +{ + int compno, resno, bandno, precno, cblkno, passno; + + tcd_tile->distolayer[layno] = 0; //add fixed_quality + + 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) { + layer->disto = 0; + continue; + } + + if (cblk->numpassesinlayers == 0) { + layer->len = cblk->passes[n - 1].rate; + layer->data = cblk->data; + layer->disto = cblk->passes[n - 1].distortiondec; + } else { + layer->len = cblk->passes[n - 1].rate - + cblk->passes[cblk->numpassesinlayers - 1].rate; + layer->data = + cblk->data + + cblk->passes[cblk->numpassesinlayers - 1].rate; + layer->disto = + cblk->passes[n - 1].distortiondec - + cblk->passes[cblk->numpassesinlayers - 1].distortiondec; + } + + tcd_tile->distolayer[layno] += layer->disto; //add fixed_quality + + 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; + double cumdisto[100]; //add fixed_quality + const double K = 1; // 1.1; //add fixed_quality + + double maxSE = 0; + min = DBL_MAX; + max = 0; + + tcd_tile->nbpix = 0; //add fixed_quality + + for (compno = 0; compno < tcd_tile->numcomps; compno++) { + tcd_tilecomp_t *tilec = &tcd_tile->comps[compno]; + + tilec->nbpix = 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]; + 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 */ + + tcd_tile->nbpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0)); //add fixed_quality + + tilec->nbpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0)); //add fixed_quality + + } /* cbklno */ + } /* precno */ + } /* bandno */ + } /* resno */ + + maxSE+=(double)(((1<comps[compno].prec)-1)*((1<comps[compno].prec)-1))*(tilec->nbpix); + } /* compno */ + + /* add antonin index */ + if (info_IM->index_on) { + info_tile *info_TL = &info_IM->tile[tcd_tileno]; + info_TL->nbpix = tcd_tile->nbpix; + info_TL->distotile = tcd_tile->distotile; + info_TL->thresh = + (double *) malloc(tcd_tcp->numlayers * sizeof(double)); + } + /* dda */ + + 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; + double distotarget; //add fixed_quality + + distotarget = tcd_tile->distotile - ((K * maxSE) / pow(10, tcd_tcp->distoratio[layno] / 10)); // add fixed_quality + + for (i = 0; i < 32; i++) { + volatile double thresh = (lo + hi) / 2; + int l=0; + double distoachieved = 0; // add fixed_quality + + tcd_makelayer(layno, thresh, 0); + + if (tcd_cp->fixed_quality) { // add fixed_quality + distoachieved = + layno == + 0 ? tcd_tile->distolayer[0] : cumdisto[layno - 1] + + tcd_tile->distolayer[layno]; + if (distoachieved < distotarget) { + hi = thresh; + continue; + } + lo = thresh; + } else { + 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); + } + + if (info_IM->index_on) { /* Threshold for Marcela Index */ + info_IM->tile[tcd_tileno].thresh[layno] = goodthresh; + } + tcd_makelayer(layno, goodthresh, 1); + + cumdisto[layno] = + + layno == + + 0 ? tcd_tile->distolayer[0] : cumdisto[layno - 1] + + + tcd_tile->distolayer[layno]; // add fixed_quality + } +} + +int tcd_encode_tile_pxm(int tileno, unsigned char *dest, int len, + info_image * info_IM) +{ + int compno; + int l,i; + clock_t time7; + 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]; //Based on Component 0 + + for (i=0;inumresolutions;i++) { + + tcd_resolution_t *res_idx = &tilec_idx->resolutions[i]; + + info_IM->tile[tileno].pw[i] = res_idx->pw; + info_IM->tile[tileno].ph[i] = res_idx->ph; + + info_IM->tile[tileno].pdx[i] = tccp->prcw[i]; + info_IM->tile[tileno].pdy[i] = tccp->prch[i]; + + } + } + /* << INDEX */ + +/*---------------TILE-------------------*/ + + time7 = 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); + } + +/*----------------MCT-------------------*/ + + 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)); + } + } +/*----------------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); + } + } +/*------------------TIER1-----------------*/ + + t1_init_luts(); + t1_encode_cblks(tile, tcd_tcp); + +/*-----------RATE-ALLOCATE------------------*/ + info_IM->index_write = 0; /* INDEX */ + + if (tcd_cp->disto_alloc || tcd_cp->fixed_quality) // mod fixed_quality + /* Normal Rate/distortion allocation */ + tcd_rateallocate(dest, len, info_IM); + else + /* Fixed layer allocation */ + tcd_rateallocate_fixed(); + +/*--------------TIER2------------------*/ + info_IM->index_write = 1; /* INDEX */ + l = t2_encode_packets(tcd_img, tcd_cp, tileno, tile, + tcd_tcp->numlayers, dest, len, info_IM); +/*---------------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,i; + clock_t time; + 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]; //Based on Component 0 + + for (i=0;inumresolutions;i++) { + + tcd_resolution_t *res_idx = &tilec_idx->resolutions[i]; + + + + info_IM->tile[tileno].pw[i] = res_idx->pw; + + info_IM->tile[tileno].ph[i] = res_idx->ph; + + + + info_IM->tile[tileno].pdx[i] = tccp->prcw[i]; + + info_IM->tile[tileno].pdy[i] = tccp->prch[i]; + + } + + } + + /* << INDEX */ +/*---------------TILE-------------------*/ + time = 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); + } + +/*----------------MCT-------------------*/ + + 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)); + } + } + +/*----------------DWT---------------------*/ + + 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); + } + } + +/*------------------TIER1-----------------*/ + + t1_init_luts(); + t1_encode_cblks(tile, tcd_tcp); + +/*-----------RATE-ALLOCATE------------------*/ + + info_IM->index_write = 0; /* INDEX */ + + if (tcd_cp->disto_alloc || tcd_cp->fixed_quality) // mod fixed_quality + + /* Normal Rate/distortion allocation */ + + tcd_rateallocate(dest, len, info_IM); + + else + + /* Fixed layer allocation */ + + tcd_rateallocate_fixed(); + +/*--------------TIER2------------------*/ + info_IM->index_write = 1; /* INDEX */ + + l = t2_encode_packets(tcd_img, tcd_cp, tileno, tile, + tcd_tcp->numlayers, dest, len, info_IM); + + /*---------------CLEAN-------------------*/ + time = clock() - time; + printf("total: %ld.%.3ld s\n", time / CLOCKS_PER_SEC, + (time % 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 time; + tcd_tile_t *tile; + + tcd_tileno = tileno; + tcd_tile = &tcd_image.tiles[tileno]; + tcd_tcp = &tcd_cp->tcps[tileno]; + tile = tcd_tile; + + time = clock(); + + fprintf(stderr, "tile decoding time %d/%d: ", tileno + 1, + tcd_cp->tw * tcd_cp->th); + + /*--------------TIER2------------------*/ + + l = t2_decode_packets(src, len, tcd_img, tcd_cp, tileno, tile); + + if (l == -999) { + eof = 1; + fprintf(stderr, "tcd_decode: incomplete bistream\n"); + } + + /*------------------TIER1-----------------*/ + t1_init_luts(); + t1_decode_cblks(tile, tcd_tcp); + + /*----------------DWT---------------------*/ + + for (compno = 0; compno < tile->numcomps; compno++) { + tcd_tilecomp_t *tilec = &tile->comps[compno]; + if (tcd_cp->reduce_on == 1) { + tcd_img->comps[compno].resno_decoded = + tile->comps[compno].numresolutions - tcd_cp->reduce_value - 1; + } + + + if (tcd_tcp->tccps[compno].qmfbid == 1) { + dwt_decode(tilec->data, tilec->x1 - tilec->x0, + tilec->y1 - tilec->y0, tilec, + tilec->numresolutions - 1, + tilec->numresolutions - 1 - + tcd_img->comps[compno].resno_decoded); + } else { + dwt_decode_real(tilec->data, tilec->x1 - tilec->x0, + tilec->y1 - tilec->y0, tilec, + tilec->numresolutions - 1, + tilec->numresolutions - 1 - + tcd_img->comps[compno].resno_decoded); + } + + if (tile->comps[compno].numresolutions > 0) + tcd_img->comps[compno].factor = + tile->comps[compno].numresolutions - + (tcd_img->comps[compno].resno_decoded + 1); + } + + /*----------------MCT-------------------*/ + + if (tcd_tcp->mct) { + if (tcd_tcp->tccps[0].qmfbid == 1) { + mct_decode(tile->comps[0].data, tile->comps[1].data, + tile->comps[2].data, + (tile->comps[0].x1 - + tile->comps[0].x0) * (tile->comps[0].y1 - + tile->comps[0].y0)); + } else { + mct_decode_real(tile->comps[0].data, tile->comps[1].data, + tile->comps[2].data, + (tile->comps[0].x1 - + tile->comps[0].x0) * (tile->comps[0].y1 - + tile->comps[0].y0)); + } + } + + /*---------------TILE-------------------*/ + + for (compno = 0; compno < tile->numcomps; compno++) { + tcd_tilecomp_t *tilec = &tile->comps[compno]; + tcd_resolution_t *res = + &tilec->resolutions[tcd_img->comps[compno].resno_decoded]; + 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 = tcd_img->comps[compno].w; + + int i, j; + int offset_x = int_ceildivpow2(tcd_img->comps[compno].x0, + tcd_img->comps[compno].factor); + int offset_y = int_ceildivpow2(tcd_img->comps[compno].y0, + tcd_img->comps[compno].factor); + + for (j = res->y0; j < res->y1; j++) { + for (i = res->x0; i < res->x1; i++) { + + int v; + + double tmp= (double) tilec->data[i - res->x0 + (j - res->y0) * tw]; + if (tcd_tcp->tccps[compno].qmfbid == 1) { + v = (int) tmp; + } else { + + //v = (int) tmp >> 13; + + //Mod antonin : multbug1 + v = (int) ((fabs(tmp/8192.0)>=floor(fabs(tmp/8192.0))+0.5)?fabs(tmp/8192.0)+1.0:fabs(tmp/8192.0)); + + v = (tmp<0)?-v:v; + + //doM + } + v += adjust; + + tcd_img->comps[compno].data[(i - offset_x) + + (j - offset_y) * w] = + int_clamp(v, min, max); + } + } + } + + time = clock() - time; + fprintf(stderr, "total: %ld.%.3ld s\n", time / CLOCKS_PER_SEC, + (time % CLOCKS_PER_SEC) * 1000 / CLOCKS_PER_SEC); + + for (compno = 0; compno < tile->numcomps; compno++) { + free(tcd_image.tiles[tileno].comps[compno].data); + } + + if (eof) { + longjmp(j2k_error, 1); + } + + return l; +} diff --git a/jpwl/decoder/libopenjpeg/tcd.h b/jpwl/decoder/libopenjpeg/tcd.h new file mode 100644 index 00000000..6e64717d --- /dev/null +++ b/jpwl/decoder/libopenjpeg/tcd.h @@ -0,0 +1,182 @@ +/* + * 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; /* Number of passes in the layer */ + int len; /* len of information */ + double disto; /* add for index (Cfr. Marcela) */ + unsigned char *data; /* data */ +} tcd_layer_t; + +typedef struct { + int x0, y0, x1, y1; /* dimension of the code-blocks : left upper corner (x0, y0) right low corner (x1,y1) */ + int numbps; + int lastbp; /* Add antonin : quantizbug1 */ + int numlenbits; + int len; /* length */ + int numpasses; /* number of pass already done for the code-blocks */ + int numnewpasses; /* number of pass added to the code-blocks */ + int numsegs; /* number of segments */ + tcd_seg_t segs[100]; /* segments informations */ + unsigned char data[8192]; /* Data */ + int numpassesinlayers; /* number of passes in the layer */ + tcd_layer_t layers[100]; /* layer information */ + int totalpasses; /* total number of passes */ + tcd_pass_t passes[100]; /* information about the passes */ +} tcd_cblk_t; + +typedef struct { + int x0, y0, x1, y1; /* dimension of the precinct : left upper corner (x0, y0) right low corner (x1,y1) */ + int cw, ch; /* number of precinct in width and heigth */ + tcd_cblk_t *cblks; /* code-blocks informations */ + tgt_tree_t *incltree; /* inclusion tree */ + tgt_tree_t *imsbtree; /* IMSB tree */ +} tcd_precinct_t; + +typedef struct { + int x0, y0, x1, y1; /* dimension of the subband : left upper corner (x0, y0) right low corner (x1,y1) */ + int bandno; + tcd_precinct_t *precincts; /* precinct information */ + int numbps; + int stepsize; +} tcd_band_t; + +typedef struct { + int x0, y0, x1, y1; /* dimension of the resolution level : left upper corner (x0, y0) right low corner (x1,y1) */ + int pw, ph; + int numbands; /* number sub-band for the resolution level */ + tcd_band_t bands[3]; /* subband information */ +} tcd_resolution_t; + +typedef struct { + int x0, y0, x1, y1; /* dimension of component : left upper corner (x0, y0) right low corner (x1,y1) */ + int numresolutions; /* number of resolutions level */ + tcd_resolution_t *resolutions; /* resolutions information */ + int *data; /* data of the component */ + int nbpix; /* add fixed_quality */ +} tcd_tilecomp_t; + +typedef struct { + int x0, y0, x1, y1; /* dimension of the tile : left upper corner (x0, y0) right low corner (x1,y1) */ + int numcomps; /* number of components in tile */ + tcd_tilecomp_t *comps; /* Components information */ + int nbpix; /* add fixed_quality */ + double distotile; /* add fixed_quality */ + double distolayer[100]; /* add fixed_quality */ +} tcd_tile_t; + +typedef struct { + int tw, th; /* number of tiles in width and heigth */ + tcd_tile_t *tiles; /* Tiles information */ +} tcd_image_t; + +/* + * Initialize the tile coder (reuses the memory allocated by tcd_malloc_encode) + * img: raw image + * cp: coding parameters + * curtileno : number that identifies the tile that will be encoded + */ +void tcd_init_encode(j2k_image_t * img, j2k_cp_t * cp, int curtileno); + + +/* + * Initialize the tile coder (allocate the memory) + * img: raw image + * cp: coding parameters + * curtileno : number that identifies the tile that will be encoded + */ +void tcd_malloc_encode(j2k_image_t * img, j2k_cp_t * cp, int curtileno); + + +/* + * Initialize the tile decoder + * img: raw image + * cp: coding parameters + */ +void tcd_init(j2k_image_t * img, j2k_cp_t * cp); + + +/* + * Free the memory allocated for encoding + * img: raw image + * cp: coding parameters + * curtileno : number that identifies the tile that will be encoded + */ +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 + * info_IM: creation of index file + */ +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 + * info_IM: creation of index file + */ +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/jpwl/decoder/libopenjpeg/tgt.c b/jpwl/decoder/libopenjpeg/tgt.c new file mode 100644 index 00000000..0dfe9089 --- /dev/null +++ b/jpwl/decoder/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/jpwl/decoder/libopenjpeg/tgt.h b/jpwl/decoder/libopenjpeg/tgt.h new file mode 100644 index 00000000..d7b5ab7e --- /dev/null +++ b/jpwl/decoder/libopenjpeg/tgt.h @@ -0,0 +1,87 @@ +/* + * 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; + + + +/* + * Reset a tag-tree (set all leaves to 0) + * tree: tag-tree to reset + */ +void tgt_reset(tgt_tree_t * tree); + +/* + * 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); + +/* + * 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 diff --git a/jpwl/encoder/jpwlenc/.cvsignore b/jpwl/encoder/jpwlenc/.cvsignore new file mode 100644 index 00000000..5aca9ad5 --- /dev/null +++ b/jpwl/encoder/jpwlenc/.cvsignore @@ -0,0 +1,6 @@ +obj +obj.w32 +bin +bin.w32 +lib +lib.w32 diff --git a/jpwl/encoder/jpwlenc/Makefile b/jpwl/encoder/jpwlenc/Makefile new file mode 100644 index 00000000..27dc9a5c --- /dev/null +++ b/jpwl/encoder/jpwlenc/Makefile @@ -0,0 +1,94 @@ +# $Id$ +# +# makefile for OpenJPEG codec + +OPENJPEG_DIR = ../libopenjpeg + +ifndef DEBUG + LDFLAGS = -s -lm +else + LDFLAGS = -lm +endif + +CFLAGS = -Wall -O3 -fno-strength-reduce -fomit-frame-pointer -I$(OPENJPEG_DIR) + +OBJ_DIR_W32 = obj.w32 +BIN_DIR_W32 = bin.w32 +LIB_DIR_W32 = $(OPENJPEG_DIR)/lib.w32 + +ifdef MINGW32 + CC = i386-mingw32-gcc + CFLAGS += -DDONT_HAVE_GETOPT + OBJ_DIR = $(OBJ_DIR_W32) + BIN_DIR = $(BIN_DIR_W32) + LIB_DIR = lib.w32 + all: $(BIN_DIR) $(OBJ_DIR) $(LIB_DIR) \ + $(addprefix $(BIN_DIR)/,j2k_to_image.exe image_to_j2k.exe) +else + CC = gcc + OBJ_DIR = obj + BIN_DIR = bin + LIB_DIR = lib + all: $(BIN_DIR) $(OBJ_DIR) $(LIB_DIR) \ + $(addprefix $(BIN_DIR)/,j2k_to_image image_to_j2k) +endif + +ifdef DYNAMIC + ifdef MINGW32 + LIB_OPENJPEG = $(LIB_DIR)/libopenjpeg.dll + LDFLAGS += -L$(LIB_DIR) -lopenjpeg + else + LIB_OPENJPEG = $(OPENJPEG_DIR)/$(LIB_DIR)/libopenjpeg.so + LDFLAGS += -L$(OPENJPEG_DIR)/$(LIB_DIR) -lopenjpeg + endif +else + LIB_OPENJPEG = $(OPENJPEG_DIR)/$(LIB_DIR)/libopenjpeg.a + LDFLAGS += $(LIB_OPENJPEG) +endif + +$(BIN_DIR): + mkdir $(BIN_DIR) + +$(OBJ_DIR): + mkdir $(OBJ_DIR) + +$(LIB_DIR): + mkdir $(LIB_DIR) + +$(LIB_DIR)/libopenjpeg.dll: $(OPENJPEG_DIR)/$(LIB_DIR)/libopenjpeg.dll + ln -sf ../$< $@ +$(OPENJPEG_DIR)/$(LIB_DIR)/libopenjpeg.dll: + cd $(OPENJPEG_DIR) && \ + $(MAKE) $(OBJ_DIR) $(LIB_DIR) $(LIB_DIR)/libopenjpeg.dll +$(OPENJPEG_DIR)/$(LIB_DIR)/libopenjpeg.a: + cd $(OPENJPEG_DIR) && \ + $(MAKE) $(OBJ_DIR) $(LIB_DIR) $(LIB_DIR)/libopenjpeg.a +$(OPENJPEG_DIR)/$(LIB_DIR)/libopenjpeg.so: + cd $(OPENJPEG_DIR) && \ + $(MAKE) $(LIB_DIR) $(LIB_DIR)/libopenjpeg.so + +$(OBJ_DIR)/%.o: + $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $< + +$(OBJ_DIR)/getopt.o: compat/getopt.c +$(OBJ_DIR)/convert.o: convert.c +$(OBJ_DIR)/j2k_to_image.o: j2k_to_image.c +$(OBJ_DIR)/image_to_j2k.o: image_to_j2k.c convert.h + +J2I_OBJS = $(addprefix $(OBJ_DIR)/,j2k_to_image.o) +I2J_OBJS = $(addprefix $(OBJ_DIR)/,image_to_j2k.o convert.o) + +$(BIN_DIR)/j2k_to_image: $(J2I_OBJS) $(LIB_OPENJPEG) + ${CC} -o $@ $(J2I_OBJS) ${LDFLAGS} + +$(BIN_DIR)/image_to_j2k: $(I2J_OBJS) $(LIB_OPENJPEG) + ${CC} -o $@ $(I2J_OBJS) ${LDFLAGS} + +$(BIN_DIR)/j2k_to_image.exe: $(J2I_OBJS) $(LIB_OPENJPEG) + ${CC} -o $@ $(J2I_OBJS) ${LDFLAGS} + +$(BIN_DIR)/image_to_j2k.exe: $(I2J_OBJS) $(LIB_OPENJPEG) $(OBJ_DIR)/getopt.o + ${CC} -o $@ $(I2J_OBJS) ${LDFLAGS} $(OBJ_DIR)/getopt.o + +clean: + rm -f $(BIN_DIR_W32)/* $(BIN_DIR)/* $(OBJ_DIR_W32)/* $(OBJ_DIR)/* diff --git a/jpwl/encoder/jpwlenc/compat/getopt.c b/jpwl/encoder/jpwlenc/compat/getopt.c new file mode 100644 index 00000000..d0082c51 --- /dev/null +++ b/jpwl/encoder/jpwlenc/compat/getopt.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 1987, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* last review : october 29th, 2002 */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include + +int opterr = 1, /* if error message should be printed */ + optind = 1, /* index into parent argv vector */ + optopt, /* character checked for validity */ + optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ + +#define BADCH (int)'?' +#define BADARG (int)':' +#define EMSG "" + +/* + * getopt -- + * Parse argc/argv argument vector. + */ +int getopt(nargc, nargv, ostr) +int nargc; +char *const *nargv; +const char *ostr; +{ +# define __progname nargv[0] + static char *place = EMSG; /* option letter processing */ + char *oli; /* option letter list index */ + + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc || *(place = nargv[optind]) != '-') { + place = EMSG; + return (-1); + } + if (place[1] && *++place == '-') { /* found "--" */ + ++optind; + place = EMSG; + return (-1); + } + } /* option letter okay? */ + if ((optopt = (int) *place++) == (int) ':' || + !(oli = strchr(ostr, optopt))) { + /* + * if the user didn't specify '-' as an option, + * assume it means -1. + */ + if (optopt == (int) '-') + return (-1); + if (!*place) + ++optind; + if (opterr && *ostr != ':') + (void) fprintf(stderr, + "%s: illegal option -- %c\n", __progname, optopt); + return (BADCH); + } + if (*++oli != ':') { /* don't need argument */ + optarg = NULL; + if (!*place) + ++optind; + } else { /* need an argument */ + if (*place) /* no white space */ + optarg = place; + else if (nargc <= ++optind) { /* no arg */ + place = EMSG; + if (*ostr == ':') + return (BADARG); + if (opterr) + (void) fprintf(stderr, + "%s: option requires an argument -- %c\n", + __progname, optopt); + return (BADCH); + } else /* white space */ + optarg = nargv[optind]; + place = EMSG; + ++optind; + } + return (optopt); /* dump back option letter */ +} diff --git a/jpwl/encoder/jpwlenc/compat/getopt.h b/jpwl/encoder/jpwlenc/compat/getopt.h new file mode 100644 index 00000000..ab9c1a7b --- /dev/null +++ b/jpwl/encoder/jpwlenc/compat/getopt.h @@ -0,0 +1,14 @@ +/* last review : october 29th, 2002 */ + +#ifndef _GETOPT_H_ +#define _GETOPT_H_ + +extern int opterr; +extern int optind; +extern int optopt; +extern int optreset; +extern char *optarg; + +extern int getopt(int nargc, char *const *nargv, const char *ostr); + +#endif /* _GETOPT_H_ */ diff --git a/jpwl/encoder/jpwlenc/convert.c b/jpwl/encoder/jpwlenc/convert.c new file mode 100644 index 00000000..0bbb022a --- /dev/null +++ b/jpwl/encoder/jpwlenc/convert.c @@ -0,0 +1,913 @@ +/* + * Copyright (c) 2001-2003, 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 + +/* -->> -->> -->> -->> + + BMP IMAGE FORMAT + + <<-- <<-- <<-- <<-- */ + +/* UINT2 defines a two byte word */ +typedef unsigned short int UINT2; + +/* UINT4 defines a four byte word */ +typedef unsigned long int UINT4; + +typedef struct { + UINT2 bfType; /* 'BM' for Bitmap (19776) */ + UINT4 bfSize; /* Size of the file */ + UINT2 bfReserved1; /* Reserved : 0 */ + UINT2 bfReserved2; /* Reserved : 0 */ + UINT4 bfOffBits; /* Offset */ +} BITMAPFILEHEADER_t; + +typedef struct { + UINT4 biSize; /* Size of the structure in bytes */ + UINT4 biWidth; /* Width of the image in pixels */ + UINT4 biHeight; /* Heigth of the image in pixels */ + UINT2 biPlanes; /* 1 */ + UINT2 biBitCount; /* Number of color bits by pixels */ + UINT4 biCompression; /* Type of encoding 0: none 1: RLE8 2: RLE4 */ + UINT4 biSizeImage; /* Size of the image in bytes */ + UINT4 biXpelsPerMeter; /* Horizontal (X) resolution in pixels/meter */ + UINT4 biYpelsPerMeter; /* Vertical (Y) resolution in pixels/meter */ + UINT4 biClrUsed; /* Number of color used in the image (0: ALL) */ + UINT4 biClrImportant; /* Number of important color (0: ALL) */ +} BITMAPINFOHEADER_t; + +int bmptoimage(char *filename, j2k_image_t * img, int subsampling_dx, + int subsampling_dy, int Dim[2]) +{ + FILE *IN; + FILE *Compo0 = NULL, *Compo1 = NULL, *Compo2 = NULL; + BITMAPFILEHEADER_t File_h; + BITMAPINFOHEADER_t Info_h; + unsigned char *RGB; + unsigned char *table_R, *table_G, *table_B; + unsigned int j, w, h, PAD, type = 0; + + int i; + int gray_scale = 1, not_end_file = 1; + + unsigned int line = 0, col = 0; + unsigned char v, v2; + UINT4 W, H; + + IN = fopen(filename, "rb"); + if (!IN) { + fprintf(stderr, + "\033[0;33mFailed to open %s for reading !!\033[0;39m\n", + filename); + return 0; + } + + File_h.bfType = getc(IN); + File_h.bfType = (getc(IN) << 8) + File_h.bfType; + + if (File_h.bfType != 19778) { + printf("Error, not a BMP file!\n"); + return 0; + } else { + /* FILE HEADER */ + /* ------------- */ + File_h.bfSize = getc(IN); + File_h.bfSize = (getc(IN) << 8) + File_h.bfSize; + File_h.bfSize = (getc(IN) << 16) + File_h.bfSize; + File_h.bfSize = (getc(IN) << 24) + File_h.bfSize; + + File_h.bfReserved1 = getc(IN); + File_h.bfReserved1 = (getc(IN) << 8) + File_h.bfReserved1; + + File_h.bfReserved2 = getc(IN); + File_h.bfReserved2 = (getc(IN) << 8) + File_h.bfReserved2; + + File_h.bfOffBits = getc(IN); + File_h.bfOffBits = (getc(IN) << 8) + File_h.bfOffBits; + File_h.bfOffBits = (getc(IN) << 16) + File_h.bfOffBits; + File_h.bfOffBits = (getc(IN) << 24) + File_h.bfOffBits; + + /* INFO HEADER */ + /* ------------- */ + + Info_h.biSize = getc(IN); + Info_h.biSize = (getc(IN) << 8) + Info_h.biSize; + Info_h.biSize = (getc(IN) << 16) + Info_h.biSize; + Info_h.biSize = (getc(IN) << 24) + Info_h.biSize; + + Info_h.biWidth = getc(IN); + Info_h.biWidth = (getc(IN) << 8) + Info_h.biWidth; + Info_h.biWidth = (getc(IN) << 16) + Info_h.biWidth; + Info_h.biWidth = (getc(IN) << 24) + Info_h.biWidth; + w = Info_h.biWidth; + + Info_h.biHeight = getc(IN); + Info_h.biHeight = (getc(IN) << 8) + Info_h.biHeight; + Info_h.biHeight = (getc(IN) << 16) + Info_h.biHeight; + Info_h.biHeight = (getc(IN) << 24) + Info_h.biHeight; + h = Info_h.biHeight; + + Info_h.biPlanes = getc(IN); + Info_h.biPlanes = (getc(IN) << 8) + Info_h.biPlanes; + + Info_h.biBitCount = getc(IN); + Info_h.biBitCount = (getc(IN) << 8) + Info_h.biBitCount; + + Info_h.biCompression = getc(IN); + Info_h.biCompression = (getc(IN) << 8) + Info_h.biCompression; + Info_h.biCompression = (getc(IN) << 16) + Info_h.biCompression; + Info_h.biCompression = (getc(IN) << 24) + Info_h.biCompression; + + Info_h.biSizeImage = getc(IN); + Info_h.biSizeImage = (getc(IN) << 8) + Info_h.biSizeImage; + Info_h.biSizeImage = (getc(IN) << 16) + Info_h.biSizeImage; + Info_h.biSizeImage = (getc(IN) << 24) + Info_h.biSizeImage; + + Info_h.biXpelsPerMeter = getc(IN); + Info_h.biXpelsPerMeter = (getc(IN) << 8) + Info_h.biXpelsPerMeter; + Info_h.biXpelsPerMeter = (getc(IN) << 16) + Info_h.biXpelsPerMeter; + Info_h.biXpelsPerMeter = (getc(IN) << 24) + Info_h.biXpelsPerMeter; + + Info_h.biYpelsPerMeter = getc(IN); + Info_h.biYpelsPerMeter = (getc(IN) << 8) + Info_h.biYpelsPerMeter; + Info_h.biYpelsPerMeter = (getc(IN) << 16) + Info_h.biYpelsPerMeter; + Info_h.biYpelsPerMeter = (getc(IN) << 24) + Info_h.biYpelsPerMeter; + + Info_h.biClrUsed = getc(IN); + Info_h.biClrUsed = (getc(IN) << 8) + Info_h.biClrUsed; + Info_h.biClrUsed = (getc(IN) << 16) + Info_h.biClrUsed; + Info_h.biClrUsed = (getc(IN) << 24) + Info_h.biClrUsed; + + Info_h.biClrImportant = getc(IN); + Info_h.biClrImportant = (getc(IN) << 8) + Info_h.biClrImportant; + Info_h.biClrImportant = (getc(IN) << 16) + Info_h.biClrImportant; + Info_h.biClrImportant = (getc(IN) << 24) + Info_h.biClrImportant; + + /* Read the data and store them in the OUT file */ + + if (Info_h.biBitCount == 24) { + img->x0 = Dim[0]; + img->y0 = Dim[1]; + img->x1 = + !Dim[0] ? (w - 1) * subsampling_dx + 1 : Dim[0] + (w - + 1) * + subsampling_dx + 1; + img->y1 = + !Dim[1] ? (h - 1) * subsampling_dy + 1 : Dim[1] + (h - + 1) * + subsampling_dy + 1; + img->numcomps = 3; + img->color_space = 1; + img->comps = + (j2k_comp_t *) malloc(img->numcomps * sizeof(j2k_comp_t)); + for (i = 0; i < img->numcomps; i++) { + img->comps[i].prec = 8; + img->comps[i].bpp = 8; + img->comps[i].sgnd = 0; + img->comps[i].dx = subsampling_dx; + img->comps[i].dy = subsampling_dy; + } + Compo0 = fopen("Compo0", "wb"); + if (!Compo0) { + fprintf(stderr, + "\033[0;33mFailed to open Compo0 for writing !\033[0;39m\n"); + } + Compo1 = fopen("Compo1", "wb"); + if (!Compo1) { + fprintf(stderr, + "\033[0;33mFailed to open Compo1 for writing !\033[0;39m\n"); + } + Compo2 = fopen("Compo2", "wb"); + if (!Compo2) { + fprintf(stderr, + "\033[0;33mFailed to open Compo2 for writing !\033[0;39m\n"); + } + + /* Place the cursor at the beginning of the image information */ + fseek(IN, 0, SEEK_SET); + fseek(IN, File_h.bfOffBits, SEEK_SET); + + W = Info_h.biWidth; + H = Info_h.biHeight; + + // PAD = 4 - (3 * W) % 4; + // PAD = (PAD == 4) ? 0 : PAD; + PAD = (3 * W) % 4 ? 4 - (3 * W) % 4 : 0; + + + RGB = + (unsigned char *) malloc((3 * W + PAD) * H * + sizeof(unsigned char)); + + fread(RGB, sizeof(unsigned char), (3 * W + PAD) * H, IN); + + for (j = 0; j < (3 * W + PAD) * H; j++) { + unsigned char elmt; + int Wp = 3 * W + PAD; + + elmt = RGB[(H - (j / Wp + 1)) * Wp + j % Wp]; + if ((j % Wp) < (3 * W)) { + switch (type) { + case 0: + fprintf(Compo2, "%c", elmt); + type = 1; + break; + case 1: + fprintf(Compo1, "%c", elmt); + type = 2; + break; + case 2: + fprintf(Compo0, "%c", elmt); + type = 0; + break; + } + } + } + + fclose(Compo0); + fclose(Compo1); + fclose(Compo2); + free(RGB); + } else if (Info_h.biBitCount == 8 && Info_h.biCompression == 0) { + img->x0 = Dim[0]; + img->y0 = Dim[1]; + img->x1 = + !Dim[0] ? (w - 1) * subsampling_dx + 1 : Dim[0] + (w - + 1) * + subsampling_dx + 1; + img->y1 = + !Dim[1] ? (h - 1) * subsampling_dy + 1 : Dim[1] + (h - + 1) * + subsampling_dy + 1; + + table_R = (unsigned char *) malloc(256 * sizeof(unsigned char)); + table_G = (unsigned char *) malloc(256 * sizeof(unsigned char)); + table_B = (unsigned char *) malloc(256 * sizeof(unsigned char)); + + for (j = 0; j < Info_h.biClrUsed; j++) { + table_B[j] = getc(IN); + table_G[j] = getc(IN); + table_R[j] = getc(IN); + getc(IN); + if (table_R[j] != table_G[j] && table_R[j] != table_B[j] + && table_G[j] != table_B[j]) + gray_scale = 0; + } + + /* Place the cursor at the beginning of the image information */ + fseek(IN, 0, SEEK_SET); + fseek(IN, File_h.bfOffBits, SEEK_SET); + + W = Info_h.biWidth; + H = Info_h.biHeight; + if (Info_h.biWidth % 2) + W++; + + RGB = (unsigned char *) malloc(W * H * sizeof(unsigned char)); + + fread(RGB, sizeof(unsigned char), W * H, IN); + if (gray_scale) { + img->numcomps = 1; + img->comps = + (j2k_comp_t *) malloc(img->numcomps * sizeof(j2k_comp_t)); + img->comps[0].prec = 8; + img->comps[0].bpp = 8; + img->comps[0].sgnd = 0; + img->comps[0].dx = subsampling_dx; + img->comps[0].dy = subsampling_dy; + Compo0 = fopen("Compo0", "wb"); + if (!Compo0) { + fprintf(stderr, + "\033[0;33mFailed to open Compo0 for writing !\033[0;39m\n"); + } + for (j = 0; j < W * H; j++) { + if ((j % W < W - 1 && Info_h.biWidth % 2) + || !(Info_h.biWidth % 2)) + fprintf(Compo0, "%c", + table_R[RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)]]); + } + fclose(Compo0); + } else { + img->numcomps = 3; + img->comps = + (j2k_comp_t *) malloc(img->numcomps * sizeof(j2k_comp_t)); + for (i = 0; i < img->numcomps; i++) { + img->comps[i].prec = 8; + img->comps[i].bpp = 8; + img->comps[i].sgnd = 0; + img->comps[i].dx = subsampling_dx; + img->comps[i].dy = subsampling_dy; + } + + Compo0 = fopen("Compo0", "wb"); + if (!Compo0) { + fprintf(stderr, + "\033[0;33mFailed to open Compo0 for writing !\033[0;39m\n"); + } + Compo1 = fopen("Compo1", "wb"); + if (!Compo1) { + fprintf(stderr, + "\033[0;33mFailed to open Compo1 for writing !\033[0;39m\n"); + } + Compo2 = fopen("Compo2", "wb"); + if (!Compo2) { + fprintf(stderr, + "\033[0;33mFailed to open Compo2 for writing !\033[0;39m\n"); + } + + for (j = 0; j < W * H; j++) { + if ((j % W < W - 1 && Info_h.biWidth % 2) + || !(Info_h.biWidth % 2)) { + fprintf(Compo0, "%c", + table_R[RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)]]); + fprintf(Compo1, "%c", + table_G[RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)]]); + fprintf(Compo2, "%c", + table_B[RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)]]); + } + + } + fclose(Compo0); + fclose(Compo1); + fclose(Compo2); + } + free(RGB); + + } else if (Info_h.biBitCount == 8 && Info_h.biCompression == 1) { + img->x0 = Dim[0]; + img->y0 = Dim[1]; + img->x1 = + !Dim[0] ? (w - 1) * subsampling_dx + 1 : Dim[0] + (w - + 1) * + subsampling_dx + 1; + img->y1 = + !Dim[1] ? (h - 1) * subsampling_dy + 1 : Dim[1] + (h - + 1) * + subsampling_dy + 1; + + table_R = (unsigned char *) malloc(256 * sizeof(unsigned char)); + table_G = (unsigned char *) malloc(256 * sizeof(unsigned char)); + table_B = (unsigned char *) malloc(256 * sizeof(unsigned char)); + + for (j = 0; j < Info_h.biClrUsed; j++) { + table_B[j] = getc(IN); + table_G[j] = getc(IN); + table_R[j] = getc(IN); + getc(IN); + if (table_R[j] != table_G[j] && table_R[j] != table_B[j] + && table_G[j] != table_B[j]) + gray_scale = 0; + } + + /* Place the cursor at the beginning of the image information */ + fseek(IN, 0, SEEK_SET); + fseek(IN, File_h.bfOffBits, SEEK_SET); + + if (gray_scale) { + img->numcomps = 1; + img->comps = (j2k_comp_t *) malloc(sizeof(j2k_comp_t)); + img->comps[0].prec = 8; + img->comps[0].bpp = 8; + img->comps[0].sgnd = 0; + img->comps[0].dx = subsampling_dx; + img->comps[0].dy = subsampling_dy; + Compo0 = fopen("Compo0", "wb"); + if (!Compo0) { + fprintf(stderr, + "\033[0;33mFailed to open Compo0 for writing !\033[0;39m\n"); + } + } else { + img->numcomps = 3; + img->comps = + (j2k_comp_t *) malloc(img->numcomps * sizeof(j2k_comp_t)); + for (i = 0; i < img->numcomps; i++) { + img->comps[i].prec = 8; + img->comps[i].bpp = 8; + img->comps[i].sgnd = 0; + img->comps[i].dx = subsampling_dx; + img->comps[i].dy = subsampling_dy; + } + Compo0 = fopen("Compo0", "wb"); + if (!Compo0) { + fprintf(stderr, + "\033[0;33mFailed to open Compo0 for writing !\033[0;39m\n"); + } + Compo1 = fopen("Compo1", "wb"); + if (!Compo1) { + fprintf(stderr, + "\033[0;33mFailed to open Compo1 for writing !\033[0;39m\n"); + } + Compo2 = fopen("Compo2", "wb"); + if (!Compo2) { + fprintf(stderr, + "\033[0;33mFailed to open Compo2 for writing !\033[0;39m\n"); + } + } + + RGB = + (unsigned char *) malloc(Info_h.biWidth * Info_h.biHeight * + sizeof(unsigned char)); + + while (not_end_file) { + v = getc(IN); + if (v) { + v2 = getc(IN); + for (i = 0; i < (int) v; i++) { + RGB[line * Info_h.biWidth + col] = v2; + col++; + } + } else { + v = getc(IN); + switch (v) { + case 0: + col = 0; + line++; + break; + case 1: + line++; + not_end_file = 0; + break; + case 2: + printf("No Delta supported\n"); + return 1; + break; + default: + for (i = 0; i < v; i++) { + v2 = getc(IN); + RGB[line * Info_h.biWidth + col] = v2; + col++; + } + if (v % 2) + v2 = getc(IN); + } + } + } + if (gray_scale) { + for (line = 0; line < Info_h.biHeight; line++) + for (col = 0; col < Info_h.biWidth; col++) + fprintf(Compo0, "%c", table_R[(int) + RGB[(Info_h.biHeight - line - + 1) * Info_h.biWidth + + col]]); + fclose(Compo0); + } else { + for (line = 0; line < Info_h.biHeight; line++) + for (col = 0; col < Info_h.biWidth; col++) { + fprintf(Compo0, "%c", table_R[(int) + RGB[(Info_h.biHeight - line - + 1) * Info_h.biWidth + + col]]); + fprintf(Compo1, "%c", table_G[(int) + RGB[(Info_h.biHeight - line - + 1) * Info_h.biWidth + + col]]); + fprintf(Compo2, "%c", table_B[(int) + RGB[(Info_h.biHeight - line - + 1) * Info_h.biWidth + + col]]); + } + fclose(Compo0); + fclose(Compo1); + fclose(Compo2); + } + free(RGB); + } else + fprintf(stderr, + "Other system than 24 bits/pixels or 8 bits (no RLE coding) is not yet implemented [%d]\n", + Info_h.biBitCount); + + fclose(IN); + return 1; + } +} + + /* -->> -->> -->> -->> + + PGX IMAGE FORMAT + + <<-- <<-- <<-- <<-- */ + + +unsigned char readuchar(FILE * f) +{ + unsigned char c1; + fread(&c1, 1, 1, f); + return c1; +} + +unsigned short readushort(FILE * f, int bigendian) +{ + unsigned char c1, c2; + fread(&c1, 1, 1, f); + fread(&c2, 1, 1, f); + if (bigendian) + return (c1 << 8) + c2; + else + return (c2 << 8) + c1; +} + +unsigned int readuint(FILE * f, int bigendian) +{ + unsigned char c1, c2, c3, c4; + fread(&c1, 1, 1, f); + fread(&c2, 1, 1, f); + fread(&c3, 1, 1, f); + fread(&c4, 1, 1, f); + if (bigendian) + return (c1 << 24) + (c2 << 16) + (c3 << 8) + c4; + else + return (c4 << 24) + (c3 << 16) + (c2 << 8) + c1; +} + +int pgxtoimage(char *filename, j2k_image_t * img, int tdy, + int subsampling_dx, int subsampling_dy, int Dim[2], + j2k_cp_t cp) +{ + FILE *f; + int w, h, prec; + int i, compno, bandno; + char str[256], endian[16]; + char sign; + int bigendian; + j2k_comp_t *comp; + + img->numcomps = 1; + img->color_space = 2; + img->comps = (j2k_comp_t *) malloc(img->numcomps * sizeof(j2k_comp_t)); + for (compno = 0; compno < img->numcomps; compno++) { + FILE *src; + char tmp[16]; + int max = 0; + int Y1; + comp = &img->comps[compno]; + sprintf(str, "%s", filename); + f = fopen(str, "rb"); + if (!f) { + fprintf(stderr, "Failed to open %s for reading !\n", str); + return 0; + } + if (fscanf(f, "PG %s %c %d %d %d", endian, &sign, &prec, &w, &h) == 5) { + fgetc(f); + if (!strcmp(endian, "ML")) + bigendian = 1; + else + bigendian = 0; + if (compno == 0) { + img->x0 = Dim[0]; + img->y0 = Dim[1]; + img->x1 = + !Dim[0] ? (w - 1) * subsampling_dx + 1 : Dim[0] + (w - + 1) * + subsampling_dx + 1; + img->y1 = + !Dim[1] ? (h - 1) * subsampling_dy + 1 : Dim[1] + (h - + 1) * + subsampling_dy + 1; + } else { + if (w != img->x1 || h != img->y1) + return 0; + } + + if (sign == '-') { + comp->sgnd = 1; + } else { + comp->sgnd = 0; + } + comp->prec = prec; + comp->dx = subsampling_dx; + comp->dy = subsampling_dy; + bandno = 1; + + Y1 = cp.ty0 + bandno * cp.tdy < + img->y1 ? cp.ty0 + bandno * cp.tdy : img->y1; + Y1 -= img->y0; + + sprintf(tmp, "bandtile%d", bandno); /* bandtile file */ + src = fopen(tmp, "wb"); + if (!src) { + fprintf(stderr, "failed to open %s for writing !\n", tmp); + } + for (i = 0; i < w * h; i++) { + int v; + if (i == Y1 * w / subsampling_dy && tdy != -1) { /* bandtile is full */ + fclose(src); + bandno++; + sprintf(tmp, "bandtile%d", bandno); + src = fopen(tmp, "wb"); + if (!src) { + fprintf(stderr, "failed to open %s for writing !\n", tmp); + } + Y1 = cp.ty0 + bandno * cp.tdy < + img->y1 ? cp.ty0 + bandno * cp.tdy : img->y1; + Y1 -= img->y0; + } + if (comp->prec <= 8) { + if (!comp->sgnd) { + v = readuchar(f); + } else { + v = (char) readuchar(f); + } + } else if (comp->prec <= 16) { + if (!comp->sgnd) { + v = readushort(f, bigendian); + } else { + v = (short) readushort(f, bigendian); + } + } else { + if (!comp->sgnd) { + v = readuint(f, bigendian); + } else { + v = (int) readuint(f, bigendian); + } + } + if (v > max) + max = v; + fprintf(src, "%d ", v); + } + } else { + return 0; + } + fclose(f); + fclose(src); + comp->bpp = int_floorlog2(max) + 1; + } + return 1; +} + +/* -->> -->> -->> -->> + + PNM IMAGE FORMAT + + <<-- <<-- <<-- <<-- */ + +int pnmtoimage(char *filename, j2k_image_t * img, int subsampling_dx, + int subsampling_dy, int Dim[2]) +{ + FILE *f; + FILE *Compo0, *Compo1, *Compo2; + int w, h; + int i; + char value; + char comment[256]; + + f = fopen(filename, "rb"); + if (!f) { + fprintf(stderr, + "\033[0;33mFailed to open %s for reading !!\033[0;39m\n", + filename); + return 0; + } + + if (fgetc(f) != 'P') + return 0; + value = fgetc(f); + + if (value == '2') { + fgetc(f); + if (fgetc(f) == '#') { + fseek(f, 0, SEEK_SET); + fscanf(f, "P2\n"); + fgets(comment, 256, f); + fscanf(f, "%d %d\n255", &w, &h); + } else { + fseek(f, 0, SEEK_SET); + fscanf(f, "P2\n%d %d\n255", &w, &h); + } + + fgetc(f); + img->x0 = Dim[0]; + img->y0 = Dim[1]; + img->x1 = + !Dim[0] ? (w - 1) * subsampling_dx + 1 : Dim[0] + (w - + 1) * + subsampling_dx + 1; + img->y1 = + !Dim[1] ? (h - 1) * subsampling_dy + 1 : Dim[1] + (h - + 1) * + subsampling_dy + 1; + + img->numcomps = 1; + img->color_space = 2; + img->comps = (j2k_comp_t *) malloc(sizeof(j2k_comp_t)); + img->comps[0].prec = 8; + img->comps[0].bpp = 8; + img->comps[0].sgnd = 0; + img->comps[0].dx = subsampling_dx; + img->comps[0].dy = subsampling_dy; + + Compo0 = fopen("Compo0", "wb"); + if (!Compo0) { + fprintf(stderr, + "\033[0;33mFailed to open Compo0 for writing !\033[0;39m\n"); + } + for (i = 0; i < w * h; i++) { + unsigned int l; + fscanf(f, "%d", &l); + fprintf(Compo0, "%c", l); + } + fclose(Compo0); + } else if (value == '5') { + fgetc(f); + if (fgetc(f) == '#') { + fseek(f, 0, SEEK_SET); + fscanf(f, "P5\n"); + fgets(comment, 256, f); + fscanf(f, "%d %d\n255", &w, &h); + } else { + fseek(f, 0, SEEK_SET); + fscanf(f, "P5\n%d %d\n255", &w, &h); + } + + fgetc(f); + img->x0 = Dim[0]; + img->y0 = Dim[1]; + img->x1 = + !Dim[0] ? (w - 1) * subsampling_dx + 1 : Dim[0] + (w - + 1) * + subsampling_dx + 1; + img->y1 = + !Dim[1] ? (h - 1) * subsampling_dy + 1 : Dim[1] + (h - + 1) * + subsampling_dy + 1; + + img->numcomps = 1; + img->color_space = 2; + img->comps = (j2k_comp_t *) malloc(sizeof(j2k_comp_t)); + img->comps[0].prec = 8; + img->comps[0].bpp = 8; + img->comps[0].sgnd = 0; + img->comps[0].dx = subsampling_dx; + img->comps[0].dy = subsampling_dy; + Compo0 = fopen("Compo0", "wb"); + if (!Compo0) { + fprintf(stderr, + "\033[0;33mFailed to open Compo0 for writing !\033[0;39m\n"); + } + for (i = 0; i < w * h; i++) { + unsigned char l; + fread(&l, 1, 1, f); + fwrite(&l, 1, 1, Compo0); + } + fclose(Compo0); + } else if (value == '3') { + fgetc(f); + if (fgetc(f) == '#') { + fseek(f, 0, SEEK_SET); + fscanf(f, "P3\n"); + fgets(comment, 256, f); + fscanf(f, "%d %d\n255", &w, &h); + } else { + fseek(f, 0, SEEK_SET); + fscanf(f, "P3\n%d %d\n255", &w, &h); + } + + fgetc(f); + img->x0 = Dim[0]; + img->y0 = Dim[1]; + img->x1 = + !Dim[0] ? (w - 1) * subsampling_dx + 1 : Dim[0] + (w - + 1) * + subsampling_dx + 1; + img->y1 = + !Dim[1] ? (h - 1) * subsampling_dy + 1 : Dim[1] + (h - + 1) * + subsampling_dy + 1; + img->numcomps = 3; + img->color_space = 1; + img->comps = (j2k_comp_t *) malloc(img->numcomps * sizeof(j2k_comp_t)); + for (i = 0; i < img->numcomps; i++) { + img->comps[i].prec = 8; + img->comps[i].bpp = 8; + img->comps[i].sgnd = 0; + img->comps[i].dx = subsampling_dx; + img->comps[i].dy = subsampling_dy; + } + Compo0 = fopen("Compo0", "wb"); + if (!Compo0) { + fprintf(stderr, + "\033[0;33mFailed to open Compo0 for writing !\033[0;39m\n"); + } + + Compo1 = fopen("Compo1", "wb"); + if (!Compo1) { + fprintf(stderr, + "\033[0;33mFailed to open Compo1 for writing !\033[0;39m\n"); + } + + Compo2 = fopen("Compo2", "wb"); + if (!Compo2) { + fprintf(stderr, + "\033[0;33mFailed to open Compo2 for writing !\033[0;39m\n"); + } + + for (i = 0; i < w * h; i++) { + unsigned int r, g, b; + fscanf(f, "%d", &r); + fscanf(f, "%d", &g); + fscanf(f, "%d", &b); + fprintf(Compo0, "%c", r); + fprintf(Compo1, "%c", g); + fprintf(Compo2, "%c", b); + } + fclose(Compo0); + fclose(Compo1); + fclose(Compo2); + } else if (value == '6') { + fgetc(f); + if (fgetc(f) == '#') { + fseek(f, 0, SEEK_SET); + fscanf(f, "P6\n"); + fgets(comment, 256, f); + fscanf(f, "%d %d\n255", &w, &h); + } else { + fseek(f, 0, SEEK_SET); + fscanf(f, "P6\n%d %d\n255", &w, &h); + } + + fgetc(f); + img->x0 = Dim[0]; + img->y0 = Dim[1]; + img->x1 = + !Dim[0] ? (w - 1) * subsampling_dx + 1 : Dim[0] + (w - + 1) * + subsampling_dx + 1; + img->y1 = + !Dim[1] ? (h - 1) * subsampling_dy + 1 : Dim[1] + (h - + 1) * + subsampling_dy + 1; + img->numcomps = 3; + img->color_space = 1; + img->comps = (j2k_comp_t *) malloc(img->numcomps * sizeof(j2k_comp_t)); + for (i = 0; i < img->numcomps; i++) { + img->comps[i].prec = 8; + img->comps[i].bpp = 8; + img->comps[i].sgnd = 0; + img->comps[i].dx = subsampling_dx; + img->comps[i].dy = subsampling_dy; + } + Compo0 = fopen("Compo0", "wb"); + if (!Compo0) { + fprintf(stderr, + "\033[0;33mFailed to open Compo0 for writing !\033[0;39m\n"); + } + + Compo1 = fopen("Compo1", "wb"); + if (!Compo1) { + fprintf(stderr, + "\033[0;33mFailed to open Compo1 for writing !\033[0;39m\n"); + } + + Compo2 = fopen("Compo2", "wb"); + if (!Compo2) { + fprintf(stderr, + "\033[0;33mFailed to open Compo2 for writing !\033[0;39m\n"); + } + + for (i = 0; i < w * h; i++) { + unsigned char r, g, b; + fread(&r, 1, 1, f); + fread(&g, 1, 1, f); + fread(&b, 1, 1, f); + fwrite(&r, 1, 1, Compo0); + fwrite(&g, 1, 1, Compo1); + fwrite(&b, 1, 1, Compo2); + } + fclose(Compo0); + fclose(Compo1); + fclose(Compo2); + } else { + return 0; + } + fclose(f); + return 1; +} diff --git a/jpwl/encoder/jpwlenc/convert.h b/jpwl/encoder/jpwlenc/convert.h new file mode 100644 index 00000000..337dae76 --- /dev/null +++ b/jpwl/encoder/jpwlenc/convert.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2001-2003, 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 "j2k.h" + +int bmptoimage(char *filename, j2k_image_t * img, int subsampling_dx, + int subsampling_dy, int Dim[2]); + +int pgxtoimage(char *filename, j2k_image_t * img, int tdy, + int subsampling_dx, int subsampling_dy, int Dim[2], + j2k_cp_t cp); + +int pnmtoimage(char *filename, j2k_image_t * img, int subsampling_dx, + int subsampling_dy, int Dim[2]); diff --git a/jpwl/encoder/jpwlenc/image_to_j2k.c b/jpwl/encoder/jpwlenc/image_to_j2k.c new file mode 100644 index 00000000..c1e16c0c --- /dev/null +++ b/jpwl/encoder/jpwlenc/image_to_j2k.c @@ -0,0 +1,948 @@ +/* + * Copyright (c) 2001-2003, 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 +#ifndef DONT_HAVE_GETOPT +#include +#else +#include "compat/getopt.h" +#endif +#include "convert.h" + + +JPWL_cp_t jpwl_cp; +extern info_image info_IM; +int use_index; + +void help_display() +{ + printf("HELP\n----\n\n"); + printf("- the option -help displays the readme.txt file on screen\n\n"); + + + printf("List of parameters for the coder JPEG 2000 :\n"); + printf("\n"); + printf + ("- The markers COD and QCD are writed both of two in the main_header and never appear in the tile_header. The markers in the main header are : SOC SIZ COD QCD COM.\n"); + printf("\n"); + printf + ("- This coder can encode mega image, a test was made on a 24000x24000 pixels color image. You need enough disk space memory (twice the original) to encode the image. (i.e. for a 1.5 Gb image you need a minimum of 3Gb of disk memory)\n"); + printf("\n"); + printf("REMARKS :\n"); + printf("---------\n"); + printf("\n"); + printf + ("* the value of rate enter in the code line is the compression factor !\n"); + printf("exemple :\n"); + printf("\n"); + printf + ("-r 20,10,1 means quality 1 : compress 20x, quality 2 : compress 10x and quality 3 : compress 1x = lossless\n"); + printf("\n"); + printf("By default :\n"); + printf("------------\n"); + printf("\n"); + printf(" * lossless\n"); + printf(" * 1 tile\n"); + printf(" * size of precinct 2^15 x 2^15 (means 1 precinct)\n"); + printf(" * size of code-block 64 x 64\n"); + printf(" * Number of resolution : 6\n"); + printf(" * No SOP marker in the codestream\n"); + printf(" * No EPH marker in the codestream\n"); + printf(" * No sub-sampling in x and y direction\n"); + printf(" * No mode switch activated\n"); + printf(" * progression order : LRCP\n"); + printf(" * No index file\n"); + printf(" * No ROI upshifted\n"); + printf(" * No offset of the origin of the image\n"); + printf(" * No offset of the origin of the tiles\n"); + printf(" * Reversible DWT 5-3\n"); + printf("\n"); + printf("Parameters :\n"); + printf("------------\n"); + printf("\n"); + printf + ("-i : source file (-i source.pnm also *.pgm, *.ppm) required\n"); + printf("\n"); + printf("-o : destination file (-o dest.j2k or .jp2) required\n"); + printf("\n"); + printf("-help : Display the help information optional\n "); + printf("\n"); + printf("-r : different rates (-r 20,10,5) optional\n "); + printf("\n"); + printf("-n : Number of resolution (-n 3) optional\n"); + printf("\n"); + printf("-b : size of code block (-b 32,32) optional\n"); + printf("\n"); + printf("-c : size of precinct (-c 128,128) optional\n"); + printf("\n"); + printf("-t : size of tile (-t 512,512) optional\n"); + printf("\n"); + printf + ("-p : progression order (-p LRCP) [LRCP, RLCP, RPCL, PCRL, CPRL] optional\n"); + printf("\n"); + printf + ("-s : subsampling factor (-s 2,2) [-s X,Y] optional\n"); + printf("\n"); + printf + ("-SOP : write SOP marker before each packet optional\n"); + printf("\n"); + printf + ("-EPH : write EPH marker after each header packet optional\n"); + printf("\n"); + printf + ("-M : mode switch (-M 3) [1=BYPASS(LAZY) 2=RESET 4=RESTART(TERMALL) 8=VSC 16=ERTERM(SEGTERM) 32=SEGMARK(SEGSYM)] optional\n"); + printf + (" for several mode switch you have to add the value of each mode you want\n"); + printf + (" ex : RESTART(4) + RESET(2) + SEGMARK(32) = -M 38\n"); + printf("\n"); + printf + ("-x : Create an index file *.Idx (-x index_name.Idx) optional\n"); + printf("\n"); + printf + ("-ROI:c=%%d,U=%%d : quantization indices upshifted for component c=%%d [%%d = 0,1,2]\n"); + printf + (" with a value of U=%%d [0 <= %%d <= 37] (i.e. -ROI:c=0,U=25) optional\n"); + printf("\n"); + printf + ("-d : offset of the origin of the image (-d 150,300) optional\n"); + printf("\n"); + printf + ("-T : offset of the origin of the tiles (-T 100,75) optional\n"); + printf("\n"); + printf("-I : Use the irreversible DWT 9-7 (-I) optional\n"); + printf("\n"); + printf("IMPORTANT :\n"); + printf("-----------\n"); + printf("\n"); + printf("* subsampling bigger than 2 can produce error\n"); + printf("\n"); + printf("The index file respect the structure below :\n"); + printf("---------------------------------------------\n"); + printf("\n"); + printf("Image_height Image_width\n"); + printf("progression order\n"); + printf("Tiles_size_X Tiles_size_Y\n"); + printf("Components_nb\n"); + printf("Layers_nb\n"); + printf("decomposition_levels\n"); + printf("Precincts_size_X Precincts_size_Y\n"); + printf("Main_header_end_position\n"); + printf("Codestream_size\n"); + printf("Tile0 start_pos end_Theader end_pos\n"); + printf("Tile1 '' '' ''\n"); + printf("...\n"); + printf("TileN '' '' ''\n"); + printf("Tpacket_0 Tile layer res. comp. prec. start_pos end_pos\n"); + printf("...\n"); + printf("Tpacket_M '' '' '' '' '' '' ''\n"); +} + +int give_progression(char progression[4]) +{ + if (progression[0] == 'L' && progression[1] == 'R' + && progression[2] == 'C' && progression[3] == 'P') { + return 0; + } else { + if (progression[0] == 'R' && progression[1] == 'L' + && progression[2] == 'C' && progression[3] == 'P') { + return 1; + } else { + if (progression[0] == 'R' && progression[1] == 'P' + && progression[2] == 'C' && progression[3] == 'L') { + return 2; + } else { + if (progression[0] == 'P' && progression[1] == 'C' + && progression[2] == 'R' && progression[3] == 'L') { + return 3; + } else { + if (progression[0] == 'C' && progression[1] == 'P' + && progression[2] == 'R' && progression[3] == 'L') { + return 4; + } else { + return -1; + } + } + } + } + } +} + +double dwt_norms_97[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} +}; + +int floorlog2(int a) +{ + int l; + for (l = 0; a > 1; l++) { + a >>= 1; + } + return l; +} + +void encode_stepsize(int stepsize, int numbps, int *expn, int *mant) +{ + int p, n; + p = floorlog2(stepsize) - 13; + n = 11 - floorlog2(stepsize); + *mant = (n < 0 ? stepsize >> -n : stepsize << n) & 0x7ff; + *expn = numbps - p; +} + +void calc_explicit_stepsizes(j2k_tccp_t * tccp, int prec) +{ + int numbands, bandno; + numbands = 3 * tccp->numresolutions - 2; + for (bandno = 0; bandno < numbands; bandno++) { + double stepsize; + + int resno, level, orient, gain; + resno = bandno == 0 ? 0 : (bandno - 1) / 3 + 1; + orient = bandno == 0 ? 0 : (bandno - 1) % 3 + 1; + level = tccp->numresolutions - 1 - resno; + gain = + tccp->qmfbid == 0 ? 0 : (orient == + 0 ? 0 : (orient == 1 + || orient == 2 ? 1 : 2)); + if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) { + stepsize = 1.0; + } else { + double norm = dwt_norms_97[orient][level]; + stepsize = (1 << (gain + 1)) / norm; + } + encode_stepsize((int) floor(stepsize * 8192.0), prec + gain, + &tccp->stepsizes[bandno].expn, + &tccp->stepsizes[bandno].mant); + } +} + +int main(int argc, char **argv) +{ + int len; + int NumResolution, numD_min; /* NumResolution : number of resolution */ + int Tile_arg; /* Tile_arg = 0 (not in argument) ou = 1 (in argument) */ + int CSty; /* CSty : coding style */ + int Prog_order; /* progression order (default LRCP) */ + char progression[4]; + int numpocs, numpocs_tile; /* Number of progression order change (POC) default 0 */ + int prcw_init[J2K_MAXRLVLS]; /* Initialisation Precinct width */ + int prch_init[J2K_MAXRLVLS]; /* Initialisation Precinct height */ + //int prcw_init, prch_init; /* Initialisation precincts' size */ + int cblockw_init, cblockh_init; /* Initialisation codeblocks' size */ + int mode, value; /* Mode switch (cblk_style) */ + int subsampling_dx, subsampling_dy; /* subsampling value for dx and dy */ + int ROI_compno, ROI_shift; /* region of interrest */ + int Dim[2]; /* portion of the image coded */ + int TX0, TY0; /* tile off-set */ + j2k_image_t img; + j2k_cp_t cp, cp_init; /* cp_init is used to initialise in multiple tiles */ + j2k_tcp_t *tcp, *tcp_init; /* tcp_init is used to initialise in multiple tile */ + j2k_poc_t POC[32]; /* POC : used in case of Progression order change */ + j2k_poc_t *tcp_poc; + j2k_tccp_t *tccp; + + int i, tileno, j; + char *infile = 0; + char *outfile = 0; + char *index = 0; + char *s, S1, S2, S3; + int ir = 0; + int res_spec = 0; /* For various precinct sizes specification */ + char sep; + char *outbuf, *out; + FILE *f; + + + /* default value */ + /* ------------- */ + NumResolution = 6; + CSty = 0; + cblockw_init = 64; + cblockh_init = 64; + cp.tw = 1; + cp.th = 1; + cp.index_on = 0; + Prog_order = 0; + numpocs = 0; + mode = 0; + subsampling_dx = 1; + subsampling_dy = 1; + ROI_compno = -1; /* no ROI */ + ROI_shift = 0; + Dim[0] = 0; + Dim[1] = 0; + TX0 = 0; + TY0 = 0; + cp.comment = "Created by OpenJPEG version 0.9"; + cp.disto_alloc = 0; + cp.fixed_alloc = 0; + cp.fixed_quality = 0; //add fixed_quality + /* img.PPT=0; */ + + Tile_arg = 0; + cp_init.tcps = (j2k_tcp_t *) malloc(sizeof(j2k_tcp_t)); /* initialisation if only one tile */ + tcp_init = &cp_init.tcps[0]; + tcp_init->numlayers = 0; + jpwl_cp_init(&jpwl_cp); + + cp.intermed_file=0; + use_index=0; + + while (1) { + int c = getopt(argc, argv, + "i:o:r:q:f:t:n:c:b:x:p:s:d:h:P:S:E:M:R:T:C:I:W,F"); + if (c == -1) + break; + switch (c) { + case 'i': /* IN fill */ + infile = optarg; + s = optarg; + while (*s) { + s++; + } + s--; + S3 = *s; + s--; + S2 = *s; + s--; + S1 = *s; + + if ((S1 == 'p' && S2 == 'g' && S3 == 'x') + || (S1 == 'P' && S2 == 'G' && S3 == 'X')) { + cp.image_type = 0; + break; + } + + if ((S1 == 'p' && S2 == 'n' && S3 == 'm') + || (S1 == 'P' && S2 == 'N' && S3 == 'M') + || (S1 == 'p' && S2 == 'g' && S3 == 'm') || (S1 == 'P' + && S2 == 'G' + && S3 == 'M') + || (S1 == 'P' && S2 == 'P' && S3 == 'M') || (S1 == 'p' + && S2 == 'p' + && S3 == 'm')) { + cp.image_type = 1; + break; + } + + if ((S1 == 'b' && S2 == 'm' && S3 == 'p') + || (S1 == 'B' && S2 == 'M' && S3 == 'P')) { + cp.image_type = 2; + break; + } + fprintf(stderr, + "!! Unrecognized format for infile : %c%c%c [accept only *.pnm, *.pgm, *.ppm, *.pgx or *.bmp] !!\n\n", + S1, S2, S3); + return 1; + break; + /* ----------------------------------------------------- */ + case 'o': /* OUT fill */ + outfile = optarg; + while (*outfile) { + outfile++; + } + outfile--; + S3 = *outfile; + outfile--; + S2 = *outfile; + outfile--; + S1 = *outfile; + + outfile = optarg; + + if ((S1 == 'j' && S2 == '2' && S3 == 'k') || (S1 == 'J' && S2 == '2' && S3 == 'K')) + cp.JPEG2000_format=0; + else if ((S1 == 'j' && S2 == 'p' && S3 == '2') || (S1 == 'J' && S2 == 'P' && S3 == '2')) + cp.JPEG2000_format=1; + else { + fprintf(stderr,"Unknown output format image *.%c%c%c [only *.j2k, *.jp2]!! \n",S1,S2,S3); + return 1; + } + + + + break; + /* ----------------------------------------------------- */ + case 'r': /* rates rates/distorsion */ + s = optarg; + while (sscanf(s, "%d", &tcp_init->rates[tcp_init->numlayers]) + == 1) { + tcp_init->numlayers++; + while (*s && *s != ',') { + s++; + } + if (!*s) + break; + s++; + } + cp.disto_alloc = 1; + cp.matrice = NULL; + break; + /* ----------------------------------------------------- */ + case 'q': /* add fixed_quality */ + s = optarg; + while (sscanf(s, "%f", &tcp_init->distoratio[tcp_init->numlayers]) == + 1) { + tcp_init->numlayers++; + while (*s && *s != ',') { + s++; + } + if (!*s) + break; + s++; + } + cp.fixed_quality = 1; + cp.matrice = NULL; + break; + /* dda */ + /* ----------------------------------------------------- */ + case 'f': /* mod fixed_quality (before : -q) */ + s = optarg; + sscanf(s, "%d", &tcp_init->numlayers); + s++; + if (tcp_init->numlayers > 9) + s++; + cp.matrice = + (int *) malloc(tcp_init->numlayers * NumResolution * 3 * + sizeof(int)); + s = s + 2; + for (i = 0; i < tcp_init->numlayers; i++) { + tcp_init->rates[i] = 1; + sscanf(s, "%d,", &cp.matrice[i * NumResolution * 3]); + s += 2; + if (cp.matrice[i * NumResolution * 3] > 9) + s++; + cp.matrice[i * NumResolution * 3 + 1] = 0; + cp.matrice[i * NumResolution * 3 + 2] = 0; + for (j = 1; j < NumResolution; j++) { + sscanf(s, "%d,%d,%d", + &cp.matrice[i * NumResolution * 3 + j * 3 + 0], + &cp.matrice[i * NumResolution * 3 + j * 3 + 1], + &cp.matrice[i * NumResolution * 3 + j * 3 + 2]); + s += 6; + if (cp.matrice[i * NumResolution * 3 + j * 3] > 9) + s++; + if (cp.matrice[i * NumResolution * 3 + j * 3 + 1] > 9) + s++; + if (cp.matrice[i * NumResolution * 3 + j * 3 + 2] > 9) + s++; + } + if (i < tcp_init->numlayers - 1) + s++; + } + cp.fixed_alloc = 1; + break; + /* ----------------------------------------------------- */ + case 't': /* tiles */ + sscanf(optarg, "%d,%d", &cp.tdx, &cp.tdy); + Tile_arg = 1; + break; + /* ----------------------------------------------------- */ + case 'n': /* resolution */ + sscanf(optarg, "%d", &NumResolution); + break; + /* ----------------------------------------------------- */ + case 'c': /* precinct dimension */ + s = optarg; + do { + sep = 0; + sscanf(s, "[%d,%d]%c", &prcw_init[res_spec], + &prch_init[res_spec], &sep); + CSty |= 0x01; + res_spec++; + s = strpbrk(s, "]") + 2; + } while (sep == ','); + break; + /* ----------------------------------------------------- */ + case 'b': /* code-block dimension */ + sscanf(optarg, "%d,%d", &cblockw_init, &cblockh_init); + if (cblockw_init * cblockh_init > 4096 || cblockw_init > 1024 + || cblockw_init < 4 || cblockh_init > 1024 || cblockh_init < 4) { + fprintf(stderr, + "!! Size of code_block error (option -b) !!\n\nRestriction :\n * width*height<=4096\n * 4<=width,height<= 1024\n\n"); + return 1; + } + break; + /* ----------------------------------------------------- */ + case 'x': /* creation of index file */ + index = optarg; + cp.index_on = 1; + use_index = 1; + break; + /* ----------------------------------------------------- */ + case 'p': /* progression order */ + s = optarg; + for (i = 0; i < 4; i++) { + progression[i] = *s; + s++; + } + Prog_order = give_progression(progression); + + if (Prog_order == -1) { + fprintf(stderr, + "Unrecognized progression order [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n"); + return 1; + } + break; + /* ----------------------------------------------------- */ + case 's': /* subsampling factor */ + if (sscanf(optarg, "%d,%d", &subsampling_dx, &subsampling_dy) + != 2) { + fprintf(stderr, + "'-s' sub-sampling argument error ! [-s dx,dy]\n"); + return 1; + } + break; + /* ----------------------------------------------------- */ + case 'd': /* coordonnate of the reference grid */ + if (sscanf(optarg, "%d,%d", &Dim[0], &Dim[1]) != 2) { + fprintf(stderr, + "-d 'coordonnate of the reference grid' argument error !! [-d x0,y0]\n"); + return 1; + } + break; + /* ----------------------------------------------------- */ + case 'h': /* Display an help description */ + help_display(); + return 0; + break; + /* ----------------------------------------------------- */ + case 'P': /* POC */ + fprintf(stderr, "/----------------------------------\\\n"); + fprintf(stderr, "| POC option not fully tested !! |\n"); + fprintf(stderr, "\\----------------------------------/\n"); + + s = optarg; + while (sscanf(s, "T%d=%d,%d,%d,%d,%d,%s", &POC[numpocs].tile, + &POC[numpocs].resno0, &POC[numpocs].compno0, + &POC[numpocs].layno1, &POC[numpocs].resno1, + &POC[numpocs].compno1, POC[numpocs].progorder) == 7) { + POC[numpocs].prg = give_progression(POC[numpocs].progorder); + /* POC[numpocs].tile; */ + numpocs++; + while (*s && *s != '/') { + s++; + } + if (!*s) + break; + s++; + } + break; + /* ------------------------------------------------------ */ + case 'S': /* SOP marker */ + CSty |= 0x02; + break; + /* ------------------------------------------------------ */ + case 'E': /* EPH marker */ + CSty |= 0x04; + break; + /* ------------------------------------------------------ */ + case 'M': /* Mode switch pas tous au point !! */ + if (sscanf(optarg, "%d", &value) == 1) { + for (i = 0; i <= 5; i++) { + int cache = value & (1 << i); + if (cache) + mode |= (1 << i); + } + } + break; + /* ------------------------------------------------------ */ + case 'R': /* ROI */ + if (sscanf(optarg, "OI:c=%d,U=%d", &ROI_compno, &ROI_shift) != 2) { + fprintf(stderr, "ROI error !! [-ROI:c='compno',U='shift']\n"); + return 1; + } + break; + /* ------------------------------------------------------ */ + case 'T': /* Tile offset */ + if (sscanf(optarg, "%d,%d", &TX0, &TY0) != 2) { + fprintf(stderr, "-T 'tile offset' argument error !! [-T X0,Y0]"); + return 1; + } + break; + /* ------------------------------------------------------ */ + case 'C': /* Add a comment */ + cp.comment = optarg; + break; + /* ------------------------------------------------------ */ + case 'I': /* reversible or not */ + ir = 1; + break; + /* ------------------------------------------------------ */ + case 'W': /* version 0.2 enables only EPC on main header and epb in fixed way*/ + jpwl_cp.JPWL_on = 1; + break; + /* ------------------------------------------------------ */ + case 'F': /* use intermed files*/ + cp.intermed_file=1; + break; + /* ------------------------------------------------------ */ + default: + return 1; + } + } + + cp.tx0 = TX0; + cp.ty0 = TY0; + + // inserici i parametri jpwl + + if(jpwl_cp.JPWL_on) + get_jpwl_cp(& cp); + + + + + + /* Error messages */ + /* -------------- */ + if (!infile || !outfile) { + fprintf(stderr, + "usage: image_to_j2k -i image-file -o j2k/jp2-file (+ options)\n"); + return 1; + } + + if ((cp.disto_alloc || cp.fixed_alloc || cp.fixed_quality)&&(!(cp.disto_alloc ^ cp.fixed_alloc ^ cp.fixed_quality))) { + fprintf(stderr, + "Error: options -r -q and -f can not be used together !!\n"); + return 1; + } // mod fixed_quality + + /* if no rate entered, lossless by default */ + if (tcp_init->numlayers == 0) { + tcp_init->rates[tcp_init->numlayers] = 1; + tcp_init->numlayers++; + cp.disto_alloc = 1; + } + + if (TX0 > Dim[0] || TY0 > Dim[1]) { + fprintf(stderr, + "Error: Tile offset dimension is unnappropriate --> TX0(%d)<=IMG_X0(%d) TYO(%d)<=IMG_Y0(%d) \n", + TX0, Dim[0], TY0, Dim[1]); + return 1; + } + + for (i = 0; i < numpocs; i++) { + if (POC[i].prg == -1) { + fprintf(stderr, + "Unrecognized progression order in option -P (POC n %d) [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n", + i + 1); + } + } + + switch (cp.image_type) { + case 0: + if (Tile_arg) { + if (!pgxtoimage + (infile, &img, cp.tdy, subsampling_dx, subsampling_dy, Dim, + cp)) { + fprintf(stderr, "not a pgx file\n"); + return 1; + } + } else { + if (!pgxtoimage + (infile, &img, -1, subsampling_dx, subsampling_dy, Dim, cp)) { + fprintf(stderr, " not a pgx file\n"); + return 1; + } + } + break; + + case 1: + if (!pnmtoimage(infile, &img, subsampling_dx, subsampling_dy, Dim)) { + fprintf(stderr, " not a pnm file\n"); + return 1; + } + break; + + case 2: + if (!bmptoimage(infile, &img, subsampling_dx, subsampling_dy, Dim)) { + fprintf(stderr, " not a bmp file\n"); + return 1; + } + break; + } + /* to respect profile - 0 */ + /* ---------------------- */ + numD_min = 0; + /* while (int_ceildiv(img.x1,(1<120 || int_ceildiv(img.y1,(1<160) numD_min++; + if ((numD_min+1)>NumResolution) + { + fprintf(stderr,"\n********************************************************************************\n\n"); + fprintf(stderr, "In view to respect Profile-0, the number of resolution used is %d in place of %d\n\n",numD_min+1,NumResolution); + fprintf(stderr, "********************************************************************************\n\n"); + NumResolution=numD_min+1; + } */ + + if (Tile_arg == 1) { + cp.tw = int_ceildiv(img.x1 - cp.tx0, cp.tdx); + cp.th = int_ceildiv(img.y1 - cp.ty0, cp.tdy); + } else { + cp.tdx = img.x1 - cp.tx0; + cp.tdy = img.y1 - cp.ty0; + } + + /* Initialization for PPM marker */ + cp.ppm = 0; + cp.ppm_data = NULL; + cp.ppm_previous = 0; + cp.ppm_store = 0; + + /* Init the mutiple tiles */ + /* ---------------------- */ + cp.tcps = (j2k_tcp_t *) malloc(cp.tw * cp.th * sizeof(j2k_tcp_t)); + + for (tileno = 0; tileno < cp.tw * cp.th; tileno++) { + tcp = &cp.tcps[tileno]; + tcp->numlayers = tcp_init->numlayers; + for (j = 0; j < tcp->numlayers; j++) { + if (cp.fixed_quality) // add fixed_quality + tcp->distoratio[j] = tcp_init->distoratio[j]; + else + tcp->rates[j] = tcp_init->rates[j]; + } + tcp->csty = CSty; + tcp->prg = Prog_order; + tcp->mct = img.numcomps == 3 ? 1 : 0; + tcp->ppt = 0; + tcp->ppt_data = NULL; + tcp->ppt_store = 0; + + numpocs_tile = 0; + tcp->POC = 0; + if (numpocs) { + /* intialisation of POC */ + tcp->POC = 1; + for (i = 0; i < numpocs; i++) { + if (tileno == POC[i].tile - 1 || POC[i].tile == -1) { + tcp_poc = &tcp->pocs[numpocs_tile]; + tcp_poc->resno0 = POC[numpocs_tile].resno0; + tcp_poc->compno0 = POC[numpocs_tile].compno0; + tcp_poc->layno1 = POC[numpocs_tile].layno1; + tcp_poc->resno1 = POC[numpocs_tile].resno1; + tcp_poc->compno1 = POC[numpocs_tile].compno1; + tcp_poc->prg = POC[numpocs_tile].prg; + tcp_poc->tile = POC[numpocs_tile].tile; + numpocs_tile++; + } + } + } + tcp->numpocs = numpocs_tile; + tcp->tccps = (j2k_tccp_t *) malloc(img.numcomps * sizeof(j2k_tccp_t)); + + for (i = 0; i < img.numcomps; i++) { + tccp = &tcp->tccps[i]; + tccp->csty = CSty & 0x01; /* 0 => one precinct || 1 => custom precinct */ + tccp->numresolutions = NumResolution; + tccp->cblkw = int_floorlog2(cblockw_init); + tccp->cblkh = int_floorlog2(cblockh_init); + tccp->cblksty = mode; + tccp->qmfbid = ir ? 0 : 1; + tccp->qntsty = ir ? J2K_CCP_QNTSTY_SEQNT : J2K_CCP_QNTSTY_NOQNT; + tccp->numgbits = 2; + if (i == ROI_compno) + tccp->roishift = ROI_shift; + else + tccp->roishift = 0; + if (CSty & J2K_CCP_CSTY_PRT) { + int p = 0; + for (j = tccp->numresolutions - 1; j >= 0; j--) { + if (p < res_spec) { + if (prcw_init[p] < 1) + tccp->prcw[j] = 1; + else + tccp->prcw[j] = int_floorlog2(prcw_init[p]); + + if (prch_init[p] < 1) + tccp->prch[j] = 1; + else + tccp->prch[j] = int_floorlog2(prch_init[p]); + } else { + int size_prcw, size_prch; + size_prcw = prcw_init[res_spec - 1] >> (p - (res_spec - 1)); + size_prch = prch_init[res_spec - 1] >> (p - (res_spec - 1)); + if (size_prcw < 1) + tccp->prcw[j] = 1; + else + tccp->prcw[j] = int_floorlog2(size_prcw); + if (size_prch < 1) + tccp->prch[j] = 1; + else + tccp->prch[j] = int_floorlog2(size_prch); + } + p++; + /*printf("\nsize precinct pour level %d : %d,%d\n", j, + tccp->prcw[j], tccp->prch[j]);*/ + } + } else { + for (j = 0; j < tccp->numresolutions; j++) { + tccp->prcw[j] = 15; + tccp->prch[j] = 15; + } + } + calc_explicit_stepsizes(tccp, img.comps[i].prec); + } + } + + if (cp.JPEG2000_format==0) { /* J2K format output */ + if (cp.intermed_file==1) { /* After the encoding of each tile, j2k_encode + stores the data in the file*/ + len = j2k_encode(&img, &cp, outfile, cp.tdx * cp.tdy * 10, index); + if (len == 0) { + fprintf(stderr, "failed to encode image\n"); + return 1; + } + } + else { + outbuf = (char *) malloc( cp.tdx * cp.tdy * cp.tw * cp.th * 4*sizeof(char)); /* Allocate memory for all tiles */ + cio_init(outbuf, cp.tdx * cp.tdy * cp.tw * cp.th * 4); + len = j2k_encode(&img, &cp, outbuf, cp.tdx * cp.tdy * cp.tw * cp.th * 4, index); + if (len == 0) { + fprintf(stderr, "failed to encode image\n"); + return 1; + } + // non uso l'intermed file + if (jpwl_cp.JPWL_on){ + out= (char *) malloc(len*4*sizeof(char)); + len=jpwl_encode(outbuf,out,len); + if (len == 0) { + fprintf(stderr, "failed to encode image\n"); + return 1; + } + + if (cp.index_on && use_index){ + //printf("num: %d\n",info_IM.num); + write_index(index, len); + } + + f = fopen(outfile, "wb"); + if (!f) { + fprintf(stderr, "failed to open %s for writing\n", outfile); + return 1; + } + fwrite(out, 1, len, f); + free(outbuf); + free(out); + fclose(f); + if(cp.index_on) + j2k_free_info(); + + + } + else { + f = fopen(outfile, "wb"); + if (!f) { + fprintf(stderr, "failed to open %s for writing\n", outfile); + return 1; + } + fwrite(outbuf, 1, len, f); + free(outbuf); + fclose(f); + if(cp.index_on) + j2k_free_info(); + + + + } + } + } + else /* JP2 format output */ + { + jp2_struct_t * jp2_struct; + jp2_struct = (jp2_struct_t *) malloc(sizeof(jp2_struct_t)); + jp2_struct->image = &img; + + /* Initialising the standard JP2 box content*/ + /* If you wish to modify those boxes, you have to modify the jp2_struct content*/ + if (jp2_init_stdjp2(jp2_struct, &img)) + { + fprintf(stderr,"Error with jp2 initialization"); + return 1; + }; + + if (cp.intermed_file==1) { + /*For the moment, JP2 format does not use intermediary files for each tile*/ + cp.intermed_file=0; + } + outbuf = (char *) malloc( cp.tdx * cp.tdy * cp.tw * cp.th * 10 *sizeof(char)); + cio_init(outbuf, cp.tdx * cp.tdy * cp.tw * cp.th * 10); + len = jp2_encode(jp2_struct, &cp, outbuf, index); + if (len == 0) { + fprintf(stderr, "failed to encode image\n"); + return 1; + } + f = fopen(outfile, "wb"); + if (!f) { + fprintf(stderr, "failed to open %s for writing\n", outfile); + return 1; + } + fwrite(outbuf, 1, len, f); + free(outbuf); + fclose(f); + } + + /* Remove the temporary files */ + /* -------------------------- */ + if (cp.image_type) { /* PNM PGM PPM */ + for (i = 0; i < img.numcomps; i++) { + char tmp[7]; // risolto il bug finale (stack corrupted)!!! + sprintf(tmp, "Compo%d", i); + if (remove(tmp) == -1) { + fprintf(stderr, "failed to kill %s file !\n", tmp); + } + } + } else { /* PGX */ + for (i = 0; i < cp.th; i++) { + char tmp[10]; + sprintf(tmp, "bandtile%d", i + 1); + + if (remove(tmp) == -1) { + fprintf(stderr, "failed to kill %s file !\n", tmp); + } + } + } + + /* Free memory */ + free(img.comps); + free(cp_init.tcps); + if (tcp_init->numlayers > 9) free(cp.matrice); + for (tileno = 0; tileno < cp.tw * cp.th; tileno++) + free(cp.tcps[tileno].tccps); + free(cp.tcps); + + system("pause"); + return 0; +} diff --git a/jpwl/encoder/jpwlenc/image_to_j2k.dsp b/jpwl/encoder/jpwlenc/image_to_j2k.dsp new file mode 100644 index 00000000..07e5a0a2 --- /dev/null +++ b/jpwl/encoder/jpwlenc/image_to_j2k.dsp @@ -0,0 +1,249 @@ +# Microsoft Developer Studio Project File - Name="image_to_j2k" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=image_to_j2k - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "image_to_j2k.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "image_to_j2k.mak" CFG="image_to_j2k - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "image_to_j2k - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "image_to_j2k - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "image_to_j2k - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../libopenjpeg" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "DONT_HAVE_GETOPT" /YX /FD /c +# ADD BASE RSC /l 0x80c /d "NDEBUG" +# ADD RSC /l 0x80c /i "../libopenjpeg" /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "image_to_j2k - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../libopenjpeg" /D "_DEBUG" /D "DONT_HAVE_GETOPT" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c +# ADD BASE RSC /l 0x80c /d "_DEBUG" +# ADD RSC /l 0x80c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "image_to_j2k - Win32 Release" +# Name "image_to_j2k - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\libopenjpeg\bio.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\cio.c +# End Source File +# Begin Source File + +SOURCE=.\convert.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\dwt.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\fix.c +# End Source File +# Begin Source File + +SOURCE=.\compat\getopt.c +# End Source File +# Begin Source File + +SOURCE=.\image_to_j2k.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\int.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\j2k.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\jp2.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\jpt.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\mct.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\mqc.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\pi.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\raw.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\t1.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\t2.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\tcd.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\tgt.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\libopenjpeg\bio.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\cio.h +# End Source File +# Begin Source File + +SOURCE=.\convert.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\dwt.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\fix.h +# End Source File +# Begin Source File + +SOURCE=.\compat\getopt.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\int.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\j2k.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\jp2.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\jpt.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\mct.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\mqc.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\openjpeg.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\pi.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\raw.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\t1.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\t2.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\tcd.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\tgt.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/jpwl/encoder/jpwlenc/image_to_j2k.dsw b/jpwl/encoder/jpwlenc/image_to_j2k.dsw new file mode 100644 index 00000000..3d060bc5 --- /dev/null +++ b/jpwl/encoder/jpwlenc/image_to_j2k.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "image_to_j2k"=.\image_to_j2k.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/jpwl/encoder/jpwlenc/image_to_j2k.ncb b/jpwl/encoder/jpwlenc/image_to_j2k.ncb new file mode 100644 index 00000000..9057ebac --- /dev/null +++ b/jpwl/encoder/jpwlenc/image_to_j2k.ncb @@ -0,0 +1 @@ +Microsoft C/C++ MSF 7.00 diff --git a/jpwl/encoder/jpwlenc/image_to_j2k.opt b/jpwl/encoder/jpwlenc/image_to_j2k.opt new file mode 100644 index 00000000..3599f1b0 --- /dev/null +++ b/jpwl/encoder/jpwlenc/image_to_j2k.opt @@ -0,0 +1 @@ +ÐÏࡱ \ No newline at end of file diff --git a/jpwl/encoder/jpwlenc/image_to_j2k.plg b/jpwl/encoder/jpwlenc/image_to_j2k.plg new file mode 100644 index 00000000..6e7889c3 --- /dev/null +++ b/jpwl/encoder/jpwlenc/image_to_j2k.plg @@ -0,0 +1,41 @@ + + +
+

Build Log

+

+--------------------Configuration: image_to_j2k - Win32 Debug-------------------- +

+

Command Lines

+Creating temporary file "D:\DOCUME~1\baruffa\IMPOST~1\Temp\RSPE40.tmp" with contents +[ +/nologo /o"Debug/image_to_j2k.bsc" +".\Debug\bio.sbr" +".\Debug\cio.sbr" +".\Debug\convert.sbr" +".\Debug\dwt.sbr" +".\Debug\fix.sbr" +".\Debug\getopt.sbr" +".\Debug\image_to_j2k.sbr" +".\Debug\int.sbr" +".\Debug\j2k.sbr" +".\Debug\jp2.sbr" +".\Debug\jpt.sbr" +".\Debug\mct.sbr" +".\Debug\mqc.sbr" +".\Debug\pi.sbr" +".\Debug\raw.sbr" +".\Debug\t1.sbr" +".\Debug\t2.sbr" +".\Debug\tcd.sbr" +".\Debug\tgt.sbr"] +Creating command line "bscmake.exe @D:\DOCUME~1\baruffa\IMPOST~1\Temp\RSPE40.tmp" +Creating browse info file... +

Output Window

+ + + +

Results

+image_to_j2k.exe - 0 error(s), 0 warning(s) +
+ + diff --git a/jpwl/encoder/jpwlenc/image_to_j2k.sln b/jpwl/encoder/jpwlenc/image_to_j2k.sln new file mode 100644 index 00000000..198c5396 --- /dev/null +++ b/jpwl/encoder/jpwlenc/image_to_j2k.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "image_to_j2k", "image_to_j2k.vcproj", "{F67C0B66-E4AD-42E6-8D70-CF7F00BB31BE}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {F67C0B66-E4AD-42E6-8D70-CF7F00BB31BE}.Debug.ActiveCfg = Debug|Win32 + {F67C0B66-E4AD-42E6-8D70-CF7F00BB31BE}.Debug.Build.0 = Debug|Win32 + {F67C0B66-E4AD-42E6-8D70-CF7F00BB31BE}.Release.ActiveCfg = Release|Win32 + {F67C0B66-E4AD-42E6-8D70-CF7F00BB31BE}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/jpwl/encoder/jpwlenc/image_to_j2k.suo b/jpwl/encoder/jpwlenc/image_to_j2k.suo new file mode 100644 index 00000000..3599f1b0 --- /dev/null +++ b/jpwl/encoder/jpwlenc/image_to_j2k.suo @@ -0,0 +1 @@ +ÐÏࡱ \ No newline at end of file diff --git a/jpwl/encoder/jpwlenc/image_to_j2k.vcproj b/jpwl/encoder/jpwlenc/image_to_j2k.vcproj new file mode 100644 index 00000000..7a158d23 --- /dev/null +++ b/jpwl/encoder/jpwlenc/image_to_j2k.vcproj @@ -0,0 +1,280 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jpwl/encoder/jpwlenc/irdeto.j2k b/jpwl/encoder/jpwlenc/irdeto.j2k new file mode 100644 index 00000000..eafc615c Binary files /dev/null and b/jpwl/encoder/jpwlenc/irdeto.j2k differ diff --git a/jpwl/encoder/jpwlenc/j2k_to_image.c b/jpwl/encoder/jpwlenc/j2k_to_image.c new file mode 100644 index 00000000..53104736 --- /dev/null +++ b/jpwl/encoder/jpwlenc/j2k_to_image.c @@ -0,0 +1,557 @@ +/* Copyright (c) 2001 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 + +int ceildiv(int a, int b) +{ + return (a + b - 1) / b; +} + +int main(int argc, char **argv) +{ + FILE *f; + char *src, *src_name; + char *dest, S1, S2, S3; + int len; + + j2k_image_t img; + + j2k_cp_t cp; + int w, wr, wrr, h, hr, hrr, max; + int i, image_type = -1, compno, pad, j; + int adjust; + jp2_struct_t *jp2_struct; + + if (argc < 3) { + fprintf(stderr, + "usage: %s j2k-file image-file [-reduce n]\n", argv[0]); + return 1; + } + + f = fopen(argv[1], "rb"); + if (!f) { + fprintf(stderr, "failed to open %s for reading\n", argv[1]); + return 1; + } + + dest = argv[2]; + + cp.reduce_on = 0; + cp.reduce_value = 0; + + /* OPTION REDUCE IS ACTIVE */ + if (argc == 5) { + if (strcmp(argv[3], "-reduce")) { + fprintf(stderr, + "usage: options " "-reduce n" + " where n is the factor of reduction [%s]\n", argv[3]); + return 1; + } + cp.reduce_on = 1; + sscanf(argv[4], "%d", &cp.reduce_value); + } + + while (*dest) { + dest++; + } + dest--; + S3 = *dest; + dest--; + S2 = *dest; + dest--; + S1 = *dest; + + if ((S1 == 'p' && S2 == 'g' && S3 == 'x') + || (S1 == 'P' && S2 == 'G' && S3 == 'X')) { + image_type = 0; + + dest--; + + *dest = '\0'; + } + + if ((S1 == 'p' && S2 == 'n' && S3 == 'm') + || (S1 == 'P' && S2 == 'N' && S3 == 'M') || (S1 == 'p' && S2 == 'g' + && S3 == 'm') + || (S1 == 'P' && S2 == 'G' && S3 == 'M') || (S1 == 'P' && S2 == 'P' + && S3 == 'M') + || (S1 == 'p' && S2 == 'p' && S3 == 'm')) { + image_type = 1; + } + + if ((S1 == 'b' && S2 == 'm' && S3 == 'p') + || (S1 == 'B' && S2 == 'M' && S3 == 'P')) { + image_type = 2; + } + + if (image_type == -1) { + fprintf(stderr, + "!! Unrecognized format for infile : %c%c%c [accept only *.pnm, *.pgm, *.ppm, *.pgx or *.bmp] !!\n\n", + S1, S2, S3); + return 1; + } + + fseek(f, 0, SEEK_END); + len = ftell(f); + fseek(f, 0, SEEK_SET); + src = (char *) malloc(len); + fread(src, 1, len, f); + fclose(f); + + src_name = argv[1]; + while (*src_name) { + src_name++; + } + src_name--; + S3 = *src_name; + src_name--; + S2 = *src_name; + src_name--; + S1 = *src_name; + + /* J2K format */ + if ((S1 == 'j' && S2 == '2' && S3 == 'k') + || (S1 == 'J' && S2 == '2' && S3 == 'K') || (S1 == 'j' && S2 == '2' + && S3 == 'c') + || (S1 == 'J' && S2 == '2' && S3 == 'C')) { + if (!j2k_decode(src, len, &img, &cp)) { + fprintf(stderr, "j2k_to_image: failed to decode image!\n"); + return 1; + } + } + + /* JP2 format */ + else if ((S1 == 'j' && S2 == 'p' && S3 == '2') + || (S1 == 'J' && S2 == 'P' && S3 == '2')) { + jp2_struct = (jp2_struct_t *) malloc(sizeof(jp2_struct_t)); + + jp2_struct->image = &img; + + if (jp2_decode(src, len, jp2_struct, &cp)) { + fprintf(stderr, "j2k_to_image: failed to decode image!\n"); + return 1; + } + /* Insert code here if you want to create actions on jp2_struct before deleting it */ + free(jp2_struct); + } + + /* JPT format */ + else if ((S1 == 'j' && S2 == 'p' && S3 == 't') + || (S1 == 'J' && S2 == 'P' && S3 == 'T')) { + if (!j2k_decode_jpt_stream(src, len, &img, &cp)) { + fprintf(stderr, "j2k_to_image: failed to decode image!\n"); + return 1; + } + } + + /* otherwise : error */ + else { + fprintf(stderr, + "j2k_to_image : Unknown format image *.%c%c%c [only *.j2k, *.jp2, *.jpc or *.jpt]!! \n", + S1, S2, S3); + return 1; + } + + free(src); + /* ------------------ CREATE OUT IMAGE WITH THE RIGHT FORMAT ----------------------- */ + + /* ---------------------------- / */ + /* / / */ + /* / FORMAT : PNM, PGM or PPM / */ + /* / / */ + /* ---------------------------- / */ + + switch (image_type) { + case 1: /* PNM PGM PPM */ + if (img.numcomps == 3 && img.comps[0].dx == img.comps[1].dx + && img.comps[1].dx == img.comps[2].dx + && img.comps[0].dy == img.comps[1].dy + && img.comps[1].dy == img.comps[2].dy + && img.comps[0].prec == img.comps[1].prec + && img.comps[1].prec == img.comps[2].prec) { + f = fopen(argv[2], "wb"); + w = ceildiv(img.x1 - img.x0, img.comps[0].dx); + // wr = ceildiv(int_ceildivpow2(img.x1 - img.x0,img.factor),img.comps[0].dx); + wr = img.comps[0].w; + wrr = int_ceildivpow2(img.comps[0].w, img.comps[0].factor); + + h = ceildiv(img.y1 - img.y0, img.comps[0].dy); + // hr = ceildiv(int_ceildivpow2(img.y1 - img.y0,img.factor), img.comps[0].dy); + hr = img.comps[0].h; + hrr = int_ceildivpow2(img.comps[0].h, img.comps[0].factor); + + max = img.comps[0].prec > 8 ? 255 : (1 << img.comps[0].prec) - 1; + + img.comps[0].x0 = + int_ceildivpow2(img.comps[0].x0 - + int_ceildiv(img.x0, img.comps[0].dx), + img.comps[0].factor); + img.comps[0].y0 = + int_ceildivpow2(img.comps[0].y0 - + int_ceildiv(img.y0, img.comps[0].dy), + img.comps[0].factor); + + + fprintf(f, "P6\n# %d %d %d %d %d\n%d %d\n%d\n", + cp.tcps[cp.tileno[0]].tccps[0].numresolutions, w, h, + img.comps[0].x0, img.comps[0].y0, wrr, hrr, max); + adjust = img.comps[0].prec > 8 ? img.comps[0].prec - 8 : 0; + for (i = 0; i < wrr * hrr; i++) { + char r, g, b; + r = img.comps[0].data[i / wrr * wr + i % wrr]; + r += (img.comps[0].sgnd ? 1 << (img.comps[0].prec - 1) : 0); + r = r >> adjust; + + g = img.comps[1].data[i / wrr * wr + i % wrr]; + g += (img.comps[1].sgnd ? 1 << (img.comps[1].prec - 1) : 0); + g = g >> adjust; + + b = img.comps[2].data[i / wrr * wr + i % wrr]; + b += (img.comps[2].sgnd ? 1 << (img.comps[2].prec - 1) : 0); + b = b >> adjust; + + fprintf(f, "%c%c%c", r, g, b); + } + free(img.comps[0].data); + free(img.comps[1].data); + free(img.comps[2].data); + fclose(f); + } else { + for (compno = 0; compno < img.numcomps; compno++) { + char name[256]; + if (img.numcomps > 1) { + sprintf(name, "%d.%s", compno, argv[2]); + } else { + sprintf(name, "%s", argv[2]); + } + f = fopen(name, "wb"); + w = ceildiv(img.x1 - img.x0, img.comps[compno].dx); + // wr = ceildiv(int_ceildivpow2(img.x1 - img.x0,img.factor),img.comps[compno].dx); + wr = img.comps[compno].w; + wrr = + int_ceildivpow2(img.comps[compno].w, img.comps[compno].factor); + + h = ceildiv(img.y1 - img.y0, img.comps[compno].dy); + // hr = ceildiv(int_ceildivpow2(img.y1 - img.y0,img.factor), img.comps[compno].dy); + hr = img.comps[compno].h; + hrr = + int_ceildivpow2(img.comps[compno].h, img.comps[compno].factor); + + max = + img.comps[compno].prec > + 8 ? 255 : (1 << img.comps[compno].prec) - 1; + + img.comps[compno].x0 = + int_ceildivpow2(img.comps[compno].x0 - + int_ceildiv(img.x0, + img.comps[compno].dx), + img.comps[compno].factor); + img.comps[compno].y0 = + int_ceildivpow2(img.comps[compno].y0 - + int_ceildiv(img.y0, + img.comps[compno].dy), + img.comps[compno].factor); + + fprintf(f, "P5\n# %d %d %d %d %d\n%d %d\n%d\n", + cp.tcps[cp.tileno[0]].tccps[compno]. + numresolutions, w, h, img.comps[compno].x0, + img.comps[compno].y0, wrr, hrr, max); + adjust = + img.comps[compno].prec > 8 ? img.comps[compno].prec - 8 : 0; + for (i = 0; i < wrr * hrr; i++) { + char l; + l = img.comps[compno].data[i / wrr * wr + i % wrr]; + l += (img.comps[compno]. + sgnd ? 1 << (img.comps[compno].prec - 1) : 0); + l = l >> adjust; + fprintf(f, "%c", l); + } + fclose(f); + free(img.comps[compno].data); + } + } + break; + + /* ------------------------ / */ + /* / / */ + /* / FORMAT : PGX / */ + /* / / */ + /* /----------------------- / */ + case 0: /* PGX */ + for (compno = 0; compno < img.numcomps; compno++) { + j2k_comp_t *comp = &img.comps[compno]; + char name[256]; + + int nbytes = 0; + //if (img.numcomps > 1) + sprintf(name, "%s-%d.pgx", argv[2], compno); + + //else + + //sprintf(name, "%s.pgx", argv[2]); + + f = fopen(name, "wb"); + // w = ceildiv(img.x1 - img.x0, comp->dx); + // wr = ceildiv(int_ceildivpow2(img.x1 - img.x0,img.factor), comp->dx); + w = img.comps[compno].w; + wr = int_ceildivpow2(img.comps[compno].w, img.comps[compno].factor); + + // h = ceildiv(img.y1 - img.y0, comp->dy); + // hr = ceildiv(int_ceildivpow2(img.y1 - img.y0,img.factor), comp->dy); + h = img.comps[compno].h; + hr = int_ceildivpow2(img.comps[compno].h, img.comps[compno].factor); + + fprintf(f, "PG ML %c %d %d %d\n", comp->sgnd ? '-' : '+', + comp->prec, wr, hr); + + if (comp->prec <= 8) + nbytes = 1; + + else if (comp->prec <= 16) + nbytes = 2; + + else + nbytes = 4; + for (i = 0; i < wr * hr; i++) { + int v = img.comps[compno].data[i / wr * w + i % wr]; + + for (j = nbytes - 1; j >= 0; j--) { + + char byte = (char) (v >> (j * 8)); + + fwrite(&byte, 1, 1, f); + + } + } + free(img.comps[compno].data); + fclose(f); + } + break; + + /* ------------------------ / */ + /* / / */ + /* / FORMAT : BMP / */ + /* / / */ + /* /----------------------- / */ + + case 2: /* BMP */ + if (img.numcomps == 3 && img.comps[0].dx == img.comps[1].dx + && img.comps[1].dx == img.comps[2].dx + && img.comps[0].dy == img.comps[1].dy + && img.comps[1].dy == img.comps[2].dy + && img.comps[0].prec == img.comps[1].prec + && img.comps[1].prec == img.comps[2].prec) { + /* -->> -->> -->> -->> + + 24 bits color + + <<-- <<-- <<-- <<-- */ + + f = fopen(argv[2], "wb"); + // w = ceildiv(img.x1 - img.x0, img.comps[0].dx); + // wr = ceildiv(int_ceildivpow2(img.x1 - img.x0,img.factor), img.comps[0].dx); + w = img.comps[0].w; + wr = int_ceildivpow2(img.comps[0].w, img.comps[0].factor); + + // h = ceildiv(img.y1 - img.y0, img.comps[0].dy); + // hr = ceildiv(int_ceildivpow2(img.y1 - img.y0,img.factor), img.comps[0].dy); + h = img.comps[0].h; + hr = int_ceildivpow2(img.comps[0].h, img.comps[0].factor); + + fprintf(f, "BM"); + + /* FILE HEADER */ + /* ------------- */ + fprintf(f, "%c%c%c%c", + (unsigned char) (hr * wr * 3 + 3 * hr * (wr % 2) + + 54) & 0xff, + (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54) + >> 8) & 0xff, + (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54) + >> 16) & 0xff, + (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54) + >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, + ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (54) & 0xff, ((54) >> 8) & 0xff, + ((54) >> 16) & 0xff, ((54) >> 24) & 0xff); + + /* INFO HEADER */ + /* ------------- */ + fprintf(f, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff, + ((40) >> 16) & 0xff, ((40) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (unsigned char) ((wr) & 0xff), + (unsigned char) ((wr) >> 8) & 0xff, + (unsigned char) ((wr) >> 16) & 0xff, + (unsigned char) ((wr) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (unsigned char) ((hr) & 0xff), + (unsigned char) ((hr) >> 8) & 0xff, + (unsigned char) ((hr) >> 16) & 0xff, + (unsigned char) ((hr) >> 24) & 0xff); + fprintf(f, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff); + fprintf(f, "%c%c", (24) & 0xff, ((24) >> 8) & 0xff); + fprintf(f, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, + ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", + (unsigned char) (3 * hr * wr + + 3 * hr * (wr % 2)) & 0xff, + (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >> + 8) & 0xff, + (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >> + 16) & 0xff, + (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >> + 24) & 0xff); + fprintf(f, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, + ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, + ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, + ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, + ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); + + for (i = 0; i < wr * hr; i++) { + unsigned char R, G, B; + /* a modifier */ + // R = img.comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; + R = img.comps[0].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)]; + // G = img.comps[1].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; + G = img.comps[1].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)]; + // B = img.comps[2].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; + B = img.comps[2].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)]; + fprintf(f, "%c%c%c", B, G, R); + + if ((i + 1) % wr == 0) { + for (pad = (3 * wr) % 4 ? 4 - (3 * wr) % 4 : 0; pad > 0; pad--) /* ADD */ + fprintf(f, "%c", 0); + } + } + fclose(f); + free(img.comps[1].data); + free(img.comps[2].data); + } else { /* Gray-scale */ + + /* -->> -->> -->> -->> + + 8 bits non code (Gray scale) + + <<-- <<-- <<-- <<-- */ + f = fopen(argv[2], "wb"); + // w = ceildiv(img.x1 - img.x0, img.comps[0].dx); + // wr = ceildiv(int_ceildivpow2(img.x1 - img.x0,img.factor), img.comps[0].dx); + w = img.comps[0].w; + wr = int_ceildivpow2(img.comps[0].w, img.comps[0].factor); + + // h = ceildiv(img.y1 - img.y0, img.comps[0].dy); + // hr = ceildiv(int_ceildivpow2(img.y1 - img.y0,img.factor), img.comps[0].dy); + h = img.comps[0].h; + hr = int_ceildivpow2(img.comps[0].h, img.comps[0].factor); + + fprintf(f, "BM"); + + /* FILE HEADER */ + /* ------------- */ + fprintf(f, "%c%c%c%c", + (unsigned char) (hr * wr + 54 + 1024 + + hr * (wr % 2)) & 0xff, + (unsigned char) ((hr * wr + 54 + 1024 + hr * (wr % 2)) + >> 8) & 0xff, + (unsigned char) ((hr * wr + 54 + 1024 + hr * (wr % 2)) + >> 16) & 0xff, + (unsigned char) ((hr * wr + 54 + 1024 + wr * (wr % 2)) + >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, + ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (54 + 1024) & 0xff, + ((54 + 1024) >> 8) & 0xff, ((54 + 1024) >> 16) & 0xff, + ((54 + 1024) >> 24) & 0xff); + + /* INFO HEADER */ + /* ------------- */ + fprintf(f, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff, + ((40) >> 16) & 0xff, ((40) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (unsigned char) ((wr) & 0xff), + (unsigned char) ((wr) >> 8) & 0xff, + (unsigned char) ((wr) >> 16) & 0xff, + (unsigned char) ((wr) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (unsigned char) ((hr) & 0xff), + (unsigned char) ((hr) >> 8) & 0xff, + (unsigned char) ((hr) >> 16) & 0xff, + (unsigned char) ((hr) >> 24) & 0xff); + fprintf(f, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff); + fprintf(f, "%c%c", (8) & 0xff, ((8) >> 8) & 0xff); + fprintf(f, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, + ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", + (unsigned char) (hr * wr + hr * (wr % 2)) & 0xff, + (unsigned char) ((hr * wr + hr * (wr % 2)) >> 8) & + 0xff, + (unsigned char) ((hr * wr + hr * (wr % 2)) >> 16) & + 0xff, + (unsigned char) ((hr * wr + hr * (wr % 2)) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, + ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, + ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, + ((256) >> 16) & 0xff, ((256) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, + ((256) >> 16) & 0xff, ((256) >> 24) & 0xff); + } + + for (i = 0; i < 256; i++) { + fprintf(f, "%c%c%c%c", i, i, i, 0); + } + + for (i = 0; i < wr * hr; i++) { + /* a modifier !! */ + // fprintf(f, "%c", img.comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]); + fprintf(f, "%c", + img.comps[0].data[w * hr - ((i) / (wr) + 1) * w + + (i) % (wr)]); + /*if (((i + 1) % w == 0 && w % 2)) + fprintf(f, "%c", 0); */ + if ((i + 1) % wr == 0) { + for (pad = wr % 4 ? 4 - wr % 4 : 0; pad > 0; pad--) /* ADD */ + fprintf(f, "%c", 0); + } + } + fclose(f); + free(img.comps[0].data); + break; + default: + break; + } + + return 0; +} diff --git a/jpwl/encoder/jpwlenc/j2k_to_image.dsp b/jpwl/encoder/jpwlenc/j2k_to_image.dsp new file mode 100644 index 00000000..6a633191 --- /dev/null +++ b/jpwl/encoder/jpwlenc/j2k_to_image.dsp @@ -0,0 +1,240 @@ +# Microsoft Developer Studio Project File - Name="j2k_to_image" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=j2k_to_image - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "j2k_to_image.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "j2k_to_image.mak" CFG="j2k_to_image - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "j2k_to_image - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "j2k_to_image - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "j2k_to_image - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../libopenjpeg" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "DONT_HAVE_GETOPT" /YX /FD /c +# ADD BASE RSC /l 0x80c /d "NDEBUG" +# ADD RSC /l 0x80c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "j2k_to_image - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "j2k_to_image___Win32_Debug" +# PROP BASE Intermediate_Dir "j2k_to_image___Win32_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "j2k_to_image___Win32_Debug" +# PROP Intermediate_Dir "j2k_to_image___Win32_Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../libopenjpeg" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "DONT_HAVE_GETOPT" /YX /FD /GZ /c +# ADD BASE RSC /l 0x80c /d "_DEBUG" +# ADD RSC /l 0x80c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "j2k_to_image - Win32 Release" +# Name "j2k_to_image - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\libopenjpeg\bio.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\cio.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\dwt.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\fix.c +# End Source File +# Begin Source File + +SOURCE=.\compat\getopt.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\int.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\j2k.c +# End Source File +# Begin Source File + +SOURCE=.\j2k_to_image.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\jp2.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\jpt.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\mct.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\mqc.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\pi.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\raw.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\t1.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\t2.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\tcd.c +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\tgt.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\libopenjpeg\bio.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\cio.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\dwt.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\fix.h +# End Source File +# Begin Source File + +SOURCE=.\compat\getopt.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\int.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\j2k.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\jp2.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\jpt.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\mct.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\mqc.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\openjpeg.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\pi.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\raw.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\t1.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\t2.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\tcd.h +# End Source File +# Begin Source File + +SOURCE=..\libopenjpeg\tgt.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/jpwl/encoder/libopenjpeg/.cvsignore b/jpwl/encoder/libopenjpeg/.cvsignore new file mode 100644 index 00000000..5aca9ad5 --- /dev/null +++ b/jpwl/encoder/libopenjpeg/.cvsignore @@ -0,0 +1,6 @@ +obj +obj.w32 +bin +bin.w32 +lib +lib.w32 diff --git a/jpwl/encoder/libopenjpeg/Makefile b/jpwl/encoder/libopenjpeg/Makefile new file mode 100644 index 00000000..d5f2727b --- /dev/null +++ b/jpwl/encoder/libopenjpeg/Makefile @@ -0,0 +1,78 @@ +# $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: $(OBJ_DIR) $(LIB_DIR) \ + $(LIB_DIR)/libopenjpeg.a $(LIB_DIR)/libopenjpeg.dll +else + CC = gcc + AR = ar + OBJ_DIR = obj + LIB_DIR = lib + all: $(OBJ_DIR) $(LIB_DIR) \ + $(LIB_DIR)/libopenjpeg.a $(LIB_DIR)/libopenjpeg.so +endif + +$(OBJ_DIR): + mkdir $(OBJ_DIR) + +$(LIB_DIR): + mkdir $(LIB_DIR) + +$(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 +$(OBJ_DIR)/jpt.o: jpt.c jpt.h cio.h +$(OBJ_DIR)/jp2.o: jp2.c jp2.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 jpt.o jp2.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/jpwl/encoder/libopenjpeg/bio.c b/jpwl/encoder/libopenjpeg/bio.c new file mode 100644 index 00000000..ed846fae --- /dev/null +++ b/jpwl/encoder/libopenjpeg/bio.c @@ -0,0 +1,194 @@ +/* + * 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; /* pointer to the start of the buffer */ +static unsigned char *bio_end; /* pointer to the end of the buffer */ +static unsigned char *bio_bp; /* pointer to the present position in the buffer */ +static unsigned int bio_buf; /* temporary place where each byte is read or written */ +static int bio_ct; /* coder : number of bits free to write // decoder : number of bits read */ + +extern jmp_buf j2k_error; + +/* + * Number of bytes written. + */ +int bio_numbytes() +{ + return bio_bp - bio_start; +} + +/* + * Init encoder. + * + * bp : Output buffer + * len : 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. + * + * bp : Input buffer + * len : 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. + * + * b : 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. + * + * v : Value of bits + * n : 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. + * + * n : 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; +} + +/* + * Passes the ending bits (coming from flushing) + */ +int bio_inalign() +{ + bio_ct = 0; + if ((bio_buf & 0xff) == 0xff) { + if (bio_bytein()) + return 1; + bio_ct = 0; + } + return 0; +} diff --git a/jpwl/encoder/libopenjpeg/bio.h b/jpwl/encoder/libopenjpeg/bio.h new file mode 100644 index 00000000..58995b05 --- /dev/null +++ b/jpwl/encoder/libopenjpeg/bio.h @@ -0,0 +1,75 @@ +/* + * 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 + +/* + * Number of bytes written. + */ +int bio_numbytes(); + +/* + * Init encoder. + * + * bp : Output buffer + * len : Output buffer length + */ +void bio_init_enc(unsigned char *bp, int len); + +/* + * Init decoder. + * + * bp : Input buffer + * len : Input buffer length + */ +void bio_init_dec(unsigned char *bp, int len); + +/* + * Write bits. + * + * v : Value of bits + * n : Number of bits to write + */ +void bio_write(int v, int n); + +/* + * Read bits. + * + * n : Number of bits to read + */ +int bio_read(int n); + +/* + * Flush bits. Modified to eliminate longjmp !! + */ +int bio_flush(); + +int bio_inalign(); /* modified to eliminated longjmp !! */ + +#endif diff --git a/jpwl/encoder/libopenjpeg/cio.c b/jpwl/encoder/libopenjpeg/cio.c new file mode 100644 index 00000000..7aecffca --- /dev/null +++ b/jpwl/encoder/libopenjpeg/cio.c @@ -0,0 +1,152 @@ +/* + * 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; /* pointer to the start of the stream */ +static unsigned char *cio_end; /* pointer to the end of the stream */ +static unsigned char *cio_bp; /* pointer to the present position */ + +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. + * + * pos : position, in number of bytes, from the beginning of the 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 + * + * bp : destination/source stream + * len : length of the stream + */ +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 some bytes. + * + * v : value to write + * n : number of bytes to write + */ +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. + * + * n : number of bytes to read + * + * return : value of the n bytes read + */ +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; +} + +/* + * Skip some bytes. + * + * n : number of bytes to skip + */ +void cio_skip(int n) +{ + cio_bp += n; +} diff --git a/jpwl/encoder/libopenjpeg/cio.h b/jpwl/encoder/libopenjpeg/cio.h new file mode 100644 index 00000000..c75a4653 --- /dev/null +++ b/jpwl/encoder/libopenjpeg/cio.h @@ -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. + */ + +#ifndef __CIO_H +#define __CIO_H + +/* + * Number of bytes written. + * + * returns number of bytes written + */ +int cio_numbytes(); + +/* + * Get position in byte stream. + * + * return position in bytes + */ +int cio_tell(); + +/* + * Set position in byte stream. + * + * pos : position, in number of bytes, from the beginning of the stream + */ +void cio_seek(int pos); + +/* + * Number of bytes left before the end of the stream. + * + * Returns the number of bytes before the end of the stream + */ +int cio_numbytesleft(); + +/* + * Get pointer to the current position in the stream. + * + * return : pointer to the position + */ +unsigned char *cio_getbp(); + +/* + * Initialize byte IO + * + * bp : destination/source stream + * len : length of the stream + */ +void cio_init(unsigned char *bp, int len); + +/* + * Write some bytes. + * + * v : value to write + * n : number of bytes to write + */ +void cio_write(unsigned int v, int n); + +/* + * Read some bytes. + * + * n : number of bytes to read + * + * return : value of the n bytes read + */ +unsigned int cio_read(int n); + +/* + * Skip some bytes. + * + * n : number of bytes to skip + */ +void cio_skip(int n); + +#endif diff --git a/jpwl/encoder/libopenjpeg/dwt.c b/jpwl/encoder/libopenjpeg/dwt.c new file mode 100644 index 00000000..92d006ad --- /dev/null +++ b/jpwl/encoder/libopenjpeg/dwt.c @@ -0,0 +1,454 @@ +/* + * Copyright (c) 2001-2002, David Janssens + * Copyright (c) 2002-2004, Yannick Verschueren + * Copyright (c) 2002-2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "dwt.h" +#include "int.h" +#include "fix.h" +#include "tcd.h" +#include +#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; + +/* */ +/* Cleaning memory. */ +/* */ + +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]; +} + +/* */ +/* 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]; +} + +/* */ +/* 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; + 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; + int rw; /* width of the resolution level computed */ + int rh; /* heigth of the resolution level computed */ + int rw1; /* width of the resolution level once lower than computed one */ + int rh1; /* height of the resolution level once lower than computed one */ + + for (i = 0; i < l; i++) { + int cas_col = 0; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ + int cas_row = 0; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ + 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; + + cas_row = tilec->resolutions[l - i].x0 % 2; + cas_col = tilec->resolutions[l - i].y0 % 2; + + 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, + int stop) +{ + int i, j; + int rw; /* width of the resolution level computed */ + int rh; /* heigth of the resolution level computed */ + int rw1; /* width of the resolution level once lower than computed one */ + int rh1; /* height of the resolution level once lower than computed one */ + + for (i = l - 1; i >= stop; i--) { + int cas_col = 0; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ + int cas_row = 0; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ + + 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; + + cas_row = tilec->resolutions[l - i].x0 % 2; + cas_col = tilec->resolutions[l - i].y0 % 2; + + 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); /*5038 */ + for (i = 0; i < sn; i++) + D(i) = fix_mul(D(i), 6659); /*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); /*5038 */ + for (i = 0; i < sn; i++) + S(i) = fix_mul(S(i), 6659); /*6660 */ + } + } + dwt_deinterleave(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(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), 10078); /* 10076 */ + for (i = 0; i < dn; i++) + S(i) = fix_mul(S(i), 13318); /* 13320 */ + for (i = 0; i < sn; i++) + D(i) -= fix_mul(SS_(i) + SS_(i + 1), 3633); + for (i = 0; i < dn; i++) + S(i) -= fix_mul(DD_(i) + DD_(i - 1), 7233); + for (i = 0; i < sn; i++) + D(i) += fix_mul(SS_(i) + SS_(i + 1), 434); + for (i = 0; i < dn; i++) + S(i) += fix_mul(DD_(i) + DD_(i - 1), 12993); + } + } else { + if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */ + for (i = 0; i < sn; i++) + S(i) = fix_mul(S(i), 10078); /* 10076 */ + for (i = 0; i < dn; i++) + D(i) = fix_mul(D(i), 13318); /* 13320 */ + for (i = 0; i < sn; i++) + S(i) -= fix_mul(D_(i - 1) + D_(i), 3633); + for (i = 0; i < dn; i++) + D(i) -= fix_mul(S_(i) + S_(i + 1), 7233); + for (i = 0; i < sn; i++) + S(i) += fix_mul(D_(i - 1) + D_(i), 434); + for (i = 0; i < dn; i++) + D(i) += fix_mul(S_(i) + S_(i + 1), 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; + int rw; /* width of the resolution level computed */ + int rh; /* heigth of the resolution level computed */ + int rw1; /* width of the resolution level once lower than computed one */ + int rh1; /* height of the resolution level once lower than computed one */ + + for (i = 0; i < l; i++) { + int cas_col = 0; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ + int cas_row = 0; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ + 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; + + cas_row = tilec->resolutions[l - i].x0 % 2; + cas_col = tilec->resolutions[l - i].y0 % 2; + + 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, + int stop) +{ + int i, j; + int rw; /* width of the resolution level computed */ + int rh; /* heigth of the resolution level computed */ + int rw1; /* width of the resolution level once lower than computed one */ + int rh1; /* height of the resolution level once lower than computed one */ + + for (i = l - 1; i >= stop; i--) { + int cas_col = 0; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ + int cas_row = 0; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ + + 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; + + cas_row = tilec->resolutions[l - i].x0 % 2; + cas_col = tilec->resolutions[l - i].y0 % 2; + + 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/jpwl/encoder/libopenjpeg/dwt.h b/jpwl/encoder/libopenjpeg/dwt.h new file mode 100644 index 00000000..ec9860b6 --- /dev/null +++ b/jpwl/encoder/libopenjpeg/dwt.h @@ -0,0 +1,101 @@ +/* + * 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 + * tilec : tile component information (present tile) + * 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 + * tilec : tile component information (present tile) + * l: number of decomposition levels in the DWT + * row_tilec : tile component information (previous tile on the same row) + * col_tilec : tile component information (previous tile on the same column) + */ +void dwt_decode(int *a, int w, int h, tcd_tilecomp_t * tilec, int l, + int stop); + +/* + * 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, + int stop); +/* + * 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/jpwl/encoder/libopenjpeg/fix.c b/jpwl/encoder/libopenjpeg/fix.c new file mode 100644 index 00000000..77ca6d63 --- /dev/null +++ b/jpwl/encoder/libopenjpeg/fix.c @@ -0,0 +1,54 @@ +/* + * 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" +#include //Add Antonin : multbug1 + +#ifdef 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); +//} + +//Mod Antonin : multbug1 +int fix_mul(int a, int b) +{ + double tmp= (double) ((int64) a * (int64) b); + int64 v = (int64) ((fabs(tmp/8192.0)>=floor(fabs(tmp/8192.0))+0.5)?fabs(tmp/8192.0)+1.0:fabs(tmp/8192.0)); + v = (tmp<0)?-v:v; + return (int) v; +} +//doM + diff --git a/jpwl/encoder/libopenjpeg/fix.h b/jpwl/encoder/libopenjpeg/fix.h new file mode 100644 index 00000000..768cada2 --- /dev/null +++ b/jpwl/encoder/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/jpwl/encoder/libopenjpeg/int.c b/jpwl/encoder/libopenjpeg/int.c new file mode 100644 index 00000000..7bb5f23d --- /dev/null +++ b/jpwl/encoder/libopenjpeg/int.c @@ -0,0 +1,113 @@ +/* + * 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. + * + * returns a if a < b else b + */ +int int_min(int a, int b) +{ + return a < b ? a : b; +} + +/* + * Get the maximum of two integers. + * + * returns a if a > b else b + */ +int int_max(int a, int b) +{ + return a > b ? a : b; +} + +/* + * Clamp an integer inside an interval. + * + * return a if (min < a < max) + * return max if (a > max) + * return min if (a < min) + */ +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. + * + * a divided by b + */ +int int_ceildiv(int a, int b) +{ + return (a + b - 1) / b; +} + +/* + * Divide an integer by a power of 2 and round upwards. + * + * a divided by 2^b + */ +int int_ceildivpow2(int a, int b) +{ + return (a + (1 << b) - 1) >> b; +} + +/* + * Divide an integer by a power of 2 and round downwards. + * + * a divided by 2^b + */ +int int_floordivpow2(int a, int b) +{ + return a >> b; +} + +/* + * Get logarithm of an integer and round downwards. + * + * log2(a) + */ +int int_floorlog2(int a) +{ + int l; + for (l = 0; a > 1; l++) { + a >>= 1; + } + return l; +} diff --git a/jpwl/encoder/libopenjpeg/int.h b/jpwl/encoder/libopenjpeg/int.h new file mode 100644 index 00000000..a1b590dd --- /dev/null +++ b/jpwl/encoder/libopenjpeg/int.h @@ -0,0 +1,86 @@ +/* + * 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 + +/* + * Get the minimum of two integers. + * + * returns a if a < b else b + */ +int int_min(int a, int b); + +/* + * Get the maximum of two integers. + * + * returns a if a > b else b + */ +int int_max(int a, int b); + +/* + * Clamp an integer inside an interval. + * + * return a if (min < a < max) + * return max if (a > max) + * return min if (a < min) + */ +int int_clamp(int a, int min, int max); + +/* + * Get absolute value of integer. + */ +int int_abs(int a); + +/* + * Divide an integer and round upwards. + * + * a divided by b + */ +int int_ceildiv(int a, int b); + +/* + * Divide an integer by a power of 2 and round upwards. + * + * a divided by 2^b + */ +int int_ceildivpow2(int a, int b); + +/* + * Divide an integer by a power of 2 and round downwards. + * + * a divided by 2^b + */ +int int_floordivpow2(int a, int b); + +/* + * Get logarithm of an integer and round downwards. + * + * log2(a) + */ +int int_floorlog2(int a); + +#endif diff --git a/jpwl/encoder/libopenjpeg/j2k.c b/jpwl/encoder/libopenjpeg/j2k.c new file mode 100644 index 00000000..3c6d7762 --- /dev/null +++ b/jpwl/encoder/libopenjpeg/j2k.c @@ -0,0 +1,1917 @@ +/* + * Copyright (c) 2001-2002, David Janssens + * Copyright (c) 2002-2004, Yannick Verschueren + * Copyright (c) 2002-2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include "j2k.h" +#include "cio.h" +#include "tcd.h" +#include "dwt.h" +#include "int.h" +#include "jpt.h" +#include "jpw.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 +//JPWL Markers +#define JPWL_MS_EPC 0xff97 +#define JPWL_MS_EPB 0xff96 +#define JPWL_MS_ESD 0xff98 + + +#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 +#define J2K_STATE_MHEPB 0x0080 +#define J2K_STATE_MHEPB 0x0080 +#define J2K_STATE_TPHEPB 0x0100 + + +jmp_buf j2k_error; + +extern JPWL_cp_t jpwl_cp; +extern int use_index; +int j2k_state; + + +static int j2k_curtileno; +static j2k_tcp_t j2k_default_tcp; +static unsigned char *j2k_eot; +static int pos_correction; +static int j2k_sot_start; +static j2k_image_t *j2k_img; +j2k_cp_t *j2k_cp; + +static unsigned char **j2k_tile_data; +static int *j2k_tile_len; + + 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 */ + +/* add Andrea */ +void j2k_free_info(){ + int tileno = 0; + for (tileno = 0; tileno < j2k_cp->tw * j2k_cp->th; tileno++) { + free(info_IM.tile[tileno].packet); + } + free(info_IM.tile); +} + +void j2k_free_tcd(){ + tcd_free_encode(j2k_img, j2k_cp, j2k_curtileno); +} + +/* \add andrea */ + +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() +{ + cio_write(J2K_MS_SOC, 2); +} + +void j2k_read_soc() +{ + j2k_state = J2K_STATE_MHSIZ; +} + +void j2k_write_siz() +{ + int i; + int lenp, len; + + 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; + + len = cio_read(2); /* Lsiz */ + cio_read(2); /* Rsiz (capabilities) */ + j2k_img->x1 = cio_read(4); /* Xsiz */ + j2k_img->y1 = cio_read(4); /* Ysiz */ + j2k_img->x0 = cio_read(4); /* X0siz */ + j2k_img->y0 = cio_read(4); /* Y0siz */ + j2k_cp->tdx = cio_read(4); /* XTsiz */ + j2k_cp->tdy = cio_read(4); /* YTsiz */ + j2k_cp->tx0 = cio_read(4); /* XT0siz */ + j2k_cp->ty0 = cio_read(4); /* YT0siz */ + + j2k_img->numcomps = cio_read(2); /* Csiz */ + 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); /* Ssiz_i */ + j2k_img->comps[i].prec = (tmp & 0x7f) + 1; + j2k_img->comps[i].sgnd = tmp >> 7; + j2k_img->comps[i].dx = cio_read(1); /* XRsiz_i */ + j2k_img->comps[i].dy = cio_read(1); /* YRsiz_i */ + 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].resno_decoded = 0; /* number of resolution decoded */ + j2k_img->comps[i].factor = 0; /* reducing factor by component */ + } + + 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(j2k_cp->tw * j2k_cp->th, sizeof(j2k_tcp_t)); + j2k_cp->tileno = (int *) calloc(j2k_cp->tw * j2k_cp->th, sizeof(int)); + j2k_cp->tileno_size = 0; + + for (i = 0; i < j2k_cp->tw * j2k_cp->th; i++) { + j2k_cp->tcps[i].POC = 0; + j2k_cp->tcps[i].numpocs = 0; + j2k_cp->tcps[i].first = 1; + } + + /* Initialization for PPM marker */ + j2k_cp->ppm = 0; + j2k_cp->ppm_data = NULL; + j2k_cp->ppm_previous = 0; + j2k_cp->ppm_store = 0; + + 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); + + 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; + + 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; /* SPcox (D) */ + tccp->cblkw = cio_read(1) + 2; /* SPcox (E) */ + tccp->cblkh = cio_read(1) + 2; /* SPcox (F) */ + tccp->cblksty = cio_read(1); /* SPcox (G) */ + tccp->qmfbid = cio_read(1); /* SPcox (H) */ + if (tccp->csty & J2K_CP_CSTY_PRT) { + for (i = 0; i < tccp->numresolutions; i++) { + int tmp = cio_read(1); /* SPcox (I_i) */ + tccp->prcw[i] = tmp & 0xf; + tccp->prch[i] = tmp >> 4; + } + } +} + +void j2k_write_cod() +{ + j2k_tcp_t *tcp; + int lenp, len; + + 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; + + tcp = + j2k_state == + J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp; + len = cio_read(2); /* Lcod */ + tcp->csty = cio_read(1); /* Scod */ + tcp->prg = cio_read(1); /* SGcod (A) */ + tcp->numlayers = cio_read(2); /* SGcod (B) */ + tcp->mct = cio_read(1); /* SGcod (C) */ + + 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; + + 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; + + tcp = + j2k_state == + J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp; + len = cio_read(2); /* Lcoc */ + compno = cio_read(j2k_img->numcomps <= 256 ? 1 : 2); /* Ccoc */ + tcp->tccps[compno].csty = cio_read(1); /* Scoc */ + 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); /* Sqcx */ + 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) { + expn = cio_read(1) >> 3; /* SPqcx_i */ + mant = 0; + } else { + tmp = cio_read(2); /* SPqcx_i */ + expn = tmp >> 11; + mant = tmp & 0x7ff; + } + tccp->stepsizes[bandno].expn = expn; + tccp->stepsizes[bandno].mant = mant; + } + + + + /* Add Antonin : if scalar_derived -> compute other stepsizes */ + + + + if (tccp->qntsty==J2K_CCP_QNTSTY_SIQNT) { + + for (bandno=1 ; bandnostepsizes[bandno].expn = ((tccp->stepsizes[0].expn)-((bandno-1)/3)>0)?(tccp->stepsizes[0].expn)-((bandno-1)/3):0; + + tccp->stepsizes[bandno].mant = tccp->stepsizes[0].mant; + + } + + } + + + + /* ddA */ +} + +void j2k_write_qcd() +{ + int lenp, len; + + 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; + + len = cio_read(2); /* Lqcd */ + 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; + + cio_write(J2K_MS_QCC, 2); /* QCC */ + lenp = cio_tell(); + cio_skip(2); + cio_write(compno, j2k_img->numcomps <= 256 ? 1 : 2); /* Cqcc */ + j2k_write_qcx(compno); + len = cio_tell() - lenp; + cio_seek(lenp); + cio_write(len, 2); /* Lqcc */ + cio_seek(lenp + len); +} + +void j2k_read_qcc() +{ + int len, compno; + + len = cio_read(2); /* Lqcc */ + compno = cio_read(j2k_img->numcomps <= 256 ? 1 : 2); /* Cqcc */ + j2k_read_qcx(compno, len - 2 - (j2k_img->numcomps <= 256 ? 1 : 2)); +} + +void j2k_write_poc() +{ + int len, numpchgs, i; + j2k_tcp_t *tcp; + j2k_tccp_t *tccp; + + tcp = &j2k_cp->tcps[j2k_curtileno]; + tccp = &tcp->tccps[0]; + numpchgs = tcp->numpocs; + cio_write(J2K_MS_POC, 2); /* POC */ + len = 2 + (5 + 2 * (j2k_img->numcomps <= 256 ? 1 : 2)) * numpchgs; + cio_write(len, 2); /* Lpoc */ + for (i = 0; i < numpchgs; i++) { + // MODIF + j2k_poc_t *poc; + poc = &tcp->pocs[i]; + cio_write(poc->resno0, 1); /* RSpoc_i */ + cio_write(poc->compno0, (j2k_img->numcomps <= 256 ? 1 : 2)); /* CSpoc_i */ + cio_write(poc->layno1, 2); /* LYEpoc_i */ + poc->layno1 = int_min(poc->layno1, tcp->numlayers); + cio_write(poc->resno1, 1); /* REpoc_i */ + poc->resno1 = int_min(poc->resno1, tccp->numresolutions); + cio_write(poc->compno1, (j2k_img->numcomps <= 256 ? 1 : 2)); /* CEpoc_i */ + poc->compno1 = int_min(poc->compno1, j2k_img->numcomps); + cio_write(poc->prg, 1); /* Ppoc_i */ + } +} + +void j2k_read_poc() +{ + int len, numpchgs, i, old_poc; + j2k_tcp_t *tcp; + j2k_tccp_t *tccp; + + tcp = + j2k_state == + J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp; + + old_poc = tcp->POC ? tcp->numpocs + 1 : 0; + tcp->POC = 1; + tccp = &tcp->tccps[0]; + len = cio_read(2); /* Lpoc */ + numpchgs = (len - 2) / (5 + 2 * (j2k_img->numcomps <= 256 ? 1 : 2)); + + for (i = old_poc; i < numpchgs + old_poc; i++) { + j2k_poc_t *poc; + poc = &tcp->pocs[i]; + poc->resno0 = cio_read(1); /* RSpoc_i */ + poc->compno0 = cio_read(j2k_img->numcomps <= 256 ? 1 : 2); /* CSpoc_i */ + poc->layno1 = int_min(cio_read(2), tcp->numlayers); /* LYEpoc_i */ + poc->resno1 = int_min(cio_read(1), tccp->numresolutions); /* REpoc_i */ + poc->compno1 = int_min(cio_read(j2k_img->numcomps <= 256 ? 1 : 2), j2k_img->numcomps); /* CEpoc_i */ + poc->prg = cio_read(1); /* Ppoc_i */ + } + + tcp->numpocs = numpchgs + old_poc - 1; +} + +void j2k_read_crg() +{ + int len, i, Xcrg_i, Ycrg_i; + + len = cio_read(2); /* Lcrg */ + for (i = 0; i < j2k_img->numcomps; i++) { + Xcrg_i = cio_read(2); /* Xcrg_i */ + Ycrg_i = cio_read(2); /* Ycrg_i */ + } +} + +void j2k_read_tlm() +{ + int len, Ztlm, Stlm, ST, SP, tile_tlm, i; + long int Ttlm_i, Ptlm_i; + + len = cio_read(2); /* Ltlm */ + Ztlm = cio_read(1); /* Ztlm */ + Stlm = cio_read(1); /* Stlm */ + ST = ((Stlm >> 4) & 0x01) + ((Stlm >> 4) & 0x02); + SP = (Stlm >> 6) & 0x01; + tile_tlm = (len - 4) / ((SP + 1) * 2 + ST); + for (i = 0; i < tile_tlm; i++) { + Ttlm_i = cio_read(ST); /* Ttlm_i */ + Ptlm_i = cio_read(SP ? 4 : 2); /* Ptlm_i */ + } +} + +void j2k_read_plm() +{ + int len, i, Zplm, Nplm, add, packet_len = 0; + + len = cio_read(2); /* Lplm */ + Zplm = cio_read(1); /* Zplm */ + len -= 3; + while (len > 0) { + Nplm = cio_read(4); /* Nplm */ + len -= 4; + for (i = Nplm; i > 0; i--) { + add = cio_read(1); + len--; + packet_len = (packet_len << 7) + add; /* Iplm_ij */ + if ((add & 0x80) == 0) { + /* New packet */ + packet_len = 0; + } + if (len <= 0) + break; + } + } +} + +void j2k_read_plt() +{ + int len, i, Zplt, packet_len = 0, add; + + len = cio_read(2); /* Lplt */ + Zplt = cio_read(1); /* Zplt */ + for (i = len - 3; i > 0; i--) { + add = cio_read(1); + packet_len = (packet_len << 7) + add; /* Iplt_i */ + if ((add & 0x80) == 0) { + /* New packet */ + packet_len = 0; + } + } +} + +void j2k_read_ppm() +{ + int len, Z_ppm, i, j; + int N_ppm; + + len = cio_read(2); + j2k_cp->ppm = 1; + + Z_ppm = cio_read(1); /* Z_ppm */ + len -= 3; + while (len > 0) { + if (j2k_cp->ppm_previous == 0) { + N_ppm = cio_read(4); /* N_ppm */ + len -= 4; + } else { + N_ppm = j2k_cp->ppm_previous; + } + + j = j2k_cp->ppm_store; + if (Z_ppm == 0) { /* First PPM marker */ + j2k_cp->ppm_data = + (unsigned char *) calloc(N_ppm, sizeof(unsigned char)); + + j2k_cp->ppm_len = N_ppm; //Add antonin : ppmbug1 + + } else { /* NON-first PPM marker */ + j2k_cp->ppm_data = + (unsigned char *) realloc(j2k_cp->ppm_data, + (N_ppm + + j2k_cp->ppm_store) * + sizeof(unsigned char)); + + j2k_cp->ppm_len = N_ppm + j2k_cp->ppm_store; //Add antonin : ppmbug1 + + } + + for (i = N_ppm; i > 0; i--) { /* Read packet header */ + j2k_cp->ppm_data[j] = cio_read(1); + j++; + len--; + if (len == 0) + break; /* Case of non-finished packet header in present marker but finished in next one */ + } + + j2k_cp->ppm_previous = i - 1; + j2k_cp->ppm_store = j; + } +} + +void j2k_read_ppt() +{ + int len, Z_ppt, i, j = 0; + j2k_tcp_t *tcp; + + len = cio_read(2); + Z_ppt = cio_read(1); + tcp = &j2k_cp->tcps[j2k_curtileno]; + tcp->ppt = 1; + if (Z_ppt == 0) { /* First PPT marker */ + tcp->ppt_data = + (unsigned char *) calloc(len - 3, sizeof(unsigned char)); + tcp->ppt_store = 0; + + tcp->ppt_len = len-3; //Add antonin : ppmbug1 + } else { /* NON-first PPT marker */ + tcp->ppt_data = + (unsigned char *) realloc(tcp->ppt_data, + (len - 3 + + tcp->ppt_store) * sizeof(unsigned char)); + + tcp->ppt_len=len - 3 + tcp->ppt_store; //Add antonin : ppmbug1 + + } + + j = tcp->ppt_store; + for (i = len - 3; i > 0; i--) { + tcp->ppt_data[j] = cio_read(1); + j++; + } + tcp->ppt_store = j; +} + +void j2k_write_sot() +{ + int lenp, len; + + 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; + char status = 0; + + len = cio_read(2); + tileno = cio_read(2); + + if (j2k_cp->tileno_size == 0) { + j2k_cp->tileno[j2k_cp->tileno_size] = tileno; + j2k_cp->tileno_size++; + } else { + i = 0; + while (i < j2k_cp->tileno_size && status == 0) { + status = j2k_cp->tileno[i] == tileno ? 1 : 0; + i++; + } + if (status == 0) { + j2k_cp->tileno[j2k_cp->tileno_size] = tileno; + j2k_cp->tileno_size++; + } + } + + 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]; + + if (tcp->first == 1) { + tmp = tcp->tccps; + *tcp = j2k_default_tcp; + + /* Initialization PPT */ + tcp->ppt = 0; + tcp->ppt_data = NULL; + + tcp->tccps = tmp; + for (i = 0; i < j2k_img->numcomps; i++) { + tcp->tccps[i] = j2k_default_tcp.tccps[i]; + } + j2k_cp->tcps[j2k_curtileno].first = 0; + } +} + +void j2k_write_sod() +{ + int l, layno; + int totlen; + j2k_tcp_t *tcp; + static int j2k_sod_start; + + 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 *) calloc(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)); + } + + 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, i; + unsigned char *data; + + len = int_min(j2k_eot - cio_getbp(), cio_numbytesleft() + 1); + if (len == cio_numbytesleft() + 1) + truncate = 1; /* Case of a truncate codestream */ + + data = + (unsigned char *) malloc((j2k_tile_len[j2k_curtileno] + len) * + sizeof(unsigned char)); + for (i = 0; i < j2k_tile_len[j2k_curtileno]; i++) + data[i] = j2k_tile_data[j2k_curtileno][i]; + for (i = 0; i < len; i++) + data[i + j2k_tile_len[j2k_curtileno]] = cio_read(1); + + j2k_tile_len[j2k_curtileno] += len; + free(j2k_tile_data[j2k_curtileno]); + j2k_tile_data[j2k_curtileno] = data; + data = NULL; + + 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]; + + 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; + + tcp = + j2k_state == + J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp; + len = cio_read(2); /* Lrgn */ + compno = cio_read(j2k_img->numcomps <= 256 ? 1 : 2); /* Crgn */ + roisty = cio_read(1); /* Srgn */ + tcp->tccps[compno].roishift = cio_read(1); /* SPrgn */ +} + +void j2k_write_eoc() +{ + /* fprintf(stderr, "%.8x: EOC\n", cio_tell() + pos_correction); */ + cio_write(J2K_MS_EOC, 2); +} + +void j2k_read_eoc() +{ + int i, tileno; + + tcd_init(j2k_img, j2k_cp); + + for (i = 0; i < j2k_cp->tileno_size; i++) { + tileno = j2k_cp->tileno[i]; + tcd_decode_tile(j2k_tile_data[tileno], j2k_tile_len[tileno], tileno); + free(j2k_tile_data[tileno]); + } + + j2k_state = J2K_STATE_MT; + longjmp(j2k_error, 1); +} + +void j2k_read_unk() +{ + //c'era un bug in questa funzione occorre leggere la lunghezza di un marker sconosciuto per proseguire il parsing + int len; + fprintf(stderr, "warning: unknown marker\n"); + len = cio_read(2); + cio_skip(len - 2); //bug corretto +} + + +void write_index(char *index, unsigned long CL){ + double DistoTotal = 0; + FILE *INDEX; + int tileno, compno, layno, resno, precno, pack_nb; + + info_IM.codestream_size = CL; /* 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 %d\n", info_IM.tw, info_IM.th); + + fprintf(INDEX, "%d\n", info_IM.Comp); + + fprintf(INDEX, "%d\n", info_IM.Layer); + + fprintf(INDEX, "%d\n", info_IM.Decomposition); + + for (resno=info_IM.Decomposition;resno>=0;resno--) { + + fprintf(INDEX, "[%d,%d] ", (1<intermed_file==1) { + f = fopen(output, "wb"); + if (!f) { + fprintf(stderr, "failed to open %s for writing\n", output); + return 1; + } + dest = (char *) malloc(len); + cio_init(dest, len); + } + pos_correction=0; + j2k_img = img; + j2k_cp = cp; + + /* j2k_dump_cp(j2k_img, j2k_cp); */ + + /* INDEX >> */ + info_IM.index_on = j2k_cp->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.tw=j2k_cp->tw; + info_IM.th=j2k_cp->th; + 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 */ + //if (info_IM.index_on && !(cp->intermed_file)) + // get_info(&info_IM); + + j2k_state = J2K_STATE_MHSOC; + j2k_write_soc(); + j2k_state = J2K_STATE_MHSIZ; + j2k_write_siz(); + j2k_state = J2K_STATE_MH; + set_epb=cio_tell(); + + // scrivo i marker jpwl direttamente solo se uso gli intermed files + if (jpwl_cp.JPWL_on && cp->intermed_file) // se è attiva l'opzione jpwl allora scrive l'epc + jpwl_write_EPC(); + + 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(); + + if (jpwl_cp.EPB_on && cp->intermed_file){ + /* inserimento EPB */ + cur_pos = cio_tell(); + len_data = cur_pos - set_epb; + buf = (char *) malloc(len_data * sizeof(char)); + cio_seek(set_epb); + for (i = 0; i < len_data; i++){ + buf[i] = cio_read(1); + } + cio_seek(set_epb); + JPWL_write_EPB(buf, len_data, jpwl_cp.pepb[0], 0x40); + for (i = 0; i < len_data; i++){ + cio_write(buf[i],1); + } + free(buf); + } + + + + if (cp->intermed_file==1) { + /* 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, "Tile number %d / %d ", tileno + 1, + cp->tw * cp->th); + + if (cp->intermed_file==1) { + /* 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_state = J2K_STATE_TPHSOT; + j2k_write_sot(); + j2k_state = J2K_STATE_TPH; + set_epb=cio_tell(); + + for (compno = 1; compno < img->numcomps; compno++) { + j2k_write_coc(compno); + j2k_write_qcc(compno); + } + + if (cp->tcps[tileno].numpocs) + j2k_write_poc(); + end_tph=cio_tell(); + j2k_write_sod(); + + //inserimento ESD se uso l'intermed file o se uso il packet range mode(problema dell'indice di pacchettto) + if ((jpwl_cp.ESD_on && cp->intermed_file)||(((jpwl_cp.pesd & 0xC0)>>6)==2)){ + cur_pos = cio_tell(); + len_data = cur_pos - set_epb; + buf = (char *) malloc(len_data * sizeof(char)); + cio_seek(set_epb); + for (i = 0; i < len_data; i++){ + buf[i] = cio_read(1); + } + cio_seek(set_epb); + info_IM.tile[j2k_curtileno].end_pos = cur_pos + pos_correction - 1; + jpwl_write_ESD(jpwl_cp.pesd, tileno + 1); + len_esd = cio_tell() - set_epb; + for (i = 0; i < len_data; i++){ + cio_write(buf[i],1); + } + free(buf); + //correzione di psot + cio_seek(j2k_sot_start + 6); + x = cio_read(4); + cio_skip(-4); + cio_write(x + len_esd, 4); + + end_tph += len_esd; + /* INDEX >> */ + if (info_IM.index_on) { + info_IM.tile[j2k_curtileno].end_pos = cur_pos + len_esd - 1; + if (jpwl_cp.ESD_on && cp->intermed_file){ + info_IM.tile[j2k_curtileno].end_header += len_esd; + pack_corr(len_esd, tileno); + } + } + + cio_seek(cur_pos + len_esd); + } + + if (jpwl_cp.EPB_on && cp->intermed_file){ + /*inserimento di due EPB: uno a protezione del tph e l'altro dei dati*/ + cur_pos = cio_tell(); + len_data = end_tph - set_epb; + len_data2 = cur_pos - end_tph; + buf = (char *) malloc(len_data * sizeof(char)); + save = (char *) malloc(len_data2 * sizeof(char)); + cio_seek(set_epb); + for (i = 0; i < len_data; i++){ + buf[i] = cio_read(1); + } + for (i = 0; i < len_data2; i++){ + save[i] = cio_read(1); + } + if(jpwl_cp.UEP_on){ + cio_seek(set_epb); + Psot_corr=uep(tileno+1,save,buf,len_data); + free(buf); + + } else { + Psot_corr=0; + //correzione di psot + cio_seek(j2k_sot_start + 6); + if(len_data) + Psot_corr += JPWL_len_EPB(len_data, jpwl_cp.pepb[0], 0)+2; + //Psot_corr += JPWL_len_EPB(len_data2, jpwl_cp.pepb2, 0x41); + lmax = pianifica_epb(len_data2, jpwl_cp.pepb[1], &no_epb); + //printf("num epb: %d\n", no_epb); + if(no_epb > 1){ + if (len_data) + Psot_corr += (no_epb-1)*JPWL_len_EPB((lmax), jpwl_cp.pepb[1], 0x41) + JPWL_len_EPB((len_data2 % lmax), jpwl_cp.pepb[1], 0x41); + else + Psot_corr += JPWL_len_EPB(lmax, jpwl_cp.pepb[1], 0) + (no_epb-2)*JPWL_len_EPB((lmax), jpwl_cp.pepb[1], 0x41) + JPWL_len_EPB((len_data2 % lmax), jpwl_cp.pepb[1], 0x41); + } + else{ + if (len_data) + Psot_corr += JPWL_len_EPB((len_data2), jpwl_cp.pepb[1], 0x41); + else + Psot_corr += JPWL_len_EPB((len_data2), jpwl_cp.pepb[1], 0x0); + } + Psot_corr += 2*(no_epb); + + x = cio_read(4); + cio_skip(-4); + cio_write(x + Psot_corr, 4); + + + cio_seek(set_epb); + if (len_data){ + JPWL_write_EPB(buf, len_data, jpwl_cp.pepb[0], 0); + h=1; + } + for (i = 0; i < len_data; i++){ + cio_write(buf[i],1); + } + free(buf); + //JPWL_write_EPB(save, len_data2, jpwl_cp.pepb2, 0x41); + mask = (no_epb == 1) ? 0x40 : 0x80; + data = (unsigned char *)malloc(lmax*sizeof(unsigned char)); + for (i=0; i < no_epb; i++){ + cont=0; + depb = mask|((i+h)&0x3F); + while (((cont + i*lmax)< len_data2)&&(cont < lmax)){ + data[cont] = save[cont + i*lmax]; + cont++; + } + if (cont < lmax) + depb |= 0x40; + JPWL_write_EPB(data, cont, jpwl_cp.pepb[0], depb); + + } + free(data); + } + + for (i = 0; i < len_data2; i++){ + cio_write(save[i],1); + } + free(save); + } + + + /* INDEX >> */ + if (info_IM.index_on) { + info_IM.tile[j2k_curtileno].end_pos = cio_tell() + pos_correction - 1; + if (jpwl_cp.EPB_on && cp->intermed_file){ + info_IM.tile[j2k_curtileno].end_header += Psot_corr + 4; + pack_corr(Psot_corr + 4, tileno); + } + } + /* << 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"); + } + */ + if (cp->intermed_file==1) { + fwrite(dest, 1, cio_tell(), f); + pos_correction = cio_tell() + pos_correction; + } + } + + if (cp->intermed_file==1) { + free(dest); + dest = (char *) malloc(len); + cio_init(dest, len); + } + + j2k_write_eoc(); + + if (cp->intermed_file==1) { + fwrite(dest, 1, 2, f); + free(dest); + /* closing file *.j2k */ + fclose(f); + } + + /* Creation of the index file */ + + if ((info_IM.index_on && use_index && cp->intermed_file) || (info_IM.index_on && use_index &&!(jpwl_cp.JPWL_on))){ + cod_len = cio_tell() + pos_correction; + //printf("num: %d\n",info_IM.num); + write_index(index, cod_len); + } + + + +if(!(info_IM.index_on)||(cp->intermed_file)) + j2k_clean(); + +//if((info_IM.index_on)&&(!(cp->intermed_file))) +// j2k_free_tcd(); + + + return (cio_tell() + pos_correction); +} + +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; + } + j2k_clean(); + return cio_numbytes(); /* Correct way of ending j2k_decode */ + } + + j2k_img = img; + + j2k_cp = 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; +} + +/* + * Read a JPT-stream and decode file + * + */ +int j2k_decode_jpt_stream(unsigned char *src, int len, j2k_image_t * img, + j2k_cp_t * cp) +{ + jpt_msg_header_struct_t header; + int position; + + if (setjmp(j2k_error)) { + if (j2k_state != J2K_STATE_MT) { + fprintf(stderr, "WARNING: incomplete bitstream\n"); + return 0; + } + return cio_numbytes(); + } + + j2k_img = img; + + j2k_cp = cp; + + j2k_state = J2K_STATE_MHSOC; + cio_init(src, len); + + /* Initialize the header */ + jpt_init_Msg_Header(&header); + /* Read the first header of the message */ + jpt_read_Msg_Header(&header); + + position = cio_tell(); + if (header.Class_Id != 6) { /* 6 : Main header data-bin message */ + fprintf(stderr, + "[JPT-stream] : Expecting Main header first [class_Id %d] !\n", + header.Class_Id); + return 0; + } + + for (;;) { + j2k_dec_mstabent_t *e; + int id; + + if (!cio_numbytesleft()) { + j2k_read_eoc(); + return 0; + } + /* data-bin read -> need to read a new header */ + if ((unsigned int) (cio_tell() - position) == header.Msg_length) { + jpt_read_Msg_Header(&header); + position = cio_tell(); + if (header.Class_Id != 4) { /* 4 : Tile data-bin message */ + fprintf(stderr, "[JPT-stream] : Expecting Tile info !\n"); + return 0; + } + } + + 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/jpwl/encoder/libopenjpeg/j2k.h b/jpwl/encoder/libopenjpeg/j2k.h new file mode 100644 index 00000000..4b328f6f --- /dev/null +++ b/jpwl/encoder/libopenjpeg/j2k.h @@ -0,0 +1,238 @@ +/* + * 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" +//#include "jpw.h" +#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 /* Number of maximum resolution level authorized */ +#define J2K_MAXBANDS (3*J2K_MAXRLVLS-2) /* Number of maximum sub-band linked to number of resolution level */ + +#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 w, h; /* width and height of data */ + int x0, y0; /* offset of the component compare to the whole image */ + int prec; /* precision */ + int bpp; /* deapth of image in bits */ + int sgnd; /* signed */ + int resno_decoded; /* number of decoded resolution */ + int factor; /* number of division by 2 of the out image compare to the original size of image */ + 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 color_space; /* sRGB, Greyscale or YUV */ + 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 quantization */ + 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 first; /* 1 : first part-tile of a tile */ + 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 */ + int POC; /* Precise if a POC marker has been used O:NO, 1:YES */ + j2k_poc_t pocs[32]; /* progression order changes */ + unsigned char *ppt_data; /* packet header store there for futur use in t2_decode_packet */ + int ppt; /* If ppt == 1 --> there was a PPT marker for the present tile */ + int ppt_store; /* Use in case of multiple marker PPT (number of info already store) */ + int ppt_len; /* ppmbug1 */ + float distoratio[100]; /* add fixed_quality */ + j2k_tccp_t *tccps; /* tile-component coding parameters */ +} j2k_tcp_t; + +typedef struct { + int JPEG2000_format; /* 0: J2K 1:JP2 */ + int intermed_file; /* 1: Store each encoded tile one by one in the output file (for mega-Images)*/ + int image_type; /* 0: PNM, PGM, PPM 1: PGX */ + int disto_alloc; /* Allocation by rate/distortion */ + int fixed_alloc; /* Allocation by fixed layer */ + int fixed_quality; /* add fixed_quality */ + int reduce_on; /* option reduce is used if reduce = 1 */ + int reduce_value; /* if option reduce is used -> original dimension divided by 2^value */ + int index_on; /* 0 = no index || 1 = index */ + int tx0, ty0; /* XTOsiz, YTOsiz */ + int tdx, tdy; /* XTsiz, YTsiz */ + char *comment; /* comment for coding */ + int tw, th; /* number of tiles in width and heigth */ + int *tileno; /* ID number of the tiles present in the codestream */ + int tileno_size; /* size of the vector tileno */ + unsigned char *ppm_data; /* packet header store there for futur use in t2_decode_packet */ + int ppm; /* If ppm == 1 --> there was a PPM marker for the present tile */ + int ppm_store; /* Use in case of multiple marker PPM (number of info already store) */ + int ppm_previous; /* Use in case of multiple marker PPM (case on non-finished previous info) */ + int ppm_len; /* ppmbug1 */ + j2k_tcp_t *tcps; /* tile coding parameters */ + int *matrice; /* Fixed layer */ +} j2k_cp_t; + +typedef struct { + int start_pos, end_pos; /* start and end position */ + double disto; /* ADD for Marcela */ +} info_packet; /* Index struct */ + +typedef struct { + double *thresh; /* value of thresh for each layer by tile cfr. Marcela */ + 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[33], ph[33]; /* precinct number for each resolution level */ + + int pdx[33], pdy[33]; /* precinct size (in power of 2), in X and Y for each resolution level */ + info_packet *packet; /* information concerning packets inside tile */ + int nbpix; /* add fixed_quality */ + double distotile; /* add fixed_quality */ +} 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; /* Tile size in x and y */ + int tw, th; /* Number of Tile in X and Y */ + int Comp; /* Component numbers */ + int Layer; /* number of layer */ + int Decomposition; /* number of decomposition */ + 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 */ + +// index struct correction +void pack_corr(unsigned long corr, int tileno); + +//write index file +void write_index(char *index, unsigned long CL); + +void j2k_clean(); + +void j2k_free_info(); + +void j2k_free_tcd(); + + +/* + * Encode an image into a JPEG-2000 codestream + * i: image to encode + * cp: coding parameters + * output: destination buffer or name of the output file when cp->intermed_file==1 + * len: length of destination buffer + * index : index file name + */ +LIBJ2K_API int j2k_encode(j2k_image_t * i, j2k_cp_t * cp, char *output, + 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 * img, + j2k_cp_t * cp); + + +/* + * Decode an image form a JPT-stream (JPEG 2000, JPIP) + * src: source buffer + * len: length of source buffer + * i: decode image + * cp: coding parameters that were used to encode the image + * + */ +int j2k_decode_jpt_stream(unsigned char *src, int len, j2k_image_t * img, + j2k_cp_t * cp); + +#endif diff --git a/jpwl/encoder/libopenjpeg/jp2.c b/jpwl/encoder/libopenjpeg/jp2.c new file mode 100644 index 00000000..b070ed8d --- /dev/null +++ b/jpwl/encoder/libopenjpeg/jp2.c @@ -0,0 +1,590 @@ +/* +* Copyright (c) 2003-2004, Yannick Verschueren +* Copyright (c) 2003-2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include + +#include "j2k.h" +#include "jp2.h" +#include "cio.h" +#include "tcd.h" +#include "int.h" +#include "jpw.h" + +#define JPIP_JPIP 0x6a706970 + +#define JP2_JP 0x6a502020 +#define JP2_FTYP 0x66747970 +#define JP2_JP2H 0x6a703268 +#define JP2_IHDR 0x69686472 +#define JP2_COLR 0x636f6c72 +#define JP2_JP2C 0x6a703263 +#define JP2_URL 0x75726c20 +#define JP2_DBTL 0x6474626c +#define JP2_BPCC 0x62706363 +#define JP2_JP2 0x6a703220 + + +extern JPWL_cp_t jpwl_cp; +extern info_image info_IM; +extern int use_index; + +/* +* +* Read box headers +* +*/ + +int jp2_read_boxhdr(jp2_box_t * box) +{ + box->init_pos = cio_tell(); + box->length = cio_read(4); + box->type = cio_read(4); + if (box->length == 1) { + if (cio_read(4) != 0) { + fprintf(stderr, "Error: Cannot handle box sizes higher than 2^32\n"); + return 1; + }; + box->length = cio_read(4); + } + return 0; +} + +/* +* +* Initialisation of a Standard JP2 structure +*/ + +int jp2_init_stdjp2(jp2_struct_t * jp2_struct, j2k_image_t * img) +{ + int depth_0, sign, depth, i; + + + jp2_struct->h = img->y1 - img->y0; // HEIGHT + jp2_struct->w = img->x1 - img->x0; // WIDTH + jp2_struct->numcomps = img->numcomps; // NC + jp2_struct->comps = (jp2_comps_t *) malloc(jp2_struct->numcomps * sizeof(jp2_comps_t)); + + depth_0 = img->comps[0].prec - 1; + sign = img->comps[0].sgnd; + jp2_struct->bpc = depth_0 + (sign << 7); + + for (i = 1; i < img->numcomps; i++) { + depth = img->comps[i].prec - 1; + sign = img->comps[i].sgnd; + if (depth_0 != depth) + jp2_struct->bpc = 255; + } + + + + jp2_struct->C = 7; // C : Always 7 + jp2_struct->UnkC = 0; // UnkC, colorspace specified in colr box + jp2_struct->IPR = 0; // IPR, no intellectual property + + for (i = 0; i < img->numcomps; i++) + jp2_struct->comps[i].bpcc = + img->comps[i].prec - 1 + (img->comps[i].sgnd << 7); + + jp2_struct->precedence = 0; // PRECEDENCE + jp2_struct->approx = 0; // APPROX + + if ((img->numcomps == 1 || img->numcomps == 3) + && (jp2_struct->bpc != 255)) + jp2_struct->meth = 1; + else + jp2_struct->meth = 2; + + if (jp2_struct->meth == 1) { + if (img->color_space == 1) + jp2_struct->enumcs = 16; + else if (img->color_space == 2) + jp2_struct->enumcs = 17; + else if (img->color_space == 3) + jp2_struct->enumcs = 18; // YUV + } else + jp2_struct->enumcs = 0; // PROFILE (??) + + jp2_struct->brand = JP2_JP2; /* BR */ + jp2_struct->minversion = 0; /* MinV */ + jp2_struct->numcl = 1; + jp2_struct->cl = (int *) malloc(jp2_struct->numcl * sizeof(int)); + jp2_struct->cl[0] = JP2_JP2; /* CL0 : JP2 */ + return 0; +} + + +void jp2_write_url(char *Idx_file) +{ + unsigned int i; + char str[256]; + jp2_box_t box; + + sprintf(str, "%s", Idx_file); + + + box.init_pos = cio_tell(); + cio_skip(4); + cio_write(JP2_URL, 4); // DBTL + cio_write(0, 1); // VERS + cio_write(0, 3); // FLAG + + for (i = 0; i < strlen(str); i++) { + cio_write(str[i], 1); + } + + box.length = cio_tell() - box.init_pos; + cio_seek(box.init_pos); + cio_write(box.length, 4); /* L */ + cio_seek(box.init_pos + box.length); +} + +/* +* Read the IHDR box +* +* Image Header box +* +*/ +int jp2_read_ihdr(jp2_struct_t * jp2_struct) +{ + jp2_box_t box; + + jp2_read_boxhdr(&box); + if (JP2_IHDR != box.type) { + fprintf(stderr, "Error: Expected IHDR Marker\n"); + return 1; + } + + jp2_struct->h = cio_read(4); // HEIGHT + jp2_struct->w = cio_read(4); // WIDTH + jp2_struct->numcomps = cio_read(2); // NC + + jp2_struct->bpc = cio_read(1); // BPC + + jp2_struct->C = cio_read(1); // C + jp2_struct->UnkC = cio_read(1); // UnkC + jp2_struct->IPR = cio_read(1); // IPR + + if (cio_tell() - box.init_pos != box.length) { + fprintf(stderr, "Error with IHDR Box\n"); + return 1; + } + return 0; +} + +void jp2_write_ihdr(jp2_struct_t * jp2_struct) +{ + jp2_box_t box; + + box.init_pos = cio_tell(); + cio_skip(4); + cio_write(JP2_IHDR, 4); // IHDR + + cio_write(jp2_struct->h, 4); // HEIGHT + cio_write(jp2_struct->w, 4); // WIDTH + cio_write(jp2_struct->numcomps, 2); // NC + + cio_write(jp2_struct->bpc, 1); // BPC + + cio_write(jp2_struct->C, 1); // C : Always 7 + cio_write(jp2_struct->UnkC, 1); // UnkC, colorspace unknow + cio_write(jp2_struct->IPR, 1); // IPR, no intellectual property + + box.length = cio_tell() - box.init_pos; + cio_seek(box.init_pos); + cio_write(box.length, 4); /* L */ + cio_seek(box.init_pos + box.length); +} + + +void jp2_write_bpcc(jp2_struct_t * jp2_struct) +{ + unsigned int i; + jp2_box_t box; + + box.init_pos = cio_tell(); + cio_skip(4); + cio_write(JP2_BPCC, 4); // BPCC + + for (i = 0; i < jp2_struct->numcomps; i++) + cio_write(jp2_struct->comps[i].bpcc, 1); + + box.length = cio_tell() - box.init_pos; + cio_seek(box.init_pos); + cio_write(box.length, 4); /* L */ + cio_seek(box.init_pos + box.length); +} + + +int jp2_read_bpcc(jp2_struct_t * jp2_struct) +{ + unsigned int i; + jp2_box_t box; + + jp2_read_boxhdr(&box); + if (JP2_BPCC != box.type) { + fprintf(stderr, "Error: Expected BPCC Marker\n"); + return 1; + } + + for (i = 0; i < jp2_struct->numcomps; i++) + jp2_struct->comps[i].bpcc = cio_read(1); + + if (cio_tell() - box.init_pos != box.length) { + fprintf(stderr, "Error with BPCC Box\n"); + return 1; + } + return 0; +} + +void jp2_write_colr(jp2_struct_t * jp2_struct) +{ + jp2_box_t box; + + box.init_pos = cio_tell(); + cio_skip(4); + cio_write(JP2_COLR, 4); // COLR + + cio_write(jp2_struct->meth, 1); // METH + cio_write(jp2_struct->precedence, 1); // PRECEDENCE + cio_write(jp2_struct->approx, 1); // APPROX + + if (jp2_struct->meth == 1) + cio_write(jp2_struct->enumcs, 4); // EnumCS + else + cio_write(0, 1); // PROFILE (??) + + box.length = cio_tell() - box.init_pos; + cio_seek(box.init_pos); + cio_write(box.length, 4); /* L */ + cio_seek(box.init_pos + box.length); +} + +int jp2_read_colr(jp2_struct_t * jp2_struct) +{ + jp2_box_t box; + + jp2_read_boxhdr(&box); + if (JP2_COLR != box.type) { + fprintf(stderr, "Error: Expected COLR Marker\n"); + return 1; + } + + jp2_struct->meth = cio_read(1); // METH + jp2_struct->precedence = cio_read(1); // PRECEDENCE + jp2_struct->approx = cio_read(1); // APPROX + + if (jp2_struct->meth == 1) + jp2_struct->enumcs = cio_read(4); // EnumCS + else + cio_read(1); // PROFILE + + if (cio_tell() - box.init_pos != box.length) { + fprintf(stderr, "Error with BPCC Box\n"); + return 1; + } + return 0; +} + +/* +* Write the JP2H box +* +* JP2 Header box +* +*/ +void jp2_write_jp2h(jp2_struct_t * jp2_struct) +{ + jp2_box_t box; + + box.init_pos = cio_tell(); + cio_skip(4);; + cio_write(JP2_JP2H, 4); /* JP2H */ + + jp2_write_ihdr(jp2_struct); + + if (jp2_struct->bpc == 255) + jp2_write_bpcc(jp2_struct); + jp2_write_colr(jp2_struct); + + box.length = cio_tell() - box.init_pos; + cio_seek(box.init_pos); + cio_write(box.length, 4); /* L */ + cio_seek(box.init_pos + box.length); +} + + +/* +* Read the JP2H box +* +* JP2 Header box +* +*/ +int jp2_read_jp2h(jp2_struct_t * jp2_struct) +{ + jp2_box_t box; + + jp2_read_boxhdr(&box); + if (JP2_JP2H != box.type) { + fprintf(stderr, "Error: Expected JP2H Marker\n"); + return 1; + } + + if (jp2_read_ihdr(jp2_struct)) + return 1; + + if (jp2_struct->bpc == 255) + if (jp2_read_bpcc(jp2_struct)) + return 1; + if (jp2_read_colr(jp2_struct)) + return 1; + + if (cio_tell() - box.init_pos != box.length) { + fprintf(stderr, "Error with JP2H Box\n"); + return 1; + } + return 0; +} + +/* +* Write the FTYP box +* +* File type box +* +*/ +void jp2_write_ftyp(jp2_struct_t * jp2_struct) +{ + unsigned int i; + jp2_box_t box; + + box.init_pos = cio_tell(); + cio_skip(4); + cio_write(JP2_FTYP, 4); /* FTYP */ + + cio_write(jp2_struct->brand, 4); /* BR */ + cio_write(jp2_struct->minversion, 4); /* MinV */ + + for (i = 0; i < jp2_struct->numcl; i++) + cio_write(jp2_struct->cl[i], 4); /* CL */ + + box.length = cio_tell() - box.init_pos; + cio_seek(box.init_pos); + cio_write(box.length, 4); /* L */ + cio_seek(box.init_pos + box.length); +} + +/* +* Read the FTYP box +* +* File type box +* +*/ +int jp2_read_ftyp(jp2_struct_t * jp2_struct) +{ + int i; + jp2_box_t box; + + jp2_read_boxhdr(&box); + + if (JP2_FTYP != box.type) { + fprintf(stderr, "Error: Excpected FTYP Marker\n"); + return 1; + } + + jp2_struct->brand = cio_read(4); /* BR */ + jp2_struct->minversion = cio_read(4); /* MinV */ + jp2_struct->numcl = (box.length - 16) / 4; + jp2_struct->cl = + (unsigned int *) malloc(jp2_struct->numcl * sizeof(unsigned int)); + + for (i = jp2_struct->numcl; i > 0; i--) + jp2_struct->cl[i] = cio_read(4); /* CLi */ + + if (cio_tell() - box.init_pos != box.length) { + fprintf(stderr, "Error with FTYP Box\n"); + return 1; + } + return 0; +} + +int jp2_write_jp2c(j2k_image_t * img, j2k_cp_t * cp, char *jp2_buffer, + char *index) +{ + int len, i, set; + char *cstr, *out; + jp2_box_t box; + + box.init_pos = cio_tell(); + cio_skip(4); + cio_write(JP2_JP2C, 4); // JP2C + if (jpwl_cp.JPWL_on){ + set=cio_tell(); + cstr = (char *) malloc( cp->tdx * cp->tdy * cp->tw * cp->th * 10*sizeof(char)); /* Allocate memory for all tiles */ + cio_init(cstr, cp->tdx * cp->tdy * cp->tw * cp->th * 10); + len = j2k_encode(img, cp, cstr, cp->tdx * cp->tdy * cp->tw * cp->th * 10, index); + if (len == 0) { + fprintf(stderr, "failed to encode image\n"); + return 1; + } + out= (char *) malloc(len*6*sizeof(char)); + len=jpwl_encode(cstr,out,len); + if (len == 0) { + fprintf(stderr, "failed to encode image\n"); + return 1; + } + //ricopio la codestream, sono nel buffer out + cio_seek(0); + for(i=0;itdx * cp->tdy * cp->tw * cp->th * 10); + //aggiorno la lunghezza della codestream + len += set; + cio_seek(len); + //correggo l'index file e lo scrivo + if (info_IM.index_on){ + info_IM.Main_head_end += set; + //printf("fine_mh: %d\n",info_IM.Main_head_end); + //printf("%d\n", info_IM.tile[0].start_pos); + info_IM.tile[0].start_pos += set; + for (i=0; i < cp->th * cp->tw; i++){ + info_IM.tile[i].end_header += set; + info_IM.tile[i].end_pos += set; + if (i < cp->tw * cp->th) + info_IM.tile[i+1].start_pos += set; + pack_corr(set, i); + } + } + if (cp->index_on && use_index){ + write_index(index, len); + } + free(cstr); + free(out); + } + else{ + len = j2k_encode(img, cp, jp2_buffer, cp->tdx * cp->tdy * cp->th * cp->tw * 2, index); + } + box.length = cio_tell() - box.init_pos; + cio_seek(box.init_pos); + cio_write(box.length, 4); /* L */ + cio_seek(box.init_pos + box.length); + return box.length; +} + + +int jp2_read_jp2c(unsigned char *src, int len, jp2_struct_t * jp2_struct, + j2k_cp_t * cp) +{ + jp2_box_t box; + + jp2_read_boxhdr(&box); + if (JP2_JP2C != box.type) { + fprintf(stderr, "Error: Expected JP2C Marker\n"); + return 1; + } + + src += cio_tell(); + + if (j2k_decode(src, len, jp2_struct->image, cp) == 0) { + fprintf(stderr, "JP2F box: failed to decode J2K bitstream image!\n"); + return 1; + } + + return 0; +} + +void jp2_write_jp() +{ + jp2_box_t box; + + box.init_pos = cio_tell(); + cio_skip(4); + cio_write(JP2_JP, 4); // JP + cio_write(0x0d0a870a, 4); + + box.length = cio_tell() - box.init_pos; + cio_seek(box.init_pos); + cio_write(box.length, 4); /* L */ + cio_seek(box.init_pos + box.length); +} + +/* +* Read the JP box +* +* JPEG 2000 signature +* +* return 1 if error else 0 +*/ +int jp2_read_jp() +{ + jp2_box_t box; + + jp2_read_boxhdr(&box); + if (JP2_JP != box.type) { + fprintf(stderr, "Error: Expected JP Marker\n"); + return 1; + } + if (0x0d0a870a != cio_read(4)) { + fprintf(stderr, "Error with JP Marker\n"); + return 1; + } + if (cio_tell() - box.init_pos != box.length) { + fprintf(stderr, "Error with JP Box size\n"); + return 1; + } + return 0; + +} + +int jp2_decode(unsigned char *src, int len, jp2_struct_t * jp2_struct, + j2k_cp_t * cp) +{ + cio_init(src, len); + + if (jp2_read_jp()) + return 1; + if (jp2_read_ftyp(jp2_struct)) + return 1; + if (jp2_read_jp2h(jp2_struct)) + return 1; + if (jp2_read_jp2c(src, len, jp2_struct, cp)) + return 1; + return 0; +} + +int jp2_encode(jp2_struct_t * jp2_struct, j2k_cp_t * cp, char *output, + char *index) +{ + int len; + + jp2_write_jp(); + jp2_write_ftyp(jp2_struct); + jp2_write_jp2h(jp2_struct); + len = jp2_write_jp2c(jp2_struct->image, cp, output, index); + + return cio_tell(); +} diff --git a/jpwl/encoder/libopenjpeg/jp2.h b/jpwl/encoder/libopenjpeg/jp2.h new file mode 100644 index 00000000..21ee133d --- /dev/null +++ b/jpwl/encoder/libopenjpeg/jp2.h @@ -0,0 +1,122 @@ +/* + * 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 __JP2_H +#define __JP2_H + +#include "j2k.h" + +typedef struct { + int depth; + int sgnd; + int bpcc; +} jp2_comps_t; + +typedef struct { + unsigned int w; + unsigned int h; + unsigned int numcomps; + unsigned int bpc; + unsigned int C; + unsigned int UnkC; + unsigned int IPR; + unsigned int meth; + unsigned int approx; + unsigned int enumcs; + unsigned int precedence; + unsigned int brand; + unsigned int minversion; + unsigned int numcl; + unsigned int *cl; + jp2_comps_t *comps; + j2k_image_t *image; +} jp2_struct_t; + +typedef struct { + int length; + int type; + int init_pos; +} jp2_box_t; + +/* int jp2_init_stdjp2(jp2_struct_t * jp2_struct, j2k_image_t * img); + * + * Create a standard jp2_structure + * jp2_struct: the structure you are creating + * img: a j2k_image_t wich will help you to create the jp2_structure + */ +int jp2_init_stdjp2(jp2_struct_t * jp2_struct, j2k_image_t * img); + +/* int jp2_write_jp2c(j2k_image_t * img, j2k_cp_t * cp, char *jp2_buffer, + * char *index); + * + * Write the jp2c codestream box + * img: the j2k_image that will be compressed + * jp2_buffer: the buffer that will recieve the compressed data + * index: the name of the index file + */ +int jp2_write_jp2c(j2k_image_t * img, j2k_cp_t * cp, char *jp2_buffer, + char *index); + + +/* int jp2_write_jp2h(jp2_struct_t * jp2_struct); + * + * Write the jp2h header box + * jp2_struct: the jp2 structure you are working with + */ +void jp2_write_jp2h(jp2_struct_t * jp2_struct); + +/* int jp2_read_jp2h(jp2_struct_t * jp2_struct); + * + * Read the jp2h header box + * jp2_struct: the jp2 structure you are working with + */ +int jp2_read_jp2h(jp2_struct_t * jp2_struct); + +/* int jp2_encode(jp2_struct_t * jp2_struct, j2k_cp_t * cp, char *output, + * char *index); + * + * Encode a JP2 file + * jp2_buffer: the buffer containing the pointer to the image to encode + * cp: coding parameters of the image + * outbuf: pointer to memory where compressed data will be written + * index: the name of the index file + */ +int jp2_encode(jp2_struct_t * jp2_struct, j2k_cp_t * cp, char *output, + char *index); + +/* int jp2_decode(unsigned char *src, int len, jp2_struct_t * jp2_struct, + * j2k_cp_t * cp); + * + * Decode a JP2 file + * src: pointer to memory where compressed data is stored + * len: length of src buffer + * jp2_struct: the jp2 structure that will be created + * cp: coding parameters of the image + */ +int jp2_decode(unsigned char *src, int len, jp2_struct_t * jp2_struct, + j2k_cp_t * cp); + +#endif diff --git a/jpwl/encoder/libopenjpeg/jpt.c b/jpwl/encoder/libopenjpeg/jpt.c new file mode 100644 index 00000000..de0c8746 --- /dev/null +++ b/jpwl/encoder/libopenjpeg/jpt.c @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2004, Yannick Verschueren + * Copyright (c) 2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#include "jpt.h" +#include "j2k.h" +#include "cio.h" + + +/* + * Read the information contains in VBAS [JPP/JPT stream message header] + * Store information (7 bits) in value + * + */ +unsigned int jpt_read_VBAS_info(unsigned int value) +{ + unsigned char elmt; + + elmt = cio_read(1); + while ((elmt >> 7) == 1) { + value = (value << 7); + value |= (elmt & 0x7f); + elmt = cio_read(1); + } + value = (value << 7); + value |= (elmt & 0x7f); + + return value; +} + +/* + * Initialize the value of the message header structure + * + */ +void jpt_init_Msg_Header(jpt_msg_header_struct_t * header) +{ + header->Id = 0; /* In-class Identifier */ + header->last_byte = 0; /* Last byte information */ + header->Class_Id = 0; /* Class Identifier */ + header->CSn_Id = 0; /* CSn : index identifier */ + header->Msg_offset = 0; /* Message offset */ + header->Msg_length = 0; /* Message length */ + header->Layer_nb = 0; /* Auxiliary for JPP case */ +} + +/* + * Re-initialize the value of the message header structure + * + * Only parameters always present in message header + * + */ +void jpt_reinit_Msg_Header(jpt_msg_header_struct_t * header) +{ + header->Id = 0; /* In-class Identifier */ + header->last_byte = 0; /* Last byte information */ + header->Msg_offset = 0; /* Message offset */ + header->Msg_length = 0; /* Message length */ +} + +/* + * Read the message header for a JPP/JPT - stream + * + */ +void jpt_read_Msg_Header(jpt_msg_header_struct_t * header) +{ + unsigned char elmt, Class = 0, CSn = 0; + jpt_reinit_Msg_Header(header); + + /* ------------- */ + /* VBAS : Bin-ID */ + /* ------------- */ + elmt = cio_read(1); + + /* See for Class and CSn */ + switch ((elmt >> 5) & 0x03) { + case 0: + fprintf(stderr, "Forbidden value encounter in message header !!\n"); + break; + case 1: + Class = 0; + CSn = 0; + break; + case 2: + Class = 1; + CSn = 0; + break; + case 3: + Class = 1; + CSn = 1; + break; + default: + break; + } + + /* see information on bits 'c' [p 10 : A.2.1 general, ISO/IEC FCD 15444-9] */ + if (((elmt >> 3) & 0x01) == 1) + header->last_byte = 1; + + /* In-class identifier */ + header->Id |= (elmt & 0x0f); + if ((elmt >> 7) == 1) + header->Id = jpt_read_VBAS_info(header->Id); + + /* ------------ */ + /* VBAS : Class */ + /* ------------ */ + if (Class == 1) { + header->Class_Id = 0; + header->Class_Id = jpt_read_VBAS_info(header->Class_Id); + } + + /* ---------- */ + /* VBAS : CSn */ + /* ---------- */ + if (CSn == 1) { + header->CSn_Id = 0; + header->CSn_Id = jpt_read_VBAS_info(header->CSn_Id); + } + + /* ----------------- */ + /* VBAS : Msg_offset */ + /* ----------------- */ + header->Msg_offset = jpt_read_VBAS_info(header->Msg_offset); + + /* ----------------- */ + /* VBAS : Msg_length */ + /* ----------------- */ + header->Msg_length = jpt_read_VBAS_info(header->Msg_length); + + /* ---------- */ + /* VBAS : Aux */ + /* ---------- */ + if (header->CSn_Id == 1) { + header->Layer_nb = 0; + header->Layer_nb = jpt_read_VBAS_info(header->Layer_nb); + } +} diff --git a/jpwl/encoder/libopenjpeg/jpt.h b/jpwl/encoder/libopenjpeg/jpt.h new file mode 100644 index 00000000..ea784e0e --- /dev/null +++ b/jpwl/encoder/libopenjpeg/jpt.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2004, Yannick Verschueren + * Copyright (c) 2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Message Header JPT_stream Structure + * + */ +typedef struct { + unsigned int Id; /* In-class Identifier */ + unsigned int last_byte; /* Last byte information */ + unsigned int Class_Id; /* Class Identifier */ + unsigned int CSn_Id; /* CSn : index identifier */ + unsigned int Msg_offset; /* Message offset */ + unsigned int Msg_length; /* Message length */ + unsigned int Layer_nb; /* Auxiliary for JPP case */ +} jpt_msg_header_struct_t; + +/* + * Initialize the value of the message header structure + * + * header : Message header structure + * + */ +void jpt_init_Msg_Header(jpt_msg_header_struct_t * header); + +/* + * Read the message header for a JPP/JPT - stream + * + * header : Message header structure + * + */ +void jpt_read_Msg_Header(jpt_msg_header_struct_t * header); diff --git a/jpwl/encoder/libopenjpeg/jpw.c b/jpwl/encoder/libopenjpeg/jpw.c new file mode 100644 index 00000000..6ef0254b --- /dev/null +++ b/jpwl/encoder/libopenjpeg/jpw.c @@ -0,0 +1,2084 @@ +/* + * Copyright 2004-2005 Andrea Betti and Michele Massarelli + * Copyright 2004-2005 DIEI, University of Perugia + * + * + * 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. + */ + + +/* questa è un' estensione della libreria dell'openjpeg in grado di implementare + * la parte 11 dello standard JPEG2000 ossia il JPWL + */ + +#include +#include +#include +#include +#include +#include +#include "j2k.h" +#include "cio.h" +#include "jpw.h" +#include "rs.h" + +// JPWL MARKERS +#define JPWL_MS_EPC 0xff68 +#define JPWL_MS_EPB 0xff66 +#define JPWL_MS_ESD 0xff67 +#define JPWL_MS_RED 0xff69 + + +//stati del codec +#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 +#define J2K_STATE_MHEPB 0x0080 +#define J2K_STATE_TPHEPB 0x0100 + +//carica la struttura relativa ai parametri JPWL +extern JPWL_cp_t jpwl_cp; +extern int j2k_state; +extern j2k_cp_t *j2k_cp; +extern info_image info_IM; + +static long crcSum; +static long pepbs[1000]; +static int cont_epb=0; +static int scavalcato=0; + +static int CrcT16[256] = +{0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, +0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, +0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, +0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, +0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, +0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, +0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, +0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, +0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, +0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, +0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, +0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, +0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, +0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, +0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, +0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, +0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, +0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, +0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, +0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, +0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, +0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, +0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, +0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, +0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, +0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, +0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, +0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, +0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, +0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, +0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, +0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0}; + +static long CrcT32[256] = {0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, +0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, +0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, +0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, +0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, +0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, +0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, +0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd, +0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, +0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, +0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, +0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, +0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, +0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, +0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, +0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, +0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, +0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, +0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, +0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, +0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, +0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, +0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, +0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, +0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, +0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692, +0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, +0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, +0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, +0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, +0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, +0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a, +0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, +0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, +0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, +0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, +0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, +0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b, +0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, +0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, +0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, +0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, +0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, +0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, +0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, +0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, +0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, +0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, +0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, +0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, +0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, +0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, +0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, +0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, +0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, +0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, +0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, +0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, +0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, +0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, +0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, +0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c, +0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, +0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4}; + + +/* inizializza i parametri relativi al JPWL * + * disabilitando le funzionalità */ + +void jpwl_cp_init(JPWL_cp_t *jpwl_cp){ + jpwl_cp->JPWL_on = 0; + jpwl_cp->EPB_on = 0; + jpwl_cp->ESD_on = 0; + jpwl_cp->RED_on = 0; + jpwl_cp->info_tech_on = 0; +} + +/**************************************************************************************** + * * + * Marker JPWL * + * * + ****************************************************************************************/ + +/* Scrive il marker segment EPC + version 0.1: in questa prima fase questo andrà subito dopo il SIZ */ + +void jpwl_write_EPC(){ + int lenp, len, i; + char c, P_EPC = 0; + cio_write(JPWL_MS_EPC, 2); + lenp = cio_tell(); + cio_skip(2); + // calcola il crc + cio_skip(2); + // per adesso lascio uno spazio vuoto (16 bit) + // CL settore di 32bit che indica la lungheza della codestream: + // per ora metto tutto uguale a zero (info non disponibile) + cio_write(0, 4); + // P_EPC indica se nella codestream saranno usati gli altri + // marker segment oppure tecniche informative aggiuntive + if (jpwl_cp.ESD_on) + P_EPC += 0x10; + if (jpwl_cp.RED_on) + P_EPC += 0x20; + if (jpwl_cp.EPB_on) + P_EPC += 0x40; + if (jpwl_cp.info_tech_on) + P_EPC += 0x80; + cio_write(P_EPC, 1); + //scrivo i Pepb + + if(jpwl_cp.EPB_on) + JPWL_write_Pepbs(NULL,0); + + + + + /* Al momento non esistono tecniche informative aggiuntive per richiamarle + * opereremo in questo modo: + * 0) dovrò inserire nella struttura jpwl_cp_t un campo contenente un puntatore + * ad un array che conterrà gli ID delle tecniche informative da usare; + * 1) conrollo il campo info_tech_on; + * 2) eseguo delle funzioni da inserire nel file jpw.c e jpw.h relative alle + * tecniche informative desiderate; tali funzioni dovranno preoccuparsi di + * creare i campi corretti nel marker segment. + * if( jpwl_cp->info_tech_on){ + * qui inserirò i comandi desiderati + * } + */ + len = cio_tell() - lenp; + cio_seek(lenp); + cio_write(len, 2); + // calcola il crc + cio_skip(-4); + ResetCRC(); + for (i=0; i<4; i++){ + c = cio_read(1); + UpdateCRC16(c); + } + cio_skip(2); + for (i=6; i<(len + 2); i++){ + c = cio_read(1); + UpdateCRC16(c); + } + cio_seek(lenp + 2); + cio_write(crcSum, 2); + cio_seek(lenp + len); + +} + + +void jpwl_write_EPC_fin(unsigned long CL, long *pepbs, int num_epb){ + int lenp, len, i; + unsigned long len_codestr; + char c, P_EPC = 0; + cio_write(JPWL_MS_EPC, 2); + lenp = cio_tell(); + cio_skip(2); + // calcola il crc + cio_skip(2); + // per adesso lascio uno spazio vuoto (16 bit) + // CL settore di 32bit che indica la lungheza della codestream: + // per ora metto tutto uguale a zero (info non disponibile) + cio_write(0, 4); + // P_EPC indica se nella codestream saranno usati gli altri + // marker segment oppure tecniche informative aggiuntive + if (jpwl_cp.ESD_on) + P_EPC += 0x10; + if (jpwl_cp.RED_on) + P_EPC += 0x20; + if (jpwl_cp.EPB_on) + P_EPC += 0x40; + if (jpwl_cp.info_tech_on) + P_EPC += 0x80; + cio_write(P_EPC, 1); + //scrivo i Pepb + + if(jpwl_cp.EPB_on) + JPWL_write_Pepbs(pepbs, num_epb); + + + + + /* Al momento non esistono tecniche informative aggiuntive per richiamarle + * opereremo in questo modo: + * 0) dovrò inserire nella struttura jpwl_cp_t un campo contenente un puntatore + * ad un array che conterrà gli ID delle tecniche informative da usare; + * 1) conrollo il campo info_tech_on; + * 2) eseguo delle funzioni da inserire nel file jpw.c e jpw.h relative alle + * tecniche informative desiderate; tali funzioni dovranno preoccuparsi di + * creare i campi corretti nel marker segment. + * if( jpwl_cp->info_tech_on){ + * qui inserirò i comandi desiderati + * } + */ + len = cio_tell() - lenp; + cio_seek(lenp); + cio_write(len, 2); + //scrivo la lunghezza della codestream + cio_skip(2); + len_codestr = CL + len + 2; + cio_write(len_codestr, 4); + // calcola il crc + cio_skip(-10); + ResetCRC(); + for (i=0; i<4; i++){ + c = cio_read(1); + UpdateCRC16(c); + } + cio_skip(2); + for (i=6; i<(len + 2); i++){ + c = cio_read(1); + UpdateCRC16(c); + } + cio_seek(lenp + 2); + cio_write(crcSum, 2); + cio_seek(lenp + len); + +} + + + +void JPWL_write_EPB(char *buf, unsigned long LDPepb, unsigned long Pepb, unsigned char Depb){ + int *alpha_to, *index_of, *gg, *data_, *bb; + unsigned long i=0; + unsigned int len = 11, lenp, scrivi_pb, cont, leggi, tenta=0; + char pos_epb; + unsigned data_unprot = 0, RS = 0; + int n1, n2, k1, k2, j, n=255, k, CRC = 0, go_back; // 0 = disabilitato, 1 = CRC CCITT 16 bit, 2 = Ethernet CRC 32 bit + //prova + /*FILE *f; + FILE *fp;*/ + + + cio_write(JPWL_MS_EPB, 2); + lenp = cio_tell(); + /* determino len_epb e i parametri di codifica*/ + pos_epb= Depb & 0x3F; + if ((j2k_state == J2K_STATE_MH) && !(pos_epb)){ // sto scrivendo il primo epb del mh + + n1=160; + k1=64; + go_back =lenp + 11; + len += (n1 - k1)*(unsigned int)ceil((double)go_back/k1); + } else {if ((j2k_state == J2K_STATE_TPH) && !(pos_epb)&& !(scavalcato)){ // primo epb di un tph + n1=80; + k1=go_back=25; + len += 55; + + } else { // altro epb + n1=40; + k1=go_back=13; + len += 27; + //tenta=1; + } + } + if (!Pepb) { // per codificare i dati seguenti uso lo stesso codice di prima + RS = 1; + n2 = n1; + k2 = k1; + len +=(unsigned int) ceil((double)LDPepb/k2)*(n2 - k2); + + } else{ + if (Pepb == 0xffffffff) + data_unprot=1; + else {if ((Pepb >> 28)== 1){ + if ((Pepb & 0x00000001)){ + CRC = 2; + len += 4; + } else { + CRC = 1; + len +=2; + } + } else {if ((Pepb >> 28)== 2){ + n2 = ((Pepb & 0x0000ff00)>> 8); + k2 = (Pepb & 0x000000ff); + RS = 1; + len +=(unsigned int) ceil((double)LDPepb/k2)*(n2 - k2); + } + } + } + } + cio_write(len, 2); // Lepb + cio_write(Depb, 1); //Depb + cio_write((LDPepb & 0xffff0000) >> 16, 2); //LDPepb + cio_write((LDPepb & 0x0000ffff), 2); + cio_write((Pepb & 0xffff0000) >> 16, 2); //Pepb + cio_write((Pepb & 0x0000ffff), 2); + //printf("start\n"); + + // devi implementare il codice rs per la protezione dell'epb + // cio_write(0, (int) ceil((lenp+11)*(n1 - k1)/k1)); + if(!(alpha_to=(int *) calloc(256,sizeof(int)))) + printf("Non può essere allocata memoria per eseguire il programma1\n "); + + if(!(index_of=(int *) calloc(256,sizeof(int)))) + printf("Non può essere allocata memoria per eseguire il programma2\n "); + + if(!(gg=(int *) calloc((n1 - k1 +1),sizeof(int)))) + printf("Non può essere allocata memoria per eseguire il programma3\n "); + + k = 255-(n1-k1); + + if(!(data_=(int *) calloc(k, sizeof(int)))) + printf("Non può essere allocata memoria per eseguire il programma4\n "); + + if(!(bb=(int *) calloc((n1 - k1),sizeof(int)))) + printf("Non può essere allocata memoria per eseguire il programma5\n "); + + generate_gf(alpha_to, index_of); + + gen_poly(k, alpha_to, index_of, gg); + + scrivi_pb = cio_tell(); + + //prova + + + cio_skip(-go_back); + for (cont = 0; cont < (unsigned int) ceil((double)go_back/k1); cont++) { + for (j=0; j> 16, 2); + cio_write((crcSum & 0x0000ffff), 2); + } + if (RS) { + //printf("n2, k2: %d %d\n", n2, k2); + k = 255-(n2-k2); + + if(!(alpha_to=(int *) malloc(256*sizeof(int)))) + printf("Non può essere allocata memoria per eseguire il programma1\n "); + + if(!(index_of=(int *) malloc(256*sizeof(int)))) + printf("Non può essere allocata memoria per eseguire il programma2\n "); + + if(!(gg=(int *) malloc((n2 - k2 +1)*sizeof(int)))) + printf("Non può essere allocata memoria per eseguire il programma3\n "); + + if(!(data_=(int *) malloc(k*sizeof(int)))) + printf("Non può essere allocata memoria per eseguire il programma4\n "); + + if(!(bb=(int *) malloc((n2 - k2)*sizeof(int)))) + printf("Non può essere allocata memoria per eseguire il programma5\n "); + + generate_gf(alpha_to, index_of); + + gen_poly(k, alpha_to, index_of, gg); + //printf("num blocchi: %f\n", ceil((double)LDPepb/k2)); + //printf("resto: %d\n", LDPepb%k2); + + for (cont = 0; cont < (unsigned int)ceil((double)LDPepb/k2); cont++) { + + for (j=0; j>1)==0) ? 2 : 4; + nb_sv = (((Pesd & 0x04)>>2)==0) ? 1 : 2; + metric = ((Pesd & 0x38)>>3); + mode = ((Pesd & 0xC0)>>6); + M = 65025; + // creo le matrici che conterranno i valori di deltaMSE e deltaPSNR + // in realtà spreco un po' di memoria nel caso in cui la scrivo nei tile... + dMSE = (double **) malloc(j2k_cp->th * j2k_cp->tw * sizeof(double)); + for (i=0; ith * j2k_cp->tw; i++) + dMSE[i]=(double*) malloc(info_IM.num *sizeof(double)); + dPSNR = (double **) malloc(j2k_cp->th * j2k_cp->tw * sizeof(double)); + for (i=0; ith * j2k_cp->tw; i++) + dPSNR[i]=(double*) malloc(info_IM.num *sizeof(double)); + PSNR = (double **) malloc(j2k_cp->th * j2k_cp->tw * sizeof(double)); + for (i=0; ith * j2k_cp->tw; i++) + PSNR[i]=(double*) malloc(info_IM.num * sizeof(double)); + + // a questo punto se notil=0 vuol dire che scrivo l'esd nel main header + // altrimenti notil indica il tile a cui mi riferisco + ult = (notil == 0) ? j2k_cp->th * j2k_cp->tw : notil; + if (notil != 0) notil--; + + // calcolo di dPSNR, dMSE e PSNR + // nuova routine più snella!! + for (i = notil; i < ult; i++){ + val = 0; + npix = info_IM.tile[i].nbpix; + maxMSE = info_IM.tile[i].distotile / npix; + for(npack=0; npack < (info_IM.num); npack++){ + dMSE[i][npack] = info_IM.tile[i].packet[npack].disto / npix; + if (dMSE[i][npack]!=0){ + val += dMSE[i][npack]; + PSNR[i][npack] = (10 * log10(M/(maxMSE - val))); + x = (npack==0) ? 0 : PSNR[i][npack-1]; + dPSNR[i][npack] = PSNR[i][npack] - x; + } + else { + dPSNR[i][npack] = 0; + PSNR[i][npack] = PSNR[i][npack-1]; + } + } + } + + //ora scrivo i valori di sensibilità in base alla metrica scelta + switch (metric){ + case 0: + //relative error sensitivity: i lvelli di sensibilità coincidono con i layer (livello 0 = header) + //uso sette livelli di sensibilità relativa + switch (mode){ + case 0: + //packet mode + + for (i = notil; i < ult; i++){ + for (npack=0; npack < (info_IM.num); npack++){ + if (dPSNR[i][npack]>10) + cio_write(1, 1); + else if ((dPSNR[i][npack]<=10)&&(dPSNR[i][npack]>8)) + cio_write(2,1); + else if ((dPSNR[i][npack]<=8)&&(dPSNR[i][npack]>6)) + cio_write(3,1); + else if ((dPSNR[i][npack]<=6)&&(dPSNR[i][npack]> 4.5)) + cio_write(4,1); + else if ((dPSNR[i][npack]<=4.5)&&(dPSNR[i][npack]>3)) + cio_write(5,1); + else if ((dPSNR[i][npack]<=3)&&(dPSNR[i][npack]>1.7)) + cio_write(6,1); + else + //(dPSNR[i][npack]<=1.7) + cio_write(7,1); + } + } + + break; + + case 1: + //byte range mode + for (i = notil; i < ult; i++){ + //inizializzazioni + lev = 0; + start = 0; + end = 1; + for (npack=0; npack < (info_IM.num); npack++){ + temp=lev; + //determinazione dei livelli + if (dPSNR[i][npack]>10) + lev = 1; + else if ((dPSNR[i][npack]<=10)&&(dPSNR[i][npack]>8)) + lev = 2; + else if ((dPSNR[i][npack]<=8)&&(dPSNR[i][npack]>6)) + lev = 3; + else if ((dPSNR[i][npack]<=6)&&(dPSNR[i][npack]> 4.5)) + lev = 4; + else if ((dPSNR[i][npack]<=4.5)&&(dPSNR[i][npack]>3)) + lev = 5; + else if ((dPSNR[i][npack]<=3)&&(dPSNR[i][npack]>1.7)) + lev = 6; + else + //(dPSNR[i][npack]<=1.7) + lev = 7; + if (lev == temp){ + end++; + continue; + } else { + cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos); + cio_write(info_IM.tile[i].packet[end-1].end_pos, nb_pos); + cio_write(lev, nb_sv); + start = end; + end++; + } + } + cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos); + cio_write(info_IM.tile[i].packet[end-1].end_pos, nb_pos); + cio_write(lev, nb_sv); + } + break; + + case 2: + //packet range mode + for (i = notil; i < ult; i++){ + //inizializzazioni + lev = 0; + start = 0; + end = 1; + for (npack=0; npack < (info_IM.num); npack++){ + temp=lev; + //determinazione dei livelli (catena di if-else-if) + if (dPSNR[i][npack]>10) + lev = 1; + else if ((dPSNR[i][npack]<=10)&&(dPSNR[i][npack]>8)) + lev = 2; + else if ((dPSNR[i][npack]<=8)&&(dPSNR[i][npack]>6)) + lev = 3; + else if ((dPSNR[i][npack]<=6)&&(dPSNR[i][npack]> 4.5)) + lev = 4; + else if ((dPSNR[i][npack]<=4.5)&&(dPSNR[i][npack]>3)) + lev = 5; + else if ((dPSNR[i][npack]<=3)&&(dPSNR[i][npack]>1.7)) + lev = 6; + else + //(dPSNR[i][npack]<=1.7) + lev = 7; + if (lev == temp){ + end++; + continue; + } else { + cio_write(start, nb_pos); + cio_write(end-1, nb_pos); + cio_write(lev, nb_sv); + start = end; + end++; + } + } + cio_write(start, nb_pos); + cio_write(end - 1, nb_pos); + cio_write(lev, nb_sv); + } + + break; + default: + printf("errore\n"); + } + break; + case 1: + // MSE + switch (mode){ + case 0: + //packet mode + for (i = notil; i < ult; i++){ + npix = info_IM.tile[i].nbpix; + val = info_IM.tile[i].distotile / npix; + cio_write(d2pfp(val), nb_sv); + for (npack=0; npack < (info_IM.num); npack++){ + val -= dMSE[i][npack]; + cio_write(d2pfp(val), nb_sv); + } + } + break; + case 1: + //byte range mode + //divido in blocchi da 10 pacchetti (l'ultimo blocco dipende da quanti pacchetti restano + for (i = notil; i < ult; i++){ + npix = info_IM.tile[i].nbpix; + val = info_IM.tile[i].distotile / npix; + start = 0; + end = 0; + for (npack=0; npack < (info_IM.num); npack++){ + val -= dMSE[i][npack]; + if (((npack+1) % 10)==0){ + cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos); + cio_write(info_IM.tile[i].packet[end].end_pos, nb_pos); + cio_write(d2pfp(val), nb_sv); + start = end+1; + } + end++; + } + if (start != end){ + cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos); + cio_write(info_IM.tile[i].packet[end-1].end_pos, nb_pos); + cio_write(d2pfp(val), nb_sv); + } + } + + break; + case 2: + //packet range mode + //divido in blocchi da 10 pacchetti (l'ultimo blocco dipende da quanti pacchetti restano + for (i = notil; i < ult; i++){ + npix = info_IM.tile[i].nbpix; + val = info_IM.tile[i].distotile / npix; + start = 0; + end = 0; + for (npack=0; npack < (info_IM.num); npack++){ + val -= dMSE[i][npack]; + if (((npack+1) % 10)==0){ + cio_write(start, nb_pos); + cio_write(end, nb_pos); + cio_write(d2pfp(val), nb_sv); + start = end+1; + } + end++; + } + if (start != end){ + cio_write(start, nb_pos); + cio_write(end-1, nb_pos); + cio_write(d2pfp(val), nb_sv); + } + } + break; + default: + printf("errore\n"); + } + + break; + case 2: + // MSE reduction + switch (mode){ + case 0: + //packet mode + for (i = notil; i < ult; i++) + for (npack=0; npack < (info_IM.num); npack++) + cio_write(d2pfp(dMSE[i][npack]), nb_sv); + + break; + case 1: + //byte range mode + //scrivo la mse reduction media relativa ad un blocco di dieci pacchetti + for (i = notil; i < ult; i++){ + val = 0; + start = 0; + end = 0; + for (npack=0; npack < (info_IM.num); npack++){ + val += dMSE[i][npack]; + if (((npack+1) % 10)==0){ + val /= 10; + cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos); + cio_write(info_IM.tile[i].packet[end].end_pos, nb_pos); + cio_write(d2pfp(val), nb_sv); + start = end+1; + val = 0; + } + end++; + } + if (start != end){ + val /= npack%10; + cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos); + cio_write(info_IM.tile[i].packet[end-1].end_pos, nb_pos); + cio_write(d2pfp(val), nb_sv); + } + } + break; + case 2: + //packet range mode + //scrivo la mse reduction media relativa ad un blocco di dieci pacchetti + for (i = notil; i < ult; i++){ + val = 0; + start = 0; + end = 0; + for (npack=0; npack < (info_IM.num); npack++){ + val += dMSE[i][npack]; + if (((npack+1) % 10)==0){ + val /= 10; + cio_write(start, nb_pos); + cio_write(end, nb_pos); + cio_write(d2pfp(val), nb_sv); + start = end+1; + val = 0; + } + end++; + } + if (start != end){ + val /= npack%10; + cio_write(start, nb_pos); + cio_write(end-1, nb_pos); + cio_write(d2pfp(val), nb_sv); + } + } + break; + default: + printf("errore\n"); + } + + break; + case 3: + //PSNR + + switch (mode){ + case 0: + //packet mode + for (i = notil; i < ult; i++) + for (npack=0; npack < (info_IM.num); npack++) + cio_write(d2pfp(PSNR[i][npack]),nb_sv); + break; + case 1: + //byte range mode + //divido in blocchi da 10 pacchetti (l'ultimo blocco dipende da quanti pacchetti restano + for (i = notil; i < ult; i++){ + start = 0; + end = 0; + for (npack=0; npack < (info_IM.num); npack++){ + if (((npack+1) % 10)==0){ + cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos); + //printf("start: %d\n",info_IM.tile[i].packet[start].start_pos); + cio_write(info_IM.tile[i].packet[end].end_pos, nb_pos); + //printf("end: %d\n", info_IM.tile[i].packet[end].end_pos); + cio_write(d2pfp(PSNR[i][npack]), nb_sv); + start = end+1; + } + end++; + } + if (start != end){ + cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos); + //printf("start: %d\n",info_IM.tile[i].packet[start].start_pos); + cio_write(info_IM.tile[i].packet[end-1].end_pos, nb_pos); + //printf("end: %d\n", info_IM.tile[i].packet[end-1].end_pos); + cio_write(d2pfp(PSNR[i][end-1]), nb_sv); + } + } + break; + case 2: + //packet range mode + //divido in blocchi da 10 pacchetti (l'ultimo blocco dipende da quanti pacchetti restano + for (i = notil; i < ult; i++){ + start = 0; + end = 0; + for (npack=0; npack < (info_IM.num); npack++){ + if (((npack+1) % 10)==0){ + cio_write(start, nb_pos); + cio_write(end, nb_pos); + cio_write(d2pfp(PSNR[i][npack]), nb_sv); + start = end+1; + } + end++; + } + if (start != end){ + cio_write(start, nb_pos); + cio_write(end-1, nb_pos); + cio_write(d2pfp(PSNR[i][end-1]), nb_sv); + } + } + + break; + default: + printf("errore\n"); + } + + break; + case 4: + //PSNR increases + + switch (mode){ + case 0: + //packet mode + for (i = notil; i < ult; i++) + for (npack=0; npack < (info_IM.num); npack++) + cio_write(d2pfp(dPSNR[i][npack]), nb_sv); + break; + case 1: + //byte range mode + //scrivo il psnr increase medio relativo ad un blocco di dieci pacchetti + for (i = notil; i < ult; i++){ + val = 0; + start = 0; + end = 0; + for (npack=0; npack < (info_IM.num); npack++){ + val += dPSNR[i][npack]; + if (((npack+1) % 10)==0){ + val /= 10; + cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos); + cio_write(info_IM.tile[i].packet[end].end_pos, nb_pos); + cio_write(d2pfp(val), nb_sv); + start = end+1; + val = 0; + } + end++; + } + if (start != end){ + val /= npack%10; + cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos); + cio_write(info_IM.tile[i].packet[end-1].end_pos, nb_pos); + cio_write(d2pfp(val), nb_sv); + } + } + break; + case 2: + //packet range mode + //scrivo il psnr increase medio relativo ad un blocco di dieci pacchetti + for (i = notil; i < ult; i++){ + val = 0; + start = 0; + end = 0; + for (npack=0; npack < (info_IM.num); npack++){ + val += dPSNR[i][npack]; + if (((npack+1) % 10)==0){ + val /= 10; + cio_write(start, nb_pos); + cio_write(end, nb_pos); + cio_write(d2pfp(val), nb_sv); + start = end+1; + val = 0; + } + end++; + } + if (start != end){ + val /= npack%10; + cio_write(start, nb_pos); + cio_write(end-1, nb_pos); + cio_write(d2pfp(val), nb_sv); + } + } + break; + default: + printf("errore\n"); + } + + break; + case 5: + //MAXERR + printf("Opzione MAXERR non supportata\n"); + break; + default: + printf("opzione riservata per uso futuro\n"); + } + for (i=0; ith * j2k_cp->tw; i++) + free(PSNR[i]); + free(PSNR); + for (i=0; ith * j2k_cp->tw; i++) + free(dPSNR[i]); + free(dPSNR); + for (i=0; ith * j2k_cp->tw; i++) + free(dMSE[i]); + free(dMSE); + + len = cio_tell() - set; + cio_seek(set); + cio_write(len, 2); + cio_skip(len - 2); +} + + +int JPWL_len_EPB(unsigned int LDPepb, unsigned int Pepb, unsigned char Depb){ + unsigned int len = 11, n1, n2, k1, k2, lenp; + char pos_epb; + + + lenp = cio_tell(); + /* determino len_epb e i parametri di codifica*/ + pos_epb= Depb & 0x3F; + if ((j2k_state == J2K_STATE_MH) && !(pos_epb)){ // sto scrivendo il primo epb del mh + n1=160; + k1=64; + len += (n1 - k1)*(unsigned int)ceil((double)(lenp + 11)/k1); + } else {if ((j2k_state == J2K_STATE_TPH) && !(pos_epb)){ // primo epb di un tph + n1=80; + k1=25; + len += 55; + } else { // altro epb + n1=40; + k1=13; + len += 27; + } + } + if (!Pepb) { // per codificare i dati seguenti uso lo stesso codice di prima + n2 = n1; + k2 = k1; + len +=(unsigned int) ceil((double)LDPepb/k2)*(n2 - k2); + + } else{ + if (Pepb == 0xffffffff) + 1; + + else {if ((Pepb >> 28)== 1){ + if ((Pepb & 0x00000001)){ + len += 4; + } else { + len +=2; + } + } else {if ((Pepb >> 28)== 2){ + n2 = ((Pepb & 0x0000ff00)>> 8); + k2 = (Pepb & 0x000000ff); + len +=(unsigned int) ceil((double)LDPepb/k2)*(n2 - k2); + } + } + } + } + + + return len; + +} + +void jpwl_write_RED(){ + //questa funzione scrive un marker RED di test vuoto + cio_write(JPWL_MS_RED,2); + //già scrivo la len(non metto informazioni nel marker, poichè la codestream sarà corretta) + cio_write(3,2); + cio_write(jpwl_cp.pred,1); +} + + + + + +void JPWL_write_Pepbs(long *pepbs, int num_epb){ + int i, lenp, pos; + + cio_write(0,2); // id relativo all'uso degli epb + cio_skip(2); + lenp=cio_tell(); + /* + Qui in base a come deciderò di far operare l'encoder dovrò trovare il modo di inserire + i Pepb relativi alla struttura; In questo caso uso una struttura fissa che prevede un + solo epb nel main header che usa lo stesso codice relativo al primo epb e più epb per + ogni tile part header, il primo che protegge tutto il tph con lo stesso codice relativo + al primo epb del tile part, gli altri a protezione dei dati con un codice rs specificato + */ + for (i=0; i>1)==0) ? 2 : 4; + nb_sv = (((Pesd & 0x04)>>2)==0) ? 1 : 2; + //printf("offset: %x\n",offset); + //printf("len_esd: %d\n", len_esd); + //procedo alla correzione + while ((cio_tell()-p)> 28)== 2){ + n2 = ((Pepb & 0x0000ff00)>> 8); + k2 = (Pepb & 0x000000ff); + len_max = 0xFF80 * k2 / (n2 - k2); + *num_epb = (int) ceil((double) LDPepb / len_max); + } else if (!Pepb){ + n2 = 40; + k2 = 13; + len_max = 0xFF80 * k2 / (n2 - k2); + *num_epb = (int) ceil((double) LDPepb / len_max); + } else { + *num_epb = 1; + len_max = LDPepb+2; + } + return len_max; +} + + + +int uep(int notil, char *bs, char *header, int len_header){ + //questa funzione ritorna il valore di psot_corr + double maxMSE, val, dMSE, M; + int depb, mask, corr=0, len_til, npix, lung=0, i, h=0, k, l=0, npack, start[6], end[6], fa=0, pkt=0, Psot_cor=0, lmax[6], no_epb[6], len[6], set, cont, tot_epb=0; + char *data; + double *PSNR; + + PSNR = (double *) malloc(info_IM.num*sizeof(double)); + //printf("uep\n"); + + //mi piazzo alla fine di SOT + set=cio_tell(); + + //determino il psnr che si raggiunge con ogni pacchetto + M = 65025; + //printf("M: %f\n",M); + val = 0; + npix = info_IM.tile[notil-1].nbpix; + maxMSE = info_IM.tile[notil-1].distotile / npix; + //printf("max mse:%f\n", maxMSE); + for(npack=0; npack < (info_IM.num); npack++){ + dMSE = info_IM.tile[notil-1].packet[npack].disto / npix; + //printf("dmse: %f\n", dMSE); + if (dMSE!=0){ + val += dMSE; + PSNR[npack] = (10 * log10(M/(maxMSE - val))); + } + else { + PSNR[npack] = PSNR[npack-1]; + } + printf("psnr %d: %f\n ", npack, PSNR[npack] ); + } + + //a questo punto determino le fasce + npack=0; + + //inizializzo le posizioni + for (i=0;i<6;i++){ + start[i]=-1; + end[i]=-1; + } + start[0]=0; + while (npack=20)&&(PSNR[npack]<23)){ + if (fa!=1){ + fa=1; + end[0]=npack++; + start[1]=npack; + } + else + npack++; + + } + else if ((PSNR[npack]>=23)&&(PSNR[npack]<26)){ + if (fa!=2){ + end[fa]=npack++; + start[2]=npack; + fa=2; + } + else + npack++; + + } + else if ((PSNR[npack]>=26)&&(PSNR[npack]<35)){ + if (fa!=3){ + end[fa]=npack++; + start[3]=npack; + fa=3; + } + else + npack++; + + } + else if ((PSNR[npack]>=35)&&(PSNR[npack]<37)){ + if (fa!=4){ + end[fa]=npack++; + start[4]=npack; + fa=4; + } + else + npack++; + + } + else{ + end[fa]=info_IM.num-1; + npack=info_IM.num; + fa=5; + + } + + } + // devo mettere la fine all'ultima fascia abilitata + if (fa!=5){ + //risolvo un bug!! + if(start[fa] == info_IM.num){ + //disattivo l'ultima fascia se non correttamente abilitata + start[fa] = -1; + fa--; + } + else + end[fa]=info_IM.num-1; + } + printf("livello start end\n"); + for (i=0;i<6;i++) + printf("%d\t%d\t%d\n", i, start[i], end[i]); + + for (i=0;i<6;i++) + printf("pepb[%d]: %x\n", i, jpwl_cp.pepb[i]); + + //determino anticipatamente le lunghezze degli epb + if (len_header) + Psot_cor += JPWL_len_EPB((len_header), jpwl_cp.pepb[0], 0) + 2; + fa=0; + //devo calcolare le lunghezze degli epb necessari per ogni fascia + for(i=0;i<5;i++){ + len[i]=0; + if ((start[i]!=-1)&&(end[i]!=-1)){ + len[i]= (info_IM.tile[notil-1].packet[end[i]].end_pos) - info_IM.tile[notil-1].packet[start[i]].start_pos +1; + /*printf("len[%d]: %d\n",i, len[i]); */ + if (i==0) + //poichè non viene considerato il marker SOD + len[i]+=2; + lmax[i] = pianifica_epb(len[i], jpwl_cp.pepb[i+1], &no_epb[i]); + /*printf("lmax[%d]: %d\n", i, lmax[i]);*/ + tot_epb+=no_epb[i]; + /*printf("num epb[%d]: %d\n",i, no_epb[i]);*/ + if(no_epb[i] > 1){ + if ((!(len_header))&&(i==1)) + Psot_cor += JPWL_len_EPB(lmax[i], jpwl_cp.pepb[i+1], 0) + (no_epb[i]-2)*JPWL_len_EPB((lmax[i]), jpwl_cp.pepb[i+1], 0x41) + JPWL_len_EPB((len[i] % lmax[i]), jpwl_cp.pepb[i+1], 0x41); + else + Psot_cor += (no_epb[i]-1)*JPWL_len_EPB((lmax[i]), jpwl_cp.pepb[i+1], 0x41) + JPWL_len_EPB((len[i] % lmax[i]), jpwl_cp.pepb[i+1], 0x41); + } + else{ + if ((!(len_header))&&(i==1)) + Psot_cor += JPWL_len_EPB((len[i]), jpwl_cp.pepb[i+1], 0x0); + else + Psot_cor += JPWL_len_EPB((len[i]), jpwl_cp.pepb[i+1], 0x41); + } + + Psot_cor += 2*(no_epb[i]); + fa=i; + + + } + } + /*printf("fa: %d\n", fa); + printf("psot_cor: %d\n", Psot_cor); + printf("tot_epb: %d\n", tot_epb);*/ + /*len[5]=0; + for(i=0;i<5;i++){ + len[5]+=len[i]; + }*/ + /*printf("lendata: %d\n", len[5]);*/ + cio_seek(set - 6); + len_til=cio_read(4); + cio_skip(-4); + cio_write(Psot_cor + len_til,4); + + cio_seek(set); + //correzione index + if (info_IM.index_on){ + corr += Psot_cor; + info_IM.tile[notil-1].end_header += corr; + info_IM.tile[notil-1].end_pos += corr; + if (notil < j2k_cp->tw * j2k_cp->th) + info_IM.tile[notil].start_pos += corr; + pack_corr(corr, notil-1); + } + //scrivo gli EPB e riporto i buffer + if (len_header){ + JPWL_write_EPB(header, len_header, jpwl_cp.pepb[0], 0); + h=1; + pepbs[cont_epb++]=jpwl_cp.pepb[0]; + } + for (i = 0; i < len_header; i++) + cio_write(header[i],1); + free(header); + mask = (tot_epb == 1) ? 0x40 : 0x80; + for(i=0;i<5;i++){ + if ((start[i]!=-1)&&(end[i]!=-1)){ + data = (unsigned char *)malloc(lmax[i]*sizeof(unsigned char)); + for (k=0; k < no_epb[i]; k++){ + cont=0; + depb = mask | ((l+h)&0x3F); + + while (((cont + k*lmax[i])< len[i])&&(cont < lmax[i])){ + data[cont] = bs[cont + k*lmax[i] + lung]; + cont++; + } + if ((cont < lmax[i])&&(i==fa)) + depb |= 0x40; + /*printf("depb[%d]: %x\n",i, depb);*/ + JPWL_write_EPB(data, cont, jpwl_cp.pepb[i+1], depb); + pepbs[cont_epb++]=jpwl_cp.pepb[i+1]; + if (l==1) + scavalcato=1; + l++; + } + free(data); + lung+=len[i]; + } + } + + /*printf("lung: %d\n", lung );*/ + return Psot_cor; + +} + + + +int uep_lay(int notil, char *bs, char *header, int len_header){ + //questa funzione ritorna il valore di psot_corr + int depb, mask, corr=0, len_til, n_lay, lung=0, i, h=0, k, l=0, npack, Psot_cor=0, set, cont, tot_epb=0; + char *data; + int *lmax, *no_epb, *len; + + //determino il numero dei layer + n_lay = info_IM.Layer; + + //determino il numero di pacchetti per layer + npack = info_IM.num / n_lay; + + //preparo i vettori necessari + + if(!(lmax=(int *) malloc(n_lay * sizeof(int)))) + printf("Non può essere allocata memoria per eseguire il programma3\n "); + if(!(no_epb=(int *) malloc(n_lay * sizeof(int)))) + printf("Non può essere allocata memoria per eseguire il programma3\n "); + if(!(len=(int *) malloc(n_lay * sizeof(int)))) + printf("Non può essere allocata memoria per eseguire il programma3\n "); + + //mi piazzo alla fine di SOT + set=cio_tell(); + + + //determino anticipatamente le lunghezze degli epb + if (len_header) + Psot_cor += JPWL_len_EPB((len_header), jpwl_cp.pepb[0], 0) + 2; + + //devo calcolare le lunghezze degli epb necessari per ogni fascia + for(i=0;i 1){ + if ((!(len_header))&&(i==1)) + Psot_cor += JPWL_len_EPB(lmax[i], jpwl_cp.pepb[i+1], 0) + (no_epb[i]-2)*JPWL_len_EPB((lmax[i]), jpwl_cp.pepb[i+1], 0x41) + JPWL_len_EPB((len[i] % lmax[i]), jpwl_cp.pepb[i+1], 0x41); + else + Psot_cor += (no_epb[i]-1)*JPWL_len_EPB((lmax[i]), jpwl_cp.pepb[i+1], 0x41) + JPWL_len_EPB((len[i] % lmax[i]), jpwl_cp.pepb[i+1], 0x41); + } + else{ + if ((!(len_header))&&(i==1)) + Psot_cor += JPWL_len_EPB((len[i]), jpwl_cp.pepb[i+1], 0x0); + else + Psot_cor += JPWL_len_EPB((len[i]), jpwl_cp.pepb[i+1], 0x41); + } + + Psot_cor += 2*(no_epb[i]); + } + + //correzione di psot + cio_seek(set - 6); + len_til=cio_read(4); + cio_skip(-4); + cio_write(Psot_cor + len_til,4); + cio_seek(set); + + //correzione index + if (info_IM.index_on){ + corr += Psot_cor; + info_IM.tile[notil-1].end_header += corr; + info_IM.tile[notil-1].end_pos += corr; + if (notil < j2k_cp->tw * j2k_cp->th) + info_IM.tile[notil].start_pos += corr; + pack_corr(corr, notil-1); + } + + //scrivo gli EPB e riporto i buffer + if (len_header){ + JPWL_write_EPB(header, len_header, jpwl_cp.pepb[0], 0); + h=1; + pepbs[cont_epb++]=jpwl_cp.pepb[0]; + } + for (i = 0; i < len_header; i++) + cio_write(header[i],1); + free(header); + + //EPB a protezione della bitstream + mask = (tot_epb == 1) ? 0x40 : 0x80; + for(i=0;itw * j2k_cp->th; notil++){ + Psot_cor = 0; + //trucco per non fare sbagliare nella scrittura di più di 64 epb + scavalcato=0; + cio_skip(4); + len_til = cio_read(4); + cio_skip(2); + set = cio_tell(); + mark = cio_read(2); + //printf("mark: %x\n",mark); + while (mark!=0xff93){ + len_mar = cio_read(2); + cio_skip(len_mar-2); + mark = cio_read(2); + //printf("mark: %x\n",mark); + } + end_tph = cio_tell()-2; + len_data1= end_tph - set; + len_data2= len_til+set-end_tph-12; + /*printf("lendata2: %d\n",len_data2);*/ + buf1 = (unsigned char *) malloc(len_data1*sizeof(unsigned char)); + buf2 = (unsigned char *) malloc(len_data2*sizeof(unsigned char)); + cio_seek(set); + for (i=0; i 1){ + if (len_data1) + Psot_cor += (no_epb-1)*JPWL_len_EPB((lmax), jpwl_cp.pepb[1], 0x41) + JPWL_len_EPB((len_data2 % lmax), jpwl_cp.pepb[1], 0x41); + else + Psot_cor += JPWL_len_EPB(lmax, jpwl_cp.pepb[1], 0) + (no_epb-2)*JPWL_len_EPB((lmax), jpwl_cp.pepb[1], 0x41) + JPWL_len_EPB((len_data2 % lmax), jpwl_cp.pepb[1], 0x41); + } + else{ + if (len_data1) + Psot_cor += JPWL_len_EPB((len_data2), jpwl_cp.pepb[1], 0x41); + else + Psot_cor += JPWL_len_EPB((len_data2), jpwl_cp.pepb[1], 0x0); + } + Psot_cor += 2*(no_epb); + len_tot += Psot_cor; + //Psot_cor += len_til; + cio_seek(set - 6); + cio_write(Psot_cor + len_til,4); + + cio_seek(set); + //correzione index + if (info_IM.index_on){ + corr += Psot_cor; + info_IM.tile[notil-1].end_header += corr; + info_IM.tile[notil-1].end_pos += corr; + if (notil < j2k_cp->tw * j2k_cp->th) + info_IM.tile[notil].start_pos += corr; + pack_corr(corr, notil-1); + } + //scrivo gli EPB e riporto i buffer + if (len_data1){ + JPWL_write_EPB(buf1, len_data1, jpwl_cp.pepb[0], 0); + h=1; + pepbs[cont_epb++]=jpwl_cp.pepb[0]; + } + for (i = 0; i < len_data1; i++) + cio_write(buf1[i],1); + free(buf1); + mask = (no_epb == 1) ? 0x40 : 0x80; + data = (unsigned char *)malloc(lmax*sizeof(unsigned char)); + for (i=0; i < no_epb; i++){ + cont=0; + depb = mask | ((i+h)&0x3F); + while (((cont + i*lmax)< len_data2)&&(cont < lmax)){ + data[cont] = buf2[cont + i*lmax]; + cont++; + } + if (cont < lmax) + depb |= 0x40; + JPWL_write_EPB(data, cont, jpwl_cp.pepb[1], depb); + pepbs[cont_epb++]=jpwl_cp.pepb[1]; + if (i==1) + scavalcato=1; + } + free(data); + } + for (i = 0; i < len_data2; i++) + cio_write(buf2[i],1); + cur_pos=cio_tell(); + free(buf2); + for (i=0; i < len_data3; i++) + cio_write(buf3[i],1); + free(buf3); + cio_seek(cur_pos); + mark = cio_read(2); + + } + + //ora mi trovo alla fine della codestream + len_tot=cio_tell(); + // controllo se devo inserire l'esd (non lo devo inserire qui se è attivo il packet range mode) + if ((jpwl_cp.ESD_on)&(!(((jpwl_cp.pesd & 0xC0)>>6)==2))){ + cio_seek(end_siz); + len_data1 = len_tot - end_siz; + buf1 = (unsigned char *) malloc(len_data1 * sizeof(unsigned char)); + for (i = 0; i < len_data1; i++){ + buf1[i] = cio_read(1); + } + //printf("%x%x\n", buf1[len_tot - set - 2], buf1[len_tot - set -1]); + cio_seek(end_siz); + jpwl_write_ESD(jpwl_cp.pesd, 0); + len_esd = cio_tell() - end_siz; + //printf("len esd: %d\n",len_esd); + len_tot += len_esd; + for (i = 0; i < len_data1; i++){ + cio_write(buf1[i],1); + } + free(buf1); + } + + //scrivo l'epc ed il primo epb + cio_init(output, len_tot*2); + j2k_state = J2K_STATE_MH; + for (i=0; i< 6; i++){ + output[i]=input[i]; + } + cio_skip(4); + len_SIZ = cio_read(2); + for (i=6; i< 4+len_SIZ; i++){ + output[i]=input[i]; + } + cio_skip(len_SIZ-2); + set = cio_tell(); + len_epc = 15 + cont_epb*4; + len_primo_epb=JPWL_len_EPB(fine_mh - set + len_epc, jpwl_cp.pepb[0], 0); + len_red=(jpwl_cp.RED_on)? 5 : 0; + if (info_IM.index_on){ + corr=len_epc + len_primo_epb + 2 + len_esd + len_red; + info_IM.Main_head_end += corr; + //printf("fine_mh: %d\n",info_IM.Main_head_end); + //printf("%d\n", info_IM.tile[0].start_pos); + info_IM.tile[0].start_pos += corr; + for (i=0; i < j2k_cp->th * j2k_cp->tw; i++){ + info_IM.tile[i].end_header += corr; + info_IM.tile[i].end_pos += corr; + if (i < j2k_cp->tw * j2k_cp->th) + info_IM.tile[i+1].start_pos += corr; + pack_corr(corr, i); + } + } + + jpwl_write_EPC_fin(len_tot+len_primo_epb+2+len_esd+len_red, pepbs, cont_epb); + //controllo se devo inserire la red (solo test) + if (jpwl_cp.RED_on) + jpwl_write_RED(); + pos=cio_tell(); + //scrivo da input il main header + for (i=4+len_SIZ; i>6)==1) ){ + cio_seek(pos); + correggi_esd(corr, len_esd, jpwl_cp.pesd); + } + + len_data1=cur_pos-set; + buf1= (unsigned char *) malloc((len_data1)*sizeof(unsigned char)); + cio_seek(set); + for (i=0; i< len_data1; i++){ + buf1[i]=cio_read(1); + } + cio_seek(set); + JPWL_write_EPB(buf1, len_data1, jpwl_cp.pepb[0], 0x40); + for (i = 0; i < len_data1; i++) + cio_write(buf1[i],1); + free(buf1); + for (i = fine_mh+len_esd; i < len_tot; i++) + cio_write(input[i],1); + + + } + + + // se devo inserire l'epc da solo lo posiziono subito dopo SIZ + else { + len_esd=0; + cio_init(output, CL*2); + for (i=0; i< 6; i++){ + output[i]=input[i]; + } + cio_skip(4); + len_SIZ = cio_read(2); + for (i=6; i< 4+len_SIZ; i++){ + output[i]=input[i]; + } + cio_skip(len_SIZ-2); + set = cio_tell(); + // controllo se devo inserire l'esd + if ((jpwl_cp.ESD_on)&(!(((jpwl_cp.pesd & 0xC0)>>6)==2))){ + jpwl_write_ESD(jpwl_cp.pesd, 0); + len_esd = cio_tell() - set; + cio_seek(set); + buf1 = (unsigned char *) malloc(len_esd * sizeof(unsigned char)); + for (i = 0; i < len_esd; i++){ + buf1[i] = cio_read(1); + } + cio_seek(set); + len_red=(jpwl_cp.RED_on)? 5 : 0; + corr=len_esd+11+len_red; + //correzione delle posizioni dei pack nella struttura info image da fare nel caso di esd nel main header + if (info_IM.index_on){ + info_IM.Main_head_end += corr; + //printf("fine_mh: %d\n",info_IM.Main_head_end); + info_IM.tile[0].start_pos += corr; + for (i=0; i < j2k_cp->th * j2k_cp->tw; i++){ + info_IM.tile[i].end_header += corr; + info_IM.tile[i].end_pos += corr; + if (i < j2k_cp->tw * j2k_cp->th) + info_IM.tile[i+1].start_pos += corr; + pack_corr(corr, i); + } + } + } + jpwl_write_EPC_fin(CL + len_esd, NULL, 0); + //controllo se devo inserire la red (solo test) + if (jpwl_cp.RED_on) + jpwl_write_RED(); + set=cio_tell(); + if (jpwl_cp.ESD_on){ + for (i = 0; i < len_esd; i++){ + cio_write(buf1[i],1); + } + free(buf1); + if (((jpwl_cp.pesd & 0xC0)>>6)==1) { + cio_seek(set); + correggi_esd(corr, len_esd, jpwl_cp.pesd); + } + } + for (i=4+len_SIZ; i < CL; i++){ + cio_write(input[i],1); + } + } + + + return cio_tell(); + +} + +void get_jpwl_cp(j2k_cp_t *cp){ + char risp, scelta,choose; + int out = 0; + unsigned long n; + j2k_cp_t *param; + + param = cp; + printf("You have chosen to activate JPWL techniques. EPC will be inserted\n"); + if (param->intermed_file){ + printf("Since intermed file option is active, EPC will not contain any information on the"); + printf("codestream length: eventual ESDs will be written in tile part headers.\n\n\n"); + } + printf("Do you want to use EPBs (y/n)?: "); + risp = (char) _getche(); + printf("\n\n\n"); + do { + switch (risp){ + case 'y': + jpwl_cp.EPB_on = 1; + do{ + printf("UEP or EEP (u,e)?: "); + choose = (char) _getche(); + printf("\n\n\n"); + }while(!strchr("ue",choose)); + if (choose=='e'){ + do{ + printf("Header protecting EPBs settings\n"); + printf("1) Adopt the same RS code used for the EPB;\n"); + printf("2) Enter a RS(n,32) code;\n"); + printf("3) Use CRC-16(CCITT);\n"); + printf("4) Use CRC-32(ETHERNET);\n"); + printf("5) No protection at all.\n\n\n"); + scelta = (char) _getche(); + printf("\n\n"); + }while(!strchr("12345",scelta)); + if (scelta == '1') + jpwl_cp.pepb[0]=0x00000000; + if (scelta == '2'){ + do { + printf("Enter the desired n value (k=32 as standard; n between 37 and 128): "); + scanf("%d", &n); + printf("\n\n\n"); + } while ((n<37)||(n>128)); + jpwl_cp.pepb[0] = ( n & 0x000000FF)<<8; + jpwl_cp.pepb[0] |= 0x20000020; + } + if (scelta == '3') + jpwl_cp.pepb[0] = 0x10000000; + if (scelta == '4') + jpwl_cp.pepb[0] = 0x10000001; + if (scelta == '5') + jpwl_cp.pepb[0] = 0xFFFFFFFF; + printf("pepb1: %x\n", jpwl_cp.pepb[0]); + do{ + printf("Data protecting EPBs settings\n"); + printf("1) Adopt the same RS code used for the EPB;\n"); + printf("2) Enter a RS(n,32) code;\n"); + printf("3) Use CRC-16(CCITT);\n"); + printf("4) Use CRC-32(ETHERNET);\n"); + printf("5) No protection at all.\n\n\n"); + scelta = (char) _getche(); + printf("\n\n"); + }while(!strchr("12345",scelta)); + if (scelta == '1') + jpwl_cp.pepb[1]=0x00000000; + if (scelta == '2'){ + do { + printf("Enter the desired n value (k=32 as standard; n between 37 and 128): "); + scanf("%d", &n); + printf("\n\n\n"); + } while ((n<37)||(n>128)); + jpwl_cp.pepb[1] = ( n & 0x000000FF)<<8; + jpwl_cp.pepb[1] |= 0x20000020; + } + if (scelta == '3') + jpwl_cp.pepb[1] = 0x10000000; + if (scelta == '4') + jpwl_cp.pepb[1] = 0x10000001; + if (scelta == '5') + jpwl_cp.pepb[1] = 0xFFFFFFFF; + printf("pepb2: %x\n", jpwl_cp.pepb[1]); + out=1; + } + if (choose=='u'){ + printf("N.B.: layer number must be less than or equal to five\n"); + param->index_on = 1; + jpwl_cp.UEP_on = 1; + jpwl_cp.pepb[0] = 0x20008020; + jpwl_cp.pepb[1] = 0x20005520; + jpwl_cp.pepb[2] = 0x20004B20; + jpwl_cp.pepb[3] = 0x20002520; + jpwl_cp.pepb[4] = 0x20002520; + jpwl_cp.pepb[5] = 0x20002520; + out=1; + } + + break; + case 'n': + out=1; + break; + default: + printf("Error in answer.\n"); + printf("Do you want to use EPBs (y/n)?: "); + risp = (char) _getche(); + printf("\n\n\n"); + } + }while (!out); + out = 0; + printf("Do you want to use ESD (y/n)?: "); + risp = (char) _getche(); + printf("\n\n\n"); + do { + switch(risp){ + case 'y': + jpwl_cp.ESD_on = 1; + param->index_on = 1; + jpwl_cp.pesd = 0x01; + do{ + printf("Enter representation mode:\n"); + printf("1) Packet mode;\n"); + printf("2) Byte range mode;\n"); + printf("3) Packet range mode.\n"); + scelta = (char) _getche(); + printf("\n\n"); + }while(!strchr("123",scelta)); + if (scelta =='1') + jpwl_cp.pesd |= 0x00; + if (scelta =='2') + jpwl_cp.pesd |= 0x42; + if (scelta =='3') + jpwl_cp.pesd |= 0x80; + do{ + printf("Enter metrics:\n"); + printf("1) Relative error sensitivity;\n"); + printf("2) MSE;\n"); + printf("3) MSE reduction;\n"); + printf("4) PSNR;\n"); + printf("5) PSNR increase.\n"); + scelta = (char) _getche(); + printf("\n\n"); + }while(!strchr("12345",scelta)); + if (scelta =='1') + jpwl_cp.pesd |= 0x00; + if (scelta =='2') + jpwl_cp.pesd |= 0x0C; + if (scelta =='3') + jpwl_cp.pesd |= 0x14; + if (scelta =='4') + jpwl_cp.pesd |= 0x1C; + if (scelta =='5') + jpwl_cp.pesd |= 0x24; + printf("pesd: %x\n", jpwl_cp.pesd); + out=1; + break; + case 'n': + out=1; + break; + default: + printf("Error entering the answer.\n"); + printf("Do you want to use ESD (y/n)?: "); + risp = (char) _getche(); + printf("\n\n\n"); + } + }while (!out); + out = 0; + printf("Do you want to use RED (y/n)?: "); + risp = (char) _getche(); + printf("\n\n\n"); + do { + switch(risp){ + case 'y': + jpwl_cp.RED_on = 1; + //suppongo che la codestream sia corretta => b0=0 e b5b4b3=000 + jpwl_cp.pred = 0x00; + do{ + printf("Enter representation mode:\n"); + printf("1) Packet mode;\n"); + printf("2) Byte range mode;\n"); + printf("3) Packet range mode.\n"); + scelta = (char) _getche(); + printf("\n\n"); + }while(!strchr("123",scelta)); + if (scelta =='1') + jpwl_cp.pred |= 0x00; + if (scelta =='2') + jpwl_cp.pred |= 0x42; + if (scelta =='3') + jpwl_cp.pred |= 0x80; + printf("pred: %x\n", jpwl_cp.pred); + out=1; + break; + case 'n': + out=1; + break; + default: + printf("Error entering the answer.\n"); + printf("Do you want to use RED (y/n)?: "); + risp = (char) _getche(); + printf("\n\n\n"); + } + }while (!out); + +} + + + +void ResetCRC() +{ + crcSum = 0xffffffff; +} + + +void UpdateCRC16(char x) +{ + int tmp; + tmp = ((x ^ (crcSum >> 8)) & 0xff); + crcSum = ((crcSum << 8) ^ CrcT16[tmp]) & 0xffff; +} + +void UpdateCRC32(char x) +{ + int tmp; + tmp = ((x ^ (crcSum >> 24)) & 0xff); + crcSum = ((crcSum << 8) ^ CrcT32[tmp]); +} +/* funzioni per l'inversione dei byte e del crc32 */ + +char reflectByte(char inbyte) +{ + // reflect one byte + + unsigned char outbyte=0; + unsigned char i=0x01; + unsigned char j; + + for (j=0x080; j; j>>=1) + { + if (inbyte & i) outbyte|=j; + i<<=1; + } + + return outbyte; +} + + +void reflectCRC32() +{ + + + unsigned long outcrc=0; + unsigned long i=0x00000001; + unsigned long j; + + for (j=0x80000000; j; j>>=1) + { + if (crcSum & i) + outcrc|=j; + i=i<<1; + } + crcSum = outcrc; +} + +/* +int crc_ccitt(char *buffer, int len){ + char c; + int i; + ResetCRC(); + for (i=0; i>9) & 0x07FF; + ex = (data>>20) & 0x07FF; + out = ex+15; + out = out << 11; + out &= 0x0000F800; + out |= mant; + return out; +} + + +double pfp2d(short int in){ + double out; + short int ex, mant; + mant = in & 0x07FF; + ex = (in >> 11) & 0x001F; + out = pow(2,ex-15)*(1+(mant/pow(2,11))); + return out; +} diff --git a/jpwl/encoder/libopenjpeg/jpw.h b/jpwl/encoder/libopenjpeg/jpw.h new file mode 100644 index 00000000..1e1e91a2 --- /dev/null +++ b/jpwl/encoder/libopenjpeg/jpw.h @@ -0,0 +1,105 @@ +/* + * Copyright 2004-2005 Andrea Betti and Michele Massarelli + * Copyright 2004-2005 DIEI, University of Perugia + * + * + * 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. + */ + + +/* questa è un' estensione della libreria dell'openjpeg in grado di implementare + * la parte 11 dello standard JPEG2000 ossia il JPWL + */ + +#ifndef __JPW_H +#define __JPW_H + + +typedef struct { + unsigned int JPWL_on; //indica se usare le funzionalità JPWL e quindi l'EPC nel main header + unsigned int EPB_on; + unsigned int ESD_on; + unsigned int RED_on; + unsigned int UEP_on; + unsigned int info_tech_on; + unsigned long pepb[6]; + unsigned char pesd; + unsigned char pred; +} JPWL_cp_t; + + +// inizializza la struttura contenente le info riguardanti l'uso dei marker jpwl + +void jpwl_cp_init(JPWL_cp_t *jpwl_cp); + +// qui iniziano le funzioni necessarie per la scrittura dei marker + +void jpwl_write_EPC(); + +void jpwl_write_ESD(char Pesd, int notil); + +void jpwl_write_RED(); + +void JPWL_write_EPB(char *buf, unsigned long LDPepb, unsigned long Pepb, unsigned char Depb); + +int JPWL_len_EPB(unsigned int LDPepb, unsigned int Pepb, unsigned char Depb); + +int pianifica_epb(unsigned int LDPepb, unsigned int Pepb, int *n_epb ); + +void JPWL_write_Pepbs(long *pepbs, int num_epb); + +void get_jpwl_cp(j2k_cp_t *cp); + +int uep(int notil, char *bs, char *header, int len_header); + +int uep_lay(int notil, char *bs, char *header, int len_header); + +void jpwl_write_EPC_fin(unsigned long CL, long *pepbs, int num_epb); + +void correggi_esd(int offset, int len_esd, int Pesd); + +int jpwl_encode(char *input, char * output, unsigned long CL); + +/* qui andrò ad inserire le funzioni necessarie per il crc oppure la codifica RS + * e le funzioni per le tecniche informative aggiuntive + */ + +void ResetCRC(); + +void UpdateCRC16(char x); + +void UpdateCRC32(char x); + +char reflectByte(char inbyte); + +void reflectCRC32(); + + +//int crc_ccitt(char *buffer, int len); + +short int d2pfp(double in); + +double pfp2d(short int in); + + + +#endif \ No newline at end of file diff --git a/jpwl/encoder/libopenjpeg/mct.c b/jpwl/encoder/libopenjpeg/mct.c new file mode 100644 index 00000000..185c1b66 --- /dev/null +++ b/jpwl/encoder/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/jpwl/encoder/libopenjpeg/mct.h b/jpwl/encoder/libopenjpeg/mct.h new file mode 100644 index 00000000..196dc6d3 --- /dev/null +++ b/jpwl/encoder/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/jpwl/encoder/libopenjpeg/mqc.c b/jpwl/encoder/libopenjpeg/mqc.c new file mode 100644 index 00000000..31adc845 --- /dev/null +++ b/jpwl/encoder/libopenjpeg/mqc.c @@ -0,0 +1,591 @@ +/* + * 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_setcurctx(0); + 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; + //add antonin initbug1 + if (len==0) mqc_c = 0xff << 16; + else mqc_c = *mqc_bp << 16; + //dda + 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/jpwl/encoder/libopenjpeg/mqc.h b/jpwl/encoder/libopenjpeg/mqc.h new file mode 100644 index 00000000..ea01d809 --- /dev/null +++ b/jpwl/encoder/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(int d); + +/* + * 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/jpwl/encoder/libopenjpeg/openjpeg.h b/jpwl/encoder/libopenjpeg/openjpeg.h new file mode 100644 index 00000000..17689097 --- /dev/null +++ b/jpwl/encoder/libopenjpeg/openjpeg.h @@ -0,0 +1,50 @@ +/* + * 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 +#include +#include + +#endif diff --git a/jpwl/encoder/libopenjpeg/pi.c b/jpwl/encoder/libopenjpeg/pi.c new file mode 100644 index 00000000..cfe5ba00 --- /dev/null +++ b/jpwl/encoder/libopenjpeg/pi.c @@ -0,0 +1,557 @@ +/* + * Copyright (c) 2001-2002, David Janssens + * Copyright (c) 2003-2004, Yannick Verschueren + * Copyright (c) 2003-2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "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, i; + int compno, resno, pino; + 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[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[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 = (rx0==rx1)?0:((px1 - px0) >> res->pdx); //Mod Antonin : sizebug1 + res->ph = (ry0==ry1)?0:((py1 - py0) >> res->pdy); //Mod Antonin : sizebug1 + } + } + + tccp = &tcp->tccps[0]; + pi[pino].step_p = 1; + pi[pino].step_c = 100 * pi[pino].step_p; + pi[pino].step_r = img->numcomps * pi[pino].step_c; + pi[pino].step_l = maxres * pi[pino].step_r; + + if (pino == 0) { + pi[pino].include = + (short int *) malloc(img->numcomps * maxres * + tcp->numlayers * 100 * sizeof(short int)); + for (i = 0; i < img->numcomps * maxres * tcp->numlayers * 100; i++) + pi[pino].include[i] = 0; + } + /* pi[pino].include=(short int*)calloc(img->numcomps*maxres*tcp->numlayers*1000,sizeof(short int)); */ + else + pi[pino].include = pi[pino - 1].include; + + if (tcp->POC == 0) { + pi[pino].first = 1; + pi[pino].poc.resno0 = 0; + pi[pino].poc.compno0 = 0; + pi[pino].poc.layno1 = tcp->numlayers; + pi[pino].poc.resno1 = maxres; + pi[pino].poc.compno1 = 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. + * + * pi: packet iterator to modify + * */ +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->step_l + + pi->resno * pi->step_r + + pi->compno * pi->step_c + pi->precno * pi->step_p]) { + pi->include[pi->layno * pi->step_l + + pi->resno * pi->step_r + + pi->compno * pi->step_c + + pi->precno * pi->step_p] = 1; + return 1; + } + skip:; + } + } + } + } + return 0; +} + +/* + * Get next packet in resolution-layer-component-precinct order. + * + * pi: packet iterator to modify + * */ +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->step_l + + pi->resno * pi->step_r + + pi->compno * pi->step_c + pi->precno * pi->step_p]) { + pi->include[pi->layno * pi->step_l + + pi->resno * pi->step_r + + pi->compno * pi->step_c + + pi->precno * pi->step_p] = 1; + return 1; + } + skip:; + } + } + } + } + return 0; +} + +/* + * Get next packet in resolution-precinct-component-layer order. + * + * pi: packet iterator to modify + * */ +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 trx1, try1;// Add antonin pcrl + 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); + trx1 = int_ceildiv(pi->tx1, comp->dx << levelno);// Add antonin pcrl + try1 = int_ceildiv(pi->ty1, comp->dy << levelno);// Add antonin pcrl + 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; + } + + //Add Antonin : sizebug1 + if ((res->pw==0)||(res->pw==0)) continue; + //ddA + + //Add Antonin : pcrl + if ((trx0==trx1)||(try0==try1)) continue; + //ddA + + 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->step_l + + pi->resno * pi->step_r + + pi->compno * pi->step_c + + pi->precno * pi->step_p]) { + pi->include[pi->layno * pi->step_l + + pi->resno * pi->step_r + + pi->compno * pi->step_c + + pi->precno * pi->step_p] = 1; + return 1; + } + skip:; + } + } + } + } + } + return 0; +} + +/* + * Get next packet in precinct-component-resolution-layer order. + * + * pi: packet iterator to modify + * */ +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 trx1, try1;// Add antonin pcrl + 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); + trx1 = int_ceildiv(pi->tx1, comp->dx << levelno);// Add antonin pcrl + try1 = int_ceildiv(pi->ty1, comp->dy << levelno);// Add antonin pcrl + 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; + } + + //Add Antonin : sizebug1 + if ((res->pw==0)||(res->pw==0)) continue; + //ddA + + //Add Antonin : pcrl + if ((trx0==trx1)||(try0==try1)) continue; + //ddA + + 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->step_l + + pi->resno * pi->step_r + + pi->compno * pi->step_c + + pi->precno * pi->step_p]) { + pi->include[pi->layno * pi->step_l + + pi->resno * pi->step_r + + pi->compno * pi->step_c + + pi->precno * pi->step_p] = 1; + return 1; + } +skip:; + } + } + } + } + } + return 0; +} + +/* + * Get next packet in component-precinct-resolution-layer order. + * + * pi: packet iterator to modify + * */ +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 trx1, try1;// Add antonin pcrl + 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); + trx1 = int_ceildiv(pi->tx1, comp->dx << levelno);// Add antonin pcrl + try1 = int_ceildiv(pi->ty1, comp->dy << levelno);// Add antonin pcrl + 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; + } + + //Add Antonin : sizebug1 + if ((res->pw==0)||(res->pw==0)) continue; + //ddA + + //Add Antonin : pcrl + if ((trx0==trx1)||(try0==try1)) continue; + //ddA + + 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->step_l + + pi->resno * pi->step_r + + pi->compno * pi->step_c + + pi->precno * pi->step_p]) { + pi->include[pi->layno * pi->step_l + + pi->resno * pi->step_r + + pi->compno * pi->step_c + + pi->precno * pi->step_p] = 1; + return 1; + } + skip:; + } + } + } + } + } + return 0; +} + +/* + * Get next packet. + * + * pi: packet iterator to modify + * */ +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/jpwl/encoder/libopenjpeg/pi.h b/jpwl/encoder/libopenjpeg/pi.h new file mode 100644 index 00000000..acfe201a --- /dev/null +++ b/jpwl/encoder/libopenjpeg/pi.h @@ -0,0 +1,72 @@ +/* + * 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 { + short int *include; /* precise if the packet has been already used (usefull for progression order change) */ + int step_l, step_r, step_c, step_p; /* different steps (layer, resolution, component, precinct) to localize the packet in the include vector */ + int compno, resno, precno, layno; /* component, resolution, precinct and layer that indentify the packet */ + int first; /* 0 if the first packet */ + 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/jpwl/encoder/libopenjpeg/raw.c b/jpwl/encoder/libopenjpeg/raw.c new file mode 100644 index 00000000..bae2e899 --- /dev/null +++ b/jpwl/encoder/libopenjpeg/raw.c @@ -0,0 +1,81 @@ +/* + * 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; /* temporary buffer where bits are coded or decoded */ +unsigned int raw_ct; /* number of bits already read or free to write */ +unsigned int raw_lenmax; /* maximum length to decode */ +unsigned int raw_len; /* length decoded */ +unsigned char *raw_bp; /* pointer to the current position in the buffer */ +unsigned char *raw_start; /* pointer to the start of the buffer */ +unsigned char *raw_end; /* pointer to the end of the buffer */ + +/* + * Return the number of bytes already encoded. + */ +int raw_numbytes() +{ + return raw_bp - raw_start; +} + +/* + * Initialize raw-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) +{ + 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/jpwl/encoder/libopenjpeg/raw.h b/jpwl/encoder/libopenjpeg/raw.h new file mode 100644 index 00000000..08b20bc6 --- /dev/null +++ b/jpwl/encoder/libopenjpeg/raw.h @@ -0,0 +1,48 @@ +/* + * 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 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/jpwl/encoder/libopenjpeg/rs.c b/jpwl/encoder/libopenjpeg/rs.c new file mode 100644 index 00000000..3d27fe3e --- /dev/null +++ b/jpwl/encoder/libopenjpeg/rs.c @@ -0,0 +1,138 @@ +/* rs.c */ +/* This program is an encoder/decoder for Reed-Solomon codes. Encoding is in + systematic form, decoding via the Berlekamp iterative algorithm. + In the present form , the constants mm, nn, tt, and kk=nn-2tt must be + specified (the double letters are used simply to avoid clashes with + other n,k,t used in other programs into which this was incorporated!) + Also, the irreducible polynomial used to generate GF(2**mm) must also be + entered -- these can be found in Lin and Costello, and also Clark and Cain. + + The representation of the elements of GF(2**m) is either in index form, + where the number is the power of the primitive element alpha, which is + convenient for multiplication (add the powers modulo 2**m-1) or in + polynomial form, where the bits represent the coefficients of the + polynomial representation of the number, which is the most convenient form + for addition. The two forms are swapped between via lookup tables. + This leads to fairly messy looking expressions, but unfortunately, there + is no easy alternative when working with Galois arithmetic. + + The code is not written in the most elegant way, but to the best + of my knowledge, (no absolute guarantees!), it works. + However, when including it into a simulation program, you may want to do + some conversion of global variables (used here because I am lazy!) to + local variables where appropriate, and passing parameters (eg array + addresses) to the functions may be a sensible move to reduce the number + of global variables and thus decrease the chance of a bug being introduced. + + This program does not handle erasures at present, but should not be hard + to adapt to do this, as it is just an adjustment to the Berlekamp-Massey + algorithm. It also does not attempt to decode past the BCH bound -- see + Blahut "Theory and practice of error control codes" for how to do this. + + Simon Rockliff, University of Adelaide 21/9/89 + + 26/6/91 Slight modifications to remove a compiler dependent bug which hadn't + previously surfaced. A few extra comments added for clarity. + Appears to all work fine, ready for posting to net! + + Notice + -------- + This program may be freely modified and/or given to whoever wants it. + A condition of such distribution is that the author's contribution be + acknowledged by his name being left in the comments heading the program, + however no responsibility is accepted for any financial or other loss which + may result from some unforseen errors or malfunctioning of the program + during use. + Simon Rockliff, 26th June 1991 +*/ + +#include +#include + +#define mm 8 /* RS code over GF(2**4) - change to suit */ +#define nn 255 /* nn=2**mm -1 length of codeword */ + +int pp [mm+1] = { 1, 0, 1, 1, 1, 0, 0, 0, 1 } ; /* specify irreducible polynomial coeffts */ + +void generate_gf(int *alpha_to, int *index_of) +/* generate GF(2**mm) from the irreducible polynomial p(X) in pp[0]..pp[mm] + lookup tables: index->polynomial form alpha_to[] contains j=alpha**i; + polynomial form -> index form index_of[j=alpha**i] = i + alpha=2 is the primitive element of GF(2**mm) +*/ + { + register int i, mask ; + + mask = 1 ; + alpha_to[mm] = 0 ; + for (i=0; i>= 1 ; + for (i=mm+1; i= mask) + alpha_to[i] = alpha_to[mm] ^ ((alpha_to[i-1]^mask)<<1) ; + else alpha_to[i] = alpha_to[i-1]<<1 ; + index_of[alpha_to[i]] = i ; + } + index_of[0] = -1 ; + } + + +void gen_poly(int kk, int *alpha_to, int *index_of, int *gg) +/* Obtain the generator polynomial of the tt-error correcting, length + nn=(2**mm -1) Reed Solomon code from the product of (X+alpha**i), i=1..2*tt +*/ + { + register int i,j ; + + gg[0] = 2 ; /* primitive element alpha = 2 for GF(2**mm) */ + gg[1] = 1 ; /* g(x) = (X+alpha) initially */ + for (i=2; i<=nn-kk; i++) + { gg[i] = 1 ; + for (j=i-1; j>0; j--) + if (gg[j] != 0) gg[j] = gg[j-1]^ alpha_to[(index_of[gg[j]]+i)%nn] ; + else gg[j] = gg[j-1] ; + gg[0] = alpha_to[(index_of[gg[0]]+i)%nn] ; /* gg[0] can never be zero */ + } + /* convert gg[] to index form for quicker encoding */ + for (i=0; i<=nn-kk; i++) gg[i] = index_of[gg[i]] ; + } + + +void encode_rs(int kk, int *alpha_to, int *index_of, int *gg, int *bb, int *data) +/* take the string of symbols in data[i], i=0..(k-1) and encode systematically + to produce 2*tt parity symbols in bb[0]..bb[2*tt-1] + data[] is input and bb[] is output in polynomial form. + Encoding is done by using a feedback shift register with appropriate + connections specified by the elements of gg[], which was generated above. + Codeword is c(X) = data(X)*X**(nn-kk)+ b(X) */ + { + register int i,j ; + int feedback ; + + for (i=0; i=0; i--) + { feedback = index_of[data[i]^bb[nn-kk-1]] ; + if (feedback != -1) + { for (j=nn-kk-1; j>0; j--) + if (gg[j] != -1) + bb[j] = bb[j-1]^alpha_to[(gg[j]+feedback)%nn] ; + else + bb[j] = bb[j-1] ; + bb[0] = alpha_to[(gg[0]+feedback)%nn] ; + } + else + { for (j=nn-kk-1; j>0; j--) + bb[j] = bb[j-1] ; + bb[0] = 0 ; + } ; + } ; + } ; + + diff --git a/jpwl/encoder/libopenjpeg/rs.h b/jpwl/encoder/libopenjpeg/rs.h new file mode 100644 index 00000000..b04523f8 --- /dev/null +++ b/jpwl/encoder/libopenjpeg/rs.h @@ -0,0 +1,12 @@ + +/* + Header file for rs.c +*/ + + +void generate_gf(int *alpha_to, int *index_of); + +void gen_poly(int kk, int *alpha_to, int *index_of, int *gg); + +void encode_rs(int kk, int *alpha_to, int *index_of, int *gg, int *bb, int *data); + diff --git a/jpwl/encoder/libopenjpeg/t1.c b/jpwl/encoder/libopenjpeg/t1.c new file mode 100644 index 00000000..4df64799 --- /dev/null +++ b/jpwl/encoder/libopenjpeg/t1.c @@ -0,0 +1,1098 @@ +/* + * 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_MAXCBLKW]; +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, int numcomps) //mod fixed_quality +{ + double w1, w2, wmsedec; + if (qmfbid == 1) { + w1 = (numcomps > 1) ? mct_getnorm(compno) : 1; + w2 = dwt_getnorm(level, orient); + } else { /* if (qmfbid == 0) */ + w1 = (numcomps > 1) ? mct_getnorm_real(compno) : 1; + w2 = dwt_getnorm_real(level, orient); + } + wmsedec = w1 * w2 * (stepsize / 8192.0) * (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 numcomps, tcd_tile_t * tile) //mod fixed_quality +{ + 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, numcomps); //mod fixed_quality + tile->distotile += t1_getwmsedec(nmsedec, compno, level, orient, bpno, qmfbid, stepsize, numcomps); //add antonin quality + + + /* Code switch "RESTART" (i.e. TERMALL) */ + if ((cblksty & J2K_CCP_CBLKSTY_TERMALL) + && !((passtype == 2) && (bpno - 1 < 0))) { + if (type == T1_TYPE_RAW) { + mqc_flush(); + correction = 1; + /* correction = mqc_bypass_flush_enc(); */ + } else { /* correction = mqc_restart_enc(); */ + mqc_flush(); + correction = 1; + } + 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) { + mqc_flush(); + correction = 1; + /* correction = mqc_bypass_flush_enc(); */ + } else { /* correction = mqc_restart_enc(); */ + mqc_flush(); + correction = 1; + } + pass->term = 1; + } else { + pass->term = 0; + } + } + + if (++passtype == 3) { + passtype = 0; + bpno--; + } + + if (pass->term && bpno > 0) { + type = ((bpno < (cblk->numbps - 4)) && (passtype < 2) + && (cblksty & 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; + char type = T1_TYPE_MQ; //BYPASS mode + + 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 BYPASS mode + 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 + + if (bpno==0) cblk->lastbp=1; // Add Antonin : quantizbug1 + + 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_resetstates(); + mqc_setstate(T1_CTXNO_UNI, 0, 46); + mqc_setstate(T1_CTXNO_AGG, 0, 3); + mqc_setstate(T1_CTXNO_ZC, 0, 4); + } + + 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; + + tile->distotile = 0; //add fixed_quality + + 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, tile->numcomps, tile); //mod fixed_quality + } /* 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 { + // Add antonin : quantizbug1 + t1_data[j][i]<<=1; + //if (cblk->lastbp) + t1_data[j][i]+=t1_data[j][i]>0?1:-1; + // ddA + tilec->data[x + i + + (y + j) * (tilec->x1 - + tilec-> + x0)] = + fix_mul(t1_data[j][i] << 12, band->stepsize); //Mod Antonin : quantizbug1 (before : << 13) + } + } + } + } + } + } + } + } + } +} + +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/jpwl/encoder/libopenjpeg/t1.h b/jpwl/encoder/libopenjpeg/t1.h new file mode 100644 index 00000000..5e98bc09 --- /dev/null +++ b/jpwl/encoder/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/jpwl/encoder/libopenjpeg/t2.c b/jpwl/encoder/libopenjpeg/t2.c new file mode 100644 index 00000000..9ccc64c3 --- /dev/null +++ b/jpwl/encoder/libopenjpeg/t2.c @@ -0,0 +1,644 @@ +/* + * Copyright (c) 2001-2002, David Janssens + * Copyright (c) 2002-2004, Yannick Verschueren + * Copyright (c) 2002-2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "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); +} + +/* + * Encode a packet of a tile to a destination buffer + * + * Tile : the tile for which to write the packets + * tcp : the tile coding parameters + * compno : Identity of the packet --> component value + * resno : Identity of the packet --> resolution level value + * precno : Identity of the packet --> precinct value + * layno : Identity of the packet --> quality layer value + * dest : the destination buffer + * len : the length of the destination buffer + * info_IM : structure to create an index file + * tileno : number of the tile encoded +*/ +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; + + /* */ + 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) { + 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; +} + +/* + * Decode a packet of a tile from a source buffer + * + * src : the source buffer + * len : the length of the source buffer + * tile : the tile for which to write the packets + * cp : the image coding parameters + * tcp : the tile coding parameters + * compno : Identity of the packet --> component value + * resno : Identity of the packet --> resolution level value + * precno : Identity of the packet --> precinct value + * layno : Identity of the packet --> quality layer value + */ +int t2_decode_packet(unsigned char *src, int len, tcd_tile_t * tile, + j2k_cp_t * cp, 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; + unsigned char *hd = NULL; + 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]; + + //Add Antonin : sizebug1 + if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)) continue; + //ddA + + 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; + } + } + } + + // SOP markers + if (tcp->csty & J2K_CP_CSTY_SOP) { + if ((*c) != 0xff || (*(c + 1) != 0x91)) { + printf("Warning : expected SOP marker\n"); + } else { + c += 6; + } + //TODO : check the Nsop value + } + + /* When the marker PPT/PPM is used the packet header are store in PPT/PPM marker + This part deal with this caracteristic + step 1: Read packet header in the saved structure + step 2: Return to codestream for decoding */ + + if (cp->ppm == 1) { /* PPM */ + hd = cp->ppm_data; + bio_init_dec(hd, cp->ppm_len); //Mod Antonin : ppmbug1 + } else if (tcp->ppt == 1) { /* PPT */ + hd = tcp->ppt_data; + bio_init_dec(hd, tcp->ppt_len); //Mod Antonin : ppmbug1 + } else { /* Normal Case */ + hd = c; + bio_init_dec(hd, src+len-hd); + } + + present = bio_read(1); + + if (!present) { + bio_inalign(); + hd += bio_numbytes(); + + // EPH markers + if (tcp->csty & J2K_CP_CSTY_EPH) { + if ((*hd) != 0xff || (*(hd + 1) != 0x92)) { + printf("Error : expected EPH marker\n"); + } else { + hd += 2; + } + } + + if (cp->ppm == 1) { /* PPM case */ + cp->ppm_len+=cp->ppm_data-hd; + cp->ppm_data = hd; + return c - src; + } + if (tcp->ppt == 1) { /* PPT case */ + tcp->ppt_len+=tcp->ppt_data-hd; + tcp->ppt_data = hd; + return c - src; + } + + return hd - src; + } + + for (bandno = 0; bandno < res->numbands; bandno++) { + tcd_band_t *band = &res->bands[bandno]; + tcd_precinct_t *prc = &band->precincts[precno]; + + //Add Antonin : sizebug1 + if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)) continue; + //ddA + + 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; + + hd += bio_numbytes(); + + // EPH markers + if (tcp->csty & J2K_CP_CSTY_EPH) { + if ((*hd) != 0xff || (*(hd + 1) != 0x92)) { + printf("Error : expected EPH marker\n"); + } else { + hd += 2; + } + } + + if (cp->ppm==1) { + cp->ppm_len+=cp->ppm_data-hd; + cp->ppm_data = hd; + } else if (tcp->ppt == 1) { + tcp->ppt_len+=tcp->ppt_data-hd; + tcp->ppt_data = hd; + } else { + c=hd; + } + + for (bandno = 0; bandno < res->numbands; bandno++) { + tcd_band_t *band = &res->bands[bandno]; + tcd_precinct_t *prc = &band->precincts[precno]; + + //Add Antonin : sizebug1 + if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)) continue; + //ddA + + 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[0]; + cblk->numsegs++; + cblk->len = 0; + } else { + seg = &cblk->segs[cblk->numsegs - 1]; + if (seg->numpasses == seg->maxpasses) { + seg++; + cblk->numsegs++; + } + } + do { + if (c + seg->newlen > src + len) { + return -999; + } + + memcpy(cblk->data + cblk->len, c, seg->newlen); + if (seg->numpasses == 0) { + seg->data = cblk->data + cblk->len; + } + c += seg->newlen; + cblk->len += seg->newlen; + seg->len += seg->newlen; + seg->numpasses += seg->numnewpasses; + cblk->numnewpasses -= seg->numnewpasses; + if (cblk->numnewpasses > 0) { + seg++; + cblk->numsegs++; + } + } while (cblk->numnewpasses > 0); + } + } + + return c - src; +} + + + +/* + * Encode the packets of a tile to a destination buffer + * + * img : the source image + * cp : the image coding parameters + * tileno : number of the tile encoded + * tile : the tile for which to write the packets + * maxlayers : maximum number of layers + * dest : the destination buffer + * len : the length of the destination buffer + * info_IM : structure to create an index file + */ +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[0].include); + free(pi); + if (e == -999) + return e; + else + return c - dest; +} + + + +/* + * 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) +{ + unsigned char *c = src; + pi_iterator_t *pi; + int pino, compno, e = 0; + int n = 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, + &cp->tcps[tileno], pi[pino].compno, + pi[pino].resno, pi[pino].precno, + pi[pino].layno); + + /* progression in resolution */ + img->comps[pi[pino].compno].resno_decoded = + e > 0 ? int_max(pi[pino].resno, + img->comps[pi[pino].compno]. + resno_decoded) : img->comps[pi[pino]. + compno].resno_decoded; + n++; + + 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[0].include); + free(pi); + + if (e == -999) + return e; + else + return c - src; +} diff --git a/jpwl/encoder/libopenjpeg/t2.h b/jpwl/encoder/libopenjpeg/t2.h new file mode 100644 index 00000000..795fb53f --- /dev/null +++ b/jpwl/encoder/libopenjpeg/t2.h @@ -0,0 +1,64 @@ +/* + * 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 + * tileno : number of the tile encoded + * tile : the tile for which to write the packets + * maxlayers : maximum number of layers + * dest : the destination buffer + * len : the length of the destination buffer + * info_IM : structure to create an index file + */ +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/jpwl/encoder/libopenjpeg/tcd.c b/jpwl/encoder/libopenjpeg/tcd.c new file mode 100644 index 00000000..f71aec7d --- /dev/null +++ b/jpwl/encoder/libopenjpeg/tcd.c @@ -0,0 +1,1601 @@ +/* + * Copyright (c) 2001-2002, David Janssens + * Copyright (c) 2002-2004, Yannick Verschueren + * Copyright (c) 2002-2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "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 y0=%d y1=%d\n", img->tw, img->th, + tcd_img->x0, tcd_img->x1, tcd_img->y0, tcd_img->y1); + for (tileno = 0; tileno < img->th*img->tw; tileno++) { + tcd_tile_t *tile = &tcd_image.tiles[tileno]; + 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] = + int_ceildiv(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); + + tilec->data = + (int *) malloc((tilec->x1 - tilec->x0) * + (tilec->y1 - tilec->y0) * sizeof(int)); + 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); + + 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); + + tile->numcomps = img->numcomps; + /* tile->PPT=img->PPT; */ + /* Modification of the RATE >> */ + for (j = 0; j < tcp->numlayers; j++) { + tcp->rates[j] = + int_ceildiv(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); + + tilec->data = + (int *) malloc((tilec->x1 - tilec->x0) * + (tilec->y1 - tilec->y0) * sizeof(int)); + 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); + + 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, i, j; + unsigned int x0 = 0, y0 = 0, x1 = 0, y1 = 0, w, h, p, q; + 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]; */ + + for (i = 0; i < cp->tileno_size; i++) { + j2k_tcp_t *tcp = &cp->tcps[cp->tileno[i]]; + tcd_tile_t *tile = &tcd_image.tiles[cp->tileno[i]]; + tileno = cp->tileno[i]; + + + // int previous_x0, previous_x1, previous_y0, previous_y1; + /* cfr p59 ISO/IEC FDIS15444-1 : 2000 (18 august 2000) */ + p = tileno % cp->tw; /* si numerotation matricielle .. */ + 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); + + 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); + + tilec->data = + (int *) malloc((tilec->x1 - tilec->x0) * + (tilec->y1 - tilec->y0) * sizeof(int)); + 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); + + 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 = (res->x0==res->x1)?0:((brprcxend - tlprcxstart) >> pdx); // Mod Antonin : sizebug1 + res->ph = (res->y0==res->y1)?0:((brprcyend - tlprcystart) >> pdy); // Mod Antonin : sizebug1 + + 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); + + + + cblk->lastbp = 0; // Add Antonin : quantizbug1 + } + } + } + } + } + } + //tcd_dump(&tcd_image,0); + + + /* Allocate place to store the data decoded = final image */ + /* Place limited by the tile really present in the codestream */ + + + for (i = 0; i < img->numcomps; i++) { + for (j = 0; j < cp->tileno_size; j++) { + tileno = cp->tileno[j]; + x0 = j == 0 ? tcd_image.tiles[tileno].comps[i].x0 : int_min(x0, + tcd_image. + tiles[tileno].comps[i].x0); + y0 = j == 0 ? tcd_image.tiles[tileno].comps[i].y0 : int_min(y0, + tcd_image. + tiles[tileno].comps[i].y0); + x1 = j == 0 ? tcd_image.tiles[tileno].comps[i].x1 : int_max(x1, + tcd_image. + tiles[tileno].comps[i].x1); + y1 = j == 0 ? tcd_image.tiles[tileno].comps[i].y1 : int_max(y1, + tcd_image. + tiles[tileno].comps[i].y1); + } + //w = int_ceildiv(x1 - x0, img->comps[i].dx); + //h = int_ceildiv(y1 - y0, img->comps[i].dy); + + w = x1 - x0; + + h = y1 - y0; + img->comps[i].data = (int *) calloc(w * h, sizeof(int)); + img->comps[i].w = w; + img->comps[i].h = h; + img->comps[i].x0 = x0; + img->comps[i].y0 = y0; + } +} + +void tcd_makelayer_fixed(int layno, int final) +{ + int compno, resno, bandno, precno, cblkno; + int value; //, matrice[tcd_tcp->numlayers][tcd_tile->comps[0].numresolutions][3]; + int matrice[10][10][3]; + int i, j, k; + + /*matrice=(int*)malloc(tcd_tcp->numlayers*tcd_tile->comps[0].numresolutions*3*sizeof(int)); */ + + for (compno = 0; compno < tcd_tile->numcomps; compno++) { + tcd_tilecomp_t *tilec = &tcd_tile->comps[compno]; + for (i = 0; i < tcd_tcp->numlayers; i++) { + for (j = 0; j < tilec->numresolutions; j++) { + for (k = 0; k < 3; k++) { + matrice[i][j][k] = + (int) (tcd_cp-> + matrice[i * tilec->numresolutions * 3 + + j * 3 + + 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 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 */ + + if (layno == 0) { + value = matrice[layno][resno][bandno]; + if (imsb >= value) + value = 0; + else + value -= imsb; + } else { + value = + matrice[layno][resno][bandno] - + matrice[layno - 1][resno][bandno]; + if (imsb >= matrice[layno - 1][resno][bandno]) { + value -= (imsb - matrice[layno - 1][resno][bandno]); + if (value < 0) + value = 0; + } + } + + if (layno == 0) + cblk->numpassesinlayers = 0; + + n = cblk->numpassesinlayers; + if (cblk->numpassesinlayers == 0) { + if (value != 0) + n = 3 * value - 2 + cblk->numpassesinlayers; + else + n = cblk->numpassesinlayers; + } else + n = 3 * value + cblk->numpassesinlayers; + + layer->numpasses = n - cblk->numpassesinlayers; + + if (!layer->numpasses) + continue; + + if (cblk->numpassesinlayers == 0) { + layer->len = cblk->passes[n - 1].rate; + layer->data = cblk->data; + } else { + layer->len = + cblk->passes[n - 1].rate - + cblk->passes[cblk->numpassesinlayers - 1].rate; + layer->data = + cblk->data + + cblk->passes[cblk->numpassesinlayers - 1].rate; + } + if (final) + cblk->numpassesinlayers = n; + } + } + } + } + } +} + +void tcd_rateallocate_fixed() +{ + int layno; + + for (layno = 0; layno < tcd_tcp->numlayers; layno++) { + tcd_makelayer_fixed(layno, 1); + } +} + +void tcd_makelayer(int layno, double thresh, int final) +{ + int compno, resno, bandno, precno, cblkno, passno; + + tcd_tile->distolayer[layno] = 0; //add fixed_quality + + 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) { + layer->disto = 0; + continue; + } + + if (cblk->numpassesinlayers == 0) { + layer->len = cblk->passes[n - 1].rate; + layer->data = cblk->data; + layer->disto = cblk->passes[n - 1].distortiondec; + } else { + layer->len = cblk->passes[n - 1].rate - + cblk->passes[cblk->numpassesinlayers - 1].rate; + layer->data = + cblk->data + + cblk->passes[cblk->numpassesinlayers - 1].rate; + layer->disto = + cblk->passes[n - 1].distortiondec - + cblk->passes[cblk->numpassesinlayers - 1].distortiondec; + } + + tcd_tile->distolayer[layno] += layer->disto; //add fixed_quality + + 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; + double cumdisto[100]; //add fixed_quality + const double K = 1; // 1.1; //add fixed_quality + + double maxSE = 0; + min = DBL_MAX; + max = 0; + + tcd_tile->nbpix = 0; //add fixed_quality + + for (compno = 0; compno < tcd_tile->numcomps; compno++) { + tcd_tilecomp_t *tilec = &tcd_tile->comps[compno]; + + tilec->nbpix = 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]; + 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 */ + + tcd_tile->nbpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0)); //add fixed_quality + + tilec->nbpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0)); //add fixed_quality + + } /* cbklno */ + } /* precno */ + } /* bandno */ + } /* resno */ + + maxSE+=(double)(((1<comps[compno].prec)-1)*((1<comps[compno].prec)-1))*(tilec->nbpix); + } /* compno */ + + /* add antonin index */ + if (info_IM->index_on) { + info_tile *info_TL = &info_IM->tile[tcd_tileno]; + info_TL->nbpix = tcd_tile->nbpix; + info_TL->distotile = tcd_tile->distotile; + info_TL->thresh = + (double *) malloc(tcd_tcp->numlayers * sizeof(double)); + } + /* dda */ + + 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; + double distotarget; //add fixed_quality + + distotarget = tcd_tile->distotile - ((K * maxSE) / pow(10, tcd_tcp->distoratio[layno] / 10)); // add fixed_quality + + for (i = 0; i < 32; i++) { + volatile double thresh = (lo + hi) / 2; + int l=0; + double distoachieved = 0; // add fixed_quality + + tcd_makelayer(layno, thresh, 0); + + if (tcd_cp->fixed_quality) { // add fixed_quality + distoachieved = + layno == + 0 ? tcd_tile->distolayer[0] : cumdisto[layno - 1] + + tcd_tile->distolayer[layno]; + if (distoachieved < distotarget) { + hi = thresh; + continue; + } + lo = thresh; + } else { + 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); + } + + if (info_IM->index_on) { /* Threshold for Marcela Index */ + info_IM->tile[tcd_tileno].thresh[layno] = goodthresh; + } + tcd_makelayer(layno, goodthresh, 1); + + cumdisto[layno] = + + layno == + + 0 ? tcd_tile->distolayer[0] : cumdisto[layno - 1] + + + tcd_tile->distolayer[layno]; // add fixed_quality + } +} + +int tcd_encode_tile_pxm(int tileno, unsigned char *dest, int len, + info_image * info_IM) +{ + int compno; + int l,i; + clock_t time7; + 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]; //Based on Component 0 + + for (i=0;inumresolutions;i++) { + + tcd_resolution_t *res_idx = &tilec_idx->resolutions[i]; + + info_IM->tile[tileno].pw[i] = res_idx->pw; + info_IM->tile[tileno].ph[i] = res_idx->ph; + + info_IM->tile[tileno].pdx[i] = tccp->prcw[i]; + info_IM->tile[tileno].pdy[i] = tccp->prch[i]; + + } + } + /* << INDEX */ + +/*---------------TILE-------------------*/ + + time7 = 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); + } + +/*----------------MCT-------------------*/ + + 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)); + } + } +/*----------------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); + } + } +/*------------------TIER1-----------------*/ + + t1_init_luts(); + t1_encode_cblks(tile, tcd_tcp); + +/*-----------RATE-ALLOCATE------------------*/ + info_IM->index_write = 0; /* INDEX */ + + if (tcd_cp->disto_alloc || tcd_cp->fixed_quality) // mod fixed_quality + /* Normal Rate/distortion allocation */ + tcd_rateallocate(dest, len, info_IM); + else + /* Fixed layer allocation */ + tcd_rateallocate_fixed(); + +/*--------------TIER2------------------*/ + info_IM->index_write = 1; /* INDEX */ + l = t2_encode_packets(tcd_img, tcd_cp, tileno, tile, + tcd_tcp->numlayers, dest, len, info_IM); +/*---------------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,i; + clock_t time; + 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]; //Based on Component 0 + + for (i=0;inumresolutions;i++) { + + tcd_resolution_t *res_idx = &tilec_idx->resolutions[i]; + + + + info_IM->tile[tileno].pw[i] = res_idx->pw; + + info_IM->tile[tileno].ph[i] = res_idx->ph; + + + + info_IM->tile[tileno].pdx[i] = tccp->prcw[i]; + + info_IM->tile[tileno].pdy[i] = tccp->prch[i]; + + } + + } + + /* << INDEX */ +/*---------------TILE-------------------*/ + time = 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); + } + +/*----------------MCT-------------------*/ + + 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)); + } + } + +/*----------------DWT---------------------*/ + + 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); + } + } + +/*------------------TIER1-----------------*/ + + t1_init_luts(); + t1_encode_cblks(tile, tcd_tcp); + +/*-----------RATE-ALLOCATE------------------*/ + + info_IM->index_write = 0; /* INDEX */ + + if (tcd_cp->disto_alloc || tcd_cp->fixed_quality) // mod fixed_quality + + /* Normal Rate/distortion allocation */ + + tcd_rateallocate(dest, len, info_IM); + + else + + /* Fixed layer allocation */ + + tcd_rateallocate_fixed(); + +/*--------------TIER2------------------*/ + info_IM->index_write = 1; /* INDEX */ + + l = t2_encode_packets(tcd_img, tcd_cp, tileno, tile, + tcd_tcp->numlayers, dest, len, info_IM); + + /*---------------CLEAN-------------------*/ + time = clock() - time; + printf("total: %ld.%.3ld s\n", time / CLOCKS_PER_SEC, + (time % 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 time; + tcd_tile_t *tile; + + tcd_tileno = tileno; + tcd_tile = &tcd_image.tiles[tileno]; + tcd_tcp = &tcd_cp->tcps[tileno]; + tile = tcd_tile; + + time = clock(); + + fprintf(stderr, "tile decoding time %d/%d: ", tileno + 1, + tcd_cp->tw * tcd_cp->th); + + /*--------------TIER2------------------*/ + + l = t2_decode_packets(src, len, tcd_img, tcd_cp, tileno, tile); + + if (l == -999) { + eof = 1; + fprintf(stderr, "tcd_decode: incomplete bistream\n"); + } + + /*------------------TIER1-----------------*/ + t1_init_luts(); + t1_decode_cblks(tile, tcd_tcp); + + /*----------------DWT---------------------*/ + + for (compno = 0; compno < tile->numcomps; compno++) { + tcd_tilecomp_t *tilec = &tile->comps[compno]; + if (tcd_cp->reduce_on == 1) { + tcd_img->comps[compno].resno_decoded = + tile->comps[compno].numresolutions - tcd_cp->reduce_value - 1; + } + + + if (tcd_tcp->tccps[compno].qmfbid == 1) { + dwt_decode(tilec->data, tilec->x1 - tilec->x0, + tilec->y1 - tilec->y0, tilec, + tilec->numresolutions - 1, + tilec->numresolutions - 1 - + tcd_img->comps[compno].resno_decoded); + } else { + dwt_decode_real(tilec->data, tilec->x1 - tilec->x0, + tilec->y1 - tilec->y0, tilec, + tilec->numresolutions - 1, + tilec->numresolutions - 1 - + tcd_img->comps[compno].resno_decoded); + } + + if (tile->comps[compno].numresolutions > 0) + tcd_img->comps[compno].factor = + tile->comps[compno].numresolutions - + (tcd_img->comps[compno].resno_decoded + 1); + } + + /*----------------MCT-------------------*/ + + if (tcd_tcp->mct) { + if (tcd_tcp->tccps[0].qmfbid == 1) { + mct_decode(tile->comps[0].data, tile->comps[1].data, + tile->comps[2].data, + (tile->comps[0].x1 - + tile->comps[0].x0) * (tile->comps[0].y1 - + tile->comps[0].y0)); + } else { + mct_decode_real(tile->comps[0].data, tile->comps[1].data, + tile->comps[2].data, + (tile->comps[0].x1 - + tile->comps[0].x0) * (tile->comps[0].y1 - + tile->comps[0].y0)); + } + } + + /*---------------TILE-------------------*/ + + for (compno = 0; compno < tile->numcomps; compno++) { + tcd_tilecomp_t *tilec = &tile->comps[compno]; + tcd_resolution_t *res = + &tilec->resolutions[tcd_img->comps[compno].resno_decoded]; + 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 = tcd_img->comps[compno].w; + + int i, j; + int offset_x = int_ceildivpow2(tcd_img->comps[compno].x0, + tcd_img->comps[compno].factor); + int offset_y = int_ceildivpow2(tcd_img->comps[compno].y0, + tcd_img->comps[compno].factor); + + for (j = res->y0; j < res->y1; j++) { + for (i = res->x0; i < res->x1; i++) { + + int v; + + double tmp= (double) tilec->data[i - res->x0 + (j - res->y0) * tw]; + if (tcd_tcp->tccps[compno].qmfbid == 1) { + v = (int) tmp; + } else { + + //v = (int) tmp >> 13; + + //Mod antonin : multbug1 + v = (int) ((fabs(tmp/8192.0)>=floor(fabs(tmp/8192.0))+0.5)?fabs(tmp/8192.0)+1.0:fabs(tmp/8192.0)); + + v = (tmp<0)?-v:v; + + //doM + } + v += adjust; + + tcd_img->comps[compno].data[(i - offset_x) + + (j - offset_y) * w] = + int_clamp(v, min, max); + } + } + } + + time = clock() - time; + fprintf(stderr, "total: %ld.%.3ld s\n", time / CLOCKS_PER_SEC, + (time % CLOCKS_PER_SEC) * 1000 / CLOCKS_PER_SEC); + + for (compno = 0; compno < tile->numcomps; compno++) { + free(tcd_image.tiles[tileno].comps[compno].data); + } + + if (eof) { + longjmp(j2k_error, 1); + } + + return l; +} diff --git a/jpwl/encoder/libopenjpeg/tcd.h b/jpwl/encoder/libopenjpeg/tcd.h new file mode 100644 index 00000000..6e64717d --- /dev/null +++ b/jpwl/encoder/libopenjpeg/tcd.h @@ -0,0 +1,182 @@ +/* + * 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; /* Number of passes in the layer */ + int len; /* len of information */ + double disto; /* add for index (Cfr. Marcela) */ + unsigned char *data; /* data */ +} tcd_layer_t; + +typedef struct { + int x0, y0, x1, y1; /* dimension of the code-blocks : left upper corner (x0, y0) right low corner (x1,y1) */ + int numbps; + int lastbp; /* Add antonin : quantizbug1 */ + int numlenbits; + int len; /* length */ + int numpasses; /* number of pass already done for the code-blocks */ + int numnewpasses; /* number of pass added to the code-blocks */ + int numsegs; /* number of segments */ + tcd_seg_t segs[100]; /* segments informations */ + unsigned char data[8192]; /* Data */ + int numpassesinlayers; /* number of passes in the layer */ + tcd_layer_t layers[100]; /* layer information */ + int totalpasses; /* total number of passes */ + tcd_pass_t passes[100]; /* information about the passes */ +} tcd_cblk_t; + +typedef struct { + int x0, y0, x1, y1; /* dimension of the precinct : left upper corner (x0, y0) right low corner (x1,y1) */ + int cw, ch; /* number of precinct in width and heigth */ + tcd_cblk_t *cblks; /* code-blocks informations */ + tgt_tree_t *incltree; /* inclusion tree */ + tgt_tree_t *imsbtree; /* IMSB tree */ +} tcd_precinct_t; + +typedef struct { + int x0, y0, x1, y1; /* dimension of the subband : left upper corner (x0, y0) right low corner (x1,y1) */ + int bandno; + tcd_precinct_t *precincts; /* precinct information */ + int numbps; + int stepsize; +} tcd_band_t; + +typedef struct { + int x0, y0, x1, y1; /* dimension of the resolution level : left upper corner (x0, y0) right low corner (x1,y1) */ + int pw, ph; + int numbands; /* number sub-band for the resolution level */ + tcd_band_t bands[3]; /* subband information */ +} tcd_resolution_t; + +typedef struct { + int x0, y0, x1, y1; /* dimension of component : left upper corner (x0, y0) right low corner (x1,y1) */ + int numresolutions; /* number of resolutions level */ + tcd_resolution_t *resolutions; /* resolutions information */ + int *data; /* data of the component */ + int nbpix; /* add fixed_quality */ +} tcd_tilecomp_t; + +typedef struct { + int x0, y0, x1, y1; /* dimension of the tile : left upper corner (x0, y0) right low corner (x1,y1) */ + int numcomps; /* number of components in tile */ + tcd_tilecomp_t *comps; /* Components information */ + int nbpix; /* add fixed_quality */ + double distotile; /* add fixed_quality */ + double distolayer[100]; /* add fixed_quality */ +} tcd_tile_t; + +typedef struct { + int tw, th; /* number of tiles in width and heigth */ + tcd_tile_t *tiles; /* Tiles information */ +} tcd_image_t; + +/* + * Initialize the tile coder (reuses the memory allocated by tcd_malloc_encode) + * img: raw image + * cp: coding parameters + * curtileno : number that identifies the tile that will be encoded + */ +void tcd_init_encode(j2k_image_t * img, j2k_cp_t * cp, int curtileno); + + +/* + * Initialize the tile coder (allocate the memory) + * img: raw image + * cp: coding parameters + * curtileno : number that identifies the tile that will be encoded + */ +void tcd_malloc_encode(j2k_image_t * img, j2k_cp_t * cp, int curtileno); + + +/* + * Initialize the tile decoder + * img: raw image + * cp: coding parameters + */ +void tcd_init(j2k_image_t * img, j2k_cp_t * cp); + + +/* + * Free the memory allocated for encoding + * img: raw image + * cp: coding parameters + * curtileno : number that identifies the tile that will be encoded + */ +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 + * info_IM: creation of index file + */ +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 + * info_IM: creation of index file + */ +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/jpwl/encoder/libopenjpeg/tgt.c b/jpwl/encoder/libopenjpeg/tgt.c new file mode 100644 index 00000000..0dfe9089 --- /dev/null +++ b/jpwl/encoder/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/jpwl/encoder/libopenjpeg/tgt.h b/jpwl/encoder/libopenjpeg/tgt.h new file mode 100644 index 00000000..d7b5ab7e --- /dev/null +++ b/jpwl/encoder/libopenjpeg/tgt.h @@ -0,0 +1,87 @@ +/* + * 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; + + + +/* + * Reset a tag-tree (set all leaves to 0) + * tree: tag-tree to reset + */ +void tgt_reset(tgt_tree_t * tree); + +/* + * 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); + +/* + * 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