diff --git a/codec/compat/getopt.c b/codec/compat/getopt.c index d0082c51..d5420acb 100644 --- a/codec/compat/getopt.c +++ b/codec/compat/getopt.c @@ -1,6 +1,6 @@ /* * Copyright (c) 1987, 1993, 1994 - * The Regents of the University of California. All rights reserved. + * 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 @@ -12,8 +12,8 @@ * 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. + * 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. @@ -34,48 +34,44 @@ /* 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 */ +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 */ +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 "" +#define BADCH (int)'?' +#define BADARG (int)':' +#define EMSG "" /* * getopt -- - * Parse argc/argv argument vector. + * Parse argc/argv argument vector. */ -int getopt(nargc, nargv, ostr) -int nargc; -char *const *nargv; -const char *ostr; -{ +int getopt(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 */ + static char *place = EMSG; /* option letter processing */ + char *oli; /* option letter list index */ - if (optreset || !*place) { /* update scanning pointer */ + if (optreset || !*place) { /* update scanning pointer */ optreset = 0; if (optind >= nargc || *(place = nargv[optind]) != '-') { place = EMSG; return (-1); } - if (place[1] && *++place == '-') { /* found "--" */ + if (place[1] && *++place == '-') { /* found "--" */ ++optind; place = EMSG; return (-1); } - } /* option letter okay? */ + } /* option letter okay? */ if ((optopt = (int) *place++) == (int) ':' || !(oli = strchr(ostr, optopt))) { /* @@ -88,29 +84,29 @@ const char *ostr; ++optind; if (opterr && *ostr != ':') (void) fprintf(stderr, - "%s: illegal option -- %c\n", __progname, optopt); + "%s: illegal option -- %c\n", __progname, optopt); return (BADCH); } - if (*++oli != ':') { /* don't need argument */ + if (*++oli != ':') { /* don't need argument */ optarg = NULL; if (!*place) ++optind; - } else { /* need an argument */ - if (*place) /* no white space */ + } else { /* need an argument */ + if (*place) /* no white space */ optarg = place; - else if (nargc <= ++optind) { /* no arg */ + else if (nargc <= ++optind) { /* no arg */ place = EMSG; if (*ostr == ':') - return (BADARG); + return (BADARG); if (opterr) - (void) fprintf(stderr, - "%s: option requires an argument -- %c\n", - __progname, optopt); + (void) fprintf(stderr, + "%s: option requires an argument -- %c\n", + __progname, optopt); return (BADCH); - } else /* white space */ + } else /* white space */ optarg = nargv[optind]; place = EMSG; ++optind; } - return (optopt); /* dump back option letter */ + return (optopt); /* dump back option letter */ } diff --git a/codec/compat/getopt.h b/codec/compat/getopt.h index ab9c1a7b..c2b4ddde 100644 --- a/codec/compat/getopt.h +++ b/codec/compat/getopt.h @@ -11,4 +11,4 @@ extern char *optarg; extern int getopt(int nargc, char *const *nargv, const char *ostr); -#endif /* _GETOPT_H_ */ +#endif /* _GETOPT_H_ */ diff --git a/codec/convert.c b/codec/convert.c index 427d7740..813a0601 100644 --- a/codec/convert.c +++ b/codec/convert.c @@ -1,7 +1,9 @@ /* * 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 + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,11 +28,41 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include #include #include -#include #include +#include "openjpeg.h" + +/* + * Get logarithm of an integer and round downwards. + * + * log2(a) + */ +static int int_floorlog2(int a) { + int l; + for (l = 0; a > 1; l++) { + a >>= 1; + } + return l; +} + +/* + * Divide an integer by a power of 2 and round upwards. + * + * a divided by 2^b + */ +static int int_ceildivpow2(int a, int b) { + return (a + (1 << b) - 1) >> b; +} + +/* + * Divide an integer and round upwards. + * + * a divided by b + */ +static int int_ceildiv(int a, int b) { + return (a + b - 1) / b; +} /* -->> -->> -->> -->> @@ -38,63 +70,66 @@ <<-- <<-- <<-- <<-- */ -/* UINT2 defines a two byte word */ -typedef unsigned short int UINT2; +/* WORD defines a two byte word */ +typedef unsigned short int WORD; -/* UINT4 defines a four byte word */ -typedef unsigned long int UINT4; +/* DWORD defines a four byte word */ +typedef unsigned long int DWORD; 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 */ + WORD bfType; /* 'BM' for Bitmap (19776) */ + DWORD bfSize; /* Size of the file */ + WORD bfReserved1; /* Reserved : 0 */ + WORD bfReserved2; /* Reserved : 0 */ + DWORD 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) */ + DWORD biSize; /* Size of the structure in bytes */ + DWORD biWidth; /* Width of the image in pixels */ + DWORD biHeight; /* Heigth of the image in pixels */ + WORD biPlanes; /* 1 */ + WORD biBitCount; /* Number of color bits by pixels */ + DWORD biCompression; /* Type of encoding 0: none 1: RLE8 2: RLE4 */ + DWORD biSizeImage; /* Size of the image in bytes */ + DWORD biXpelsPerMeter; /* Horizontal (X) resolution in pixels/meter */ + DWORD biYpelsPerMeter; /* Vertical (Y) resolution in pixels/meter */ + DWORD biClrUsed; /* Number of color used in the image (0: ALL) */ + DWORD 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]) -{ +opj_image_t* bmptoimage(char *filename, opj_cparameters_t *parameters) { + int subsampling_dx = parameters->subsampling_dx; + int subsampling_dy = parameters->subsampling_dy; + + int i, numcomps, w, h; + OPJ_COLOR_SPACE color_space; + opj_image_cmptparm_t cmptparm[3]; /* maximum of 3 components */ + opj_image_t * image = NULL; + 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; + unsigned int j, PAD, type = 0; - int i; + int x, y, index; int gray_scale = 1, not_end_file = 1; unsigned int line = 0, col = 0; unsigned char v, v2; - UINT4 W, H; - + DWORD W, H; + IN = fopen(filename, "rb"); if (!IN) { - fprintf(stderr, - "\033[0;33mFailed to open %s for reading !!\033[0;39m\n", - filename); + 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) { fprintf(stderr,"Error, not a BMP file!\n"); return 0; @@ -174,348 +209,422 @@ int bmptoimage(char *filename, j2k_image_t * img, int subsampling_dx, 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; + numcomps = 3; + color_space = CLRSPC_SRGB; + /* initialize image components */ + memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t)); + for(i = 0; i < numcomps; i++) { + cmptparm[i].prec = 8; + cmptparm[i].bpp = 8; + cmptparm[i].sgnd = 0; + cmptparm[i].dx = subsampling_dx; + cmptparm[i].dy = subsampling_dy; + cmptparm[i].w = w; + cmptparm[i].h = h; } - 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"); + /* create the image */ + image = opj_image_create(numcomps, &cmptparm[0], color_space); + if(!image) { + fclose(IN); + return NULL; } + /* set image offset and reference grid */ + image->x0 = parameters->image_offset_x0; + image->y0 = parameters->image_offset_y0; + image->x1 = !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1; + image->y1 = !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1; + + /* set image data */ + /* 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)); - + + RGB = (unsigned char *) malloc((3 * W + PAD) * H * sizeof(unsigned char)); + fread(RGB, sizeof(unsigned char), (3 * W + PAD) * H, IN); + + index = 0; - 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; - } - } + for(y = 0; y < (int)H; y++) { + unsigned char *scanline = RGB + (3 * W + PAD) * (H - 1 - y); + for(x = 0; x < (int)W; x++) { + unsigned char *pixel = &scanline[3 * x]; + image->comps[0].data[index] = pixel[2]; /* R */ + image->comps[1].data[index] = pixel[1]; /* G */ + image->comps[2].data[index] = pixel[0]; /* B */ + index++; + } } - 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; + } else if (Info_h.biBitCount == 8 && Info_h.biCompression == 0) { 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; + 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++; + W++; + + numcomps = gray_scale ? 1 : 3; + color_space = gray_scale ? CLRSPC_GRAY : CLRSPC_SRGB; + /* initialize image components */ + memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t)); + for(i = 0; i < numcomps; i++) { + cmptparm[i].prec = 8; + cmptparm[i].bpp = 8; + cmptparm[i].sgnd = 0; + cmptparm[i].dx = subsampling_dx; + cmptparm[i].dy = subsampling_dy; + cmptparm[i].w = w; + cmptparm[i].h = h; + } + /* create the image */ + image = opj_image_create(numcomps, &cmptparm[0], color_space); + if(!image) { + fclose(IN); + return NULL; + } + + /* set image offset and reference grid */ + image->x0 = parameters->image_offset_x0; + image->y0 = parameters->image_offset_y0; + image->x1 = !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1; + image->y1 = !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1; + + /* set image data */ 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; - } + index = 0; + for (j = 0; j < W * H; j++) { + if ((j % W < W - 1 && Info_h.biWidth % 2) || !(Info_h.biWidth % 2)) { + image->comps[0].data[index] = table_R[RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)]]; + index++; + } + } - 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); + } else { + index = 0; + for (j = 0; j < W * H; j++) { + if ((j % W < W - 1 && Info_h.biWidth % 2) || !(Info_h.biWidth % 2)) { + unsigned char pixel_index = RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)]; + image->comps[0].data[index] = table_R[pixel_index]; + image->comps[1].data[index] = table_G[pixel_index]; + image->comps[2].data[index] = table_B[pixel_index]; + index++; + } + } } 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; - + + } else if (Info_h.biBitCount == 8 && Info_h.biCompression == 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; + 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; } + numcomps = gray_scale ? 1 : 3; + color_space = gray_scale ? CLRSPC_GRAY : CLRSPC_SRGB; + /* initialize image components */ + memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t)); + for(i = 0; i < numcomps; i++) { + cmptparm[i].prec = 8; + cmptparm[i].bpp = 8; + cmptparm[i].sgnd = 0; + cmptparm[i].dx = subsampling_dx; + cmptparm[i].dy = subsampling_dy; + cmptparm[i].w = w; + cmptparm[i].h = h; + } + /* create the image */ + image = opj_image_create(numcomps, &cmptparm[0], color_space); + if(!image) { + fclose(IN); + return NULL; + } + + /* set image offset and reference grid */ + image->x0 = parameters->image_offset_x0; + image->y0 = parameters->image_offset_y0; + image->x1 = !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1; + image->y1 = !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1; + + /* set image data */ + /* 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)); - + + 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: - fprintf(stderr,"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); - } - } + 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: + fprintf(stderr,"No Delta supported\n"); + opj_image_destroy(image); + fclose(IN); + return NULL; + 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); + break; + } + } } 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); + index = 0; + for (line = 0; line < Info_h.biHeight; line++) { + for (col = 0; col < Info_h.biWidth; col++) { + image->comps[0].data[index] = table_R[(int)RGB[(Info_h.biHeight - line - 1) * Info_h.biWidth + col]]; + index++; + } + } } 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); + index = 0; + for (line = 0; line < Info_h.biHeight; line++) { + for (col = 0; col < Info_h.biWidth; col++) { + unsigned char pixel_index = (int)RGB[(Info_h.biHeight - line - 1) * Info_h.biWidth + col]; + image->comps[0].data[index] = table_R[pixel_index]; + image->comps[1].data[index] = table_G[pixel_index]; + image->comps[2].data[index] = table_B[pixel_index]; + index++; + } + } } 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; + } 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 image; } - /* -->> -->> -->> -->> +int imagetobmp(opj_image_t * image, char *outfile) { + int w, wr, h, hr; + int i, pad; + FILE *fdest = NULL; - PGX IMAGE FORMAT + if (image->numcomps == 3 && image->comps[0].dx == image->comps[1].dx + && image->comps[1].dx == image->comps[2].dx + && image->comps[0].dy == image->comps[1].dy + && image->comps[1].dy == image->comps[2].dy + && image->comps[0].prec == image->comps[1].prec + && image->comps[1].prec == image->comps[2].prec) { + + /* -->> -->> -->> -->> + 24 bits color + <<-- <<-- <<-- <<-- */ + + fdest = fopen(outfile, "wb"); + if (!fdest) { + fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile); + return 1; + } + + // w = int_ceildiv(image->x1 - image->x0, image->comps[0].dx); + // wr = int_ceildiv(int_ceildivpow2(image->x1 - image->x0,image->factor), image->comps[0].dx); + w = image->comps[0].w; + wr = int_ceildivpow2(image->comps[0].w, image->comps[0].factor); + + // h = int_ceildiv(image->y1 - image->y0, image->comps[0].dy); + // hr = int_ceildiv(int_ceildivpow2(image->y1 - image->y0,image->factor), image->comps[0].dy); + h = image->comps[0].h; + hr = int_ceildivpow2(image->comps[0].h, image->comps[0].factor); + + fprintf(fdest, "BM"); + + /* FILE HEADER */ + /* ------------- */ + fprintf(fdest, "%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(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (54) & 0xff, ((54) >> 8) & 0xff,((54) >> 16) & 0xff, ((54) >> 24) & 0xff); + + /* INFO HEADER */ + /* ------------- */ + fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff, ((40) >> 16) & 0xff, ((40) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (unsigned char) ((wr) & 0xff), + (unsigned char) ((wr) >> 8) & 0xff, + (unsigned char) ((wr) >> 16) & 0xff, + (unsigned char) ((wr) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (unsigned char) ((hr) & 0xff), + (unsigned char) ((hr) >> 8) & 0xff, + (unsigned char) ((hr) >> 16) & 0xff, + (unsigned char) ((hr) >> 24) & 0xff); + fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff); + fprintf(fdest, "%c%c", (24) & 0xff, ((24) >> 8) & 0xff); + fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); + fprintf(fdest, "%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(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); + fprintf(fdest, "%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 = image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; + R = image->comps[0].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)]; + // G = image->comps[1].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; + G = image->comps[1].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)]; + // B = image->comps[2].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; + B = image->comps[2].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)]; + fprintf(fdest, "%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(fdest, "%c", 0); + } + } + fclose(fdest); + } else { /* Gray-scale */ - <<-- <<-- <<-- <<-- */ + /* -->> -->> -->> -->> + 8 bits non code (Gray scale) + <<-- <<-- <<-- <<-- */ + + fdest = fopen(outfile, "wb"); + // w = int_ceildiv(image->x1 - image->x0, image->comps[0].dx); + // wr = int_ceildiv(int_ceildivpow2(image->x1 - image->x0,image->factor), image->comps[0].dx); + w = image->comps[0].w; + wr = int_ceildivpow2(image->comps[0].w, image->comps[0].factor); + + // h = int_ceildiv(image->y1 - image->y0, image->comps[0].dy); + // hr = int_ceildiv(int_ceildivpow2(image->y1 - image->y0,image->factor), image->comps[0].dy); + h = image->comps[0].h; + hr = int_ceildivpow2(image->comps[0].h, image->comps[0].factor); + + fprintf(fdest, "BM"); + + /* FILE HEADER */ + /* ------------- */ + fprintf(fdest, "%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(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (54 + 1024) & 0xff, ((54 + 1024) >> 8) & 0xff, + ((54 + 1024) >> 16) & 0xff, + ((54 + 1024) >> 24) & 0xff); + + /* INFO HEADER */ + /* ------------- */ + fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff, ((40) >> 16) & 0xff, ((40) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (unsigned char) ((wr) & 0xff), + (unsigned char) ((wr) >> 8) & 0xff, + (unsigned char) ((wr) >> 16) & 0xff, + (unsigned char) ((wr) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (unsigned char) ((hr) & 0xff), + (unsigned char) ((hr) >> 8) & 0xff, + (unsigned char) ((hr) >> 16) & 0xff, + (unsigned char) ((hr) >> 24) & 0xff); + fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff); + fprintf(fdest, "%c%c", (8) & 0xff, ((8) >> 8) & 0xff); + fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); + fprintf(fdest, "%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(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff); + } + + for (i = 0; i < 256; i++) { + fprintf(fdest, "%c%c%c%c", i, i, i, 0); + } + + for (i = 0; i < wr * hr; i++) { + /* a modifier !! */ + // fprintf(fdest, "%c", image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]); + fprintf(fdest, "%c", image->comps[0].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)]); + /*if (((i + 1) % w == 0 && w % 2)) + fprintf(fdest, "%c", 0); */ + if ((i + 1) % wr == 0) { + for (pad = wr % 4 ? 4 - wr % 4 : 0; pad > 0; pad--) /* ADD */ + fprintf(fdest, "%c", 0); + } + } + fclose(fdest); + + return 0; +} + +/* -->> -->> -->> -->> + +PGX IMAGE FORMAT + +<<-- <<-- <<-- <<-- */ unsigned char readuchar(FILE * f) @@ -549,179 +658,199 @@ unsigned int readuint(FILE * f, int bigendian) 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; +opj_image_t* pgxtoimage(char *filename, opj_cparameters_t *parameters) { + FILE *f = NULL; int w, h, prec; - int i, compno, bandno; - char str[256]; + int i, numcomps, max; + OPJ_COLOR_SPACE color_space; + opj_image_cmptparm_t cmptparm; // maximum of 1 component + opj_image_t * image = NULL; char endian1,endian2,sign; char signtmp[32]; char temp[32]; int bigendian; - j2k_comp_t *comp; + opj_image_comp_t *comp = NULL; - 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; + numcomps = 1; + color_space = CLRSPC_GRAY; + memset(&cmptparm, 0, sizeof(opj_image_cmptparm_t)); - comp = &img->comps[compno]; - sprintf(str, "%s", filename); - + max = 0; - f = fopen(str, "rb"); - if (!f) { - fprintf(stderr, "Failed to open %s for reading !\n", str); - return 0; - } - - - - fseek(f, 0, SEEK_SET); - - fscanf(f, "PG%[ \t]%c%c%[ \t+-]%d%[ \t]%d%[ \t]%d",temp,&endian1,&endian2,signtmp,&prec,temp,&w,temp,&h); - - - - i=0; - - sign='+'; - - while (signtmp[i]!='\0') { - - if (signtmp[i]=='-') sign='-'; - - i++; - - } - - - - fgetc(f); - if (endian1=='M' && endian2=='L') - bigendian = 1; - else if (endian2=='M' && endian1=='L') - bigendian = 0; - - else { - - fprintf(stderr, "Bad pgx header, please check input file\n"); - - return 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); - } - fclose(f); - fclose(src); - comp->bpp = int_floorlog2(max) + 1; + f = fopen(filename, "rb"); + if (!f) { + fprintf(stderr, "Failed to open %s for reading !\n", filename); + return NULL; } - return 1; + + fseek(f, 0, SEEK_SET); + fscanf(f, "PG%[ \t]%c%c%[ \t+-]%d%[ \t]%d%[ \t]%d",temp,&endian1,&endian2,signtmp,&prec,temp,&w,temp,&h); + + i=0; + sign='+'; + while (signtmp[i]!='\0') { + if (signtmp[i]=='-') sign='-'; + i++; + } + + fgetc(f); + if (endian1=='M' && endian2=='L') { + bigendian = 1; + } else if (endian2=='M' && endian1=='L') { + bigendian = 0; + } else { + fprintf(stderr, "Bad pgx header, please check input file\n"); + return NULL; + } + + /* initialize image component */ + + cmptparm.x0 = parameters->image_offset_x0; + cmptparm.y0 = parameters->image_offset_y0; + cmptparm.w = !cmptparm.x0 ? (w - 1) * parameters->subsampling_dx + 1 : cmptparm.x0 + (w - 1) * parameters->subsampling_dx + 1; + cmptparm.h = !cmptparm.y0 ? (h - 1) * parameters->subsampling_dy + 1 : cmptparm.y0 + (h - 1) * parameters->subsampling_dy + 1; + + if (sign == '-') { + cmptparm.sgnd = 1; + } else { + cmptparm.sgnd = 0; + } + cmptparm.prec = prec; + cmptparm.bpp = prec; + cmptparm.dx = parameters->subsampling_dx; + cmptparm.dy = parameters->subsampling_dy; + + /* create the image */ + image = opj_image_create(numcomps, &cmptparm, color_space); + if(!image) { + fclose(f); + return NULL; + } + /* set image offset and reference grid */ + image->x0 = cmptparm.x0; + image->y0 = cmptparm.x0; + image->x1 = cmptparm.w; + image->y1 = cmptparm.h; + + /* set image data */ + + comp = &image->comps[0]; + + for (i = 0; i < w * h; i++) { + int v; + 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; + comp->data[i] = v; + } + fclose(f); + comp->bpp = int_floorlog2(max) + 1; + + return image; +} + +int imagetopgx(opj_image_t * image, char *outfile) { + int w, wr, h, hr; + int i, j, compno; + FILE *fdest = NULL; + + for (compno = 0; compno < image->numcomps; compno++) { + opj_image_comp_t *comp = &image->comps[compno]; + char name[256]; + int nbytes = 0; + char *tmp = outfile; + while (*tmp) { + tmp++; + } + while (*tmp!='.') { + tmp--; + } + *tmp='\0'; + + if (image->numcomps > 1) { + sprintf(name, "%s-%d.pgx", outfile, compno); + } else { + sprintf(name, "%s.pgx", outfile); + } + fdest = fopen(name, "wb"); + if (!fdest) { + fprintf(stderr, "ERROR -> failed to open %s for writing\n", name); + return 1; + } + // w = int_ceildiv(image->x1 - image->x0, comp->dx); + // wr = int_ceildiv(int_ceildivpow2(image->x1 - image->x0,image->factor), comp->dx); + w = image->comps[compno].w; + wr = int_ceildivpow2(image->comps[compno].w, image->comps[compno].factor); + + // h = int_ceildiv(image->y1 - image->y0, comp->dy); + // hr = int_ceildiv(int_ceildivpow2(image->y1 - image->y0,image->factor), comp->dy); + h = image->comps[compno].h; + hr = int_ceildivpow2(image->comps[compno].h, image->comps[compno].factor); + + fprintf(fdest, "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 = image->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, fdest); + } + } + fclose(fdest); + } + + return 0; } /* -->> -->> -->> -->> - PNM IMAGE FORMAT +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; +opj_image_t* pnmtoimage(char *filename, opj_cparameters_t *parameters) { + int tdy = parameters->cp_tdy; + int subsampling_dx = parameters->subsampling_dx; + int subsampling_dy = parameters->subsampling_dy; + + FILE *f = NULL; + int i, compno, numcomps, w, h; + OPJ_COLOR_SPACE color_space; + opj_image_cmptparm_t cmptparm[3]; /* maximum of 3 components */ + opj_image_t * image = NULL; 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); + fprintf(stderr, "\033[0;33mFailed to open %s for reading !!\033[0;39m\n", filename); return 0; } @@ -729,222 +858,238 @@ int pnmtoimage(char *filename, j2k_image_t * img, int subsampling_dx, 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); - } + switch(value) { + case '2': /* greyscale image type */ + case '5': + { + numcomps = 1; + color_space = CLRSPC_GRAY; - 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; + fgetc(f); - 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; + if (fgetc(f) == '#') { + /* skip comments */ + fseek(f, 0, SEEK_SET); + if (value == '2') { + fscanf(f, "P2\n"); + } else if (value == '5') { + fscanf(f, "P5\n"); + } + fgets(comment, 256, f); + fscanf(f, "%d %d\n255", &w, &h); + } else { + fseek(f, 0, SEEK_SET); + if (value == '2') { + fscanf(f, "P2\n%d %d\n255", &w, &h); + } else if (value == '5') { + fscanf(f, "P5\n%d %d\n255", &w, &h); + } + } + + fgetc(f); /* */ + } + break; - 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); - } + case '3': /* RGB image type */ + case '6': + { + numcomps = 3; + color_space = CLRSPC_SRGB; - 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; + fgetc(f); - 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); + if (fgetc(f) == '#') { + /* skip comments */ + fseek(f, 0, SEEK_SET); + if (value == '3') { + fscanf(f, "P3\n"); + } else if (value == '6') { + fscanf(f, "P6\n"); + } + fgets(comment, 256, f); + fscanf(f, "%d %d\n255", &w, &h); + } else { + fseek(f, 0, SEEK_SET); + if (value == '3') { + fscanf(f, "P3\n%d %d\n255", &w, &h); + } else if (value == '6') { + fscanf(f, "P6\n%d %d\n255", &w, &h); + } + } + + fgetc(f); /* */ } + break; - 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; + default: + fclose(f); + return NULL; } + + /* initialize image components */ + memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t)); + for(i = 0; i < numcomps; i++) { + cmptparm[i].prec = 8; + cmptparm[i].bpp = 8; + cmptparm[i].sgnd = 0; + cmptparm[i].dx = subsampling_dx; + cmptparm[i].dy = subsampling_dy; + cmptparm[i].w = w; + cmptparm[i].h = h; + } + /* create the image */ + image = opj_image_create(numcomps, &cmptparm[0], color_space); + if(!image) { + fclose(f); + return NULL; + } + + /* set image offset and reference grid */ + image->x0 = parameters->image_offset_x0; + image->y0 = parameters->image_offset_y0; + image->x1 = parameters->image_offset_x0 + (w - 1) * subsampling_dx + 1; + image->y1 = parameters->image_offset_y0 + (h - 1) * subsampling_dy + 1; + + /* set image data */ + + if ((value == '2') || (value == '3')) { /* ASCII */ + for (i = 0; i < w * h; i++) { + for(compno = 0; compno < numcomps; compno++) { + unsigned int index = 0; + fscanf(f, "%d", &index); + /* compno : 0 = GREY, (0, 1, 2) = (R, G, B) */ + image->comps[compno].data[i] = index; + } + } + } else if ((value == '5') || (value == '6')) { /* BINARY */ + for (i = 0; i < w * h; i++) { + for(compno = 0; compno < numcomps; compno++) { + unsigned char index = 0; + fread(&index, 1, 1, f); + /* compno : 0 = GREY, (0, 1, 2) = (R, G, B) */ + image->comps[compno].data[i] = index; + } + } + } + fclose(f); - return 1; + + return image; +} + +int imagetopnm(opj_image_t * image, char *outfile) { + int w, wr, wrr, h, hr, hrr, max; + int i, compno; + int adjust; + FILE *fdest = NULL; + char S2; + char *tmp = outfile; + + while (*tmp) { + tmp++; + } + tmp--; + tmp--; + S2 = *tmp; + + if (image->numcomps == 3 && image->comps[0].dx == image->comps[1].dx + && image->comps[1].dx == image->comps[2].dx + && image->comps[0].dy == image->comps[1].dy + && image->comps[1].dy == image->comps[2].dy + && image->comps[0].prec == image->comps[1].prec + && image->comps[1].prec == image->comps[2].prec + && S2 !='g' && S2 !='G') { + + fdest = fopen(outfile, "wb"); + if (!fdest) { + fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile); + return 1; + } + + w = int_ceildiv(image->x1 - image->x0, image->comps[0].dx); + // wr = int_ceildiv(int_ceildivpow2(image->x1 - image->x0,image->factor),image->comps[0].dx); + wr = image->comps[0].w; + wrr = int_ceildivpow2(image->comps[0].w, image->comps[0].factor); + + h = int_ceildiv(image->y1 - image->y0, image->comps[0].dy); + // hr = int_ceildiv(int_ceildivpow2(image->y1 - image->y0,image->factor), image->comps[0].dy); + hr = image->comps[0].h; + hrr = int_ceildivpow2(image->comps[0].h, image->comps[0].factor); + + max = image->comps[0].prec > 8 ? 255 : (1 << image->comps[0].prec) - 1; + + image->comps[0].x0 = int_ceildivpow2(image->comps[0].x0 - int_ceildiv(image->x0, image->comps[0].dx), image->comps[0].factor); + image->comps[0].y0 = int_ceildivpow2(image->comps[0].y0 - int_ceildiv(image->y0, image->comps[0].dy), image->comps[0].factor); + + fprintf(fdest, "P6\n%d %d\n%d\n", wrr, hrr, max); + adjust = image->comps[0].prec > 8 ? image->comps[0].prec - 8 : 0; + for (i = 0; i < wrr * hrr; i++) { + int r, g, b; + unsigned char rc,gc,bc; + r = image->comps[0].data[i / wrr * wr + i % wrr]; + r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0); + rc = (unsigned char) ((r >> adjust)+((r >> (adjust-1))%2)); + + g = image->comps[1].data[i / wrr * wr + i % wrr]; + g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0); + gc = (unsigned char) ((g >> adjust)+((g >> (adjust-1))%2)); + + b = image->comps[2].data[i / wrr * wr + i % wrr]; + b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0); + bc = (unsigned char) ((b >> adjust)+((b >> (adjust-1))%2)); + + fprintf(fdest, "%c%c%c", rc, gc, bc); + } + fclose(fdest); + } else { + int ncomp=(S2=='g' || S2=='G')?1:image->numcomps; + if (image->numcomps>ncomp) { + fprintf(stderr,"WARNING -> [PGM files] Only the first component\n"); + fprintf(stderr," is written to the file\n"); + } + for (compno = 0; compno < ncomp; compno++) { + char name[256]; + if (ncomp > 1) { + sprintf(name, "%d.%s", compno, outfile); + } else { + sprintf(name, "%s", outfile); + } + + fdest = fopen(name, "wb"); + if (!fdest) { + fprintf(stderr, "ERROR -> failed to open %s for writing\n", name); + return 1; + } + + w = int_ceildiv(image->x1 - image->x0, image->comps[compno].dx); + // wr = int_ceildiv(int_ceildivpow2(image->x1 - image->x0,image->factor),image->comps[compno].dx); + wr = image->comps[compno].w; + wrr = int_ceildivpow2(image->comps[compno].w, image->comps[compno].factor); + + h = int_ceildiv(image->y1 - image->y0, image->comps[compno].dy); + // hr = int_ceildiv(int_ceildivpow2(image->y1 - image->y0,image->factor), image->comps[compno].dy); + hr = image->comps[compno].h; + hrr = int_ceildivpow2(image->comps[compno].h, image->comps[compno].factor); + + max = image->comps[compno].prec > 8 ? 255 : (1 << image->comps[compno].prec) - 1; + + image->comps[compno].x0 = int_ceildivpow2(image->comps[compno].x0 - int_ceildiv(image->x0, image->comps[compno].dx), image->comps[compno].factor); + image->comps[compno].y0 = int_ceildivpow2(image->comps[compno].y0 - int_ceildiv(image->y0, image->comps[compno].dy), image->comps[compno].factor); + + fprintf(fdest, "P5\n%d %d\n%d\n", wrr, hrr, max); + adjust = image->comps[compno].prec > 8 ? image->comps[compno].prec - 8 : 0; + + for (i = 0; i < wrr * hrr; i++) { + int l; + unsigned char lc; + l = image->comps[compno].data[i / wrr * wr + i % wrr]; + l += (image->comps[compno].sgnd ? 1 << (image->comps[compno].prec - 1) : 0); + lc = (unsigned char) ((l >> adjust)+((l >> (adjust-1))%2)); + fprintf(fdest, "%c", lc); + } + fclose(fdest); + } + } + + return 0; } diff --git a/codec/convert.h b/codec/convert.h index 337dae76..dfc447d7 100644 --- a/codec/convert.h +++ b/codec/convert.h @@ -1,7 +1,9 @@ /* * 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 + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,14 +28,27 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "j2k.h" -int bmptoimage(char *filename, j2k_image_t * img, int subsampling_dx, - int subsampling_dy, int Dim[2]); +#ifndef __J2K_CONVERT_H +#define __J2K_CONVERT_H -int pgxtoimage(char *filename, j2k_image_t * img, int tdy, - int subsampling_dx, int subsampling_dy, int Dim[2], - j2k_cp_t cp); +opj_image_t* bmptoimage(char *filename, opj_cparameters_t *parameters); + +int imagetobmp(opj_image_t *image, char *outfile); + +/** +Load a single image component encoded in PGX file format +@param filename Name of the PGX file to load +@param parameters *List ?* +@return Returns a greyscale image if successful, returns NULL otherwise +*/ +opj_image_t* pgxtoimage(char *filename, opj_cparameters_t *parameters); + +int imagetopgx(opj_image_t *image, char *outfile); + +opj_image_t* pnmtoimage(char *filename, opj_cparameters_t *parameters); + +int imagetopnm(opj_image_t *image, char *outfile); + +#endif /* __J2K_CONVERT_H */ -int pnmtoimage(char *filename, j2k_image_t * img, int subsampling_dx, - int subsampling_dy, int Dim[2]); diff --git a/codec/image_to_j2k.c b/codec/image_to_j2k.c index b73941fa..0c623e0b 100644 --- a/codec/image_to_j2k.c +++ b/codec/image_to_j2k.c @@ -1,7 +1,9 @@ /* * 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 + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,55 +29,41 @@ */ - -//MEMORY LEAK - -#ifdef _DEBUG - -#define _CRTDBG_MAP_ALLOC - -#include // Must be included first - -#include - -#endif - -//MEM - -#include #include -#include -#include #include -#ifndef DONT_HAVE_GETOPT -#include -#else +#include + +#include "openjpeg.h" #include "compat/getopt.h" -#endif #include "convert.h" -void help_display() -{ +#define J2K_CFMT 0 +#define JP2_CFMT 1 +#define JPT_CFMT 2 +#define MJ2_CFMT 3 +#define PXM_DFMT 0 +#define PGX_DFMT 1 +#define BMP_DFMT 2 +#define YUV_DFMT 3 + +/* ----------------------------------------------------------------------- */ + +void encode_help_display() { fprintf(stdout,"HELP\n----\n\n"); fprintf(stdout,"- the -h option displays this help information on screen\n\n"); - fprintf(stdout,"List of parameters for the coder JPEG 2000:\n"); + fprintf(stdout,"List of parameters for the JPEG 2000 encoder:\n"); fprintf(stdout,"\n"); fprintf(stdout,"REMARKS:\n"); fprintf(stdout,"---------\n"); fprintf(stdout,"\n"); - fprintf - (stdout,"The markers written to the main_header are : SOC SIZ COD QCD COM.\n"); - fprintf - (stdout,"COD and QCD never appear in the tile_header.\n"); + fprintf(stdout,"The markers written to the main_header are : SOC SIZ COD QCD COM.\n"); + fprintf(stdout,"COD and QCD never appear in the tile_header.\n"); fprintf(stdout,"\n"); - fprintf - (stdout,"- This coder can encode a mega image, a test was made on a 24000x24000 pixels \n"); - fprintf - (stdout,"color image. You need enough disk space memory (twice the original) to encode \n"); - fprintf - (stdout,"the image,i.e. for a 1.5 GB image you need a minimum of 3GB of disk memory)\n"); + fprintf(stdout,"- This coder can encode a mega image, a test was made on a 24000x24000 pixels \n"); + fprintf(stdout,"color image. You need enough disk space memory (twice the original) to encode \n"); + fprintf(stdout,"the image,i.e. for a 1.5 GB image you need a minimum of 3GB of disk memory)\n"); fprintf(stdout,"\n"); fprintf(stdout,"By default:\n"); fprintf(stdout,"------------\n"); @@ -99,25 +87,21 @@ void help_display() fprintf(stdout,"Parameters:\n"); fprintf(stdout,"------------\n"); fprintf(stdout,"\n"); - fprintf - (stdout,"Required Parameters (except with -h):\n"); + fprintf(stdout,"Required Parameters (except with -h):\n"); fprintf(stdout,"\n"); - fprintf - (stdout,"-i : source file (-i source.pnm also *.pgm, *.ppm) \n"); + fprintf(stdout,"-i : source file (-i source.pnm also *.pgm, *.ppm) \n"); fprintf(stdout,"\n"); - fprintf - (stdout,"-o : destination file (-o dest.j2k or .jp2) \n"); + fprintf(stdout,"-o : destination file (-o dest.j2k or .jp2) \n"); fprintf(stdout,"\n"); - fprintf - (stdout,"Optional Parameters:\n"); + fprintf(stdout,"Optional Parameters:\n"); fprintf(stdout,"\n"); fprintf(stdout,"-h : display the help information \n "); fprintf(stdout,"\n"); fprintf(stdout,"-r : different compression ratios for successive layers (-r 20,10,5)\n "); - fprintf(stdout," - The rate specified for each quality level is the desired \n"); - fprintf(stdout," compression factor.\n"); - fprintf(stdout," Example: -r 20,10,1 means quality 1: compress 20x, \n"); - fprintf(stdout," quality 2: compress 10x and quality 3: compress lossless\n"); + fprintf(stdout," - The rate specified for each quality level is the desired \n"); + fprintf(stdout," compression factor.\n"); + fprintf(stdout," Example: -r 20,10,1 means quality 1: compress 20x, \n"); + fprintf(stdout," quality 2: compress 10x and quality 3: compress lossless\n"); fprintf(stdout,"\n"); fprintf(stdout," (options -r and -q cannot be used together)\n "); fprintf(stdout,"\n"); @@ -135,43 +119,29 @@ void help_display() fprintf(stdout,"\n"); fprintf(stdout,"-t : size of tile (-t 512,512) \n"); fprintf(stdout,"\n"); - fprintf - (stdout,"-p : progression order (-p LRCP) [LRCP, RLCP, RPCL, PCRL, CPRL] \n"); + fprintf(stdout,"-p : progression order (-p LRCP) [LRCP, RLCP, RPCL, PCRL, CPRL] \n"); fprintf(stdout,"\n"); - fprintf - (stdout,"-s : subsampling factor (-s 2,2) [-s X,Y] \n"); - fprintf(stdout," Remark: subsampling bigger than 2 can produce error\n"); + fprintf(stdout,"-s : subsampling factor (-s 2,2) [-s X,Y] \n"); + fprintf(stdout," Remark: subsampling bigger than 2 can produce error\n"); fprintf(stdout,"\n"); - fprintf - (stdout,"-SOP : write SOP marker before each packet \n"); + fprintf(stdout,"-SOP : write SOP marker before each packet \n"); fprintf(stdout,"\n"); - fprintf - (stdout,"-EPH : write EPH marker after each header packet \n"); + fprintf(stdout,"-EPH : write EPH marker after each header packet \n"); fprintf(stdout,"\n"); - fprintf - (stdout,"-M : mode switch (-M 3) [1=BYPASS(LAZY) 2=RESET 4=RESTART(TERMALL)\n"); - fprintf - (stdout," 8=VSC 16=ERTERM(SEGTERM) 32=SEGMARK(SEGSYM)] \n"); - fprintf - (stdout," Indicate multiple modes by adding their values. \n"); - fprintf - (stdout," ex: RESTART(4) + RESET(2) + SEGMARK(32) = -M 38\n"); + fprintf(stdout,"-M : mode switch (-M 3) [1=BYPASS(LAZY) 2=RESET 4=RESTART(TERMALL)\n"); + fprintf(stdout," 8=VSC 16=ERTERM(SEGTERM) 32=SEGMARK(SEGSYM)] \n"); + fprintf(stdout," Indicate multiple modes by adding their values. \n"); + fprintf(stdout," ex: RESTART(4) + RESET(2) + SEGMARK(32) = -M 38\n"); fprintf(stdout,"\n"); - fprintf - (stdout,"-x : create an index file *.Idx (-x index_name.Idx) \n"); + fprintf(stdout,"-x : create an index file *.Idx (-x index_name.Idx) \n"); fprintf(stdout,"\n"); - fprintf - (stdout,"-ROI : c=%%d,U=%%d : quantization indices upshifted \n"); - fprintf - (stdout," for component c=%%d [%%d = 0,1,2]\n"); - fprintf - (stdout," with a value of U=%%d [0 <= %%d <= 37] (i.e. -ROI:c=0,U=25) \n"); + fprintf(stdout,"-ROI : c=%%d,U=%%d : quantization indices upshifted \n"); + fprintf(stdout," for component c=%%d [%%d = 0,1,2]\n"); + fprintf(stdout," with a value of U=%%d [0 <= %%d <= 37] (i.e. -ROI:c=0,U=25) \n"); fprintf(stdout,"\n"); - fprintf - (stdout,"-d : offset of the origin of the image (-d 150,300) \n"); + fprintf(stdout,"-d : offset of the origin of the image (-d 150,300) \n"); fprintf(stdout,"\n"); - fprintf - (stdout,"-T : offset of the origin of the tiles (-T 100,75) \n"); + fprintf(stdout,"-T : offset of the origin of the tiles (-T 100,75) \n"); fprintf(stdout,"\n"); fprintf(stdout,"-I : use the irreversible DWT 9-7 (-I) \n"); fprintf(stdout,"\n"); @@ -204,801 +174,618 @@ void help_display() fprintf(stdout,"TotalDisto\n\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; - } - } - } +OPJ_PROG_ORDER give_progression(char progression[4]) { + if(strncmp(progression, "LRCP", 4) == 0) { + return LRCP; + } + if(strncmp(progression, "RLCP", 4) == 0) { + return RLCP; + } + if(strncmp(progression, "RPCL", 4) == 0) { + return RPCL; + } + if(strncmp(progression, "PCRL", 4) == 0) { + return PCRL; + } + if(strncmp(progression, "CPRL", 4) == 0) { + return CPRL; + } + + return PROG_UNKNOWN; +} + +int get_file_format(char *filename) { + int i; + static const char *extension[] = {"pgx", "pnm", "pgm", "ppm", "bmp", "j2k", "jp2" }; + static const int format[] = { PGX_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, BMP_DFMT, J2K_CFMT, JP2_CFMT }; + char * ext = strrchr(filename, '.') + 1; + for(i = 0; i < sizeof(format); i++) { + if(strnicmp(ext, extension[i], 3) == 0) { + return format[i]; } } + + 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; -} +int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters) { + int i, j; -void encode_stepsize(float stepsize, int numbps, int *expn, int *mant) -{ - int p, n, stepsizeTMP; - stepsizeTMP=(int) floor(stepsize * 8192.0); - p = floorlog2(stepsizeTMP) - 13; - n = 11 - floorlog2(stepsizeTMP); - *mant = (n < 0 ? stepsizeTMP >> -n : stepsizeTMP << 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++) { - float 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(stepsize, 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 *j2k_codestream; - char *jp2_codestream; - FILE *f; - int depth_0, sign, depth; - - - /* 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; + /* parse the command line */ 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"); + 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++; + case 'i': /* input file */ + { + char *infile = optarg; + parameters->decod_format = get_file_format(infile); + switch(parameters->decod_format) { + case PGX_DFMT: + case PXM_DFMT: + case BMP_DFMT: + break; + default: + fprintf(stderr, + "!! Unrecognized format for infile : %s [accept only *.pnm, *.pgm, *.ppm, *.pgx or *.bmp] !!\n\n", + infile); + return 1; + break; + } + strncpy(parameters->infile, infile, MAX_PATH); } - s--; - S3 = *s; - s--; - S2 = *s; - s--; - S1 = *s; + break; + + /* ----------------------------------------------------- */ - if ((S1 == 'p' && S2 == 'g' && S3 == 'x') - || (S1 == 'P' && S2 == 'G' && S3 == 'X')) { - cp.decod_format = PGX_DFMT; - break; + case 'o': /* output file */ + { + char *outfile = optarg; + parameters->cod_format = get_file_format(outfile); + switch(parameters->cod_format) { + case J2K_CFMT: + case JP2_CFMT: + break; + default: + fprintf(stderr, "Unknown output format image %s [only *.j2k, *.jp2]!! \n", outfile); + return 1; + break; + } + strncpy(parameters->outfile, outfile, MAX_PATH); } + 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.decod_format = PXM_DFMT; - break; + /* ----------------------------------------------------- */ + + case 'r': /* rates rates/distorsion */ + { + char *s = optarg; + while (sscanf(s, "%d", ¶meters->tcp_rates[parameters->tcp_numlayers]) == 1) { + parameters->tcp_numlayers++; + while (*s && *s != ',') { + s++; + } + if (!*s) + break; + s++; + } + parameters->cp_disto_alloc = 1; } + break; + + /* ----------------------------------------------------- */ + + case 'q': /* add fixed_quality */ + { + char *s = optarg; + while (sscanf(s, "%f", ¶meters->tcp_distoratio[parameters->tcp_numlayers]) == 1) { + parameters->tcp_numlayers++; + while (*s && *s != ',') { + s++; + } + if (!*s) + break; + s++; + } + parameters->cp_fixed_quality = 1; + } + break; + + /* dda */ + /* ----------------------------------------------------- */ - if ((S1 == 'b' && S2 == 'm' && S3 == 'p') - || (S1 == 'B' && S2 == 'M' && S3 == 'P')) { - cp.decod_format = BMP_DFMT; - 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; + case 'f': /* mod fixed_quality (before : -q) */ + { + int *row = NULL, *col = NULL; + int numlayers = 0, numresolution = 0, matrix_width = 0; - outfile = optarg; + char *s = optarg; + sscanf(s, "%d", &numlayers); + s++; + if (numlayers > 9) + s++; - if ((S1 == 'j' && S2 == '2' && S3 == 'k') - || (S1 == 'J' && S2 == '2' && S3 == 'K')) - cp.cod_format = J2K_CFMT; - else if ((S1 == 'j' && S2 == 'p' && S3 == '2') - || (S1 == 'J' && S2 == 'P' && S3 == '2')) - cp.cod_format = JP2_CFMT; - else { - fprintf(stderr, - "Unknown output format image *.%c%c%c [only *.j2k, *.jp2]!! \n", - S1, S2, S3); - return 1; - } + parameters->tcp_numlayers = numlayers; + numresolution = parameters->numresolution; + matrix_width = numresolution * 3; + parameters->cp_matrice = (int *) malloc(numlayers * matrix_width * sizeof(int)); + s = s + 2; + for (i = 0; i < numlayers; i++) { + row = ¶meters->cp_matrice[i * matrix_width]; + col = row; + parameters->tcp_rates[i] = 1; + sscanf(s, "%d,", &col[0]); + s += 2; + if (col[0] > 9) + s++; + col[1] = 0; + col[2] = 0; + for (j = 1; j < numresolution; j++) { + col += 3; + sscanf(s, "%d,%d,%d", &col[0], &col[1], &col[2]); + s += 6; + if (col[0] > 9) + s++; + if (col[1] > 9) + s++; + if (col[2] > 9) + s++; + } + if (i < numlayers - 1) + s++; + } + parameters->cp_fixed_alloc = 1; + } + break; + + /* ----------------------------------------------------- */ + case 't': /* tiles */ + { + sscanf(optarg, "%d,%d", ¶meters->cp_tdx, ¶meters->cp_tdy); + parameters->tile_size_on = true; + } + break; + + /* ----------------------------------------------------- */ + + case 'n': /* resolution */ + { + sscanf(optarg, "%d", ¶meters->numresolution); + } + break; + + /* ----------------------------------------------------- */ + case 'c': /* precinct dimension */ + { + char sep; + int res_spec = 0; - 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; + char *s = optarg; + do { + sep = 0; + sscanf(s, "[%d,%d]%c", ¶meters->prcw_init[res_spec], ¶meters->prch_init[res_spec], &sep); + parameters->csty |= 0x01; + res_spec++; + s = strpbrk(s, "]") + 2; + } + while (sep == ','); + parameters->res_spec = res_spec; } 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++; + + /* ----------------------------------------------------- */ + + case 'b': /* code-block dimension */ + { + int cblockw_init = 0, cblockh_init = 0; + 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; + } + parameters->cblockw_init = cblockw_init; + parameters->cblockh_init = cblockh_init; } - Prog_order = give_progression(progression); + break; + + /* ----------------------------------------------------- */ + + case 'x': /* creation of index file */ + { + char *index = optarg; + strncpy(parameters->index, index, MAX_PATH); + parameters->index_on = 1; + } + break; + + /* ----------------------------------------------------- */ + + case 'p': /* progression order */ + { + char progression[4]; - if (Prog_order == -1) { - fprintf(stderr, - "Unrecognized progression order [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n"); - return 1; + strncpy(progression, optarg, 4); + parameters->prog_order = give_progression(progression); + if (parameters->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; + + /* ----------------------------------------------------- */ + + case 's': /* subsampling factor */ + { + if (sscanf(optarg, "%d,%d", ¶meters->subsampling_dx, ¶meters->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; + + /* ----------------------------------------------------- */ + + case 'd': /* coordonnate of the reference grid */ + { + if (sscanf(optarg, "%d,%d", ¶meters->image_offset_x0, ¶meters->image_offset_y0) != 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; + + /* ----------------------------------------------------- */ + + case 'h': /* display an help description */ + { + encode_help_display(); + return 1; + } 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++; + case 'P': /* POC */ + { + int numpocs = 0; /* number of progression order change (POC) default 0 */ + opj_poc_t *POC = NULL; /* POC : used in case of Progression order change */ + + char *s = optarg; + POC = parameters->POC; + + fprintf(stderr, "/----------------------------------\\\n"); + fprintf(stderr, "| POC option not fully tested !! |\n"); + fprintf(stderr, "\\----------------------------------/\n"); + + 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++; + } + parameters->numpocs = numpocs; } 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); - } + + /* ------------------------------------------------------ */ + + case 'S': /* SOP marker */ + { + parameters->csty |= 0x02; } 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; + + /* ------------------------------------------------------ */ + + case 'E': /* EPH marker */ + { + parameters->csty |= 0x04; } 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; + + /* ------------------------------------------------------ */ + + case 'M': /* Mode switch pas tous au point !! */ + { + int value = 0; + if (sscanf(optarg, "%d", &value) == 1) { + for (i = 0; i <= 5; i++) { + int cache = value & (1 << i); + if (cache) + parameters->mode |= (1 << i); + } + } } break; - /* ------------------------------------------------------ */ - case 'C': /* Add a comment */ - cp.comment = optarg; + + /* ------------------------------------------------------ */ + + case 'R': /* ROI */ + { + if (sscanf(optarg, "OI:c=%d,U=%d", ¶meters->roi_compno, ¶meters->roi_shift) != 2) { + fprintf(stderr, "ROI error !! [-ROI:c='compno',U='shift']\n"); + return 1; + } + } break; - /* ------------------------------------------------------ */ - case 'I': /* reversible or not */ - ir = 1; + + /* ------------------------------------------------------ */ + + case 'T': /* Tile offset */ + { + if (sscanf(optarg, "%d,%d", ¶meters->cp_tx0, ¶meters->cp_ty0) != 2) { + fprintf(stderr, "-T 'tile offset' argument error !! [-T X0,Y0]"); + return 1; + } + } break; - /* ------------------------------------------------------ */ - default: - return 1; + + /* ------------------------------------------------------ */ + + case 'C': /* add a comment */ + { + parameters->cp_comment = (char*)malloc(strlen(optarg) + 1); + if(parameters->cp_comment) { + strcpy(parameters->cp_comment, optarg); + } + } + break; + + /* ------------------------------------------------------ */ + + case 'I': /* reversible or not */ + { + parameters->irreversible = 1; + } + break; + + /* ------------------------------------------------------ */ + + default: + fprintf(stderr, "ERROR -> this option is not valid \"-%c %s\"\n", c, optarg); + return 1; } } - cp.tx0 = TX0; - cp.ty0 = TY0; + /* check for possible errors */ - /* Error messages */ - /* -------------- */ - if (!infile || !outfile) { - fprintf(stderr, - "usage: image_to_j2k -i image-file -o j2k/jp2-file (+ options)\n"); + if((parameters->infile[0] == 0) || (parameters->outfile[0] == 0)) { + 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 cannot be used together !!\n"); + if ((parameters->cp_disto_alloc || parameters->cp_fixed_alloc || parameters->cp_fixed_quality) + && (!(parameters->cp_disto_alloc ^ parameters->cp_fixed_alloc ^ parameters->cp_fixed_quality))) { + fprintf(stderr, "Error: options -r -q and -f cannot be used together !!\n"); return 1; - } // mod fixed_quality + } /* mod fixed_quality */ /* if no rate entered, lossless by default */ - if (tcp_init->numlayers == 0) { - tcp_init->rates[0] = 0; //MOD antonin : losslessbug - tcp_init->numlayers++; - cp.disto_alloc = 1; + if (parameters->tcp_numlayers == 0) { + parameters->tcp_rates[0] = 0; /* MOD antonin : losslessbug */ + parameters->tcp_numlayers++; + parameters->cp_disto_alloc = 1; } - if (TX0 > Dim[0] || TY0 > Dim[1]) { + if((parameters->cp_tx0 > parameters->image_offset_x0) || (parameters->cp_ty0 > parameters->image_offset_y0)) { 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]); + "Error: Tile offset dimension is unnappropriate --> TX0(%d)<=IMG_X0(%d) TYO(%d)<=IMG_Y0(%d) \n", + parameters->cp_tx0, parameters->image_offset_x0, parameters->cp_ty0, parameters->image_offset_y0); return 1; } - for (i = 0; i < numpocs; i++) { - if (POC[i].prg == -1) { + for (i = 0; i < parameters->numpocs; i++) { + if (parameters->POC[i].prg == -1) { fprintf(stderr, - "Unrecognized progression order in option -P (POC n %d) [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n", - i + 1); + "Unrecognized progression order in option -P (POC n %d) [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n", + i + 1); } } - switch (cp.decod_format) { - case PGX_DFMT: - 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 PXM_DFMT: - if (!pnmtoimage(infile, &img, subsampling_dx, subsampling_dy, Dim)) { - fprintf(stderr, " not a pnm file\n"); - return 1; - } - break; - - case BMP_DFMT: - 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_data_first = 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_data_first = 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.cod_format == J2K_CFMT) { /* 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 { - j2k_codestream = (char *) malloc(cp.tdx * cp.tdy * cp.tw * cp.th * 2); - /* Allocate memory for all tiles */ - cio_init(j2k_codestream, cp.tdx * cp.tdy * cp.tw * cp.th * 2); - len = - j2k_encode(&img, &cp, j2k_codestream, - 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(j2k_codestream, 1, len, f); - free(j2k_codestream); - fclose(f); - } - } else { /* JP2 format output */ - jp2_struct_t *jp2_struct; - - if (cp.intermed_file == 1) { - /*For the moment, JP2 format does not use intermediary - files for each tile */ - cp.intermed_file = 0; - } - j2k_codestream = (char *) malloc(cp.tdx * cp.tdy * cp.tw * cp.th * 2); - jp2_codestream = (char *) malloc(cp.tdx * cp.tdy * cp.tw * cp.th * 2); - - cio_init(j2k_codestream, cp.tdx * cp.tdy * cp.tw * cp.th * 2); - len = j2k_encode(&img, &cp, j2k_codestream, - cp.tdx * cp.tdy * cp.tw * cp.th * 2, index); - if (len == 0) { - fprintf(stderr, "failed to encode image\n"); - return 1; - } - - jp2_struct = (jp2_struct_t *) malloc(sizeof(jp2_struct_t)); - jp2_struct->image = &img; - jp2_struct->j2k_codestream_len = len; - - /* Initialising the standard JP2 box content */ - /* If you wish to modify those boxes, you have to modify - the jp2_struct content */ - - jp2_struct->numcomps = img.numcomps; // NC - - if (jp2_init_stdjp2(jp2_struct)) { - fprintf(stderr, "Error with jp2 initialization"); - return 1; - }; - - jp2_struct->h = img.y1 - img.y0; // HEIGHT - jp2_struct->w = img.x1 - img.x0; // WIDTH - - 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; - } - - for (i = 0; i < img.numcomps; i++) - jp2_struct->comps[i].bpcc = - img.comps[i].prec - 1 + (img.comps[i].sgnd << 7); - - 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 (??) - - cio_init(jp2_codestream, cp.tdx * cp.tdy * cp.tw * cp.th * 2); - len = jp2_wrap_j2k(jp2_struct, j2k_codestream, jp2_codestream); - f = fopen(outfile, "wb"); - if (!f) { - fprintf(stderr, "failed to open %s for writing\n", outfile); - return 1; - } - fwrite(jp2_codestream, 1, len, f); - free(jp2_codestream); - free(j2k_codestream); - free(jp2_struct->comps); - free(jp2_struct->cl); - free(jp2_struct); - fclose(f); - } - - /* Remove the temporary files */ - /* -------------------------- */ - if (cp.decod_format != PGX_DFMT) { /* PNM PGM PPM or BMP */ - 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); - - - - - - //MEMORY LEAK - - #ifdef _DEBUG - - _CrtDumpMemoryLeaks(); - - #endif - - //MEM - return 0; } + +/* -------------------------------------------------------------------------- */ + +/** +sample error callback expecting a FILE* client object +*/ +void error_callback(const char *msg, void *client_data) { + FILE *stream = (FILE*)client_data; + fprintf(stream, "[ERROR] %s", msg); +} +/** +sample warning callback expecting a FILE* client object +*/ +void warning_callback(const char *msg, void *client_data) { + FILE *stream = (FILE*)client_data; + fprintf(stream, "[WARNING] %s", msg); +} +/** +sample debug callback expecting a FILE* client object +*/ +void info_callback(const char *msg, void *client_data) { + FILE *stream = (FILE*)client_data; + fprintf(stream, "[INFO] %s", msg); +} + +/* -------------------------------------------------------------------------- */ + +int main(int argc, char **argv) { + bool bSuccess; + bool delete_comment = true; + opj_cparameters_t parameters; /* compression parameters */ + opj_event_mgr_t event_mgr; /* event manager */ + opj_image_t *image = NULL; + + /* + configure the event callbacks (not required) + setting of each callback is optionnal + */ + memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); + event_mgr.error_handler = error_callback; + event_mgr.warning_handler = warning_callback; + event_mgr.info_handler = info_callback; + + /* set encoding parameters to default values */ + opj_set_default_encoder_parameters(¶meters); + + /* parse input and get user encoding parameters */ + if(parse_cmdline_encoder(argc, argv, ¶meters) == 1) { + return 0; + } + + if(parameters.cp_comment == NULL) { + parameters.cp_comment = "Created by OpenJPEG version 0.9"; + /* no need to delete parameters.cp_comment on exit */ + delete_comment = false; + } + + /* decode the source image */ + /* ----------------------- */ + + switch (parameters.decod_format) { + case PGX_DFMT: + image = pgxtoimage(parameters.infile, ¶meters); + if (!image) { + fprintf(stderr, " unable to load pgx file\n"); + return 1; + } + break; + + case PXM_DFMT: + image = pnmtoimage(parameters.infile, ¶meters); + if (!image) { + fprintf(stderr, " not a pnm file\n"); + return 1; + } + break; + + case BMP_DFMT: + image = bmptoimage(parameters.infile, ¶meters); + if (!image) { + fprintf(stderr, " not a bmp file\n"); + return 1; + } + break; + } + + /* encode the destination image */ + /* ---------------------------- */ + + if (parameters.cod_format == J2K_CFMT) { /* J2K format output */ + int codestream_length; + opj_cio_t *cio = NULL; + FILE *f = NULL; + + /* get a J2K compressor handle */ + opj_cinfo_t* cinfo = opj_create_compress(CODEC_J2K); + + /* catch events using our callbacks and give a local context */ + opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr); + + /* setup the encoder parameters using the current image and using user parameters */ + opj_setup_encoder(cinfo, ¶meters, image); + + /* open a byte stream for writing */ + /* allocate memory for all tiles */ + cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0); + + /* encode the image */ + bSuccess = opj_encode(cinfo, cio, image, parameters.index); + if (!bSuccess) { + opj_cio_close(cio); + fprintf(stderr, "failed to encode image\n"); + return 1; + } + codestream_length = cio_tell(cio); + + /* write the buffer to disk */ + f = fopen(parameters.outfile, "wb"); + if (!f) { + fprintf(stderr, "failed to open %s for writing\n", parameters.outfile); + return 1; + } + fwrite(cio->buffer, 1, codestream_length, f); + fclose(f); + + /* close and free the byte stream */ + opj_cio_close(cio); + + /* free remaining compression structures */ + opj_destroy_compress(cinfo); + + } else { /* JP2 format output */ + int codestream_length; + opj_cio_t *cio = NULL; + FILE *f = NULL; + + /* get a JP2 compressor handle */ + opj_cinfo_t* cinfo = opj_create_compress(CODEC_JP2); + + /* catch events using our callbacks and give a local context */ + opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr); + + /* setup the encoder parameters using the current image and using user parameters */ + opj_setup_encoder(cinfo, ¶meters, image); + + /* open a byte stream for writing */ + /* allocate memory for all tiles */ + cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0); + + /* encode the image */ + bSuccess = opj_encode(cinfo, cio, image, parameters.index); + if (!bSuccess) { + opj_cio_close(cio); + fprintf(stderr, "failed to encode image\n"); + return 1; + } + codestream_length = cio_tell(cio); + + /* write the buffer to disk */ + f = fopen(parameters.outfile, "wb"); + if (!f) { + fprintf(stderr, "failed to open %s for writing\n", parameters.outfile); + return 1; + } + fwrite(cio->buffer, 1, codestream_length, f); + fclose(f); + + /* close and free the byte stream */ + opj_cio_close(cio); + + /* free remaining compression structures */ + opj_destroy_compress(cinfo); + + } + + /* free user parameters structure */ + if(delete_comment) { + if(parameters.cp_comment) free(parameters.cp_comment); + } + if(parameters.cp_matrice) free(parameters.cp_matrice); + + /* free image data */ + opj_image_destroy(image); + + return 0; +} + diff --git a/codec/image_to_j2k.dsp b/codec/image_to_j2k.dsp index 07e5a0a2..cbb6f8f9 100644 --- a/codec/image_to_j2k.dsp +++ b/codec/image_to_j2k.dsp @@ -41,15 +41,15 @@ RSC=rc.exe # 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" +# ADD CPP /nologo /MT /W3 /GX /O2 /I "../libopenjpeg" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /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 +# 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 /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 /nologo /subsystem:console /machine:I386 !ELSEIF "$(CFG)" == "image_to_j2k - Win32 Debug" @@ -62,18 +62,17 @@ LINK32=link.exe # 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" +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../libopenjpeg" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x40c /d "_DEBUG" +# ADD RSC /l 0x40c /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 +# 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 /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 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept !ENDIF @@ -81,108 +80,17 @@ LINK32=link.exe # 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 +SOURCE=.\compat\getopt.c # End Source File # Begin Source File @@ -190,60 +98,7 @@ SOURCE=.\compat\getopt.h # End Source File # Begin Source File -SOURCE=..\libopenjpeg\int.h +SOURCE=.\image_to_j2k.c # 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/codec/j2k_to_image.c b/codec/j2k_to_image.c index 3a6dcce1..d3593c0a 100644 --- a/codec/j2k_to_image.c +++ b/codec/j2k_to_image.c @@ -1,62 +1,57 @@ -/* 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. -*/ - - - -//MEMORY LEAK - -#ifdef _DEBUG - -#define _CRTDBG_MAP_ALLOC - -#include // Must be included first - -#include - -#endif - -//MEM - - - -#include +/* + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, Hervé Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ #include -#include #include -#ifndef DONT_HAVE_GETOPT -#include -#else -#include "compat/getopt.h" -#endif +#include -void usage_display(char *prgm) -{ - fprintf(stdout,"Usage:\n"); - fprintf(stdout," %s...\n",prgm); +#include "openjpeg.h" +#include "compat/getopt.h" +#include "convert.h" + +#define J2K_CFMT 0 +#define JP2_CFMT 1 +#define JPT_CFMT 2 +#define MJ2_CFMT 3 +#define PXM_DFMT 0 +#define PGX_DFMT 1 +#define BMP_DFMT 2 +#define YUV_DFMT 3 + +/* ----------------------------------------------------------------------- */ + +void decode_help_display() { + fprintf(stdout,"HELP\n----\n\n"); + fprintf(stdout,"- the -h option displays this help information on screen\n\n"); + + fprintf(stdout,"List of parameters for the JPEG 2000 encoder:\n"); + fprintf(stdout,"\n"); fprintf(stdout," -i \n"); fprintf(stdout," REQUIRED\n"); fprintf(stdout," Currently accepts J2K-files, JP2-files and JPT-files. The file type\n"); @@ -79,668 +74,316 @@ void usage_display(char *prgm) fprintf(stdout," Set the maximum number of quality layers to decode. If there are\n"); fprintf(stdout," less quality layers than the specified number, all the quality layers\n"); fprintf(stdout," are decoded.\n"); - fprintf(stdout," -u\n"); - fprintf(stdout," print an usage statement\n"); fprintf(stdout,"\n"); } -int main(int argc, char **argv) -{ - FILE *fsrc=NULL; - FILE *fdest=NULL; - char *infile=NULL; - char *outfile=NULL; - char *tmp=NULL; - char S1, S2, S3; - - char *src=NULL; - - int len; - - j2k_image_t img; - j2k_cp_t cp; - jp2_struct_t *jp2_struct=NULL; - - int w, wr, wrr, h, hr, hrr, max; - int i, compno, pad, j; - int adjust; - - cp.layer=0; - cp.reduce=0; - cp.decod_format=-1; - cp.cod_format=-1; - +/* -------------------------------------------------------------------------- */ + +int get_file_format(char *filename) { + int i; + static const char *extension[] = {"pgx", "pnm", "pgm", "ppm", "bmp", "j2k", "jp2", "jpt" }; + static const int format[] = { PGX_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, BMP_DFMT, J2K_CFMT, JP2_CFMT, JPT_CFMT }; + char * ext = strrchr(filename, '.') + 1; + if(ext) { + for(i = 0; i < sizeof(format); i++) { + if(strnicmp(ext, extension[i], 3) == 0) { + return format[i]; + } + } + } + + return -1; +} + +/* -------------------------------------------------------------------------- */ + +int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters) { + /* parse the command line */ + while (1) { - int c = getopt(argc, argv,"i:o:r:l:u"); + 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) { - - //Input file - case 'i': - infile = optarg; - tmp = optarg; - while (*tmp) { - tmp++; + case 'i': /* input file */ + { + char *infile = optarg; + parameters->decod_format = get_file_format(infile); + switch(parameters->decod_format) { + case J2K_CFMT: + case JP2_CFMT: + case JPT_CFMT: + break; + default: + fprintf(stderr, + "!! Unrecognized format for infile : %s [accept only *.j2k, *.jp2, *.jpc or *.jpt] !!\n\n", + infile); + return 1; + break; + } + strncpy(parameters->infile, infile, MAX_PATH); } - tmp--; - S3 = *tmp; - tmp--; - S2 = *tmp; - tmp--; - S1 = *tmp; - - /* 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')) { - cp.cod_format=J2K_CFMT; - break; - } - - /* JP2 format */ - if ((S1 == 'j' && S2 == 'p' && S3 == '2') - || (S1 == 'J' && S2 == 'P' && S3 == '2')) { - cp.cod_format=JP2_CFMT; - break; - } - - /* JPT format */ - if ((S1 == 'j' && S2 == 'p' && S3 == 't') - || (S1 == 'J' && S2 == 'P' && S3 == 'T')) { - cp.cod_format=JPT_CFMT; - break; - } - - fprintf(stderr, - "j2k_to_image : Unknown input image format *.%c%c%c [only *.j2k, *.jp2, *.jpc or *.jpt]!! \n", - S1, S2, S3); - return 1; break; - - /* ----------------------------------------------------- */ - - //Output file - case 'o': - outfile = optarg; - tmp = optarg; - while (*tmp) { - tmp++; - } - tmp--; - S3 = *tmp; - tmp--; - S2 = *tmp; - tmp--; - S1 = *tmp; - - // PGX format - if ((S1 == 'p' && S2 == 'g' && S3 == 'x') - || (S1 == 'P' && S2 == 'G' && S3 == 'X')) { - cp.decod_format = PGX_DFMT; - break; - } - - // PxM format - 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.decod_format = PXM_DFMT; - break; - } - - // BMP format - if ((S1 == 'b' && S2 == 'm' && S3 == 'p') - || (S1 == 'B' && S2 == 'M' && S3 == 'P')) { - cp.decod_format = BMP_DFMT; - break; - } - - // otherwise : error - fprintf(stderr, - "!! Unrecognized output image format *.%c%c%c [only *.pnm, *.pgm, *.ppm, *.pgx or *.bmp] !!\n", - S1, S2, S3); - - return 1; - break; - - /* ----------------------------------------------------- */ - - //Reduce option - case 'r': - tmp=optarg; - sscanf(tmp, "%d", &cp.reduce); - break; - - /* ----------------------------------------------------- */ - - //Layering option - case 'l': - tmp=optarg; - sscanf(tmp, "%d", &cp.layer); - break; - - /* ----------------------------------------------------- */ - - case 'u': - usage_display(argv[0]); - return 0; - break; - /* ----------------------------------------------------- */ - - default: - fprintf(stderr,"WARNING -> this option is not valid \"-%c %s\"\n",c,optarg); - break; - - } - } - - //Check required arguments - //------------------------ - if (!infile || !outfile) { - fprintf(stderr,"ERROR -> At least one required argument is missing\nCheck j2k_to_image -u for usage information\n"); - return 1; - } - - //Read the input file and put it in memory - //---------------------------------------- - fsrc = fopen(infile, "rb"); - if (!fsrc) { - fprintf(stderr, "ERROR -> failed to open %s for reading\n", infile); - return 1; - } - fseek(fsrc, 0, SEEK_END); - len = ftell(fsrc); - fseek(fsrc, 0, SEEK_SET); - src = (char *) malloc(len); - fread(src, 1, len, fsrc); - fclose(fsrc); - - //Decode the code-stream - //---------------------- - switch(cp.cod_format) { - - case J2K_CFMT: - if (!j2k_decode(src, len, &img, &cp)) { - fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); - return 1; - } - break; - - case JP2_CFMT: - jp2_struct = (jp2_struct_t *) malloc(sizeof(jp2_struct_t)); - jp2_struct->image = &img; - - if (jp2_read_struct(src, jp2_struct, len)) { - fprintf(stderr, "ERROR -> j2k_to_image: failed to decode jp2 structure!\n"); - return 1; - } - - if (!j2k_decode(src + jp2_struct->j2k_codestream_offset, jp2_struct->j2k_codestream_len, &img, &cp)) { - fprintf(stderr, "ERROR -> 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); - break; - - case JPT_CFMT: - if (!j2k_decode_jpt_stream(src, len, &img, &cp)) { - fprintf(stderr, "ERROR -> j2k_to_image: failed to decode JPT-file!\n"); - return 1; - } - break; - - default: - fprintf(stderr, - "ERROR -> j2k_to_image : Unknown input image format\n"); - return 1; - break; - } - - //Free the memory containing the code-stream - //------------------------------------------ - - free(src); - - - //Create output image - //------------------- - - /* ---------------------------- / */ - /* / / */ - /* / FORMAT : PNM, PGM or PPM / */ - /* / / */ - /* ---------------------------- / */ - - switch (cp.decod_format) { - case PXM_DFMT: /* PNM PGM PPM */ - - tmp=outfile; - while (*tmp) { - tmp++; - } - tmp--; - tmp--; - S2 = *tmp; - - 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 - && S2 !='g' && S2 !='G') { - - fdest = fopen(outfile, "wb"); - if (!fdest) { - fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile); - return 1; - } - - w = int_ceildiv(img.x1 - img.x0, img.comps[0].dx); - // wr = int_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 = int_ceildiv(img.y1 - img.y0, img.comps[0].dy); - // hr = int_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(fdest, "P6\n%d %d\n%d\n", wrr, hrr, max); - adjust = img.comps[0].prec > 8 ? img.comps[0].prec - 8 : 0; - for (i = 0; i < wrr * hrr; i++) { - int r, g, b; - unsigned char rc,gc,bc; - r = img.comps[0].data[i / wrr * wr + i % wrr]; - r += (img.comps[0].sgnd ? 1 << (img.comps[0].prec - 1) : 0); - rc = (unsigned char) ((r >> adjust)+((r >> (adjust-1))%2)); - - g = img.comps[1].data[i / wrr * wr + i % wrr]; - g += (img.comps[1].sgnd ? 1 << (img.comps[1].prec - 1) : 0); - gc = (unsigned char) ((g >> adjust)+((g >> (adjust-1))%2)); - - b = img.comps[2].data[i / wrr * wr + i % wrr]; - b += (img.comps[2].sgnd ? 1 << (img.comps[2].prec - 1) : 0); - bc = (unsigned char) ((b >> adjust)+((b >> (adjust-1))%2)); - - fprintf(fdest, "%c%c%c", rc, gc, bc); - } - free(img.comps[0].data); - free(img.comps[1].data); - free(img.comps[2].data); - fclose(fdest); - - } else { - int ncomp=(S2=='g' || S2=='G')?1:img.numcomps; - if (img.numcomps>ncomp) { - fprintf(stderr,"WARNING -> [PGM files] Only the first component\n"); - fprintf(stderr," is written to the file\n"); - } - for (compno = 0; compno < ncomp; compno++) { - char name[256]; - if (ncomp > 1) { - sprintf(name, "%d.%s", compno, outfile); - } else { - sprintf(name, "%s", outfile); - } - - fdest = fopen(name, "wb"); - if (!fdest) { - fprintf(stderr, "ERROR -> failed to open %s for writing\n", name); - return 1; - } - - w = int_ceildiv(img.x1 - img.x0, img.comps[compno].dx); - // wr = int_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 = int_ceildiv(img.y1 - img.y0, img.comps[compno].dy); - // hr = int_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(fdest, "P5\n%d %d\n%d\n", wrr, hrr, max); - adjust = - img.comps[compno].prec > 8 ? img.comps[compno].prec - 8 : 0; - for (i = 0; i < wrr * hrr; i++) { - int l; - unsigned char lc; - l = img.comps[compno].data[i / wrr * wr + i % wrr]; - l += (img.comps[compno]. - sgnd ? 1 << (img.comps[compno].prec - 1) : 0); - lc = (unsigned char) ((l >> adjust)+((l >> (adjust-1))%2)); - fprintf(fdest, "%c", lc); - } - fclose(fdest); - free(img.comps[compno].data); - } - } - break; - - /* ------------------------ / */ - /* / / */ - /* / FORMAT : PGX / */ - /* / / */ - /* /----------------------- / */ - case PGX_DFMT: /* PGX */ - for (compno = 0; compno < img.numcomps; compno++) { - j2k_comp_t *comp = &img.comps[compno]; - char name[256]; - int nbytes = 0; - tmp = outfile; - while (*tmp) { - tmp++; - } - while (*tmp!='.') { - tmp--; - } - *tmp='\0'; - - if (img.numcomps > 1) - sprintf(name, "%s-%d.pgx", outfile, compno); - else - sprintf(name, "%s.pgx", outfile); - - fdest = fopen(name, "wb"); - if (!fdest) { - fprintf(stderr, "ERROR -> failed to open %s for writing\n", name); - return 1; - } - - // w = int_ceildiv(img.x1 - img.x0, comp->dx); - // wr = int_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 = int_ceildiv(img.y1 - img.y0, comp->dy); - // hr = int_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(fdest, "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, fdest); - - } - } - free(img.comps[compno].data); - fclose(fdest); - } - break; - - /* ------------------------ / */ - /* / / */ - /* / FORMAT : BMP / */ - /* / / */ - /* /----------------------- / */ - - case BMP_DFMT: /* 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 - - <<-- <<-- <<-- <<-- */ - - fdest = fopen(outfile, "wb"); - if (!fdest) { - fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile); - return 1; - } - - // w = int_ceildiv(img.x1 - img.x0, img.comps[0].dx); - // wr = int_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 = int_ceildiv(img.y1 - img.y0, img.comps[0].dy); - // hr = int_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(fdest, "BM"); - - /* FILE HEADER */ - /* ------------- */ - fprintf(fdest, "%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(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, - ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (54) & 0xff, ((54) >> 8) & 0xff, - ((54) >> 16) & 0xff, ((54) >> 24) & 0xff); - - /* INFO HEADER */ - /* ------------- */ - fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff, - ((40) >> 16) & 0xff, ((40) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (unsigned char) ((wr) & 0xff), - (unsigned char) ((wr) >> 8) & 0xff, - (unsigned char) ((wr) >> 16) & 0xff, - (unsigned char) ((wr) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (unsigned char) ((hr) & 0xff), - (unsigned char) ((hr) >> 8) & 0xff, - (unsigned char) ((hr) >> 16) & 0xff, - (unsigned char) ((hr) >> 24) & 0xff); - fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff); - fprintf(fdest, "%c%c", (24) & 0xff, ((24) >> 8) & 0xff); - fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, - ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); - fprintf(fdest, "%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(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, - ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, - ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, - ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); - fprintf(fdest, "%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(fdest, "%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(fdest, "%c", 0); - } - } - fclose(fdest); - free(img.comps[1].data); - free(img.comps[2].data); - } else { /* Gray-scale */ - - /* -->> -->> -->> -->> - - 8 bits non code (Gray scale) - - <<-- <<-- <<-- <<-- */ - fdest = fopen(outfile, "wb"); - // w = int_ceildiv(img.x1 - img.x0, img.comps[0].dx); - // wr = int_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 = int_ceildiv(img.y1 - img.y0, img.comps[0].dy); - // hr = int_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(fdest, "BM"); - - /* FILE HEADER */ - /* ------------- */ - fprintf(fdest, "%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(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, - ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (54 + 1024) & 0xff, - ((54 + 1024) >> 8) & 0xff, ((54 + 1024) >> 16) & 0xff, - ((54 + 1024) >> 24) & 0xff); - - /* INFO HEADER */ - /* ------------- */ - fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff, - ((40) >> 16) & 0xff, ((40) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (unsigned char) ((wr) & 0xff), - (unsigned char) ((wr) >> 8) & 0xff, - (unsigned char) ((wr) >> 16) & 0xff, - (unsigned char) ((wr) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (unsigned char) ((hr) & 0xff), - (unsigned char) ((hr) >> 8) & 0xff, - (unsigned char) ((hr) >> 16) & 0xff, - (unsigned char) ((hr) >> 24) & 0xff); - fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff); - fprintf(fdest, "%c%c", (8) & 0xff, ((8) >> 8) & 0xff); - fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, - ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); - fprintf(fdest, "%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(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, - ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, - ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, - ((256) >> 16) & 0xff, ((256) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, - ((256) >> 16) & 0xff, ((256) >> 24) & 0xff); - } - - for (i = 0; i < 256; i++) { - fprintf(fdest, "%c%c%c%c", i, i, i, 0); - } - - for (i = 0; i < wr * hr; i++) { - /* a modifier !! */ - // fprintf(fdest, "%c", img.comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]); - fprintf(fdest, "%c", - img.comps[0].data[w * hr - ((i) / (wr) + 1) * w + - (i) % (wr)]); - /*if (((i + 1) % w == 0 && w % 2)) - fprintf(fdest, "%c", 0); */ - if ((i + 1) % wr == 0) { - for (pad = wr % 4 ? 4 - wr % 4 : 0; pad > 0; pad--) /* ADD */ - fprintf(fdest, "%c", 0); - } - } - fclose(fdest); - free(img.comps[0].data); - break; + + /* ----------------------------------------------------- */ - default: - fprintf(stderr, - "ERROR -> j2k_to_image : Unknown output image format\n"); - return 1; - break; + case 'o': /* output file */ + { + char *outfile = optarg; + parameters->cod_format = get_file_format(outfile); + switch(parameters->cod_format) { + case PGX_DFMT: + case PXM_DFMT: + case BMP_DFMT: + break; + default: + fprintf(stderr, "Unknown output format image %s [only *.pnm, *.pgm, *.ppm, *.pgx or *.bmp]!! \n", outfile); + return 1; + break; + } + strncpy(parameters->outfile, outfile, MAX_PATH); + } + break; + + /* ----------------------------------------------------- */ + + + case 'r': /* reduce option */ + { + sscanf(optarg, "%d", ¶meters->cp_reduce); + } + break; + + /* ----------------------------------------------------- */ + + + case 'l': /* layering option */ + { + sscanf(optarg, "%d", ¶meters->cp_layer); + } + break; + + /* ----------------------------------------------------- */ + + case 'h': /* display an help description */ + { + decode_help_display(); + return 1; + } + break; + + /* ----------------------------------------------------- */ + + default: + fprintf(stderr,"WARNING -> this option is not valid \"-%c %s\"\n",c, optarg); + break; + } } - - - // Free remaining structures - //-------------------------- - j2k_dec_release(); - - - - // Check memory leaks if debug mode - //--------------------------------- - -#ifdef _DEBUG - - _CrtDumpMemoryLeaks(); - -#endif - + + /* check for possible errors */ + + if((parameters->infile[0] == 0) || (parameters->outfile[0] == 0)) { + fprintf(stderr,"ERROR -> At least one required argument is missing\nCheck j2k_to_image -h for usage information\n"); + return 1; + } + return 0; } + +/* -------------------------------------------------------------------------- */ + +/** +sample error callback expecting a FILE* client object +*/ +void error_callback(const char *msg, void *client_data) { + FILE *stream = (FILE*)client_data; + fprintf(stream, "[ERROR] %s", msg); +} +/** +sample warning callback expecting a FILE* client object +*/ +void warning_callback(const char *msg, void *client_data) { + FILE *stream = (FILE*)client_data; + fprintf(stream, "[WARNING] %s", msg); +} +/** +sample debug callback expecting no client object +*/ +void info_callback(const char *msg, void *client_data) { + fprintf(stdout, "[INFO] %s", msg); +} + +/* -------------------------------------------------------------------------- */ + +int main(int argc, char **argv) { + opj_dparameters_t parameters; /* decompression parameters */ + opj_event_mgr_t event_mgr; /* event manager */ + opj_image_t *image = NULL; + FILE *fsrc = NULL; + unsigned char *src = NULL; + int file_length; + + opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */ + opj_cio_t *cio = NULL; + + /* configure the event callbacks (not required) */ + memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); + event_mgr.error_handler = error_callback; + event_mgr.warning_handler = warning_callback; + event_mgr.info_handler = info_callback; + + /* set decoding parameters to default values */ + opj_set_default_decoder_parameters(¶meters); + + /* parse input and get user decoding parameters */ + if(parse_cmdline_decoder(argc, argv, ¶meters) == 1) { + return 0; + } + + /* read the input file and put it in memory */ + /* ---------------------------------------- */ + fsrc = fopen(parameters.infile, "rb"); + if (!fsrc) { + fprintf(stderr, "ERROR -> failed to open %s for reading\n", parameters.infile); + return 1; + } + fseek(fsrc, 0, SEEK_END); + file_length = ftell(fsrc); + fseek(fsrc, 0, SEEK_SET); + src = (unsigned char *) malloc(file_length); + fread(src, 1, file_length, fsrc); + fclose(fsrc); + + /* decode the code-stream */ + /* ---------------------- */ + + switch(parameters.decod_format) { + case J2K_CFMT: + { + /* JPEG-2000 codestream */ + + /* get a decoder handle */ + dinfo = opj_create_decompress(CODEC_J2K); + + /* catch events using our callbacks and give a local context */ + opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); + + /* setup the decoder decoding parameters using user parameters */ + opj_setup_decoder(dinfo, ¶meters); + + /* open a byte stream */ + cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); + + /* decode the stream and fill the image structure */ + image = opj_decode(dinfo, cio); + if(!image) { + fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); + opj_destroy_decompress(dinfo); + opj_cio_close(cio); + return 1; + } + + /* close the byte stream */ + opj_cio_close(cio); + } + break; + + case JP2_CFMT: + { + /* JPEG 2000 compressed image data */ + + /* get a decoder handle */ + dinfo = opj_create_decompress(CODEC_JP2); + + /* catch events using our callbacks and give a local context */ + opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); + + /* setup the decoder decoding parameters using the current image and using user parameters */ + opj_setup_decoder(dinfo, ¶meters); + + /* open a byte stream */ + cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); + + /* decode the stream and fill the image structure */ + image = opj_decode(dinfo, cio); + if(!image) { + fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); + opj_destroy_decompress(dinfo); + opj_cio_close(cio); + return 1; + } + + /* close the byte stream */ + opj_cio_close(cio); + + } + break; + + case JPT_CFMT: + { + /* JPEG 2000, JPIP */ + + /* get a decoder handle */ + dinfo = opj_create_decompress(CODEC_JPT); + + /* catch events using our callbacks and give a local context */ + opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); + + /* setup the decoder decoding parameters using user parameters */ + opj_setup_decoder(dinfo, ¶meters); + + /* open a byte stream */ + cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); + + /* decode the stream and fill the image structure */ + image = opj_decode(dinfo, cio); + if(!image) { + fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); + opj_destroy_decompress(dinfo); + opj_cio_close(cio); + return 1; + } + + /* close the byte stream */ + opj_cio_close(cio); + } + break; + + default: + fprintf(stderr, "ERROR -> j2k_to_image : Unknown input image format\n"); + return 1; + break; + } + + /* free the memory containing the code-stream */ + free(src); + src = NULL; + + /* create output image */ + /* ------------------- */ + + switch (parameters.cod_format) { + case PXM_DFMT: /* PNM PGM PPM */ + imagetopnm(image, parameters.outfile); + break; + + case PGX_DFMT: /* PGX */ + imagetopgx(image, parameters.outfile); + break; + + case BMP_DFMT: /* BMP */ + imagetobmp(image, parameters.outfile); + break; + } + + /* free remaining structures */ + if(dinfo) { + opj_destroy_decompress(dinfo); + } + + /* free image data structure */ + opj_image_destroy(image); + + return 0; +} + diff --git a/codec/j2k_to_image.dsp b/codec/j2k_to_image.dsp index 6a633191..826e2890 100644 --- a/codec/j2k_to_image.dsp +++ b/codec/j2k_to_image.dsp @@ -39,40 +39,41 @@ RSC=rc.exe # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 # 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" +# ADD CPP /nologo /MT /W3 /GX /O2 /I "../libopenjpeg" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /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 +# 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 /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 /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 Output_Dir "Debug" +# PROP BASE Intermediate_Dir "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 Output_Dir "Debug" +# PROP Intermediate_Dir "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" +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../libopenjpeg" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x40c /d "_DEBUG" +# ADD RSC /l 0x40c /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 +# 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 /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 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept !ENDIF @@ -80,24 +81,13 @@ LINK32=link.exe # 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 +SOURCE=.\convert.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 +SOURCE=.\convert.h # End Source File # Begin Source File @@ -105,136 +95,11 @@ SOURCE=.\compat\getopt.c # End Source File # Begin Source File -SOURCE=..\libopenjpeg\int.c -# End Source File -# Begin Source File - -SOURCE=..\libopenjpeg\j2k.c +SOURCE=.\compat\getopt.h # 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/libopenjpeg/LibOpenJPEG.dsp b/libopenjpeg/LibOpenJPEG.dsp new file mode 100644 index 00000000..566469f4 --- /dev/null +++ b/libopenjpeg/LibOpenJPEG.dsp @@ -0,0 +1,256 @@ +# Microsoft Developer Studio Project File - Name="LibOpenJPEG" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=LibOpenJPEG - 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 "LibOpenJPEG.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 "LibOpenJPEG.mak" CFG="LibOpenJPEG - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "LibOpenJPEG - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "LibOpenJPEG - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "LibOpenJPEG - 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 "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "LibOpenJPEG - 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 Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD BASE RSC /l 0x40c /d "_DEBUG" +# ADD RSC /l 0x40c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ENDIF + +# Begin Target + +# Name "LibOpenJPEG - Win32 Release" +# Name "LibOpenJPEG - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\bio.c +# End Source File +# Begin Source File + +SOURCE=.\cio.c +# End Source File +# Begin Source File + +SOURCE=.\dwt.c +# End Source File +# Begin Source File + +SOURCE=.\event.c +# End Source File +# Begin Source File + +SOURCE=.\fix.c +# End Source File +# Begin Source File + +SOURCE=.\image.c +# End Source File +# Begin Source File + +SOURCE=.\int.c +# End Source File +# Begin Source File + +SOURCE=.\j2k.c +# End Source File +# Begin Source File + +SOURCE=.\j2k_lib.c +# End Source File +# Begin Source File + +SOURCE=.\jp2.c +# End Source File +# Begin Source File + +SOURCE=.\jpt.c +# End Source File +# Begin Source File + +SOURCE=.\mct.c +# End Source File +# Begin Source File + +SOURCE=.\mqc.c +# End Source File +# Begin Source File + +SOURCE=.\openjpeg.c +# End Source File +# Begin Source File + +SOURCE=.\pi.c +# End Source File +# Begin Source File + +SOURCE=.\raw.c +# End Source File +# Begin Source File + +SOURCE=.\t1.c +# End Source File +# Begin Source File + +SOURCE=.\t2.c +# End Source File +# Begin Source File + +SOURCE=.\tcd.c +# End Source File +# Begin Source File + +SOURCE=.\tgt.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\bio.h +# End Source File +# Begin Source File + +SOURCE=.\cio.h +# End Source File +# Begin Source File + +SOURCE=.\dwt.h +# End Source File +# Begin Source File + +SOURCE=.\event.h +# End Source File +# Begin Source File + +SOURCE=.\fix.h +# End Source File +# Begin Source File + +SOURCE=.\image.h +# End Source File +# Begin Source File + +SOURCE=.\int.h +# End Source File +# Begin Source File + +SOURCE=.\j2k.h +# End Source File +# Begin Source File + +SOURCE=.\j2k_lib.h +# End Source File +# Begin Source File + +SOURCE=.\jp2.h +# End Source File +# Begin Source File + +SOURCE=.\jpt.h +# End Source File +# Begin Source File + +SOURCE=.\mct.h +# End Source File +# Begin Source File + +SOURCE=.\mqc.h +# End Source File +# Begin Source File + +SOURCE=.\openjpeg.h +# End Source File +# Begin Source File + +SOURCE=.\opj_includes.h +# End Source File +# Begin Source File + +SOURCE=.\pi.h +# End Source File +# Begin Source File + +SOURCE=.\raw.h +# End Source File +# Begin Source File + +SOURCE=.\t1.h +# End Source File +# Begin Source File + +SOURCE=.\t2.h +# End Source File +# Begin Source File + +SOURCE=.\tcd.h +# End Source File +# Begin Source File + +SOURCE=.\tgt.h +# End Source File +# End Group +# End Target +# End Project diff --git a/libopenjpeg/bio.c b/libopenjpeg/bio.c index 43b415d6..47d7299e 100644 --- a/libopenjpeg/bio.c +++ b/libopenjpeg/bio.c @@ -1,8 +1,9 @@ /* - * Copyright (c) 2001-2002, David Janssens - * Copyright (c) 2003, Yannick Verschueren - * Copyright (c) 2003, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium - * + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,170 +26,127 @@ * 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; -} +#include "opj_includes.h" -/* - * 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) +/* +========================================================== + local functions +========================================================== +*/ + +static int bio_byteout(opj_bio_t *bio) { + bio->buf = (bio->buf << 8) & 0xffff; + bio->ct = bio->buf == 0xff00 ? 7 : 8; + if (bio->bp >= bio->end) { return 1; - *bio_bp++ = bio_buf >> 8; + } + *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) +static int bio_bytein(opj_bio_t *bio) { + bio->buf = (bio->buf << 8) & 0xffff; + bio->ct = bio->buf == 0xff00 ? 7 : 8; + if (bio->bp >= bio->end) { return 1; - bio_buf |= *bio_bp++; + } + 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(); +static void bio_putbit(opj_bio_t *bio, int b) { + if (bio->ct == 0) { + bio_byteout(bio); } - bio_ct--; - bio_buf |= b << bio_ct; + bio->ct--; + bio->buf |= b << bio->ct; } -/* - * Read bit. - * - */ -int bio_getbit() -{ - if (bio_ct == 0) { - bio_bytein(); +static int bio_getbit(opj_bio_t *bio) { + if (bio->ct == 0) { + bio_bytein(bio); } - bio_ct--; - return (bio_buf >> bio_ct) & 1; + 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) -{ +/* +========================================================== + Bit Input/Output interface +========================================================== +*/ + +opj_bio_t* bio_create() { + opj_bio_t *bio = (opj_bio_t*)opj_malloc(sizeof(opj_bio_t)); + return bio; +} + +void bio_destroy(opj_bio_t *bio) { + if(bio) { + opj_free(bio); + } +} + +int bio_numbytes(opj_bio_t *bio) { + return (bio->bp - bio->start); +} + +void bio_init_enc(opj_bio_t *bio, unsigned char *bp, int len) { + bio->start = bp; + bio->end = bp + len; + bio->bp = bp; + bio->buf = 0; + bio->ct = 8; +} + +void bio_init_dec(opj_bio_t *bio, unsigned char *bp, int len) { + bio->start = bp; + bio->end = bp + len; + bio->bp = bp; + bio->buf = 0; + bio->ct = 0; +} + +void bio_write(opj_bio_t *bio, int v, int n) { int i; for (i = n - 1; i >= 0; i--) { - bio_putbit((v >> i) & 1); + bio_putbit(bio, (v >> i) & 1); } } -/* - * Read bits. - * - * n : Number of bits to read - */ -int bio_read(int n) -{ +int bio_read(opj_bio_t *bio, int n) { int i, v; v = 0; for (i = n - 1; i >= 0; i--) { - v += bio_getbit() << i; + v += bio_getbit(bio) << i; } return v; } -/* - * Flush bits. Modified to eliminate longjmp !! - * - */ -int bio_flush() -{ - bio_ct = 0; - if (bio_byteout()) +int bio_flush(opj_bio_t *bio) { + bio->ct = 0; + if (bio_byteout(bio)) { return 1; - if (bio_ct == 7) { - bio_ct = 0; - - if (bio_byteout()) + } + if (bio->ct == 7) { + bio->ct = 0; + if (bio_byteout(bio)) { 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()) +int bio_inalign(opj_bio_t *bio) { + bio->ct = 0; + if ((bio->buf & 0xff) == 0xff) { + if (bio_bytein(bio)) { return 1; - bio_ct = 0; + } + bio->ct = 0; } return 0; } diff --git a/libopenjpeg/bio.h b/libopenjpeg/bio.h index 58995b05..0f0add1e 100644 --- a/libopenjpeg/bio.h +++ b/libopenjpeg/bio.h @@ -1,7 +1,9 @@ /* - * Copyright (c) 2001-2002, David Janssens - * Copyright (c) 2003, Yannick Verschueren - * Copyright (c) 2003, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,50 +28,128 @@ * POSSIBILITY OF SUCH DAMAGE. */ + #ifndef __BIO_H #define __BIO_H +/** +@file bio.h +@brief Implementation of an individual bit input-output (BIO) -/* - * Number of bytes written. - */ -int bio_numbytes(); +The functions in BIO.C have for goal to realize an individual bit input - output. +*/ -/* - * Init encoder. - * - * bp : Output buffer - * len : Output buffer length - */ -void bio_init_enc(unsigned char *bp, int len); +/** @defgroup BIO BIO - Individual bit input-output stream */ +/*@{*/ -/* - * Init decoder. - * - * bp : Input buffer - * len : Input buffer length - */ -void bio_init_dec(unsigned char *bp, int len); +/** +Individual bit input-output stream (BIO) +*/ +typedef struct opj_bio { + /** pointer to the start of the buffer */ + unsigned char *start; + /** pointer to the end of the buffer */ + unsigned char *end; + /** pointer to the present position in the buffer */ + unsigned char *bp; + /** temporary place where each byte is read or written */ + unsigned int buf; + /** coder : number of bits free to write. decoder : number of bits read */ + int ct; +} opj_bio_t; -/* - * Write bits. - * - * v : Value of bits - * n : Number of bits to write - */ -void bio_write(int v, int n); +/** @name Local static functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Write a bit +@param bio BIO handle +@param b Bit to write (0 or 1) +*/ +static void bio_putbit(opj_bio_t *bio, int b); +/** +Read a bit +@param bio BIO handle +@return Returns the read bit +*/ +static int bio_getbit(opj_bio_t *bio); +/** +Write a byte +@param bio BIO handle +@return Returns 0 if successful, returns 1 otherwise +*/ +static int bio_byteout(opj_bio_t *bio); +/** +Read a byte +@param bio BIO handle +@return Returns 0 if successful, returns 1 otherwise +*/ +static int bio_bytein(opj_bio_t *bio); +/* ----------------------------------------------------------------------- */ +/*@}*/ -/* - * Read bits. - * - * n : Number of bits to read - */ -int bio_read(int n); +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Create a new BIO handle +@return Returns a new BIO handle if successful, returns NULL otherwise +*/ +opj_bio_t* bio_create(); +/** +Destroy a previously created BIO handle +@param bio BIO handle to destroy +*/ +void bio_destroy(opj_bio_t *bio); +/** +Number of bytes written. +@param bio BIO handle +@return Returns the number of bytes written +*/ +int bio_numbytes(opj_bio_t *bio); +/** +Init encoder +@param bio BIO handle +@param bp Output buffer +@param len Output buffer length +*/ +void bio_init_enc(opj_bio_t *bio, unsigned char *bp, int len); +/** +Init decoder +@param bio BIO handle +@param bp Input buffer +@param len Input buffer length +*/ +void bio_init_dec(opj_bio_t *bio, unsigned char *bp, int len); +/** +Write bits +@param bio BIO handle +@param v Value of bits +@param n Number of bits to write +*/ +void bio_write(opj_bio_t *bio, int v, int n); +/** +Read bits +@param bio BIO handle +@param n Number of bits to read +@return Returns the corresponding read number +*/ +int bio_read(opj_bio_t *bio, int n); +/** +Flush bits +@param bio BIO handle +@return Returns 1 if successful, returns 0 otherwise +*/ +int bio_flush(opj_bio_t *bio); +/** +Passes the ending bits (coming from flushing) +@param bio BIO handle +@return Returns 1 if successful, returns 0 otherwise +*/ +int bio_inalign(opj_bio_t *bio); +/* ----------------------------------------------------------------------- */ +/*@}*/ -/* - * Flush bits. Modified to eliminate longjmp !! - */ -int bio_flush(); +/*@}*/ -int bio_inalign(); /* modified to eliminated longjmp !! */ +#endif /* __BIO_H */ -#endif diff --git a/libopenjpeg/cio.c b/libopenjpeg/cio.c index f6d1c875..3d40cb81 100644 --- a/libopenjpeg/cio.c +++ b/libopenjpeg/cio.c @@ -1,5 +1,9 @@ /* - * Copyright (c) 2001-2002, David Janssens + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,30 +28,75 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "cio.h" -#include -#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 */ +#include "opj_includes.h" -extern jmp_buf j2k_error; +/* ----------------------------------------------------------------------- */ -/* - * Number of bytes written. - */ -int cio_numbytes() -{ - return cio_bp - cio_start; +opj_cio_t* opj_cio_open(opj_common_ptr cinfo, unsigned char *buffer, int length) { + opj_cp_t *cp = NULL; + opj_cio_t *cio = (opj_cio_t*)opj_malloc(sizeof(opj_cio_t)); + if(!cio) return NULL; + cio->cinfo = cinfo; + if(buffer && length) { + /* wrap a user buffer containing the encoded image */ + cio->openmode = OPJ_STREAM_READ; + cio->buffer = buffer; + cio->length = length; + } + else if(!buffer && !length && cinfo) { + /* allocate a buffer for the encoded image */ + cio->openmode = OPJ_STREAM_WRITE; + switch(cinfo->codec_format) { + case CODEC_J2K: + cp = ((opj_j2k_t*)cinfo->j2k_handle)->cp; + break; + case CODEC_JP2: + cp = ((opj_jp2_t*)cinfo->jp2_handle)->j2k->cp; + break; + default: + opj_free(cio); + return NULL; + } + cio->length = cp->tdx * cp->tdy * cp->tw * cp->th * 2; + cio->buffer = (unsigned char *)opj_malloc(cio->length); + if(!cio->buffer) { + opj_free(cio); + return NULL; + } + } + else { + opj_free(cio); + return NULL; + } + + /* Initialize byte IO */ + cio->start = cio->buffer; + cio->end = cio->buffer + cio->length; + cio->bp = cio->buffer; + + return cio; } +void opj_cio_close(opj_cio_t *cio) { + if(cio) { + if(cio->openmode == OPJ_STREAM_WRITE) { + /* destroy the allocated buffer */ + opj_free(cio->buffer); + } + /* destroy the cio */ + opj_free(cio); + } +} + + +/* ----------------------------------------------------------------------- */ + /* * Get position in byte stream. */ -int cio_tell() -{ - return cio_bp - cio_start; +int cio_tell(opj_cio_t *cio) { + return cio->bp - cio->start; } /* @@ -55,59 +104,45 @@ int cio_tell() * * pos : position, in number of bytes, from the beginning of the stream */ -void cio_seek(int pos) -{ - cio_bp = cio_start + pos; +void cio_seek(opj_cio_t *cio, int pos) { + cio->bp = cio->start + pos; } /* * Number of bytes left before the end of the stream. */ -int cio_numbytesleft() -{ - return cio_end - cio_bp; +int cio_numbytesleft(opj_cio_t *cio) { + return cio->end - cio->bp; } /* * Get pointer to the current position in the stream. */ -unsigned char *cio_getbp() -{ - 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; +unsigned char *cio_getbp(opj_cio_t *cio) { + return cio->bp; } /* * Write a byte. */ -void cio_byteout(unsigned char v) -{ - if (cio_bp >= cio_end) - longjmp(j2k_error, 1); - *cio_bp++ = v; - +bool cio_byteout(opj_cio_t *cio, unsigned char v) { + if (cio->bp >= cio->end) { + opg_event_msg(cio->cinfo, EVT_ERROR, "write error\n"); + return false; + } + *cio->bp++ = v; + return true; } /* * Read a byte. */ -unsigned char cio_bytein() -{ - if (cio_bp >= cio_end) - longjmp(j2k_error, 1); - return *cio_bp++; +unsigned char cio_bytein(opj_cio_t *cio) { + if (cio->bp >= cio->end) { + opg_event_msg(cio->cinfo, EVT_ERROR, "read error\n"); + return 0; + } + return *cio->bp++; } /* @@ -116,12 +151,13 @@ unsigned char cio_bytein() * v : value to write * n : number of bytes to write */ -void cio_write(unsigned int v, int n) -{ +unsigned int cio_write(opj_cio_t *cio, unsigned int v, int n) { int i; for (i = n - 1; i >= 0; i--) { - cio_byteout((unsigned char) ((v >> (i << 3)) & 0xff)); + if( !cio_byteout(cio, (unsigned char) ((v >> (i << 3)) & 0xff)) ) + return 0; } + return n; } /* @@ -131,13 +167,12 @@ void cio_write(unsigned int v, int n) * * return : value of the n bytes read */ -unsigned int cio_read(int n) -{ +unsigned int cio_read(opj_cio_t *cio, int n) { int i; unsigned int v; v = 0; for (i = n - 1; i >= 0; i--) { - v += cio_bytein() << (i << 3); + v += cio_bytein(cio) << (i << 3); } return v; } @@ -147,33 +182,9 @@ unsigned int cio_read(int n) * * n : number of bytes to skip */ -void cio_skip(int n) -{ - cio_bp += n; +void cio_skip(opj_cio_t *cio, int n) { + cio->bp += n; } -/* - * Read n bytes, copy to buffer - * - * n : number of bytes to transfer - */ -void cio_read_to_buf(unsigned char* src_buf, int n)/* Glenn adds */ -{ - if (cio_bp + n > cio_end) - longjmp(j2k_error, 1); - memcpy(cio_bp, src_buf, n); - cio_bp += n; -} -/* - * Write n bytes, copy from buffer - * - * n : number of bytes to transfer - */ -void cio_write_from_buf(unsigned char* dest_buf, int n)/* Glenn adds */ -{ - if (cio_bp + n > cio_end) - longjmp(j2k_error, 1); - memcpy(dest_buf, cio_bp, n); - cio_bp += n; -} \ No newline at end of file + diff --git a/libopenjpeg/cio.h b/libopenjpeg/cio.h index 8bf1deee..efe23ed8 100644 --- a/libopenjpeg/cio.h +++ b/libopenjpeg/cio.h @@ -1,5 +1,9 @@ /* - * Copyright (c) 2001-2002, David Janssens + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,84 +28,59 @@ * POSSIBILITY OF SUCH DAMAGE. */ + #ifndef __CIO_H #define __CIO_H +/** +@file cio.h +@brief Implementation of a byte input-output process (CIO) -/* - * Number of bytes written. - * - * returns number of bytes written - */ -int cio_numbytes(); +The functions in CIO.C have for goal to realize a byte input / output process. +*/ -/* - * Get position in byte stream. - * - * return position in bytes - */ -int cio_tell(); +/** @defgroup CIO CIO - byte input-output stream */ +/*@{*/ -/* - * Set position in byte stream. - * - * pos : position, in number of bytes, from the beginning of the stream - */ -void cio_seek(int pos); +/** @name Exported functions (see also openjpeg.h) */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Number of bytes left before the end of the stream +@param cio CIO handle +@return Returns the number of bytes before the end of the stream +*/ +int cio_numbytesleft(opj_cio_t *cio); +/** +Get pointer to the current position in the stream +@param cio CIO handle +@return Returns a pointer to the current position +*/ +unsigned char *cio_getbp(opj_cio_t *cio); +/** +Write some bytes +@param cio CIO handle +@param v Value to write +@param n Number of bytes to write +@return Returns the number of bytes written or 0 if an error occured +*/ +unsigned int cio_write(opj_cio_t *cio, unsigned int v, int n); +/** +Read some bytes +@param cio CIO handle +@param n Number of bytes to read +@return Returns the value of the n bytes read +*/ +unsigned int cio_read(opj_cio_t *cio, int n); +/** +Skip some bytes +@param cio CIO handle +@param n Number of bytes to skip +*/ +void cio_skip(opj_cio_t *cio, int n); +/* ----------------------------------------------------------------------- */ +/*@}*/ -/* - * 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(); +#endif /* __CIO_H */ -/* - * 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); - -/* - * Read n bytes, copy to buffer - */ -void cio_read_to_buf(unsigned char* src_buf, int n);/* Glenn Pearson adds */ - -/* - * Write n bytes, copy from buffer - */ -void cio_write_from_buf(unsigned char* dest_buf, int n);/* Glenn Pearson adds */ - -#endif diff --git a/libopenjpeg/dwt.c b/libopenjpeg/dwt.c index 66ee3827..18532cb5 100644 --- a/libopenjpeg/dwt.c +++ b/libopenjpeg/dwt.c @@ -1,8 +1,9 @@ /* - * 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 - * Copyright (c) 2005, Reiner Wahler + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -50,11 +51,7 @@ */ -#include "dwt.h" -#include "int.h" -#include "fix.h" -#include "tcd.h" -#include +#include "opj_includes.h" #define S(i) a[(i)*2] #define D(i) a[(1+(i)*2)] @@ -67,7 +64,7 @@ /* */ /* This table contains the norms of the 5-3 wavelets for different bands. */ /* */ -double dwt_norms[4][10] = { +static const 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}, @@ -77,19 +74,24 @@ double dwt_norms[4][10] = { /* */ /* This table contains the norms of the 9-7 wavelets for different bands. */ /* */ -double dwt_norms_real[4][10] = { +static const 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} }; +/* +========================================================== + local functions +========================================================== +*/ -/* */ +/* */ /* Forward lazy transform (horizontal). */ /* */ -void dwt_deinterleave_h(int *a, int *b, int dn, int sn, int cas) { - int i; +static void dwt_deinterleave_h(int *a, int *b, int dn, int sn, int cas) { + int i; for (i=0; i */ /* Forward lazy transform (vertical). */ /* */ -void dwt_deinterleave_v(int *a, int *b, int dn, int sn, int x, int cas) { +static void dwt_deinterleave_v(int *a, int *b, int dn, int sn, int x, int cas) { int i; for (i=0; i */ /* Inverse lazy transform (horizontal). */ /* */ -void dwt_interleave_h(int *a, int *b, int dn, int sn, int cas) { +static void dwt_interleave_h(int *a, int *b, int dn, int sn, int cas) { int i; -/* for (i=0; i */ /* Inverse lazy transform (vertical). */ /* */ -void dwt_interleave_v(int *a, int *b, int dn, int sn, int x, int cas) { +static void dwt_interleave_v(int *a, int *b, int dn, int sn, int x, int cas) { int i; -/* for (i=0; i */ /* Forward 5-3 wavelet tranform in 1-D. */ /* */ -void dwt_encode_1(int *a, int dn, int sn, int cas) -{ +static void dwt_encode_1(int *a, int dn, int sn, int cas) { int i; - + if (!cas) { - if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */ + 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; } } else { - if (!sn && dn == 1) /* NEW : CASE ONE ELEMENT */ + if (!sn && dn == 1) /* NEW : CASE ONE ELEMENT */ S(0) *= 2; else { for (i = 0; i < dn; i++) S(i) -= (DD_(i) + DD_(i - 1)) >> 1; for (i = 0; i < sn; i++) D(i) += (SS_(i) + SS_(i + 1) + 2) >> 2; } - } } /* */ /* Inverse 5-3 wavelet tranform in 1-D. */ /* */ -void dwt_decode_1(int *a, int dn, int sn, int cas) -{ +static void dwt_decode_1(int *a, int dn, int sn, int cas) { int i; - + if (!cas) { - if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */ + 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; } @@ -191,61 +194,148 @@ void dwt_decode_1(int *a, int dn, int sn, int cas) } } +/* */ +/* Forward 9-7 wavelet transform in 1-D. */ +/* */ +static void dwt_encode_1_real(int *a, int dn, int sn, int cas) { + int i; + if (!cas) { + if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */ + for (i = 0; i < dn; i++) + D(i) -= fix_mul(S_(i) + S_(i + 1), 12993); + for (i = 0; i < sn; i++) + S(i) -= fix_mul(D_(i - 1) + D_(i), 434); + for (i = 0; i < dn; i++) + D(i) += fix_mul(S_(i) + S_(i + 1), 7233); + for (i = 0; i < sn; i++) + S(i) += fix_mul(D_(i - 1) + D_(i), 3633); + for (i = 0; i < dn; i++) + D(i) = fix_mul(D(i), 5038); /*5038 */ + for (i = 0; i < sn; i++) + S(i) = fix_mul(S(i), 6659); /*6660 */ + } + } else { + if ((sn > 0) || (dn > 1)) { /* NEW : CASE ONE ELEMENT */ + for (i = 0; i < dn; i++) + S(i) -= fix_mul(DD_(i) + DD_(i - 1), 12993); + for (i = 0; i < sn; i++) + D(i) -= fix_mul(SS_(i) + SS_(i + 1), 434); + for (i = 0; i < dn; i++) + S(i) += fix_mul(DD_(i) + DD_(i - 1), 7233); + for (i = 0; i < sn; i++) + D(i) += fix_mul(SS_(i) + SS_(i + 1), 3633); + for (i = 0; i < dn; i++) + S(i) = fix_mul(S(i), 5038); /*5038 */ + for (i = 0; i < sn; i++) + D(i) = fix_mul(D(i), 6659); /*6660 */ + } + } +} + +/* */ +/* Inverse 9-7 wavelet transform in 1-D. */ +/* */ +static void dwt_decode_1_real(int *a, int dn, int sn, int cas) { + int i; + if (!cas) { + if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */ + for (i = 0; i < sn; i++) + S(i) = fix_mul(S(i), 10078); /* 10076 */ + for (i = 0; i < dn; i++) + D(i) = fix_mul(D(i), 13318); /* 13320 */ + for (i = 0; i < sn; i++) + S(i) -= fix_mul(D_(i - 1) + D_(i), 3633); + for (i = 0; i < dn; i++) + D(i) -= fix_mul(S_(i) + S_(i + 1), 7233); + for (i = 0; i < sn; i++) + S(i) += fix_mul(D_(i - 1) + D_(i), 434); + for (i = 0; i < dn; i++) + D(i) += fix_mul(S_(i) + S_(i + 1), 12994); /* 12993 */ + } + } else { + if ((sn > 0) || (dn > 1)) { /* NEW : CASE ONE ELEMENT */ + for (i = 0; i < sn; i++) + D(i) = fix_mul(D(i), 10078); /* 10076 */ + for (i = 0; i < dn; i++) + S(i) = fix_mul(S(i), 13318); /* 13320 */ + for (i = 0; i < sn; i++) + D(i) -= fix_mul(SS_(i) + SS_(i + 1), 3633); + for (i = 0; i < dn; i++) + S(i) -= fix_mul(DD_(i) + DD_(i - 1), 7233); + for (i = 0; i < sn; i++) + D(i) += fix_mul(SS_(i) + SS_(i + 1), 434); + for (i = 0; i < dn; i++) + S(i) += fix_mul(DD_(i) + DD_(i - 1), 12994); /* 12993 */ + } + } +} + +static void dwt_encode_stepsize(int stepsize, int numbps, opj_stepsize_t *bandno_stepsize) { + int p, n; + p = int_floorlog2(stepsize) - 13; + n = 11 - int_floorlog2(stepsize); + bandno_stepsize->mant = (n < 0 ? stepsize >> -n : stepsize << n) & 0x7ff; + bandno_stepsize->expn = numbps - p; +} + +/* +========================================================== + DWT interface +========================================================== +*/ /* */ /* Forward 5-3 wavelet tranform in 2-D. */ /* */ -void dwt_encode(tcd_tilecomp_t * tilec) -{ +void dwt_encode(opj_tcd_tilecomp_t * tilec) { int i, j, k; - int* a; - int* aj; - int* bj; + int *a = NULL; + int *aj = NULL; + int *bj = NULL; int w, l; - + w = tilec->x1-tilec->x0; l = tilec->numresolutions-1; a = tilec->data; - + for (i = 0; i < l; i++) { - 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 */ - int cas_col; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ - int cas_row; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ + int 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 */ + int cas_col; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ + int cas_row; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ int dn, sn; - + 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; - - + sn = rh1; dn = rh - rh1; - bj=(int*)malloc(rh*sizeof(int)); - for (j=0; j */ /* Inverse 5-3 wavelet tranform in 2-D. */ /* */ -void dwt_decode(tcd_tilecomp_t * tilec, int stop) -{ +void dwt_decode(opj_tcd_tilecomp_t * tilec, int stop) { int i, j, k; - int* a; - int* aj; - int* bj; + int *a = NULL; + int *aj = NULL; + int *bj = NULL; int w, l; - + w = tilec->x1-tilec->x0; l = tilec->numresolutions-1; a = tilec->data; - + for (i = l - 1; i >= stop; i--) { - 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 */ - int cas_col; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ - int cas_row; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ + int 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 */ + int cas_col; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ + int cas_row; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ int dn, sn; - + 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; - + sn = rw1; dn = rw - rw1; - bj=(int*)malloc(rw*sizeof(int)); + bj = (int*)opj_malloc(rw * sizeof(int)); for (j = 0; j < rh; j++) { - aj = a+j*w; + aj = a + j*w; dwt_interleave_h(aj, bj, dn, sn, cas_row); dwt_decode_1(bj, dn, sn, cas_row); for (k = 0; k < rw; k++) aj[k] = bj[k]; } - free(bj); - + opj_free(bj); + sn = rh1; dn = rh - rh1; - bj=(int*)malloc(rh*sizeof(int)); + bj = (int*)opj_malloc(rh * sizeof(int)); for (j = 0; j < rw; j++) { - aj = a+j; + aj = a + j; dwt_interleave_v(aj, bj, dn, sn, w, cas_col); dwt_decode_1(bj, dn, sn, cas_col); for (k = 0; k < rh; k++) aj[k * w] = bj[k]; } - free(bj); - + opj_free(bj); } } @@ -311,8 +399,7 @@ void dwt_decode(tcd_tilecomp_t * tilec, int stop) /* */ /* Get gain of 5-3 wavelet transform. */ /* */ -int dwt_getgain(int orient) -{ +int dwt_getgain(int orient) { if (orient == 0) return 0; if (orient == 1 || orient == 2) @@ -323,143 +410,63 @@ int dwt_getgain(int orient) /* */ /* Get norm of 5-3 wavelet. */ /* */ -double dwt_getnorm(int level, int orient) -{ +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 dn, int sn, int cas) -{ - int i; - if (!cas) { - if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */ - for (i = 0; i < dn; i++) - D(i) -= fix_mul(S_(i) + S_(i + 1), 12993); - for (i = 0; i < sn; i++) - S(i) -= fix_mul(D_(i - 1) + D_(i), 434); - for (i = 0; i < dn; i++) - D(i) += fix_mul(S_(i) + S_(i + 1), 7233); - for (i = 0; i < sn; i++) - S(i) += fix_mul(D_(i - 1) + D_(i), 3633); - for (i = 0; i < dn; i++) - D(i) = fix_mul(D(i), 5038); /*5038 */ - for (i = 0; i < sn; i++) - S(i) = fix_mul(S(i), 6659); /*6660 */ - } - } else { - if ((sn > 0) || (dn > 1)) { /* NEW : CASE ONE ELEMENT */ - for (i = 0; i < dn; i++) - S(i) -= fix_mul(DD_(i) + DD_(i - 1), 12993); - for (i = 0; i < sn; i++) - D(i) -= fix_mul(SS_(i) + SS_(i + 1), 434); - for (i = 0; i < dn; i++) - S(i) += fix_mul(DD_(i) + DD_(i - 1), 7233); - for (i = 0; i < sn; i++) - D(i) += fix_mul(SS_(i) + SS_(i + 1), 3633); - for (i = 0; i < dn; i++) - S(i) = fix_mul(S(i), 5038); /*5038 */ - for (i = 0; i < sn; i++) - D(i) = fix_mul(D(i), 6659); /*6660 */ - } - } -} - -/* */ -/* Inverse 9-7 wavelet transform in 1-D. */ -/* */ -void dwt_decode_1_real(int *a, int dn, int sn, int cas) -{ - int i; - if (!cas) { - if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */ - for (i = 0; i < sn; i++) - S(i) = fix_mul(S(i), 10078); /* 10076 */ - for (i = 0; i < dn; i++) - D(i) = fix_mul(D(i), 13318); /* 13320 */ - for (i = 0; i < sn; i++) - S(i) -= fix_mul(D_(i - 1) + D_(i), 3633); - for (i = 0; i < dn; i++) - D(i) -= fix_mul(S_(i) + S_(i + 1), 7233); - for (i = 0; i < sn; i++) - S(i) += fix_mul(D_(i - 1) + D_(i), 434); - for (i = 0; i < dn; i++) - D(i) += fix_mul(S_(i) + S_(i + 1), 12994); /* 12993 */ - } - } else { - if ((sn > 0) || (dn > 1)) { /* NEW : CASE ONE ELEMENT */ - for (i = 0; i < sn; i++) - D(i) = fix_mul(D(i), 10078); /* 10076 */ - for (i = 0; i < dn; i++) - S(i) = fix_mul(S(i), 13318); /* 13320 */ - for (i = 0; i < sn; i++) - D(i) -= fix_mul(SS_(i) + SS_(i + 1), 3633); - for (i = 0; i < dn; i++) - S(i) -= fix_mul(DD_(i) + DD_(i - 1), 7233); - for (i = 0; i < sn; i++) - D(i) += fix_mul(SS_(i) + SS_(i + 1), 434); - for (i = 0; i < dn; i++) - S(i) += fix_mul(DD_(i) + DD_(i - 1), 12994); /* 12993 */ - } - } -} - /* */ /* Forward 9-7 wavelet transform in 2-D. */ /* */ -void dwt_encode_real(tcd_tilecomp_t * tilec) -{ +void dwt_encode_real(opj_tcd_tilecomp_t * tilec) { int i, j, k; - int* a; - int* aj; - int* bj; + int *a = NULL; + int *aj = NULL; + int *bj = NULL; int w, l; - + w = tilec->x1-tilec->x0; l = tilec->numresolutions-1; a = tilec->data; - + for (i = 0; i < l; i++) { - 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 */ - int cas_col; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ - int cas_row; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ + int 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 */ + int cas_col; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ + int cas_row; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ int dn, sn; - + 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; - + sn = rh1; dn = rh - rh1; - bj=(int*)malloc(rh*sizeof(int)); + bj = (int*)opj_malloc(rh * sizeof(int)); for (j = 0; j < rw; j++) { aj = a + j; for (k = 0; k < rh; k++) bj[k] = aj[k*w]; dwt_encode_1_real(bj, dn, sn, cas_col); dwt_deinterleave_v(bj, aj, dn, sn, w, cas_col); } - free(bj); - + opj_free(bj); + sn = rw1; dn = rw - rw1; - bj=(int*)malloc(rw*sizeof(int)); + bj = (int*)opj_malloc(rw * sizeof(int)); for (j = 0; j < rh; j++) { aj = a + j * w; for (k = 0; k < rw; k++) bj[k] = aj[k]; dwt_encode_1_real(bj, dn, sn, cas_row); dwt_deinterleave_h(bj, aj, dn, sn, cas_row); } - free(bj); + opj_free(bj); } } @@ -467,57 +474,55 @@ void dwt_encode_real(tcd_tilecomp_t * tilec) /* */ /* Inverse 9-7 wavelet transform in 2-D. */ /* */ -void dwt_decode_real(tcd_tilecomp_t * tilec, int stop) -{ - +void dwt_decode_real(opj_tcd_tilecomp_t * tilec, int stop) { int i, j, k; - int* a; - int* aj; - int* bj; + int *a = NULL; + int *aj = NULL; + int *bj = NULL; int w, l; - + w = tilec->x1-tilec->x0; l = tilec->numresolutions-1; a = tilec->data; - + for (i = l-1; i >= stop; i--) { - 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 */ - int cas_col; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ - int cas_row; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ + int 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 */ + int cas_col; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ + int cas_row; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ int dn, sn; - + 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_col = tilec->resolutions[l - i].x0 % 2; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ cas_row = tilec->resolutions[l - i].y0 % 2; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ - + sn = rw1; dn = rw-rw1; - bj = (int*)malloc(rw * sizeof(int)); + bj = (int*)opj_malloc(rw * sizeof(int)); for (j = 0; j < rh; j++) { - aj = a+j*w; + aj = a + j * w; dwt_interleave_h(aj, bj, dn, sn, cas_col); dwt_decode_1_real(bj, dn, sn, cas_col); for (k = 0; k < rw; k++) aj[k] = bj[k]; } - free(bj); - + opj_free(bj); + sn = rh1; dn = rh-rh1; - bj = (int*)malloc(rh * sizeof(int)); - for (j=0; j */ /* Get gain of 9-7 wavelet transform. */ /* */ -int dwt_getgain_real(int orient) -{ - (void)orient; +int dwt_getgain_real(int orient) { return 0; } /* */ /* Get norm of 9-7 wavelet. */ /* */ -double dwt_getnorm_real(int level, int orient) -{ +double dwt_getnorm_real(int level, int orient) { return dwt_norms_real[orient][level]; } + +void dwt_calc_explicit_stepsizes(opj_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_real[orient][level]; + stepsize = (1 << (gain + 1)) / norm; + } + dwt_encode_stepsize((int) floor(stepsize * 8192.0), prec + gain, &tccp->stepsizes[bandno]); + } +} diff --git a/libopenjpeg/dwt.h b/libopenjpeg/dwt.h index a9c30ca7..4cda5eda 100644 --- a/libopenjpeg/dwt.h +++ b/libopenjpeg/dwt.h @@ -1,7 +1,9 @@ /* - * Copyright (c) 2001-2002, David Janssens + * 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 + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,56 +28,126 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "tcd.h" - #ifndef __DWT_H #define __DWT_H +/** +@file dwt.h +@brief Implementation of a discrete wavelet transform (DWT) -/* - * Apply a reversible DWT transform to a component of an image - * tilec : tile component information (present tile) - */ -/* void dwt_encode(int* a, int w, int h, int l); */ -void dwt_encode(tcd_tilecomp_t * tilec); -/* - * Apply a reversible inverse DWT transform to a component of an image - * tilec : tile component information (present tile) - */ -void dwt_decode(tcd_tilecomp_t * tilec, int stop); +The functions in DWT.C have for goal to realize forward and inverse discret wavelet +transform with filter 5-3 (reversible) and filter 9-7 (irreversible). The functions in +DWT.C are used by some function in TCD.C. +*/ -/* - * Get the gain of a subband for the reversible DWT - * orient: number that identifies the subband (0->LL, 1->HL, 2->LH, 3->HH) - */ +/** @defgroup DWT DWT - Implementation of a discrete wavelet transform */ +/*@{*/ + +/** @name Local static functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Forward lazy transform (horizontal) +*/ +static void dwt_deinterleave_h(int *a, int *b, int dn, int sn, int cas); +/** +Forward lazy transform (vertical) +*/ +static void dwt_deinterleave_v(int *a, int *b, int dn, int sn, int x, int cas); +/** +Inverse lazy transform (horizontal) +*/ +static void dwt_interleave_h(int *a, int *b, int dn, int sn, int cas); +/** +Inverse lazy transform (vertical) +*/ +static void dwt_interleave_v(int *a, int *b, int dn, int sn, int x, int cas); +/** +Forward 5-3 wavelet tranform in 1-D +*/ +static void dwt_encode_1(int *a, int dn, int sn, int cas); +/** +Inverse 5-3 wavelet tranform in 1-D +*/ +static void dwt_decode_1(int *a, int dn, int sn, int cas); +/** +Forward 9-7 wavelet transform in 1-D +*/ +static void dwt_encode_1_real(int *a, int dn, int sn, int cas); +/** +Inverse 9-7 wavelet transform in 1-D +*/ +static void dwt_decode_1_real(int *a, int dn, int sn, int cas); +/** +FIXME : comment ??? +*/ +static void dwt_encode_stepsize(int stepsize, int numbps, opj_stepsize_t *bandno_stepsize); +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Forward 5-3 wavelet tranform in 2-D. +Apply a reversible DWT transform to a component of an image. +@param tilec Tile component information (current tile) +*/ +void dwt_encode(opj_tcd_tilecomp_t * tilec); +/** +Inverse 5-3 wavelet tranform in 2-D. +Apply a reversible inverse DWT transform to a component of an image. +@param tilec Tile component information (current tile) +@param stop FIXME Number of decoded resolution levels ? +*/ +void dwt_decode(opj_tcd_tilecomp_t * tilec, int stop); +/** +Get the gain of a subband for the reversible 5-3 DWT. +@param orient Number that identifies the subband (0->LL, 1->HL, 2->LH, 3->HH) +@return Returns 0 if orient = 0, returns 1 if orient = 1 or 2, returns 2 otherwise +*/ 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 - */ +/** +Get the norm of a wavelet function of a subband at a specified level for the reversible 5-3 DWT. +@param level Level of the wavelet function +@param orient Band of the wavelet function +@return Returns the norm of the wavelet function +*/ double dwt_getnorm(int level, int orient); - -/* - * Apply an irreversible DWT transform to a component of an image - */ -void dwt_encode_real(tcd_tilecomp_t * tilec); - -/* - * Apply an irreversible inverse DWT transform to a component of an image - */ -void dwt_decode_real(tcd_tilecomp_t * tilec, 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) - */ +/** +Forward 9-7 wavelet transform in 2-D. +Apply an irreversible DWT transform to a component of an image. +@param tilec Tile component information (current tile) +*/ +void dwt_encode_real(opj_tcd_tilecomp_t * tilec); +/** +Inverse 9-7 wavelet transform in 2-D. +Apply an irreversible inverse DWT transform to a component of an image. +@param tilec Tile component information (current tile) +@param stop FIXME Number of decoded resolution levels ? +*/ +void dwt_decode_real(opj_tcd_tilecomp_t * tilec, int stop); +/** +Get the gain of a subband for the irreversible 9-7 DWT. +@param orient Number that identifies the subband (0->LL, 1->HL, 2->LH, 3->HH) +@return Returns the gain of the 9-7 wavelet transform +*/ 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 - */ +/** +Get the norm of a wavelet function of a subband at a specified level for the irreversible 9-7 DWT +@param level Level of the wavelet function +@param orient Band of the wavelet function +@return Returns the norm of the 9-7 wavelet +*/ double dwt_getnorm_real(int level, int orient); +/** +FIXME : comment ??? +@param tccp +@param prec +*/ +void dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, int prec); +/* ----------------------------------------------------------------------- */ +/*@}*/ -#endif +/*@}*/ + +#endif /* __DWT_H */ diff --git a/libopenjpeg/event.c b/libopenjpeg/event.c new file mode 100644 index 00000000..9b87f734 --- /dev/null +++ b/libopenjpeg/event.c @@ -0,0 +1,148 @@ + +/* + * Copyright (c) 2005, Hervé Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "opj_includes.h" + +opj_event_mgr_t* opj_set_event_mgr(opj_common_ptr cinfo, opj_event_mgr_t *event_mgr, void *context) { + if(cinfo) { + opj_event_mgr_t *previous = cinfo->event_mgr; + cinfo->event_mgr = event_mgr; + cinfo->client_data = context; + return previous; + } + + return NULL; +} + +bool opg_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...) { +#define MSG_SIZE 512 /* 512 bytes should be more than enough for a short message */ + opj_msg_callback msg_handler = NULL; + + opj_event_mgr_t *event_mgr = cinfo->event_mgr; + if(event_mgr != NULL) { + switch(event_type) { + case EVT_ERROR: + msg_handler = event_mgr->error_handler; + break; + case EVT_WARNING: + msg_handler = event_mgr->warning_handler; + break; + case EVT_INFO: + msg_handler = event_mgr->info_handler; + break; + default: + break; + } + if(msg_handler == NULL) { + return false; + } + } else { + return false; + } + + if ((fmt != NULL) && (event_mgr != NULL)) { + va_list arg; + int str_length, i, j; + char message[MSG_SIZE]; + memset(message, 0, MSG_SIZE); + /* initialize the optional parameter list */ + va_start(arg, fmt); + /* check the length of the format string */ + str_length = (strlen(fmt) > MSG_SIZE) ? MSG_SIZE : strlen(fmt); + /* parse the format string and put the result in 'message' */ + for (i = 0, j = 0; i < str_length; ++i) { + if (fmt[i] == '%') { + if (i + 1 < str_length) { + switch(tolower(fmt[i + 1])) { + case '%' : + message[j++] = '%'; + break; + case 'o' : /* octal numbers */ + { + char tmp[16]; + _itoa(va_arg(arg, int), tmp, 8); + strcat(message, tmp); + j += strlen(tmp); + ++i; + break; + } + case 'i' : /* decimal numbers */ + case 'd' : + { + char tmp[16]; + _itoa(va_arg(arg, int), tmp, 10); + strcat(message, tmp); + j += strlen(tmp); + ++i; + break; + } + case 'x' : /* hexadecimal numbers */ + { + char tmp[16]; + _itoa(va_arg(arg, int), tmp, 16); + strcat(message, tmp); + j += strlen(tmp); + ++i; + break; + } + case 's' : /* strings */ + { + char *tmp = va_arg(arg, char*); + strcat(message, tmp); + j += strlen(tmp); + ++i; + break; + } + case 'f' : /* floats */ + { + char tmp[16]; + double value = va_arg(arg, double); + sprintf(tmp, "%f", value); + strcat(message, tmp); + j += strlen(tmp); + ++i; + break; + } + }; + } else { + message[j++] = fmt[i]; + } + } else { + message[j++] = fmt[i]; + }; + } + /* deinitialize the optional parameter list */ + va_end(arg); + + /* output the message to the user program */ + msg_handler(message, cinfo->client_data); + } + + return true; +} + diff --git a/libopenjpeg/event.h b/libopenjpeg/event.h new file mode 100644 index 00000000..e68c3200 --- /dev/null +++ b/libopenjpeg/event.h @@ -0,0 +1,61 @@ + +/* + * Copyright (c) 2005, Hervé Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef __EVENT_H +#define __EVENT_H +/** +@file event.h +@brief Implementation of a event callback system + +The functions in EVENT.C have for goal to send output messages (errors, warnings, debug) to the user. +*/ + +#define EVT_ERROR 1 /**< Error event type */ +#define EVT_WARNING 2 /**< Warning event type */ +#define EVT_INFO 4 /**< Debug event type */ + +/** @defgroup EVENT EVENT - Implementation of a event callback system */ +/*@{*/ + +/** @name Exported functions (see also openjpeg.h) */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Write formatted data to a string and send the string to a user callback. +@param cinfo Codec context info +@param event_type Event type or callback to use to send the message +@param fmt Format-control string (plus optionnal arguments) +@return Returns true if successful, returns false otherwise +*/ +bool opg_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...); +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __EVENT_H */ \ No newline at end of file diff --git a/libopenjpeg/fix.c b/libopenjpeg/fix.c index 81cc5f1f..701137e1 100644 --- a/libopenjpeg/fix.c +++ b/libopenjpeg/fix.c @@ -1,5 +1,9 @@ /* - * Copyright (c) 2001-2002, David Janssens + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,7 +29,6 @@ */ #include "fix.h" -#include /*Add Antonin : multbug1*/ #ifdef WIN32 #define int64 __int64 @@ -33,31 +36,10 @@ #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*/ - -int fix_mul(int a, int b) /* Luke Lee optimized : 11/16/2004*/ -{ +int fix_mul(int a, int b) { int64 temp = (int64) a * (int64) b >> 12; return (int) ((temp >> 1) + (temp & 1)) ; } + + diff --git a/libopenjpeg/fix.h b/libopenjpeg/fix.h index 768cada2..28d2e7c4 100644 --- a/libopenjpeg/fix.h +++ b/libopenjpeg/fix.h @@ -1,5 +1,9 @@ /* - * Copyright (c) 2001-2002, David Janssens + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,7 +31,24 @@ #ifndef __FIX_H #define __FIX_H +/** +@file fix.h +@brief Implementation of operations of specific multiplication (FIX) +The functions in FIX.C have for goal to realize specific multiplication. +*/ + +/** @defgroup FIX FIX - Implementation of operations of specific multiplication */ +/*@{*/ + +/** +Multiply two fixed-precision rational numbers. +@param a +@param b +@return Returns a * b +*/ int fix_mul(int a, int b); -#endif +/*@}*/ + +#endif /* __FIX_H */ diff --git a/libopenjpeg/image.c b/libopenjpeg/image.c new file mode 100644 index 00000000..0bdaa223 --- /dev/null +++ b/libopenjpeg/image.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2005, Hervé Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "opj_includes.h" + +opj_image_t* opj_image_create0() { + opj_image_t *image = (opj_image_t*)opj_malloc(sizeof(opj_image_t)); + return image; +} + +opj_image_t *opj_image_create(int numcmpts, opj_image_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc) { + int compno; + opj_image_t *image = NULL; + + image = (opj_image_t*)opj_malloc(sizeof(opj_image_t)); + if(image) { + image->color_space = clrspc; + image->numcomps = numcmpts; + /* allocate memory for the per-component information */ + image->comps = (opj_image_comp_t*)opj_malloc(image->numcomps * sizeof(opj_image_comp_t)); + if(!image->comps) { + opj_image_destroy(image); + return NULL; + } + /* create the individual image components */ + for(compno = 0; compno < numcmpts; compno++) { + opj_image_comp_t *comp = &image->comps[compno]; + comp->dx = cmptparms[compno].dx; + comp->dy = cmptparms[compno].dy; + comp->w = cmptparms[compno].w; + comp->h = cmptparms[compno].h; + comp->x0 = cmptparms[compno].x0; + comp->y0 = cmptparms[compno].y0; + comp->prec = cmptparms[compno].prec; + comp->bpp = cmptparms[compno].bpp; + comp->sgnd = cmptparms[compno].sgnd; + comp->data = (int*)opj_malloc(comp->w * comp->h * sizeof(int)); + if(!comp->data) { + opj_image_destroy(image); + return NULL; + } + } + } + + return image; +} + +void opj_image_destroy(opj_image_t *image) { + int i; + if(image) { + if(image->comps) { + /* image components */ + for(i = 0; i < image->numcomps; i++) { + opj_image_comp_t *image_comp = &image->comps[i]; + if(image_comp->data) { + opj_free(image_comp->data); + } + } + opj_free(image->comps); + } + opj_free(image); + } +} + diff --git a/libopenjpeg/image.h b/libopenjpeg/image.h new file mode 100644 index 00000000..8ced7f9a --- /dev/null +++ b/libopenjpeg/image.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2005, Hervé Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef __IMAGE_H +#define __IMAGE_H +/** +@file image.h +@brief Implementation of operations on images (IMAGE) + +The functions in IMAGE.C have for goal to realize operations on images. +*/ + +/** @defgroup IMAGE IMAGE - Implementation of operations on images */ +/*@{*/ + +/** +Create an empty image +@todo this function should be removed +@return returns an empty image if successful, returns NULL otherwise +*/ +opj_image_t* opj_image_create0(); + +/*@}*/ + +#endif /* __IMAGE_H */ + diff --git a/libopenjpeg/int.c b/libopenjpeg/int.c index a5e6a582..1367f0db 100644 --- a/libopenjpeg/int.c +++ b/libopenjpeg/int.c @@ -1,5 +1,9 @@ /* - * Copyright (c) 2001-2002, David Janssens + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,37 +28,17 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "int.h" +#include "opj_includes.h" -/* - * Get the minimum of two integers. - * - * returns a if a < b else b - */ -int int_min(int a, int 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; +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) -{ +int int_clamp(int a, int min, int max) { if (a < min) return min; if (a > max) @@ -62,54 +46,27 @@ int int_clamp(int a, int min, int max) return a; } -/* - * Get absolute value of integer. - */ -int int_abs(int a) -{ +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) -{ +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) -{ +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) -{ +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 int_floorlog2(int a) { int l; for (l = 0; a > 1; l++) { a >>= 1; } return l; } + diff --git a/libopenjpeg/int.h b/libopenjpeg/int.h index 52add1ac..d838e968 100644 --- a/libopenjpeg/int.h +++ b/libopenjpeg/int.h @@ -1,5 +1,9 @@ /* - * Copyright (c) 2001-2002, David Janssens + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,65 +28,69 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "j2k.h" - #ifndef __INT_H #define __INT_H +/** +@file int.h +@brief Implementation of operations on integers (INT) -/* - * Get the minimum of two integers. - * - * returns a if a < b else b - */ +The functions in INT.C have for goal to realize operations on integers. +*/ + +/** @defgroup INT INT - Implementation of operations on integers */ +/*@{*/ + +/** @name Exported functions (see also openjpeg.h) */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Get the minimum of two integers +@return Returns a if a < b else b +*/ int int_min(int a, int b); - -/* - * Get the maximum of two integers. - * - * returns a if a > b else b - */ +/** +Get the maximum of two integers +@return 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) - */ +/** +Clamp an integer inside an interval +@return +
    +
  • Returns a if (min < a < max) +
  • Returns max if (a > max) +
  • Returns min if (a < min) +
+*/ int int_clamp(int a, int min, int max); - -/* - * Get absolute value of integer. - */ +/** +@return Get absolute value of integer +*/ int int_abs(int a); - -/* - * Divide an integer and round upwards. - * - * a divided by b - */ +/** +Divide an integer and round upwards +@return Returns 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 - */ -LIBJ2K_API int int_ceildivpow2(int a, int b); - -/* - * Divide an integer by a power of 2 and round downwards. - * - * a divided by 2^b - */ -LIBJ2K_API int int_floordivpow2(int a, int b); - -/* - * Get logarithm of an integer and round downwards. - * - * log2(a) - */ +/** +Divide an integer by a power of 2 and round upwards +@return Returns a divided by 2^b +*/ +int int_ceildivpow2(int a, int b); +/** +Divide an integer by a power of 2 and round downwards +@return Returns a divided by 2^b +*/ +int int_floordivpow2(int a, int b); +/** +Get logarithm of an integer and round downwards +@return Returns log2(a) +*/ int int_floorlog2(int a); +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + #endif diff --git a/libopenjpeg/j2k.c b/libopenjpeg/j2k.c index 9e020db1..d633af1e 100644 --- a/libopenjpeg/j2k.c +++ b/libopenjpeg/j2k.c @@ -1,498 +1,422 @@ /* -* 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. -*/ + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ -#include -#include -#include -#include -#include +#include "opj_includes.h" -#include "j2k.h" -#include "cio.h" -#include "tcd.h" -#include "dwt.h" -#include "int.h" -#include "jpt.h" +/* ----------------------------------------------------------------------- */ -#define J2K_MS_SOC 0xff4f -#define J2K_MS_SOT 0xff90 -#define J2K_MS_SOD 0xff93 -#define J2K_MS_EOC 0xffd9 -#define J2K_MS_SIZ 0xff51 -#define J2K_MS_COD 0xff52 -#define J2K_MS_COC 0xff53 -#define J2K_MS_RGN 0xff5e -#define J2K_MS_QCD 0xff5c -#define J2K_MS_QCC 0xff5d -#define J2K_MS_POC 0xff5f -#define J2K_MS_TLM 0xff55 -#define J2K_MS_PLM 0xff57 -#define J2K_MS_PLT 0xff58 -#define J2K_MS_PPM 0xff60 -#define J2K_MS_PPT 0xff61 -#define J2K_MS_SOP 0xff91 -#define J2K_MS_EPH 0xff92 -#define J2K_MS_CRG 0xff63 -#define J2K_MS_COM 0xff64 - -#define J2K_STATE_MHSOC 0x0001 -#define J2K_STATE_MHSIZ 0x0002 -#define J2K_STATE_MH 0x0004 -#define J2K_STATE_TPHSOT 0x0008 -#define J2K_STATE_TPH 0x0010 -#define J2K_STATE_MT 0x0020 -#define J2K_STATE_NEOC 0x0040 - - -jmp_buf j2k_error; - -static int j2k_state; -static int j2k_curtileno; -j2k_tcp_t j2k_default_tcp; -static unsigned char *j2k_eot; -static int j2k_sot_start; -static int pos_correction; - -static j2k_image_t *j2k_img; -static j2k_cp_t *j2k_cp; - -static unsigned char **j2k_tile_data; -static int *j2k_tile_len; - -static info_image info_IM; - -/* Add Patrick */ -void j2k_clean() -{ - int tileno = 0; -#ifndef NO_PACKETS_DECODING - tcd_free_encode(j2k_img, j2k_cp, j2k_curtileno); -#endif - - 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) -{ +void j2k_dump_image(FILE *fd, opj_image_t * img) { int compno; - fprintf(stdout, "image {\n"); - fprintf(stdout, " x0=%d, y0=%d, x1=%d, y1=%d\n", img->x0, img->y0, - img->x1, img->y1); - fprintf(stdout, " numcomps=%d\n", img->numcomps); + fprintf(fd, "image {\n"); + fprintf(fd, " x0=%d, y0=%d, x1=%d, y1=%d\n", img->x0, img->y0, img->x1, img->y1); + fprintf(fd, " numcomps=%d\n", img->numcomps); for (compno = 0; compno < img->numcomps; compno++) { - j2k_comp_t *comp = &img->comps[compno]; - fprintf(stdout, " comp %d {\n", compno); - fprintf(stdout, " dx=%d, dy=%d\n", comp->dx, comp->dy); - fprintf(stdout, " prec=%d\n", comp->prec); - fprintf(stdout, " sgnd=%d\n", comp->sgnd); - fprintf(stdout, " }\n"); + opj_image_comp_t *comp = &img->comps[compno]; + fprintf(fd, " comp %d {\n", compno); + fprintf(fd, " dx=%d, dy=%d\n", comp->dx, comp->dy); + fprintf(fd, " prec=%d\n", comp->prec); + fprintf(fd, " sgnd=%d\n", comp->sgnd); + fprintf(fd, " }\n"); } - fprintf(stdout, "}\n"); + fprintf(fd, "}\n"); } -void j2k_dump_cp(j2k_image_t * img, j2k_cp_t * cp) -{ +void j2k_dump_cp(FILE *fd, opj_image_t * img, opj_cp_t * cp) { int tileno, compno, layno, bandno, resno, numbands; - fprintf(stdout, "coding parameters {\n"); - fprintf(stdout, " tx0=%d, ty0=%d\n", cp->tx0, cp->ty0); - fprintf(stdout, " tdx=%d, tdy=%d\n", cp->tdx, cp->tdy); - fprintf(stdout, " tw=%d, th=%d\n", cp->tw, cp->th); + fprintf(fd, "coding parameters {\n"); + fprintf(fd, " tx0=%d, ty0=%d\n", cp->tx0, cp->ty0); + fprintf(fd, " tdx=%d, tdy=%d\n", cp->tdx, cp->tdy); + fprintf(fd, " 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(stdout, " tile %d {\n", tileno); - fprintf(stdout, " csty=%x\n", tcp->csty); - fprintf(stdout, " prg=%d\n", tcp->prg); - fprintf(stdout, " numlayers=%d\n", tcp->numlayers); - fprintf(stdout, " mct=%d\n", tcp->mct); - fprintf(stdout, " rates="); + opj_tcp_t *tcp = &cp->tcps[tileno]; + fprintf(fd, " tile %d {\n", tileno); + fprintf(fd, " csty=%x\n", tcp->csty); + fprintf(fd, " prg=%d\n", tcp->prg); + fprintf(fd, " numlayers=%d\n", tcp->numlayers); + fprintf(fd, " mct=%d\n", tcp->mct); + fprintf(fd, " rates="); for (layno = 0; layno < tcp->numlayers; layno++) { - fprintf(stdout, "%d ", tcp->rates[layno]); + fprintf(fd, "%d ", tcp->rates[layno]); } - fprintf(stdout, "\n"); + fprintf(fd, "\n"); for (compno = 0; compno < img->numcomps; compno++) { - j2k_tccp_t *tccp = &tcp->tccps[compno]; - fprintf(stdout, " comp %d {\n", compno); - fprintf(stdout, " csty=%x\n", tccp->csty); - fprintf(stdout, " numresolutions=%d\n", tccp->numresolutions); - fprintf(stdout, " cblkw=%d\n", tccp->cblkw); - fprintf(stdout, " cblkh=%d\n", tccp->cblkh); - fprintf(stdout, " cblksty=%x\n", tccp->cblksty); - fprintf(stdout, " qmfbid=%d\n", tccp->qmfbid); - fprintf(stdout, " qntsty=%d\n", tccp->qntsty); - fprintf(stdout, " numgbits=%d\n", tccp->numgbits); - fprintf(stdout, " roishift=%d\n", tccp->roishift); - fprintf(stdout, " stepsizes="); - numbands = - tccp->qntsty == - J2K_CCP_QNTSTY_SIQNT ? 1 : tccp->numresolutions * 3 - 2; + opj_tccp_t *tccp = &tcp->tccps[compno]; + fprintf(fd, " comp %d {\n", compno); + fprintf(fd, " csty=%x\n", tccp->csty); + fprintf(fd, " numresolutions=%d\n", tccp->numresolutions); + fprintf(fd, " cblkw=%d\n", tccp->cblkw); + fprintf(fd, " cblkh=%d\n", tccp->cblkh); + fprintf(fd, " cblksty=%x\n", tccp->cblksty); + fprintf(fd, " qmfbid=%d\n", tccp->qmfbid); + fprintf(fd, " qntsty=%d\n", tccp->qntsty); + fprintf(fd, " numgbits=%d\n", tccp->numgbits); + fprintf(fd, " roishift=%d\n", tccp->roishift); + fprintf(fd, " stepsizes="); + numbands = tccp->qntsty == J2K_CCP_QNTSTY_SIQNT ? 1 : tccp->numresolutions * 3 - 2; for (bandno = 0; bandno < numbands; bandno++) { - fprintf(stdout, "(%d,%d) ", tccp->stepsizes[bandno].mant, - tccp->stepsizes[bandno].expn); + fprintf(fd, "(%d,%d) ", tccp->stepsizes[bandno].mant, + tccp->stepsizes[bandno].expn); } - fprintf(stdout, "\n"); + fprintf(fd, "\n"); if (tccp->csty & J2K_CCP_CSTY_PRT) { - fprintf(stdout, " prcw="); - for (resno = 0; resno < tccp->numresolutions; resno++) { - fprintf(stdout, "%d ", tccp->prcw[resno]); - } - fprintf(stdout, "\n"); - fprintf(stdout, " prch="); - for (resno = 0; resno < tccp->numresolutions; resno++) { - fprintf(stdout, "%d ", tccp->prch[resno]); - } - fprintf(stdout, "\n"); + fprintf(fd, " prcw="); + for (resno = 0; resno < tccp->numresolutions; resno++) { + fprintf(fd, "%d ", tccp->prcw[resno]); + } + fprintf(fd, "\n"); + fprintf(fd, " prch="); + for (resno = 0; resno < tccp->numresolutions; resno++) { + fprintf(fd, "%d ", tccp->prch[resno]); + } + fprintf(fd, "\n"); } - fprintf(stdout, " }\n"); + fprintf(fd, " }\n"); } - fprintf(stdout, " }\n"); + fprintf(fd, " }\n"); } - fprintf(stdout, "}\n"); + fprintf(fd, "}\n"); } -void j2k_write_soc() -{ - cio_write(J2K_MS_SOC, 2); +/* ----------------------------------------------------------------------- */ + +static void j2k_write_soc(opj_j2k_t *j2k) { + opj_cio_t *cio = j2k->cio; + cio_write(cio, J2K_MS_SOC, 2); } -void j2k_read_soc() -{ - j2k_state = J2K_STATE_MHSIZ; +static void j2k_read_soc(opj_j2k_t *j2k) { + j2k->state = J2K_STATE_MHSIZ; } -void j2k_write_siz() -{ +static void j2k_write_siz(opj_j2k_t *j2k) { int i; int lenp, len; + + opj_cio_t *cio = j2k->cio; + opj_image_t *image = j2k->image; + opj_cp_t *cp = j2k->cp; - 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 */ + cio_write(cio, J2K_MS_SIZ, 2); /* SIZ */ + lenp = cio_tell(cio); + cio_skip(cio, 2); + cio_write(cio, 0, 2); /* Rsiz (capabilities) */ + cio_write(cio, image->x1, 4); /* Xsiz */ + cio_write(cio, image->y1, 4); /* Ysiz */ + cio_write(cio, image->x0, 4); /* X0siz */ + cio_write(cio, image->y0, 4); /* Y0siz */ + cio_write(cio, cp->tdx, 4); /* XTsiz */ + cio_write(cio, cp->tdy, 4); /* YTsiz */ + cio_write(cio, cp->tx0, 4); /* XT0siz */ + cio_write(cio, cp->ty0, 4); /* YT0siz */ + cio_write(cio, image->numcomps, 2); /* Csiz */ + for (i = 0; i < image->numcomps; i++) { + cio_write(cio, image->comps[i].prec - 1 + (image->comps[i].sgnd << 7), 1); /* Ssiz_i */ + cio_write(cio, image->comps[i].dx, 1); /* XRsiz_i */ + cio_write(cio, image->comps[i].dy, 1); /* YRsiz_i */ } - len = cio_tell() - lenp; - cio_seek(lenp); - cio_write(len, 2); /* Lsiz */ - cio_seek(lenp + len); - + len = cio_tell(cio) - lenp; + cio_seek(cio, lenp); + cio_write(cio, len, 2); /* Lsiz */ + cio_seek(cio, lenp + len); } -void j2k_read_siz() -{ +static void j2k_read_siz(opj_j2k_t *j2k) { 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 */ + opj_cio_t *cio = j2k->cio; + opj_image_t *image = j2k->image; + opj_cp_t *cp = j2k->cp; - 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++) { + len = cio_read(cio, 2); /* Lsiz */ + cio_read(cio, 2); /* Rsiz (capabilities) */ + image->x1 = cio_read(cio, 4); /* Xsiz */ + image->y1 = cio_read(cio, 4); /* Ysiz */ + image->x0 = cio_read(cio, 4); /* X0siz */ + image->y0 = cio_read(cio, 4); /* Y0siz */ + cp->tdx = cio_read(cio, 4); /* XTsiz */ + cp->tdy = cio_read(cio, 4); /* YTsiz */ + cp->tx0 = cio_read(cio, 4); /* XT0siz */ + cp->ty0 = cio_read(cio, 4); /* YT0siz */ + + image->numcomps = cio_read(cio, 2); /* Csiz */ + image->comps = (opj_image_comp_t *) opj_malloc(image->numcomps * sizeof(opj_image_comp_t)); + for (i = 0; i < image->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 */ + tmp = cio_read(cio, 1); /* Ssiz_i */ + image->comps[i].prec = (tmp & 0x7f) + 1; + image->comps[i].sgnd = tmp >> 7; + image->comps[i].dx = cio_read(cio, 1); /* XRsiz_i */ + image->comps[i].dy = cio_read(cio, 1); /* YRsiz_i */ + + /* TODO: unused ? */ + w = int_ceildiv(image->x1 - image->x0, image->comps[i].dx); + h = int_ceildiv(image->y1 - image->y0, image->comps[i].dy); + + image->comps[i].resno_decoded = 0; /* number of resolution decoded */ + image->comps[i].factor = 0; /* reducing factor per 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; + cp->tw = int_ceildiv(image->x1 - cp->tx0, cp->tdx); + cp->th = int_ceildiv(image->y1 - cp->ty0, cp->tdy); + cp->tcps = (opj_tcp_t *) opj_malloc(cp->tw * cp->th * sizeof(opj_tcp_t)); + cp->tileno = (int *) opj_malloc(cp->tw * cp->th * sizeof(int)); + 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; + for (i = 0; i < cp->tw * cp->th; i++) { + cp->tcps[i].POC = 0; + cp->tcps[i].numpocs = 0; + cp->tcps[i].first = 1; } /* Initialization for PPM marker */ - j2k_cp->ppm = 0; - j2k_cp->ppm_data = NULL; - j2k_cp->ppm_data_first = NULL; - j2k_cp->ppm_previous = 0; - j2k_cp->ppm_store = 0; + cp->ppm = 0; + cp->ppm_data = NULL; + cp->ppm_data_first = NULL; + cp->ppm_previous = 0; + 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->default_tcp->tccps = (opj_tccp_t *) opj_malloc(sizeof(opj_tccp_t) * image->numcomps); + for (i = 0; i < cp->tw * cp->th; i++) { + cp->tcps[i].tccps = (opj_tccp_t *) opj_malloc(sizeof(opj_tccp_t) * image->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; - - + j2k->tile_data = (unsigned char **) opj_malloc(cp->tw * cp->th * sizeof(unsigned char *)); + j2k->tile_len = (int *) opj_malloc(cp->tw * cp->th * sizeof(int)); + j2k->state = J2K_STATE_MH; } -void j2k_write_com() -{ +static void j2k_write_com(opj_j2k_t *j2k) { 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); + + if(j2k->cp->comment) { + opj_cio_t *cio = j2k->cio; + char *comment = j2k->cp->comment; + + cio_write(cio, J2K_MS_COM, 2); + lenp = cio_tell(cio); + cio_skip(cio, 2); + cio_write(cio, 0, 2); + for (i = 0; i < strlen(comment); i++) { + cio_write(cio, comment[i], 1); + } + len = cio_tell(cio) - lenp; + cio_seek(cio, lenp); + cio_write(cio, len, 2); + cio_seek(cio, lenp + len); } - len = cio_tell() - lenp; - cio_seek(lenp); - cio_write(len, 2); - cio_seek(lenp + len); - } -void j2k_read_com() -{ +static void j2k_read_com(opj_j2k_t *j2k) { int len; - len = cio_read(2); - cio_skip(len - 2); - + opj_cio_t *cio = j2k->cio; + + len = cio_read(cio, 2); + cio_skip(cio, len - 2); } -void j2k_write_cox(int compno) -{ +static void j2k_write_cox(opj_j2k_t *j2k, int compno) { int i; - j2k_tcp_t *tcp; - j2k_tccp_t *tccp; - tcp = &j2k_cp->tcps[j2k_curtileno]; - tccp = &tcp->tccps[compno]; + + opj_cp_t *cp = j2k->cp; + opj_tcp_t *tcp = &cp->tcps[j2k->curtileno]; + opj_tccp_t *tccp = &tcp->tccps[compno]; + opj_cio_t *cio = j2k->cio; - 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) */ + cio_write(cio, tccp->numresolutions - 1, 1); /* SPcox (D) */ + cio_write(cio, tccp->cblkw - 2, 1); /* SPcox (E) */ + cio_write(cio, tccp->cblkh - 2, 1); /* SPcox (F) */ + cio_write(cio, tccp->cblksty, 1); /* SPcox (G) */ + cio_write(cio, 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) */ + cio_write(cio, tccp->prcw[i] + (tccp->prch[i] << 4), 1); /* SPcox (I_i) */ } } } -void j2k_read_cox(int compno) -{ +static void j2k_read_cox(opj_j2k_t *j2k, 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) */ - /*Check the reduce value*/ - j2k_cp->reduce=int_min((tccp->numresolutions)-1,j2k_cp->reduce); - 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) */ + + opj_cp_t *cp = j2k->cp; + opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp; + opj_tccp_t *tccp = &tcp->tccps[compno]; + opj_cio_t *cio = j2k->cio; + + tccp->numresolutions = cio_read(cio, 1) + 1; /* SPcox (D) */ + + /* check the reduce value */ + cp->reduce = int_min((tccp->numresolutions)-1, cp->reduce); + tccp->cblkw = cio_read(cio, 1) + 2; /* SPcox (E) */ + tccp->cblkh = cio_read(cio, 1) + 2; /* SPcox (F) */ + tccp->cblksty = cio_read(cio, 1); /* SPcox (G) */ + tccp->qmfbid = cio_read(cio, 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) */ + int tmp = cio_read(cio, 1); /* SPcox (I_i) */ tccp->prcw[i] = tmp & 0xf; tccp->prch[i] = tmp >> 4; } } } -void j2k_write_cod() -{ - j2k_tcp_t *tcp; +static void j2k_write_cod(opj_j2k_t *j2k) { + opj_cp_t *cp = NULL; + opj_tcp_t *tcp = NULL; int lenp, len; + + opj_cio_t *cio = j2k->cio; - cio_write(J2K_MS_COD, 2); /* COD */ + cio_write(cio, J2K_MS_COD, 2); /* COD */ - lenp = cio_tell(); - cio_skip(2); + lenp = cio_tell(cio); + cio_skip(cio, 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) */ + cp = j2k->cp; + tcp = &cp->tcps[j2k->curtileno]; + + cio_write(cio, tcp->csty, 1); /* Scod */ + cio_write(cio, tcp->prg, 1); /* SGcod (A) */ + cio_write(cio, tcp->numlayers, 2); /* SGcod (B) */ + cio_write(cio, 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); + j2k_write_cox(j2k, 0); + len = cio_tell(cio) - lenp; + cio_seek(cio, lenp); + cio_write(cio, len, 2); /* Lcod */ + cio_seek(cio, lenp + len); } -void j2k_read_cod() -{ +static void j2k_read_cod(opj_j2k_t *j2k) { 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) */ + opj_cio_t *cio = j2k->cio; + opj_cp_t *cp = j2k->cp; + opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp; + opj_image_t *image = j2k->image; - pos = cio_tell(); - for (i = 0; i < j2k_img->numcomps; i++) { + len = cio_read(cio, 2); /* Lcod */ + tcp->csty = cio_read(cio, 1); /* Scod */ + tcp->prg = (OPJ_PROG_ORDER)cio_read(cio, 1); /* SGcod (A) */ + tcp->numlayers = cio_read(cio, 2); /* SGcod (B) */ + tcp->mct = cio_read(cio, 1); /* SGcod (C) */ + + pos = cio_tell(cio); + for (i = 0; i < image->numcomps; i++) { tcp->tccps[i].csty = tcp->csty & J2K_CP_CSTY_PRT; - cio_seek(pos); - j2k_read_cox(i); + cio_seek(cio, pos); + j2k_read_cox(j2k, i); } } -void j2k_write_coc(int compno) -{ - j2k_tcp_t *tcp; +static void j2k_write_coc(opj_j2k_t *j2k, int compno) { int lenp, len; + + opj_cp_t *cp = j2k->cp; + opj_tcp_t *tcp = &cp->tcps[j2k->curtileno]; + opj_image_t *image = j2k->image; + opj_cio_t *cio = j2k->cio; - 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); + cio_write(cio, J2K_MS_COC, 2); /* COC */ + lenp = cio_tell(cio); + cio_skip(cio, 2); + cio_write(cio, compno, image->numcomps <= 256 ? 1 : 2); /* Ccoc */ + cio_write(cio, tcp->tccps[compno].csty, 1); /* Scoc */ + j2k_write_cox(j2k, compno); + len = cio_tell(cio) - lenp; + cio_seek(cio, lenp); + cio_write(cio, len, 2); /* Lcoc */ + cio_seek(cio, lenp + len); } -void j2k_read_coc() -{ +static void j2k_read_coc(opj_j2k_t *j2k) { int len, compno; - j2k_tcp_t *tcp; + + opj_cp_t *cp = j2k->cp; + opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp; + opj_image_t *image = j2k->image; + opj_cio_t *cio = j2k->cio; - 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); + len = cio_read(cio, 2); /* Lcoc */ + compno = cio_read(cio, image->numcomps <= 256 ? 1 : 2); /* Ccoc */ + tcp->tccps[compno].csty = cio_read(cio, 1); /* Scoc */ + j2k_read_cox(j2k, compno); } -void j2k_write_qcx(int compno) -{ - j2k_tcp_t *tcp; - j2k_tccp_t *tccp; +static void j2k_write_qcx(opj_j2k_t *j2k, int compno) { int bandno, numbands; int expn, mant; - tcp = &j2k_cp->tcps[j2k_curtileno]; - tccp = &tcp->tccps[compno]; + opj_cp_t *cp = j2k->cp; + opj_tcp_t *tcp = &cp->tcps[j2k->curtileno]; + opj_tccp_t *tccp = &tcp->tccps[compno]; + opj_cio_t *cio = j2k->cio; - cio_write(tccp->qntsty + (tccp->numgbits << 5), 1); /* Sqcx */ - numbands = - tccp->qntsty == - J2K_CCP_QNTSTY_SIQNT ? 1 : tccp->numresolutions * 3 - 2; + cio_write(cio, 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 */ + cio_write(cio, expn << 3, 1); /* SPqcx_i */ } else { - cio_write((expn << 11) + mant, 2); /* SPqcx_i */ + cio_write(cio, (expn << 11) + mant, 2); /* SPqcx_i */ } } - } -void j2k_read_qcx(int compno, int len) -{ +static void j2k_read_qcx(opj_j2k_t *j2k, 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 */ + + opj_cp_t *cp = j2k->cp; + opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp; + opj_tccp_t *tccp = &tcp->tccps[compno]; + opj_cio_t *cio = j2k->cio; + + tmp = cio_read(cio, 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); + 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 */ + expn = cio_read(cio, 1) >> 3; /* SPqcx_i */ mant = 0; } else { - tmp = cio_read(2); /* SPqcx_i */ + tmp = cio_read(cio, 2); /* SPqcx_i */ expn = tmp >> 11; mant = tmp & 0x7ff; } @@ -500,200 +424,197 @@ void j2k_read_qcx(int compno, int len) tccp->stepsizes[bandno].mant = mant; } - - /* Add Antonin : if scalar_derived -> compute other stepsizes */ - - - if (tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) { - for (bandno = 1; bandno < J2K_MAXBANDS; bandno++) { - - tccp->stepsizes[bandno].expn = - ((tccp->stepsizes[0].expn) - ((bandno - 1) / 3) > - 0) ? (tccp->stepsizes[0].expn) - ((bandno - 1) / 3) : 0; - + tccp->stepsizes[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() -{ +static void j2k_write_qcd(opj_j2k_t *j2k) { int lenp, len; + + opj_cio_t *cio = j2k->cio; - 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); + cio_write(cio, J2K_MS_QCD, 2); /* QCD */ + lenp = cio_tell(cio); + cio_skip(cio, 2); + j2k_write_qcx(j2k, 0); + len = cio_tell(cio) - lenp; + cio_seek(cio, lenp); + cio_write(cio, len, 2); /* Lqcd */ + cio_seek(cio, lenp + len); } -void j2k_read_qcd() -{ +static void j2k_read_qcd(opj_j2k_t *j2k) { int len, i, pos; + + opj_cio_t *cio = j2k->cio; + opj_image_t *image = j2k->image; - 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); + len = cio_read(cio, 2); /* Lqcd */ + pos = cio_tell(cio); + for (i = 0; i < image->numcomps; i++) { + cio_seek(cio, pos); + j2k_read_qcx(j2k, i, len - 2); } } -void j2k_write_qcc(int compno) -{ +static void j2k_write_qcc(opj_j2k_t *j2k, int compno) { int lenp, len; + + opj_cio_t *cio = j2k->cio; - 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); + cio_write(cio, J2K_MS_QCC, 2); /* QCC */ + lenp = cio_tell(cio); + cio_skip(cio, 2); + cio_write(cio, compno, j2k->image->numcomps <= 256 ? 1 : 2); /* Cqcc */ + j2k_write_qcx(j2k, compno); + len = cio_tell(cio) - lenp; + cio_seek(cio, lenp); + cio_write(cio, len, 2); /* Lqcc */ + cio_seek(cio, lenp + len); } -void j2k_read_qcc() -{ +static void j2k_read_qcc(opj_j2k_t *j2k) { int len, compno; + int numcomp = j2k->image->numcomps; + opj_cio_t *cio = j2k->cio; - 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)); + len = cio_read(cio, 2); /* Lqcc */ + compno = cio_read(cio, numcomp <= 256 ? 1 : 2); /* Cqcc */ + j2k_read_qcx(j2k, compno, len - 2 - (numcomp <= 256 ? 1 : 2)); } -void j2k_write_poc() -{ +static void j2k_write_poc(opj_j2k_t *j2k) { int len, numpchgs, i; - j2k_tcp_t *tcp; - j2k_tccp_t *tccp; + + int numcomps = j2k->image->numcomps; - tcp = &j2k_cp->tcps[j2k_curtileno]; - tccp = &tcp->tccps[0]; + opj_cp_t *cp = j2k->cp; + opj_tcp_t *tcp = &cp->tcps[j2k->curtileno]; + opj_tccp_t *tccp = &tcp->tccps[0]; + opj_cio_t *cio = j2k->cio; + 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 */ + cio_write(cio, J2K_MS_POC, 2); /* POC */ + len = 2 + (5 + 2 * (numcomps <= 256 ? 1 : 2)) * numpchgs; + cio_write(cio, len, 2); /* Lpoc */ for (i = 0; i < numpchgs; i++) { - /* 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 */ + opj_poc_t *poc = &tcp->pocs[i]; + cio_write(cio, poc->resno0, 1); /* RSpoc_i */ + cio_write(cio, poc->compno0, (numcomps <= 256 ? 1 : 2)); /* CSpoc_i */ + cio_write(cio, poc->layno1, 2); /* LYEpoc_i */ poc->layno1 = int_min(poc->layno1, tcp->numlayers); - cio_write(poc->resno1, 1); /* REpoc_i */ + cio_write(cio, 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 */ + cio_write(cio, poc->compno1, (numcomps <= 256 ? 1 : 2)); /* CEpoc_i */ + poc->compno1 = int_min(poc->compno1, numcomps); + cio_write(cio, poc->prg, 1); /* Ppoc_i */ } } -void j2k_read_poc() -{ +static void j2k_read_poc(opj_j2k_t *j2k) { int len, numpchgs, i, old_poc; - j2k_tcp_t *tcp; - j2k_tccp_t *tccp; + + int numcomps = j2k->image->numcomps; - tcp = - j2k_state == - J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp; + opj_cp_t *cp = j2k->cp; + opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp; + opj_tccp_t *tccp = &tcp->tccps[0]; + opj_cio_t *cio = j2k->cio; 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)); + len = cio_read(cio, 2); /* Lpoc */ + numpchgs = (len - 2) / (5 + 2 * (numcomps <= 256 ? 1 : 2)); for (i = old_poc; i < numpchgs + old_poc; i++) { - j2k_poc_t *poc; + opj_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), (unsigned int) tcp->numlayers); /* LYEpoc_i */ - poc->resno1 = int_min(cio_read(1), (unsigned int) tccp->numresolutions); /* REpoc_i */ - poc->compno1 = int_min(cio_read(j2k_img->numcomps <= 256 ? 1 : 2), (unsigned int) j2k_img->numcomps); /* CEpoc_i */ - poc->prg = cio_read(1); /* Ppoc_i */ + poc->resno0 = cio_read(cio, 1); /* RSpoc_i */ + poc->compno0 = cio_read(cio, numcomps <= 256 ? 1 : 2); /* CSpoc_i */ + poc->layno1 = int_min(cio_read(cio, 2), (unsigned int) tcp->numlayers); /* LYEpoc_i */ + poc->resno1 = int_min(cio_read(cio, 1), (unsigned int) tccp->numresolutions); /* REpoc_i */ + poc->compno1 = int_min( + cio_read(cio, numcomps <= 256 ? 1 : 2), (unsigned int) numcomps); /* CEpoc_i */ + poc->prg = (OPJ_PROG_ORDER)cio_read(cio, 1); /* Ppoc_i */ } tcp->numpocs = numpchgs + old_poc - 1; } -void j2k_read_crg() -{ +static void j2k_read_crg(opj_j2k_t *j2k) { 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 */ + opj_cio_t *cio = j2k->cio; + int numcomps = j2k->image->numcomps; + + len = cio_read(cio, 2); /* Lcrg */ + for (i = 0; i < numcomps; i++) { + Xcrg_i = cio_read(cio, 2); /* Xcrg_i */ + Ycrg_i = cio_read(cio, 2); /* Ycrg_i */ } } -void j2k_read_tlm() -{ +static void j2k_read_tlm(opj_j2k_t *j2k) { int len, Ztlm, Stlm, ST, SP, tile_tlm, i; long int Ttlm_i, Ptlm_i; + + opj_cio_t *cio = j2k->cio; - len = cio_read(2); /* Ltlm */ - Ztlm = cio_read(1); /* Ztlm */ - Stlm = cio_read(1); /* Stlm */ + len = cio_read(cio, 2); /* Ltlm */ + Ztlm = cio_read(cio, 1); /* Ztlm */ + Stlm = cio_read(cio, 1); /* Stlm */ ST = ((Stlm >> 4) & 0x01) + ((Stlm >> 4) & 0x02); SP = (Stlm >> 6) & 0x01; tile_tlm = (len - 4) / ((SP + 1) * 2 + ST); for (i = 0; i < tile_tlm; i++) { - Ttlm_i = cio_read(ST); /* Ttlm_i */ - Ptlm_i = cio_read(SP ? 4 : 2); /* Ptlm_i */ + Ttlm_i = cio_read(cio, ST); /* Ttlm_i */ + Ptlm_i = cio_read(cio, SP ? 4 : 2); /* Ptlm_i */ } } -void j2k_read_plm() -{ +static void j2k_read_plm(opj_j2k_t *j2k) { int len, i, Zplm, Nplm, add, packet_len = 0; - len = cio_read(2); /* Lplm */ - Zplm = cio_read(1); /* Zplm */ + opj_cio_t *cio = j2k->cio; + + len = cio_read(cio, 2); /* Lplm */ + Zplm = cio_read(cio, 1); /* Zplm */ len -= 3; while (len > 0) { - Nplm = cio_read(4); /* Nplm */ + Nplm = cio_read(cio, 4); /* Nplm */ len -= 4; for (i = Nplm; i > 0; i--) { - add = cio_read(1); + add = cio_read(cio, 1); len--; - packet_len = (packet_len << 7) + add; /* Iplm_ij */ + packet_len = (packet_len << 7) + add; /* Iplm_ij */ if ((add & 0x80) == 0) { - /* New packet */ - packet_len = 0; + /* New packet */ + packet_len = 0; } if (len <= 0) - break; + break; } } } -void j2k_read_plt() -{ +static void j2k_read_plt(opj_j2k_t *j2k) { int len, i, Zplt, packet_len = 0, add; - len = cio_read(2); /* Lplt */ - Zplt = cio_read(1); /* Zplt */ + opj_cio_t *cio = j2k->cio; + + len = cio_read(cio, 2); /* Lplt */ + Zplt = cio_read(cio, 1); /* Zplt */ for (i = len - 3; i > 0; i--) { - add = cio_read(1); - packet_len = (packet_len << 7) + add; /* Iplt_i */ + add = cio_read(cio, 1); + packet_len = (packet_len << 7) + add; /* Iplt_i */ if ((add & 0x80) == 0) { /* New packet */ packet_len = 0; @@ -701,685 +622,297 @@ void j2k_read_plt() } } -void j2k_read_ppm() -{ +static void j2k_read_ppm(opj_j2k_t *j2k) { int len, Z_ppm, i, j; int N_ppm; + + opj_cp_t *cp = j2k->cp; + opj_cio_t *cio = j2k->cio; - len = cio_read(2); - j2k_cp->ppm = 1; + len = cio_read(cio, 2); + cp->ppm = 1; - Z_ppm = cio_read(1); /* Z_ppm */ + Z_ppm = cio_read(cio, 1); /* Z_ppm */ len -= 3; while (len > 0) { - if (j2k_cp->ppm_previous == 0) { - N_ppm = cio_read(4); /* N_ppm */ + if (cp->ppm_previous == 0) { + N_ppm = cio_read(cio, 4); /* N_ppm */ len -= 4; } else { - N_ppm = j2k_cp->ppm_previous; + N_ppm = 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_data_first = j2k_cp->ppm_data; - - 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_data_first = j2k_cp->ppm_data; - - j2k_cp->ppm_len = N_ppm + j2k_cp->ppm_store; /*Add antonin : ppmbug1*/ - + j = cp->ppm_store; + if (Z_ppm == 0) { /* First PPM marker */ + cp->ppm_data = (unsigned char *) opj_malloc(N_ppm * sizeof(unsigned char)); + cp->ppm_data_first = cp->ppm_data; + cp->ppm_len = N_ppm; + } else { /* NON-first PPM marker */ + cp->ppm_data = (unsigned char *) j2k_realloc(cp->ppm_data, (N_ppm + cp->ppm_store) * sizeof(unsigned char)); + cp->ppm_data_first = cp->ppm_data; + cp->ppm_len = N_ppm + cp->ppm_store; } - - for (i = N_ppm; i > 0; i--) { /* Read packet header */ - j2k_cp->ppm_data[j] = cio_read(1); + for (i = N_ppm; i > 0; i--) { /* Read packet header */ + cp->ppm_data[j] = cio_read(cio, 1); j++; len--; if (len == 0) - break; /* Case of non-finished packet header in present marker but finished in next one */ + 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; + cp->ppm_previous = i - 1; + cp->ppm_store = j; } } -void j2k_read_ppt() -{ +static void j2k_read_ppt(opj_j2k_t *j2k) { 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]; + + opj_cp_t *cp = j2k->cp; + opj_tcp_t *tcp = cp->tcps + j2k->curtileno; + opj_cio_t *cio = j2k->cio; + + len = cio_read(cio, 2); + Z_ppt = cio_read(cio, 1); tcp->ppt = 1; - if (Z_ppt == 0) { /* First PPT marker */ - tcp->ppt_data = - (unsigned char *) calloc(len - 3, sizeof(unsigned char)); + if (Z_ppt == 0) { /* First PPT marker */ + tcp->ppt_data = (unsigned char *) opj_malloc((len - 3) * sizeof(unsigned char)); tcp->ppt_data_first = tcp->ppt_data; tcp->ppt_store = 0; - - tcp->ppt_len = len - 3; /*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; + } else { /* NON-first PPT marker */ + tcp->ppt_data = (unsigned char *) j2k_realloc(tcp->ppt_data, (len - 3 + tcp->ppt_store) * sizeof(unsigned char)); tcp->ppt_data_first = tcp->ppt_data; - - tcp->ppt_len = len - 3 + tcp->ppt_store; /*Add antonin : ppmbug1*/ - + tcp->ppt_len = len - 3 + tcp->ppt_store; } - j = tcp->ppt_store; for (i = len - 3; i > 0; i--) { - tcp->ppt_data[j] = cio_read(1); + tcp->ppt_data[j] = cio_read(cio, 1); j++; } tcp->ppt_store = j; } -void j2k_write_sot() -{ +static void j2k_write_sot(opj_j2k_t *j2k) { 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); + + opj_cio_t *cio = j2k->cio; + + j2k->sot_start = cio_tell(cio); + cio_write(cio, J2K_MS_SOT, 2); /* SOT */ + lenp = cio_tell(cio); + cio_skip(cio, 2); /* Lsot (further) */ + cio_write(cio, j2k->curtileno, 2); /* Isot */ + cio_skip(cio, 4); /* Psot (further in j2k_write_sod) */ + cio_write(cio, 0, 1); /* TPsot */ + cio_write(cio, 1, 1); /* TNsot */ + len = cio_tell(cio) - lenp; + cio_seek(cio, lenp); + cio_write(cio, len, 2); /* Lsot */ + cio_seek(cio, lenp + len); } -void j2k_read_sot() -{ +static void j2k_read_sot(opj_j2k_t *j2k) { int len, tileno, totlen, partno, numparts, i; - j2k_tcp_t *tcp; - j2k_tccp_t *tmp; + opj_tcp_t *tcp = NULL; + opj_tccp_t *tmp = NULL; char status = 0; + + opj_cp_t *cp = j2k->cp; + opj_cio_t *cio = j2k->cio; - len = cio_read(2); - tileno = cio_read(2); + len = cio_read(cio, 2); + tileno = cio_read(cio, 2); - if (j2k_cp->tileno_size == 0) { - j2k_cp->tileno[j2k_cp->tileno_size] = tileno; - j2k_cp->tileno_size++; + if (cp->tileno_size == 0) { + cp->tileno[cp->tileno_size] = tileno; + cp->tileno_size++; } else { i = 0; - while (i < j2k_cp->tileno_size && status == 0) { - status = j2k_cp->tileno[i] == tileno ? 1 : 0; + while (i < cp->tileno_size && status == 0) { + status = cp->tileno[i] == tileno ? 1 : 0; i++; } if (status == 0) { - j2k_cp->tileno[j2k_cp->tileno_size] = tileno; - j2k_cp->tileno_size++; + cp->tileno[cp->tileno_size] = tileno; + cp->tileno_size++; } } - totlen = cio_read(4); + totlen = cio_read(cio, 4); if (!totlen) - totlen = cio_numbytesleft() + 8; + totlen = cio_numbytesleft(cio) + 8; - partno = cio_read(1); - numparts = cio_read(1); + partno = cio_read(cio, 1); + numparts = cio_read(cio, 1); - j2k_curtileno = tileno; - j2k_eot = cio_getbp() - 12 + totlen; - j2k_state = J2K_STATE_TPH; - tcp = &j2k_cp->tcps[j2k_curtileno]; + j2k->curtileno = tileno; + j2k->eot = cio_getbp(cio) - 12 + totlen; + j2k->state = J2K_STATE_TPH; + tcp = &cp->tcps[j2k->curtileno]; if (tcp->first == 1) { - tmp = tcp->tccps; - *tcp = j2k_default_tcp; /* Initialization PPT */ + opj_tccp_t *tmp = tcp->tccps; + memcpy(tcp, j2k->default_tcp, sizeof(opj_tcp_t)); tcp->ppt = 0; tcp->ppt_data = NULL; tcp->ppt_data_first = NULL; - tcp->tccps = tmp; - for (i = 0; i < j2k_img->numcomps; i++) { - tcp->tccps[i] = j2k_default_tcp.tccps[i]; + + for (i = 0; i < j2k->image->numcomps; i++) { + tcp->tccps[i] = j2k->default_tcp->tccps[i]; } - j2k_cp->tcps[j2k_curtileno].first = 0; + cp->tcps[j2k->curtileno].first = 0; } } -void j2k_write_sod() -{ +static void j2k_write_sod(opj_j2k_t *j2k, void *tile_coder) { int l, layno; int totlen; - j2k_tcp_t *tcp; - static int j2k_sod_start; + opj_tcp_t *tcp = NULL; + opj_image_info_t *image_info = NULL; - cio_write(J2K_MS_SOD, 2); - if (j2k_curtileno == 0) { - j2k_sod_start = cio_tell() + pos_correction; + opj_tcd_t *tcd = (opj_tcd_t*)tile_coder; /* cast is needed because of conflicts in header inclusions */ + opj_cp_t *cp = j2k->cp; + opj_cio_t *cio = j2k->cio; + + cio_write(cio, J2K_MS_SOD, 2); + if (j2k->curtileno == 0) { + j2k->sod_start = cio_tell(cio) + j2k->pos_correction; } /* INDEX >> */ - if (info_IM.index_on) { - info_IM.tile[j2k_curtileno].end_header = - cio_tell() + pos_correction - 1; + image_info = j2k->image_info; + if (image_info && image_info->index_on) { + image_info->tile[j2k->curtileno].end_header = cio_tell(cio) + j2k->pos_correction - 1; } /* << INDEX */ - tcp = &j2k_cp->tcps[j2k_curtileno]; + tcp = &cp->tcps[j2k->curtileno]; for (layno = 0; layno < tcp->numlayers; layno++) { - tcp->rates[layno] -= tcp->rates[layno] ? (j2k_sod_start / (j2k_cp->th * j2k_cp->tw)) : 0; /*Mod antonin losslessbug*/ + tcp->rates[layno] -= tcp->rates[layno] ? (j2k->sod_start / (cp->th * cp->tw)) : 0; + } + if(image_info) { + image_info->num = 0; } - info_IM.num = 0; - if (j2k_cp->decod_format != PGX_DFMT) - 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); + l = tcd_encode_tile(tcd, j2k->curtileno, cio_getbp(cio), cio_numbytesleft(cio) - 2, image_info); /* 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); + totlen = cio_tell(cio) + l - j2k->sot_start; + cio_seek(cio, j2k->sot_start + 6); + cio_write(cio, totlen, 4); + cio_seek(cio, j2k->sot_start + totlen); } -void j2k_read_sod() -{ +static void j2k_read_sod(opj_j2k_t *j2k) { int len, truncate = 0, i; - unsigned char *data; + unsigned char *data = NULL, *data_ptr = NULL; + + opj_cio_t *cio = j2k->cio; + int curtileno = j2k->curtileno; - len = int_min(j2k_eot - cio_getbp(), cio_numbytesleft() + 1); + len = int_min(j2k->eot - cio_getbp(cio), cio_numbytesleft(cio) + 1); - if (len == cio_numbytesleft() + 1) - truncate = 1; /* Case of a truncate codestream */ + if (len == cio_numbytesleft(cio) + 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); + data = (unsigned char *) opj_malloc((j2k->tile_len[curtileno] + len) * sizeof(unsigned char)); + + for (i = 0; i < j2k->tile_len[curtileno]; i++) { + data[i] = j2k->tile_data[curtileno][i]; + } + + data_ptr = data + j2k->tile_len[curtileno]; + for (i = 0; i < len; i++) { + data_ptr[i] = cio_read(cio, 1); + } - j2k_tile_len[j2k_curtileno] += len; - free(j2k_tile_data[j2k_curtileno]); - j2k_tile_data[j2k_curtileno] = data; - data = NULL; + j2k->tile_len[curtileno] += len; + opj_free(j2k->tile_data[curtileno]); + j2k->tile_data[curtileno] = data; - if (!truncate) - j2k_state = J2K_STATE_TPHSOT; - else - j2k_state = J2K_STATE_NEOC; /* RAJOUTE !! */ + 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]; +static void j2k_write_rgn(opj_j2k_t *j2k, int compno, int 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 */ + opj_cp_t *cp = j2k->cp; + opj_tcp_t *tcp = &cp->tcps[tileno]; + opj_cio_t *cio = j2k->cio; + int numcomps = j2k->image->numcomps; + + cio_write(cio, J2K_MS_RGN, 2); /* RGN */ + cio_write(cio, numcomps <= 256 ? 5 : 6, 2); /* Lrgn */ + cio_write(cio, compno, numcomps <= 256 ? 1 : 2); /* Crgn */ + cio_write(cio, 0, 1); /* Srgn */ + cio_write(cio, tcp->tccps[compno].roishift, 1); /* SPrgn */ } -void j2k_read_rgn() -{ +static void j2k_read_rgn(opj_j2k_t *j2k) { 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 */ + + opj_cp_t *cp = j2k->cp; + opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp; + opj_cio_t *cio = j2k->cio; + int numcomps = j2k->image->numcomps; + + len = cio_read(cio, 2); /* Lrgn */ + compno = cio_read(cio, numcomps <= 256 ? 1 : 2); /* Crgn */ + roisty = cio_read(cio, 1); /* Srgn */ + tcp->tccps[compno].roishift = cio_read(cio, 1); /* SPrgn */ } -void j2k_write_eoc() -{ - /* fprintf(stderr, "%.8x: EOC\n", cio_tell() + pos_correction); */ - cio_write(J2K_MS_EOC, 2); +static void j2k_write_eoc(opj_j2k_t *j2k) { + opj_cio_t *cio = j2k->cio; + /* opg_event_msg(j2k->cinfo, "%.8x: EOC\n", cio_tell(cio) + j2k->pos_correction); */ + cio_write(cio, J2K_MS_EOC, 2); } -void j2k_read_eoc() -{ +static void j2k_read_eoc(opj_j2k_t *j2k) { int i, tileno; #ifndef NO_PACKETS_DECODING - tcd_init(j2k_img, j2k_cp); + opj_tcd_t *tcd = tcd_create(j2k->cinfo); + tcd_malloc_decode(tcd, j2k->image, j2k->cp); + for (i = 0; i < j2k->cp->tileno_size; i++) { + tileno = j2k->cp->tileno[i]; + tcd_decode_tile(tcd, j2k->tile_data[tileno], j2k->tile_len[tileno], tileno); + opj_free(j2k->tile_data[tileno]); + j2k->tile_data[tileno] = NULL; + } + tcd_free_decode(tcd); + tcd_destroy(tcd); +#else + for (i = 0; i < j2k->cp->tileno_size; i++) { + tileno = j2k->cp->tileno[i]; + opj_free(j2k->tile_data[tileno]); + j2k->tile_data[tileno] = NULL; + } #endif - for (i = 0; i < j2k_cp->tileno_size; i++) { - tileno = j2k_cp->tileno[i]; -#ifndef NO_PACKETS_DECODING - tcd_decode_tile(j2k_tile_data[tileno], j2k_tile_len[tileno], tileno); -#endif - free(j2k_tile_data[tileno]); - } - - j2k_state = J2K_STATE_MT; - longjmp(j2k_error, 1); + j2k->state = J2K_STATE_MT; } -void j2k_read_unk() -{ - fprintf(stderr, "warning: unknown marker\n"); +static void j2k_read_unk(opj_j2k_t *j2k) { + opg_event_msg(j2k->cinfo, EVT_WARNING, "Unknown marker\n"); } -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, x, y; - unsigned 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 = (unsigned 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.Tile_Ox = j2k_cp->tx0; /* new version parser */ - info_IM.Tile_Oy = j2k_cp->ty0; /* 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(stdout, "Tile number %d / %d ", tileno + 1, cp->tw * cp->th); - - if (cp->intermed_file == 1) { - /* new dest for each tile */ - free(dest); - dest = (unsigned 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 = (unsigned 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 << info_IM.tile[0].pdx[resno]), (1 << info_IM.tile[0].pdx[resno])); /*based on tile 0*/ - - } - - fprintf(INDEX, "\n"); - - fprintf(INDEX, "%d\n", info_IM.Main_head_end); - - fprintf(INDEX, "%d\n", info_IM.codestream_size); - - for (tileno = 0; tileno < info_IM.tw * info_IM.th; tileno++) { - - fprintf(INDEX, "%4d %9d %9d %9d %9e %9d %9e\n", - info_IM.tile[tileno].num_tile, - info_IM.tile[tileno].start_pos, - info_IM.tile[tileno].end_header, - info_IM.tile[tileno].end_pos, - info_IM.tile[tileno].distotile, info_IM.tile[tileno].nbpix, - info_IM.tile[tileno].distotile / info_IM.tile[tileno].nbpix); - - } - - for (tileno = 0; tileno < info_IM.tw * info_IM.th; tileno++) { - - int start_pos, end_pos; - - double disto = 0; - - pack_nb = 0; - - /* fprintf(INDEX, - - "pkno tileno layerno resno compno precno start_pos end_pos deltaSE \n"); */ - - if (info_IM.Prog == 0) { /* LRCP */ - /*fprintf(INDEX, "pack_nb tileno layno resno compno precno start_pos end_pos disto");*/ - for (layno = 0; layno < info_IM.Layer; layno++) { - for (resno = 0; resno < info_IM.Decomposition + 1; resno++) { - for (compno = 0; compno < info_IM.Comp; compno++) { - for (precno = 0; - precno < - info_IM.tile[tileno].pw[resno] * info_IM.tile[tileno].ph[resno]; - precno++) { - start_pos = info_IM.tile[tileno].packet[pack_nb].start_pos; - end_pos = info_IM.tile[tileno].packet[pack_nb].end_pos; - disto = info_IM.tile[tileno].packet[pack_nb].disto; - fprintf(INDEX, "%4d %6d %7d %5d %6d %6d %9d %9d %8e\n", - pack_nb, tileno, layno, resno, compno, precno, - start_pos, end_pos, disto); - DistoTotal += disto; - pack_nb++; - } - } - } - } - } else if (info_IM.Prog == 1) { /* RLCP */ - /*fprintf(INDEX, "pack_nb tileno resno layno compno precno start_pos end_pos disto");*/ - for (resno = 0; resno < info_IM.Decomposition + 1; resno++) { - for (layno = 0; layno < info_IM.Layer; layno++) { - for (compno = 0; compno < info_IM.Comp; compno++) { - for (precno = 0; precno < info_IM.tile[tileno].pw[resno] * info_IM.tile[tileno].ph[resno]; precno++) { - start_pos = info_IM.tile[tileno].packet[pack_nb].start_pos; - end_pos = info_IM.tile[tileno].packet[pack_nb].end_pos; - disto = info_IM.tile[tileno].packet[pack_nb].disto; - fprintf(INDEX, "%4d %6d %5d %7d %6d %6d %9d %9d %8e\n", - pack_nb, tileno, resno, layno, compno, precno, - start_pos, end_pos, disto); - DistoTotal += disto; - pack_nb++; - } - } - } - } - } else if (info_IM.Prog == 2) { /* RPCL */ - /*fprintf(INDEX, "\npack_nb tileno resno precno compno layno start_pos end_pos disto\n"); */ - for (resno = 0; resno < info_IM.Decomposition + 1; resno++) { - /* I suppose components have same XRsiz, YRsiz */ - int x0 = info_IM.Tile_Ox + tileno - (int)floor( tileno/info_IM.tw ) * info_IM.tw * info_IM.Tile_x; - int y0 = info_IM.Tile_Ox + (int)floor( tileno/info_IM.tw ) * info_IM.Tile_y; - int x1 = x0 + info_IM.Tile_x; - int y1 = y0 + info_IM.Tile_y; - for (y=y0; yid != 0; e++) { if (e->id == id) { break; @@ -1413,190 +949,781 @@ j2k_dec_mstabent_t *j2k_dec_mstab_lookup(int id) return e; } +/* ----------------------------------------------------------------------- */ +/* J2K / JPT decoder interface */ +/* ----------------------------------------------------------------------- */ - -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; +opj_j2k_t* j2k_create_decompress(opj_common_ptr cinfo) { + opj_j2k_t *j2k = (opj_j2k_t*)opj_malloc(sizeof(opj_j2k_t)); + if(j2k) { + j2k->cinfo = cinfo; + j2k->default_tcp = (opj_tcp_t*)opj_malloc(sizeof(opj_tcp_t)); + if(!j2k->default_tcp) { + opj_free(j2k); + return NULL; } - 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); - + return j2k; +} + +void j2k_destroy_decompress(opj_j2k_t *j2k) { + int i = 0; + + if(j2k->tile_len != NULL) { + opj_free(j2k->tile_len); + } + if(j2k->tile_data != NULL) { + opj_free(j2k->tile_data); + } + if(j2k->default_tcp != NULL) { + opj_tcp_t *default_tcp = j2k->default_tcp; + if(default_tcp->ppt_data_first != NULL) { + opj_free(default_tcp->ppt_data_first); + } + if(j2k->default_tcp->tccps != NULL) { + opj_free(j2k->default_tcp->tccps); + } + opj_free(j2k->default_tcp); + } + if(j2k->cp != NULL) { + opj_cp_t *cp = j2k->cp; + if(cp->tcps != NULL) { + for(i = 0; i < cp->tw * cp->th; i++) { + if(cp->tcps[i].ppt_data_first != NULL) { + opj_free(cp->tcps[i].ppt_data_first); + } + if(cp->tcps[i].tccps != NULL) { + opj_free(cp->tcps[i].tccps); + } + } + opj_free(cp->tcps); + } + if(cp->ppm_data_first != NULL) { + opj_free(cp->ppm_data_first); + } + if(cp->tileno != NULL) { + opj_free(cp->tileno); + } + if(cp->comment != NULL) { + opj_free(cp->comment); + } + + opj_free(cp); + } + + opj_free(j2k); +} + +void j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters) { + if(j2k && parameters) { + /* create and initialize the coding parameters structure */ + opj_cp_t *cp = (opj_cp_t*)opj_malloc(sizeof(opj_cp_t)); + cp->reduce = parameters->cp_reduce; + cp->layer = parameters->cp_layer; + + /* keep a link to cp so that we can destroy it later in j2k_destroy_decompress */ + j2k->cp = cp; + } +} + +opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio) { + opj_image_t *image = NULL; + + opj_common_ptr cinfo = j2k->cinfo; + + j2k->cio = cio; + + /* create an empty image */ + image = opj_image_create0(); + j2k->image = image; + + j2k->state = J2K_STATE_MHSOC; + for (;;) { - - - j2k_dec_mstabent_t *e; - int id = cio_read(2); + opj_dec_mstabent_t *e; + int id = cio_read(cio, 2); if (id >> 8 != 0xff) { - fprintf(stderr, "%.8x: expected a marker instead of %x\n", - cio_tell() - 2, id); + opj_image_destroy(image); + opg_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 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); + if (!(j2k->state & e->states)) { + opj_image_destroy(image); + opg_event_msg(cinfo, EVT_ERROR, "%.8x: unexpected marker %x\n", cio_tell(cio) - 2, id); return 0; } if (e->handler) { - (*e->handler) (); + (*e->handler)(j2k); + } + if (j2k->state == J2K_STATE_MT) { + break; + } + if (j2k->state == J2K_STATE_NEOC) { + break; } - - - if (j2k_state == J2K_STATE_NEOC) - break; /* RAJOUTE */ } - if (j2k_state == J2K_STATE_NEOC) - j2k_read_eoc(); /* RAJOUTE */ - - return 0; + if (j2k->state == J2K_STATE_NEOC) { + j2k_read_eoc(j2k); + } + + if (j2k->state != J2K_STATE_MT) { + opg_event_msg(cinfo, EVT_WARNING, "Incomplete bitstream\n"); + } + + return image; } /* * 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; +opj_image_t* j2k_decode_jpt_stream(opj_j2k_t *j2k, opj_cio_t *cio) { + opj_image_t *image = NULL; + opj_jpt_msg_header_t header; int position; + + opj_common_ptr cinfo = j2k->cinfo; - 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); + j2k->cio = cio; + + /* create an empty image */ + image = opj_image_create0(); + + j2k->state = J2K_STATE_MHSOC; /* Initialize the header */ - jpt_init_Msg_Header(&header); + jpt_init_msg_header(&header); /* Read the first header of the message */ - jpt_read_Msg_Header(&header); + jpt_read_msg_header(cinfo, cio, &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); + position = cio_tell(cio); + if (header.Class_Id != 6) { /* 6 : Main header data-bin message */ + opj_image_destroy(image); + opg_event_msg(cinfo, EVT_ERROR, "[JPT-stream] : Expecting Main header first [class_Id %d] !\n", header.Class_Id); return 0; } for (;;) { - j2k_dec_mstabent_t *e; + opj_dec_mstabent_t *e = NULL; int id; - if (!cio_numbytesleft()) { - j2k_read_eoc(); - return 0; + if (!cio_numbytesleft(cio)) { + j2k_read_eoc(j2k); + return image; } /* 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; + if ((unsigned int) (cio_tell(cio) - position) == header.Msg_length) { + jpt_read_msg_header(cinfo, cio, &header); + position = cio_tell(cio); + if (header.Class_Id != 4) { /* 4 : Tile data-bin message */ + opj_image_destroy(image); + opg_event_msg(cinfo, EVT_ERROR, "[JPT-stream] : Expecting Tile info !\n"); + return 0; } } - id = cio_read(2); + id = cio_read(cio, 2); if (id >> 8 != 0xff) { - fprintf(stderr, "%.8x: expected a marker instead of %x\n", - cio_tell() - 2, id); + opj_image_destroy(image); + opg_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 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); + if (!(j2k->state & e->states)) { + opj_image_destroy(image); + opg_event_msg(cinfo, EVT_ERROR, "%.8x: unexpected marker %x\n", cio_tell(cio) - 2, id); return 0; } if (e->handler) { - (*e->handler) (); + (*e->handler)(j2k); + } + if (j2k->state == J2K_STATE_MT) { + break; + } + if (j2k->state == J2K_STATE_NEOC) { + break; } - if (j2k_state == J2K_STATE_NEOC) - break; /* RAJOUTE */ } - if (j2k_state == J2K_STATE_NEOC) - j2k_read_eoc(); /* RAJOUTE */ + if (j2k->state == J2K_STATE_NEOC) { + j2k_read_eoc(j2k); + } - return 0; + if (j2k->state != J2K_STATE_MT) { + opg_event_msg(cinfo, EVT_WARNING, "Incomplete bitstream\n"); + } + + return image; } +/* ----------------------------------------------------------------------- */ +/* J2K encoder interface */ +/* ----------------------------------------------------------------------- */ +opj_j2k_t* j2k_create_compress(opj_common_ptr cinfo) { + opj_j2k_t *j2k = (opj_j2k_t*)opj_malloc(sizeof(opj_j2k_t)); + if(j2k) { + j2k->cinfo = cinfo; + } + return j2k; +} -void j2k_dec_release() +void j2k_destroy_compress(opj_j2k_t *j2k) { + int tileno; -{ - - int i=0; - - - - /*tcd_dec_release();*/ - - - - if (j2k_tile_len!=NULL) free(j2k_tile_len); - - if (j2k_tile_data!=NULL) free(j2k_tile_data); - - if (j2k_default_tcp.ppt_data_first!=NULL) free(j2k_default_tcp.ppt_data_first); - - if (j2k_default_tcp.tccps!=NULL) free(j2k_default_tcp.tccps); - - for (i=0;itw*j2k_cp->th;i++) { + if(!j2k) return; + + if(j2k->image_info != NULL) { + opj_image_info_t *image_info = j2k->image_info; + if (image_info->index_on && j2k->cp) { + opj_cp_t *cp = j2k->cp; + for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { + opj_tile_info_t *tile_info = &image_info->tile[tileno]; + opj_free(tile_info->thresh); + opj_free(tile_info->packet); + } + opj_free(image_info->tile); + } + opj_free(image_info); + } + if(j2k->cp != NULL) { + opj_cp_t *cp = j2k->cp; + + if(cp->comment) { + opj_free(cp->comment); + } + if(cp->matrice) { + opj_free(cp->matrice); + } + for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { + opj_free(cp->tcps[tileno].tccps); + } + opj_free(cp->tcps); + opj_free(cp); + } + + opj_free(j2k); +} + +void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_t *image) { + int i, j, tileno, numpocs_tile; + opj_cp_t *cp = NULL; + + if(!j2k || !parameters || ! image) { + return; + } + + /* create and initialize the coding parameters structure */ + cp = (opj_cp_t*)opj_malloc(sizeof(opj_cp_t)); + + /* keep a link to cp so that we can destroy it later in j2k_destroy_compress */ + j2k->cp = cp; + + /* set default values for cp */ + cp->tw = 1; + cp->th = 1; + + /* + copy user encoding parameters + */ + + cp->disto_alloc = parameters->cp_disto_alloc; + cp->fixed_alloc = parameters->cp_fixed_alloc; + cp->fixed_quality = parameters->cp_fixed_quality; + + /* mod fixed_quality */ + if(parameters->cp_matrice) { + size_t array_size = parameters->tcp_numlayers * parameters->numresolution * 3 * sizeof(int); + cp->matrice = (int *) opj_malloc(array_size); + memcpy(cp->matrice, parameters->cp_matrice, array_size); + } + + /* creation of an index file ? */ + cp->index_on = parameters->index_on; + if(cp->index_on) { + j2k->image_info = (opj_image_info_t*)opj_malloc(sizeof(opj_image_info_t)); + } + + /* tiles */ + cp->tdx = parameters->cp_tdx; + cp->tdy = parameters->cp_tdy; + + /* tile offset */ + cp->tx0 = parameters->cp_tx0; + cp->ty0 = parameters->cp_ty0; + + /* comment string */ + if(parameters->cp_comment) { + cp->comment = (char*)opj_malloc(strlen(parameters->cp_comment) + 1); + if(cp->comment) { + strcpy(cp->comment, parameters->cp_comment); + } + } + + /* + calculate other encoding parameters + */ + + if (parameters->tile_size_on) { + cp->tw = int_ceildiv(image->x1 - cp->tx0, cp->tdx); + cp->th = int_ceildiv(image->y1 - cp->ty0, cp->tdy); + } else { + cp->tdx = image->x1 - cp->tx0; + cp->tdy = image->y1 - cp->ty0; + } + + /* initialize the mutiple tiles */ + /* ---------------------------- */ + cp->tcps = (opj_tcp_t *) opj_malloc(cp->tw * cp->th * sizeof(opj_tcp_t)); + + for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { + opj_tcp_t *tcp = &cp->tcps[tileno]; + tcp->numlayers = parameters->tcp_numlayers; + for (j = 0; j < tcp->numlayers; j++) { + if (cp->fixed_quality) { /* add fixed_quality */ + tcp->distoratio[j] = parameters->tcp_distoratio[j]; + } else { + tcp->rates[j] = parameters->tcp_rates[j]; + } + } + tcp->csty = parameters->csty; + tcp->prg = parameters->prog_order; + tcp->mct = image->numcomps == 3 ? 1 : 0; + + numpocs_tile = 0; + tcp->POC = 0; + if (parameters->numpocs) { + /* initialisation of POC */ + tcp->POC = 1; + for (i = 0; i < parameters->numpocs; i++) { + if((tileno == parameters->POC[i].tile - 1) || (parameters->POC[i].tile == -1)) { + opj_poc_t *tcp_poc = &tcp->pocs[numpocs_tile]; + tcp_poc->resno0 = parameters->POC[numpocs_tile].resno0; + tcp_poc->compno0 = parameters->POC[numpocs_tile].compno0; + tcp_poc->layno1 = parameters->POC[numpocs_tile].layno1; + tcp_poc->resno1 = parameters->POC[numpocs_tile].resno1; + tcp_poc->compno1 = parameters->POC[numpocs_tile].compno1; + tcp_poc->prg = parameters->POC[numpocs_tile].prg; + tcp_poc->tile = parameters->POC[numpocs_tile].tile; + numpocs_tile++; + } + } + } + tcp->numpocs = numpocs_tile; + + tcp->tccps = (opj_tccp_t *) opj_malloc(image->numcomps * sizeof(opj_tccp_t)); - if (j2k_cp->tcps[i].ppt_data_first!=NULL) free(j2k_cp->tcps[i].ppt_data_first); + for (i = 0; i < image->numcomps; i++) { + opj_tccp_t *tccp = &tcp->tccps[i]; + tccp->csty = parameters->csty & 0x01; /* 0 => one precinct || 1 => custom precinct */ + tccp->numresolutions = parameters->numresolution; + tccp->cblkw = int_floorlog2(parameters->cblockw_init); + tccp->cblkh = int_floorlog2(parameters->cblockh_init); + tccp->cblksty = parameters->mode; + tccp->qmfbid = parameters->irreversible ? 0 : 1; + tccp->qntsty = parameters->irreversible ? J2K_CCP_QNTSTY_SEQNT : J2K_CCP_QNTSTY_NOQNT; + tccp->numgbits = 2; + if (i == parameters->roi_compno) { + tccp->roishift = parameters->roi_shift; + } else { + tccp->roishift = 0; + } + if (parameters->csty & J2K_CCP_CSTY_PRT) { + int p = 0; + for (j = tccp->numresolutions - 1; j >= 0; j--) { + if (p < parameters->res_spec) { + if (parameters->prcw_init[p] < 1) { + tccp->prcw[j] = 1; + } else { + tccp->prcw[j] = int_floorlog2(parameters->prcw_init[p]); + } + if (parameters->prch_init[p] < 1) { + tccp->prch[j] = 1; + } else { + tccp->prch[j] = int_floorlog2(parameters->prch_init[p]); + } + } else { + int res_spec = parameters->res_spec; + int size_prcw = parameters->prcw_init[res_spec - 1] >> (p - (res_spec - 1)); + int size_prch = parameters->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 for 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; + } + } + + dwt_calc_explicit_stepsizes(tccp, image->comps[i].prec); + } + } +} + +/** +Create an index file +@param j2k +@param cio +@param image_info +@param index Index filename +@return Returns 1 if successful, returns 0 otherwise +*/ +static int j2k_create_index(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_info_t *image_info, char *index) { + int tileno, compno, layno, resno, precno, pack_nb, x, y; + FILE *stream = NULL; + double total_disto = 0; + + image_info->codestream_size = cio_tell(cio) + j2k->pos_correction; /* Correction 14/4/03 suite rmq de Patrick */ + + stream = fopen(index, "w"); + if (!stream) { + opg_event_msg(j2k->cinfo, EVT_ERROR, "failed to open %s for writing\n", index); + return 0; + } + + fprintf(stream, "%d %d\n", image_info->image_w, image_info->image_h); + fprintf(stream, "%d\n", image_info->prog); + fprintf(stream, "%d %d\n", image_info->tile_x, image_info->tile_y); + fprintf(stream, "%d %d\n", image_info->tw, image_info->th); + fprintf(stream, "%d\n", image_info->comp); + fprintf(stream, "%d\n", image_info->layer); + fprintf(stream, "%d\n", image_info->decomposition); + + for (resno = image_info->decomposition; resno >= 0; resno--) { + fprintf(stream, "[%d,%d] ", + (1 << image_info->tile[0].pdx[resno]), (1 << image_info->tile[0].pdx[resno])); /* based on tile 0 */ + } + fprintf(stream, "\n"); + fprintf(stream, "%d\n", image_info->main_head_end); + fprintf(stream, "%d\n", image_info->codestream_size); + + for (tileno = 0; tileno < image_info->tw * image_info->th; tileno++) { + fprintf(stream, "%4d %9d %9d %9d %9e %9d %9e\n", + image_info->tile[tileno].num_tile, + image_info->tile[tileno].start_pos, + image_info->tile[tileno].end_header, + image_info->tile[tileno].end_pos, + image_info->tile[tileno].distotile, image_info->tile[tileno].nbpix, + image_info->tile[tileno].distotile / image_info->tile[tileno].nbpix); + } + + for (tileno = 0; tileno < image_info->tw * image_info->th; tileno++) { + int start_pos, end_pos; + double disto = 0; + pack_nb = 0; - if (j2k_cp->tcps[i].tccps!=NULL) free(j2k_cp->tcps[i].tccps); + /* + fprintf(stream, "pkno tileno layerno resno compno precno start_pos end_pos deltaSE \n"); + */ + + if (image_info->prog == LRCP) { /* LRCP */ + /* + fprintf(stream, "pack_nb tileno layno resno compno precno start_pos end_pos disto"); + */ + for (layno = 0; layno < image_info->layer; layno++) { + for (resno = 0; resno < image_info->decomposition + 1; resno++) { + for (compno = 0; compno < image_info->comp; compno++) { + int prec_max = image_info->tile[tileno].pw[resno] * image_info->tile[tileno].ph[resno]; + for (precno = 0; precno < prec_max; precno++) { + start_pos = image_info->tile[tileno].packet[pack_nb].start_pos; + end_pos = image_info->tile[tileno].packet[pack_nb].end_pos; + disto = image_info->tile[tileno].packet[pack_nb].disto; + fprintf(stream, "%4d %6d %7d %5d %6d %6d %9d %9d %8e\n", + pack_nb, tileno, layno, resno, compno, precno, start_pos, end_pos, disto); + total_disto += disto; + pack_nb++; + } + } + } + } + } /* LRCP */ + else if (image_info->prog == RLCP) { /* RLCP */ + /* + fprintf(stream, "pack_nb tileno resno layno compno precno start_pos end_pos disto"); + */ + for (resno = 0; resno < image_info->decomposition + 1; resno++) { + for (layno = 0; layno < image_info->layer; layno++) { + for (compno = 0; compno < image_info->comp; compno++) { + int prec_max = image_info->tile[tileno].pw[resno] * image_info->tile[tileno].ph[resno]; + for (precno = 0; precno < prec_max; precno++) { + start_pos = image_info->tile[tileno].packet[pack_nb].start_pos; + end_pos = image_info->tile[tileno].packet[pack_nb].end_pos; + disto = image_info->tile[tileno].packet[pack_nb].disto; + fprintf(stream, "%4d %6d %5d %7d %6d %6d %9d %9d %8e\n", + pack_nb, tileno, resno, layno, compno, precno, start_pos, end_pos, disto); + total_disto += disto; + pack_nb++; + } + } + } + } + } /* RLCP */ + else if (image_info->prog == RPCL) { /* RPCL */ + /* + fprintf(stream, "\npack_nb tileno resno precno compno layno start_pos end_pos disto\n"); + */ + for (resno = 0; resno < image_info->decomposition + 1; resno++) { + /* I suppose components have same XRsiz, YRsiz */ + int x0 = image_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)image_info->tw ) * image_info->tw * image_info->tile_x; + int y0 = image_info->tile_Ox + (int)floor( (float)tileno/(float)image_info->tw ) * image_info->tile_y; + int x1 = x0 + image_info->tile_x; + int y1 = y0 + image_info->tile_y; + for(y = y0; y < y1; y++) { + for(x = x0; x < x1; x++) { + for (compno = 0; compno < image_info->comp; compno++) { + int prec_max = image_info->tile[tileno].pw[resno] * image_info->tile[tileno].ph[resno]; + for (precno = 0; precno < prec_max; precno++) { + int pcnx = image_info->tile[tileno].pw[resno]; + int pcx = (int) pow( 2, image_info->tile[tileno].pdx[resno] + image_info->decomposition - resno ); + int pcy = (int) pow( 2, image_info->tile[tileno].pdy[resno] + image_info->decomposition - resno ); + int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx; + int precno_y = (int) floor( (float)precno/(float)pcnx ); + if (precno_y*pcy == y ) { + if (precno_x*pcx == x ) { + for (layno = 0; layno < image_info->layer; layno++) { + start_pos = image_info->tile[tileno].packet[pack_nb].start_pos; + end_pos = image_info->tile[tileno].packet[pack_nb].end_pos; + disto = image_info->tile[tileno].packet[pack_nb].disto; + fprintf(stream, "%4d %6d %5d %6d %6d %7d %9d %9d %8e\n", + pack_nb, tileno, resno, precno, compno, layno, start_pos, end_pos, disto); + total_disto += disto; + pack_nb++; + } + } + } + } /* precno */ + } /* compno */ + } /* x = x0..x1 */ + } /* y = y0..y1 */ + } /* resno */ + } /* RPCL */ + else if (image_info->prog == PCRL) { /* PCRL */ + /* I suppose components have same XRsiz, YRsiz */ + int x0 = image_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)image_info->tw ) * image_info->tw * image_info->tile_x; + int y0 = image_info->tile_Ox + (int)floor( (float)tileno/(float)image_info->tw ) * image_info->tile_y; + int x1 = x0 + image_info->tile_x; + int y1 = y0 + image_info->tile_y; + /* + fprintf(stream, "\npack_nb tileno precno compno resno layno start_pos end_pos disto\n"); + */ + for(y = y0; y < y1; y++) { + for(x = x0; x < x1; x++) { + for (compno = 0; compno < image_info->comp; compno++) { + for (resno = 0; resno < image_info->decomposition + 1; resno++) { + int prec_max = image_info->tile[tileno].pw[resno] * image_info->tile[tileno].ph[resno]; + for (precno = 0; precno < prec_max; precno++) { + int pcnx = image_info->tile[tileno].pw[resno]; + int pcx = (int) pow( 2, image_info->tile[tileno].pdx[resno] + image_info->decomposition - resno ); + int pcy = (int) pow( 2, image_info->tile[tileno].pdy[resno] + image_info->decomposition - resno ); + int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx; + int precno_y = (int) floor( (float)precno/(float)pcnx ); + if (precno_y*pcy == y ) { + if (precno_x*pcx == x ) { + for (layno = 0; layno < image_info->layer; layno++) { + start_pos = image_info->tile[tileno].packet[pack_nb].start_pos; + end_pos = image_info->tile[tileno].packet[pack_nb].end_pos; + disto = image_info->tile[tileno].packet[pack_nb].disto; + fprintf(stream, "%4d %6d %6d %6d %5d %7d %9d %9d %8e\n", + pack_nb, tileno, precno, compno, resno, layno, start_pos, end_pos, disto); + total_disto += disto; + pack_nb++; + } + } + } + } /* precno */ + } /* resno */ + } /* compno */ + } /* x = x0..x1 */ + } /* y = y0..y1 */ + } /* PCRL */ + else { /* CPRL */ + /* + fprintf(stream, "\npack_nb tileno compno precno resno layno start_pos end_pos disto\n"); + */ + for (compno = 0; compno < image_info->comp; compno++) { + /* I suppose components have same XRsiz, YRsiz */ + int x0 = image_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)image_info->tw ) * image_info->tw * image_info->tile_x; + int y0 = image_info->tile_Ox + (int)floor( (float)tileno/(float)image_info->tw ) * image_info->tile_y; + int x1 = x0 + image_info->tile_x; + int y1 = y0 + image_info->tile_y; + for(y = y0; y < y1; y++) { + for(x = x0; x < x1; x++) { + for (resno = 0; resno < image_info->decomposition + 1; resno++) { + int prec_max = image_info->tile[tileno].pw[resno] * image_info->tile[tileno].ph[resno]; + for (precno = 0; precno < prec_max; precno++) { + int pcnx = image_info->tile[tileno].pw[resno]; + int pcx = (int) pow( 2, image_info->tile[tileno].pdx[resno] + image_info->decomposition - resno ); + int pcy = (int) pow( 2, image_info->tile[tileno].pdy[resno] + image_info->decomposition - resno ); + int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx; + int precno_y = (int) floor( (float)precno/(float)pcnx ); + if (precno_y*pcy == y ) { + if (precno_x*pcx == x ) { + for (layno = 0; layno < image_info->layer; layno++) { + start_pos = image_info->tile[tileno].packet[pack_nb].start_pos; + end_pos = image_info->tile[tileno].packet[pack_nb].end_pos; + disto = image_info->tile[tileno].packet[pack_nb].disto; + fprintf(stream, "%4d %6d %6d %6d %5d %7d %9d %9d %8e\n", + pack_nb, tileno, compno, precno, resno, layno, start_pos, end_pos, disto); + total_disto += disto; + pack_nb++; + } + } + } + } /* precno */ + } /* resno */ + } /* x = x0..x1 */ + } /* y = y0..y1 */ + } /* comno */ + } /* CPRL */ + } /* tileno */ + + fprintf(stream, "%8e\n", image_info->D_max); /* SE max */ + fprintf(stream, "%.8e\n", total_disto); /* SE totale */ + fclose(stream); + + return 1; +} + +bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, char *index) { + int tileno, compno; + opj_image_info_t *image_info = NULL; + opj_cp_t *cp = NULL; + + opj_tcd_t *tcd = NULL; /* TCD component */ + + j2k->cio = cio; + j2k->image = image; + + cp = j2k->cp; + + /* j2k_dump_cp(stdout, image, cp); */ + + /* INDEX >> */ + image_info = j2k->image_info; + if (image_info && cp->index_on) { + image_info->index_on = cp->index_on; + image_info->tile = (opj_tile_info_t *) opj_malloc(cp->tw * cp->th * sizeof(opj_tile_info_t)); + image_info->image_w = image->x1 - image->x0; + image_info->image_h = image->y1 - image->y0; + image_info->prog = (&cp->tcps[0])->prg; + image_info->tw = cp->tw; + image_info->th = cp->th; + image_info->tile_x = cp->tdx; /* new version parser */ + image_info->tile_y = cp->tdy; /* new version parser */ + image_info->tile_Ox = cp->tx0; /* new version parser */ + image_info->tile_Oy = cp->ty0; /* new version parser */ + image_info->comp = image->numcomps; + image_info->layer = (&cp->tcps[0])->numlayers; + image_info->decomposition = (&cp->tcps[0])->tccps->numresolutions - 1; + image_info->D_max = 0; /* ADD Marcela */ + } + /* << INDEX */ + + j2k_write_soc(j2k); + j2k_write_siz(j2k); + j2k_write_cod(j2k); + j2k_write_qcd(j2k); + for (compno = 0; compno < image->numcomps; compno++) { + opj_tcp_t *tcp = &cp->tcps[0]; + if (tcp->tccps[compno].roishift) + j2k_write_rgn(j2k, compno, 0); + } + if (cp->comment != NULL) { + j2k_write_com(j2k); + } + /* INDEX >> */ + if(image_info && image_info->index_on) { + image_info->main_head_end = cio_tell(cio) - 1; + } + /* << INDEX */ + + /* create the tile encoder */ + tcd = tcd_create(j2k->cinfo); + + /* encode each tile */ + + for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { + opg_event_msg(j2k->cinfo, EVT_INFO, "tile number %d / %d\n", tileno + 1, cp->tw * cp->th); + + j2k->curtileno = tileno; + + /* initialisation before tile encoding */ + if (tileno == 0) { + tcd_malloc_encode(tcd, image, cp, j2k->curtileno); + } else { + tcd_init_encode(tcd, image, cp, j2k->curtileno); + } + + /* INDEX >> */ + if(image_info && image_info->index_on) { + image_info->tile[j2k->curtileno].num_tile = j2k->curtileno; + image_info->tile[j2k->curtileno].start_pos = cio_tell(cio) + j2k->pos_correction; + } + /* << INDEX */ + + j2k_write_sot(j2k); + + for (compno = 1; compno < image->numcomps; compno++) { + j2k_write_coc(j2k, compno); + j2k_write_qcc(j2k, compno); + } + if (cp->tcps[tileno].numpocs) { + j2k_write_poc(j2k); + } + + j2k_write_sod(j2k, tcd); + + /* INDEX >> */ + if(image_info && image_info->index_on) { + image_info->tile[j2k->curtileno].end_pos = cio_tell(cio) + j2k->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 (j2k_cp->ppm_data_first!=NULL) free(j2k_cp->ppm_data_first); - - if (j2k_cp->tcps!=NULL) free(j2k_cp->tcps); - - if (j2k_img->comps!=NULL) free(j2k_img->comps); - - if (j2k_cp->tileno!=NULL) free(j2k_cp->tileno); - -} + /* destroy the tile encoder */ + tcd_free_encode(tcd); + tcd_destroy(tcd); -#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; + j2k_write_eoc(j2k); + + /* Creation of the index file */ + if(image_info && image_info->index_on) { + if(!j2k_create_index(j2k, cio, image_info, index)) { + opg_event_msg(j2k->cinfo, EVT_ERROR, "failed to create index file %s\n", index); + return false; + } } - return TRUE; + + return true; } -#endif + diff --git a/libopenjpeg/j2k.h b/libopenjpeg/j2k.h index ed1abd21..0b37901f 100644 --- a/libopenjpeg/j2k.h +++ b/libopenjpeg/j2k.h @@ -1,8 +1,10 @@ /* - * Copyright (c) 2001-2002, David Janssens + * 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. + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -25,37 +27,17 @@ * 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" - -#if defined(_WIN32) && defined (OPENJPEGDLL) -#ifdef gdcmopenjpeg_EXPORTS /*LIBJ2K_EXPORTS*/ -#define LIBJ2K_API __declspec(dllexport) -#else -#define LIBJ2K_API __declspec(dllimport) -#endif -#else -#ifdef OPENJPEGSTATIC -#define LIBJ2K_API extern -#else -#define LIBJ2K_API -#endif -#endif - - #ifndef __J2K_H #define __J2K_H +/** +@file j2k.h +@brief The JPEG-2000 Codestream Reader/Writer (J2K) -#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_CFMT 0 -#define JP2_CFMT 1 -#define JPT_CFMT 2 -#define MJ2_CFMT 3 -#define PXM_DFMT 0 -#define PGX_DFMT 1 -#define BMP_DFMT 2 -#define YUV_DFMT 3 +The functions in J2K.C have for goal to read/write the several parts of the codestream: markers and data. +*/ + +/** @defgroup J2K J2K - JPEG-2000 codestream reader/writer */ +/*@{*/ #define J2K_CP_CSTY_PRT 0x01 #define J2K_CP_CSTY_SOP 0x02 @@ -71,171 +53,568 @@ #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; +#define J2K_MS_SOC 0xff4f /**< SOC marker value */ +#define J2K_MS_SOT 0xff90 /**< SOT marker value */ +#define J2K_MS_SOD 0xff93 /**< SOD marker value */ +#define J2K_MS_EOC 0xffd9 /**< EOC marker value */ +#define J2K_MS_SIZ 0xff51 /**< SIZ marker value */ +#define J2K_MS_COD 0xff52 /**< COD marker value */ +#define J2K_MS_COC 0xff53 /**< COC marker value */ +#define J2K_MS_RGN 0xff5e /**< RGN marker value */ +#define J2K_MS_QCD 0xff5c /**< QCD marker value */ +#define J2K_MS_QCC 0xff5d /**< QCC marker value */ +#define J2K_MS_POC 0xff5f /**< POC marker value */ +#define J2K_MS_TLM 0xff55 /**< TLM marker value */ +#define J2K_MS_PLM 0xff57 /**< PLM marker value */ +#define J2K_MS_PLT 0xff58 /**< PLT marker value */ +#define J2K_MS_PPM 0xff60 /**< PPM marker value */ +#define J2K_MS_PPT 0xff61 /**< PPT marker value */ +#define J2K_MS_SOP 0xff91 /**< SOP marker value */ +#define J2K_MS_EPH 0xff92 /**< EPH marker value */ +#define J2K_MS_CRG 0xff63 /**< CRG marker value */ +#define J2K_MS_COM 0xff64 /**< COM marker value */ -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; +/** +Values that specify the status of the decoding process when decoding the main header. +These values may be combined with a | operator. +*/ +typedef enum J2K_STATUS { + J2K_STATE_MHSOC = 0x0001, /**< a SOC marker is expected */ + J2K_STATE_MHSIZ = 0x0002, /**< a SIZ marker is expected */ + J2K_STATE_MH = 0x0004, /**< the decoding process is in the main header */ + J2K_STATE_TPHSOT = 0x0008, /**< the decoding process is in a tile part header and expects a SOT marker */ + J2K_STATE_TPH = 0x0010, /**< the decoding process is in a tile part header */ + J2K_STATE_MT = 0x0020, /**< the EOC marker has just been read */ + J2K_STATE_NEOC = 0x0040 /**< the decoding process must not expect a EOC marker because the codestream is truncated */ +} J2K_STATUS; -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 */ - unsigned char *ppt_data_first; /* pointer remaining on the first byte of the first header if ppt is used */ - 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; +/** +Quantization stepsize +*/ +typedef struct opj_stepsize { + /** exponent */ + int expn; + /** mantissa */ + int mant; +} opj_stepsize_t; -typedef struct { - int intermed_file; /* 1: Store each encoded tile one by one in the output file (for mega-Images)*/ - int decod_format; /* 0: PGX, 1: PxM, 2: BMP */ - int cod_format; /* 0: J2K, 1: JP2, 2: JPT */ - int disto_alloc; /* Allocation by rate/distortion */ - int fixed_alloc; /* Allocation by fixed layer */ - int fixed_quality; /* add fixed_quality */ - int reduce; /* if != 0, then original dimension divided by 2^(reduce); if == 0 or not used, image is decoded to the full resolution */ - int layer; /* if != 0, then only the first "layer" layers are decoded; if == 0 or not used, all the quality layers are decoded */ - 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 */ - unsigned char *ppm_data_first; /* pointer remaining on the first byte of the first header if ppm is used */ - 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; +/** +Tile-component coding parameters +*/ +typedef struct opj_tccp { + /** coding style */ + int csty; + /** number of resolutions */ + int numresolutions; + /** code-blocks width */ + int cblkw; + /** code-blocks height */ + int cblkh; + /** code-block coding style */ + int cblksty; + /** discrete wavelet transform identifier */ + int qmfbid; + /** quantisation style */ + int qntsty; + /** stepsizes used for quantization */ + opj_stepsize_t stepsizes[J2K_MAXBANDS]; + /** number of guard bits */ + int numgbits; + /** Region Of Interest shift */ + int roishift; + /** precinct width */ + int prcw[J2K_MAXRLVLS]; + /** precinct height */ + int prch[J2K_MAXRLVLS]; +} opj_tccp_t; -typedef struct { - int start_pos, end_pos; /* start and end position */ - double disto; /* ADD for Marcela */ -} info_packet; /* Index struct */ +/** +Tile coding parameters : +this structure is used to store coding/decoding parameters common to all +tiles (information like COD, COC in main header) +*/ +typedef struct opj_tcp { + /** 1 : first part-tile of a tile */ + int first; + /** coding style */ + int csty; + /** progression order */ + OPJ_PROG_ORDER prg; + /** number of layers */ + int numlayers; + /** multi-component transform identifier */ + int mct; + /** rates of layers */ + int rates[100]; + /** number of progression order changes */ + int numpocs; + /** indicates if a POC marker has been used O:NO, 1:YES */ + int POC; + /** progression order changes */ + opj_poc_t pocs[32]; + /** packet header store there for futur use in t2_decode_packet */ + unsigned char *ppt_data; + /** pointer remaining on the first byte of the first header if ppt is used */ + unsigned char *ppt_data_first; + /** If ppt == 1 --> there was a PPT marker for the present tile */ + int ppt; + /** used in case of multiple marker PPT (number of info already stored) */ + int ppt_store; + /** ppmbug1 */ + int ppt_len; + /** add fixed_quality */ + float distoratio[100]; + /** tile-component coding parameters */ + opj_tccp_t *tccps; +} opj_tcp_t; -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 { +/** +Coding parameters +*/ +typedef struct opj_cp { + /** allocation by rate/distortion */ + int disto_alloc; + /** allocation by fixed layer */ + int fixed_alloc; + /** add fixed_quality */ + int fixed_quality; + /** if != 0, then original dimension divided by 2^(reduce); if == 0 or not used, image is decoded to the full resolution */ + int reduce; + /** if != 0, then only the first "layer" layers are decoded; if == 0 or not used, all the quality layers are decoded */ + int layer; + /** 0 = no index || 1 = index */ int index_on; - 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 Tile_Ox, Tile_Oy; - 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 */ + /** XTOsiz */ + int tx0; + /** YTOsiz */ + int ty0; + /** XTsiz */ + int tdx; + /** YTsiz */ + int tdy; + /** comment for coding */ + char *comment; + /** number of tiles in width */ + int tw; + /** number of tiles in heigth */ + int th; + /** ID number of the tiles present in the codestream */ + int *tileno; + /** size of the vector tileno */ + int tileno_size; + /** packet header store there for futur use in t2_decode_packet */ + unsigned char *ppm_data; + /** pointer remaining on the first byte of the first header if ppm is used */ + unsigned char *ppm_data_first; + /** if ppm == 1 --> there was a PPM marker for the present tile */ + int ppm; + /** use in case of multiple marker PPM (number of info already store) */ + int ppm_store; + /** use in case of multiple marker PPM (case on non-finished previous info) */ + int ppm_previous; + /** ppmbug1 */ + int ppm_len; + /** tile coding parameters */ + opj_tcp_t *tcps; + /** fixed layer */ + int *matrice; +} opj_cp_t; -/* - * 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); +/** +Information concerning a packet inside tile +*/ +typedef struct opj_packet_info { + /** start position */ + int start_pos; + /** end position */ + int end_pos; + /** ADD for Marcela */ + double disto; +} opj_packet_info_t; -/* 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 - */ +/** +Index structure : information regarding tiles inside image +*/ +typedef struct opj_tile_info { + /** value of thresh for each layer by tile cfr. Marcela */ + double *thresh; + /** number of tile */ + int num_tile; + /** start position */ + int start_pos; + /** end position of the header */ + int end_header; + /** end position */ + int end_pos; + /** precinct number for each resolution level (width) */ + int pw[33]; + /** precinct number for each resolution level (height) */ + int ph[33]; + /** precinct size (in power of 2), in X for each resolution level */ + int pdx[33]; + /** precinct size (in power of 2), in Y for each resolution level */ + int pdy[33]; + /** information concerning packets inside tile */ + opj_packet_info_t *packet; + /** add fixed_quality */ + int nbpix; + /** add fixed_quality */ + double distotile; +} opj_tile_info_t; -LIBJ2K_API int j2k_decode(unsigned char *src, int len, j2k_image_t * img, - j2k_cp_t * cp); +/** +Index structure +*/ +typedef struct opj_image_info { + /** 0 = no index || 1 = index */ + int index_on; + /** maximum distortion reduction on the whole image (add for Marcela) */ + double D_max; + /** packet number */ + int num; + /** writing the packet in the index with t2_encode_packets */ + int index_write; + /** image width */ + int image_w; + /** image height */ + int image_h; + /** progression order */ + OPJ_PROG_ORDER prog; + /** tile size in x */ + int tile_x; + /** tile size in y */ + int tile_y; + /** */ + int tile_Ox; + /** */ + int tile_Oy; + /** number of tiles in X */ + int tw; + /** number of tiles in Y */ + int th; + /** component numbers */ + int comp; + /** number of layer */ + int layer; + /** number of decomposition */ + int decomposition; + /** main header position */ + int main_head_end; + /** codestream's size */ + int codestream_size; + /** information regarding tiles inside image */ + opj_tile_info_t *tile; +} opj_image_info_t; +/** +JPEG-2000 codestream reader/writer +*/ +typedef struct opj_j2k { + /** codec context */ + opj_common_ptr cinfo; -/* - * 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); + /** locate in which part of the codestream the decoder is (main header, tile header, end) */ + int state; + /** number of the tile curently concern by coding/decoding */ + int curtileno; + /** + locate the position of the end of the tile in the codestream, + used to detect a truncated codestream (in j2k_read_sod) + */ + unsigned char *eot; + /** + locate the start position of the SOT marker of the current coded tile: + after encoding the tile, a jump (in j2k_write_sod) is done to the SOT marker to store the value of its length. + */ + int sot_start; + int sod_start; + /** + as the J2K-file is written in several parts during encoding, + it enables to make the right correction in position return by cio_tell + */ + int pos_correction; + /** array used to store the data of each tile */ + unsigned char **tile_data; + /** array used to store the length of each tile */ + int *tile_len; + /** + decompression only : + store decoding parameters common to all tiles (information like COD, COC in main header) + */ + opj_tcp_t *default_tcp; + /** pointer to the encoded / decoded image */ + opj_image_t *image; + /** pointer to the coding parameters */ + opj_cp_t *cp; + /** helper used to write the index file */ + opj_image_info_t *image_info; + /** pointer to the byte i/o stream */ + opj_cio_t *cio; +} opj_j2k_t; -LIBJ2K_API void j2k_dec_release();/*antonin*/ +/** @name Local static functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Write the SOC marker (Start Of Codestream) +@param j2k J2K handle +*/ +static void j2k_write_soc(opj_j2k_t *j2k); +/** +Read the SOC marker (Start of Codestream) +@param j2k J2K handle +*/ +static void j2k_read_soc(opj_j2k_t *j2k); +/** +Write the SIZ marker (image and tile size) +@param j2k J2K handle +*/ +static void j2k_write_siz(opj_j2k_t *j2k); +/** +Read the SIZ marker (image and tile size) +@param j2k J2K handle +*/ +static void j2k_read_siz(opj_j2k_t *j2k); +/** +Write the COM marker (comment) +@param j2k J2K handle +*/ +static void j2k_write_com(opj_j2k_t *j2k); +/** +Read the COM marker (comment) +@param j2k J2K handle +*/ +static void j2k_read_com(opj_j2k_t *j2k); +/** +Write the value concerning the specified component in the marker COD and COC +@param j2k J2K handle +@param compno Number of the component concerned by the information written +*/ +static void j2k_write_cox(opj_j2k_t *j2k, int compno); +/** +Read the value concerning the specified component in the marker COD and COC +@param j2k J2K handle +@param compno Number of the component concerned by the information read +*/ +static void j2k_read_cox(opj_j2k_t *j2k, int compno); +/** +Write the COD marker (coding style default) +@param j2k J2K handle +*/ +static void j2k_write_cod(opj_j2k_t *j2k); +/** +Read the COD marker (coding style default) +@param j2k J2K handle +*/ +static void j2k_read_cod(opj_j2k_t *j2k); +/** +Write the COC marker (coding style component) +@param j2k J2K handle +@param compno Number of the component concerned by the information written +*/ +static void j2k_write_coc(opj_j2k_t *j2k, int compno); +/** +Read the COC marker (coding style component) +@param j2k J2K handle +*/ +static void j2k_read_coc(opj_j2k_t *j2k); +/** +Write the value concerning the specified component in the marker QCD and QCC +@param j2k J2K handle +@param compno Number of the component concerned by the information written +*/ +static void j2k_write_qcx(opj_j2k_t *j2k, int compno); +/** +Read the value concerning the specified component in the marker QCD and QCC +@param j2k J2K handle +@param compno Number of the component concern by the information read +@param len Length of the information in the QCX part of the marker QCD/QCC +*/ +static void j2k_read_qcx(opj_j2k_t *j2k, int compno, int len); +/** +Write the QCD marker (quantization default) +@param j2k J2K handle +*/ +static void j2k_write_qcd(opj_j2k_t *j2k); +/** +Read the QCD marker (quantization default) +@param j2k J2K handle +*/ +static void j2k_read_qcd(opj_j2k_t *j2k); +/** +Write the QCC marker (quantization component) +@param j2k J2K handle +@param compno Number of the component concerned by the information written +*/ +static void j2k_write_qcc(opj_j2k_t *j2k, int compno); +/** +Read the QCC marker (quantization component) +@param j2k J2K handle +*/ +static void j2k_read_qcc(opj_j2k_t *j2k); +/** +Write the POC marker (progression order change) +@param j2k J2K handle +*/ +static void j2k_write_poc(opj_j2k_t *j2k); +/** +Read the POC marker (progression order change) +@param j2k J2K handle +*/ +static void j2k_read_poc(opj_j2k_t *j2k); +/** +Read the CRG marker (component registration) +@param j2k J2K handle +*/ +static void j2k_read_crg(opj_j2k_t *j2k); +/** +Read the TLM marker (tile-part lengths) +@param j2k J2K handle +*/ +static void j2k_read_tlm(opj_j2k_t *j2k); +/** +Read the PLM marker (packet length, main header) +@param j2k J2K handle +*/ +static void j2k_read_plm(opj_j2k_t *j2k); +/** +Read the PLT marker (packet length, tile-part header) +@param j2k J2K handle +*/ +static void j2k_read_plt(opj_j2k_t *j2k); +/** +Read the PPM marker (packet packet headers, main header) +@param j2k J2K handle +*/ +static void j2k_read_ppm(opj_j2k_t *j2k); +/** +Read the PPT marker (packet packet headers, tile-part header) +@param j2k J2K handle +*/ +static void j2k_read_ppt(opj_j2k_t *j2k); +/** +Write the SOT marker (start of tile-part) +@param j2k J2K handle +*/ +static void j2k_write_sot(opj_j2k_t *j2k); +/** +Read the SOT marker (start of tile-part) +@param j2k J2K handle +*/ +static void j2k_read_sot(opj_j2k_t *j2k); +/** +Write the SOD marker (start of data) +@param j2k J2K handle +@param tile_coder Pointer to a TCD handle +*/ +static void j2k_write_sod(opj_j2k_t *j2k, void *tile_coder); +/** +Read the SOD marker (start of data) +@param j2k J2K handle +*/ +static void j2k_read_sod(opj_j2k_t *j2k); +/** +Write the RGN marker (region-of-interest) +@param j2k J2K handle +@param compno Number of the component concerned by the information written +@param tileno Number of the tile concerned by the information written +*/ +static void j2k_write_rgn(opj_j2k_t *j2k, int compno, int tileno); +/** +Read the RGN marker (region-of-interest) +@param j2k J2K handle +*/ +static void j2k_read_rgn(opj_j2k_t *j2k); +/** +Write the EOC marker (end of codestream) +@param j2k J2K handle +*/ +static void j2k_write_eoc(opj_j2k_t *j2k); +/** +Read the EOC marker (end of codestream) +@param j2k J2K handle +*/ +static void j2k_read_eoc(opj_j2k_t *j2k); +/** +Read an unknown marker +@param j2k J2K handle +*/ +static void j2k_read_unk(opj_j2k_t *j2k); +/* ----------------------------------------------------------------------- */ +/*@}*/ -#endif +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Creates a J2K decompression structure +@param cinfo Codec context info +@return Returns a handle to a J2K decompressor if successful, returns NULL otherwise +*/ +opj_j2k_t* j2k_create_decompress(opj_common_ptr cinfo); +/** +Destroy a J2K decompressor handle +@param j2k J2K decompressor handle to destroy +*/ +void j2k_destroy_decompress(opj_j2k_t *j2k); +/** +Setup the decoder decoding parameters using user parameters. +Decoding parameters are returned in j2k->cp. +@param j2k J2K decompressor handle +@param parameters decompression parameters +*/ +void j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters); +/** +Decode an image from a JPEG-2000 codestream +@param j2k J2K decompressor handle +@param cio Input buffer stream +@return Returns a decoded image if successful, returns NULL otherwise +*/ +opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio); +/** +Decode an image form a JPT-stream (JPEG 2000, JPIP) +@param j2k J2K decompressor handle +@param cio Input buffer stream +@return Returns a decoded image if successful, returns NULL otherwise +*/ +opj_image_t* j2k_decode_jpt_stream(opj_j2k_t *j2k, opj_cio_t *cio); +/** +Creates a J2K compression structure +@param cinfo Codec context info +@return Returns a handle to a J2K compressor if successful, returns NULL otherwise +*/ +opj_j2k_t* j2k_create_compress(opj_common_ptr cinfo); +/** +Destroy a J2K compressor handle +@param j2k J2K compressor handle to destroy +*/ +void j2k_destroy_compress(opj_j2k_t *j2k); +/** +Setup the encoder parameters using the current image and using user parameters. +Coding parameters are returned in j2k->cp. +@param j2k J2K compressor handle +@param parameters compression parameters +@param image input filled image +*/ +void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_t *image); +/** +Encode an image into a JPEG-2000 codestream +@param j2k J2K compressor handle +@param cio Output buffer stream +@param image Image to encode +@param index Name of the index file if required, NULL otherwise +@return Returns true if successful, returns false otherwise +*/ +bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, char *index); +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __J2K_H */ diff --git a/libopenjpeg/j2k_lib.c b/libopenjpeg/j2k_lib.c new file mode 100644 index 00000000..9ed3740b --- /dev/null +++ b/libopenjpeg/j2k_lib.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2005, Hervé Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifdef WIN32 +#include +#else +#include +#include +#endif /* WIN32 */ +#include "opj_includes.h" + +double opj_clock() { +#ifdef WIN32 + /* WIN32: use QueryPerformance (very accurate) */ + LARGE_INTEGER freq , t ; + /* freq is the clock speed of the CPU */ + QueryPerformanceFrequency(&freq) ; + /* cout << "freq = " << ((double) freq.QuadPart) << endl; */ + /* t is the high resolution performance counter (see MSDN) */ + QueryPerformanceCounter ( & t ) ; + return ( t.QuadPart /(double) freq.QuadPart ) ; +#else + /* Unix or Linux: use resource usage */ + struct rusage t; + double procTime; + /* (1) Get the rusage data structure at this moment (man getrusage) */ + getrusage(0,&t); + /* (2) What is the elapsed time ? - CPU time = User time + System time */ + /* (2a) Get the seconds */ + procTime = t.ru_utime.tv_sec + t.ru_stime.tv_sec; + /* (2b) More precisely! Get the microseconds part ! */ + return ( procTime + (t.ru_utime.tv_usec + t.ru_stime.tv_usec) * 1e-6 ) ; +#endif +} + +void* opj_malloc( size_t size ) { + void *memblock = malloc(size); + if(memblock) { + memset(memblock, 0, size); + } + return memblock; +} + +void* j2k_realloc( void *memblock, size_t size ) { + return realloc(memblock, size); +} + +void opj_free( void *memblock ) { + free(memblock); +} + + diff --git a/libopenjpeg/j2k_lib.h b/libopenjpeg/j2k_lib.h new file mode 100644 index 00000000..a57a9b83 --- /dev/null +++ b/libopenjpeg/j2k_lib.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2005, Hervé Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef __J2K_LIB_H +#define __J2K_LIB_H +/** +@file j2k_lib.h +@brief Internal functions + +The functions in J2K_LIB.C are internal utilities mainly used for memory management. +*/ + +/** @defgroup MISC MISC - Miscellaneous internal functions */ +/*@{*/ + +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ + +/** +Difference in successive opj_clock() calls tells you the elapsed time +@return Returns time in seconds +*/ +double opj_clock(); + +/** +Allocate a memory block with elements initialized to 0 +@param size Bytes to allocate +@return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available +*/ +void* opj_malloc( size_t size ); + +/** +Reallocate memory blocks. +@param memblock Pointer to previously allocated memory block +@param size New size in bytes +@return Returns a void pointer to the reallocated (and possibly moved) memory block +*/ +void* j2k_realloc( void *memblock, size_t size ); + +/** +Deallocates or frees a memory block. +@param memblock Previously allocated memory block to be freed +*/ +void opj_free( void *memblock ); + +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __J2K_LIB_H */ + diff --git a/libopenjpeg/jp2.c b/libopenjpeg/jp2.c index 74231502..45f5c2fa 100644 --- a/libopenjpeg/jp2.c +++ b/libopenjpeg/jp2.c @@ -1,529 +1,630 @@ /* -* 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. -*/ + * Copyright (c) 2004, Yannick Verschueren + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ -#include -#include -#include +#include "opj_includes.h" -#include "j2k.h" -#include "jp2.h" -#include "cio.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); +static bool jp2_read_boxhdr(opj_common_ptr cinfo, opj_cio_t *cio, opj_jp2_box_t *box) { + box->init_pos = cio_tell(cio); + box->length = cio_read(cio, 4); + box->type = cio_read(cio, 4); if (box->length == 1) { - if (cio_read(4) != 0) { - fprintf(stderr, "Error: Cannot handle box sizes higher than 2^32\n"); - return 1; + if (cio_read(cio, 4) != 0) { + opg_event_msg(cinfo, EVT_ERROR, "Cannot handle box sizes higher than 2^32\n"); + return false; } - box->length = cio_read(4); - if (box->length == 0) - box->length = cio_numbytesleft() + 12; - } else if (box->length == 0) { - box->length = cio_numbytesleft() + 8; + box->length = cio_read(cio, 4); + if (box->length == 0) + box->length = cio_numbytesleft(cio) + 12; } - return 0; + else if (box->length == 0) { + box->length = cio_numbytesleft(cio) + 8; + } + + return true; } -/* -* -* Initialisation of a Standard JP2 structure -*/ - -int jp2_init_stdjp2(jp2_struct_t * jp2_struct) -{ - - jp2_struct->comps = - (jp2_comps_t *) malloc(jp2_struct->numcomps * sizeof(jp2_comps_t)); - - jp2_struct->precedence = 0; /* PRECEDENCE*/ - jp2_struct->approx = 0; /* APPROX*/ - - jp2_struct->brand = JP2_JP2; /* BR */ - jp2_struct->minversion = 0; /* MinV */ - jp2_struct->numcl = 1; - jp2_struct->cl = (unsigned int *) malloc(jp2_struct->numcl * sizeof(int)); - jp2_struct->cl[0] = JP2_JP2; /* CL0 : JP2 */ - - 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*/ - - return 0; -} - - -void jp2_write_url(char *Idx_file) -{ +static void jp2_write_url(opj_cio_t *cio, char *Idx_file) { unsigned int i; - char str[256]; - jp2_box_t box; + opj_jp2_box_t box; - sprintf(str, "%s", Idx_file); + box.init_pos = cio_tell(cio); + cio_skip(cio, 4); + cio_write(cio, JP2_URL, 4); /* DBTL */ + cio_write(cio, 0, 1); /* VERS */ + cio_write(cio, 0, 3); /* FLAG */ - - 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); + if(Idx_file) { + for (i = 0; i < strlen(Idx_file); i++) { + cio_write(cio, Idx_file[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); + box.length = cio_tell(cio) - box.init_pos; + cio_seek(cio, box.init_pos); + cio_write(cio, box.length, 4); /* L */ + cio_seek(cio, 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; +static bool jp2_read_ihdr(opj_jp2_t *jp2, opj_cio_t *cio) { + opj_jp2_box_t box; - jp2_read_boxhdr(&box); + opj_common_ptr cinfo = jp2->cinfo; + + jp2_read_boxhdr(cinfo, cio, &box); if (JP2_IHDR != box.type) { - fprintf(stderr, "Error: Expected IHDR Marker\n"); - return 1; + opg_event_msg(cinfo, EVT_ERROR, "Expected IHDR Marker\n"); + return false; } - jp2_struct->h = cio_read(4); /* HEIGHT*/ - jp2_struct->w = cio_read(4); /* WIDTH*/ - jp2_struct->numcomps = cio_read(2); /* NC*/ + jp2->h = cio_read(cio, 4); /* HEIGHT */ + jp2->w = cio_read(cio, 4); /* WIDTH */ + jp2->numcomps = cio_read(cio, 2); /* NC */ - jp2_struct->bpc = cio_read(1); /* BPC*/ + jp2->bpc = cio_read(cio, 1); /* BPC */ - jp2_struct->C = cio_read(1); /* C */ - jp2_struct->UnkC = cio_read(1); /* UnkC*/ - jp2_struct->IPR = cio_read(1); /* IPR*/ + jp2->C = cio_read(cio, 1); /* C */ + jp2->UnkC = cio_read(cio, 1); /* UnkC */ + jp2->IPR = cio_read(cio, 1); /* IPR */ - if (cio_tell() - box.init_pos != box.length) { - fprintf(stderr, "Error with IHDR Box\n"); - return 1; + if (cio_tell(cio) - box.init_pos != box.length) { + opg_event_msg(cinfo, EVT_ERROR, "Error with IHDR Box\n"); + return false; } - return 0; + + return true; } -void jp2_write_ihdr(jp2_struct_t * jp2_struct) -{ - jp2_box_t box; +static void jp2_write_ihdr(opj_jp2_t *jp2, opj_cio_t *cio) { + opj_jp2_box_t box; - box.init_pos = cio_tell(); - cio_skip(4); - cio_write(JP2_IHDR, 4); /* IHDR*/ + box.init_pos = cio_tell(cio); + cio_skip(cio, 4); + cio_write(cio, 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(cio, jp2->h, 4); /* HEIGHT */ + cio_write(cio, jp2->w, 4); /* WIDTH */ + cio_write(cio, jp2->numcomps, 2); /* NC */ - cio_write(jp2_struct->bpc, 1); /* BPC */ + cio_write(cio, jp2->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*/ + cio_write(cio, jp2->C, 1); /* C : Always 7 */ + cio_write(cio, jp2->UnkC, 1); /* UnkC, colorspace unknown */ + cio_write(cio, jp2->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); + box.length = cio_tell(cio) - box.init_pos; + cio_seek(cio, box.init_pos); + cio_write(cio, box.length, 4); /* L */ + cio_seek(cio, box.init_pos + box.length); } - -void jp2_write_bpcc(jp2_struct_t * jp2_struct) -{ +static void jp2_write_bpcc(opj_jp2_t *jp2, opj_cio_t *cio) { unsigned int i; - jp2_box_t box; + opj_jp2_box_t box; - box.init_pos = cio_tell(); - cio_skip(4); - cio_write(JP2_BPCC, 4); /* BPCC*/ + box.init_pos = cio_tell(cio); + cio_skip(cio, 4); + cio_write(cio, JP2_BPCC, 4); /* BPCC */ - for (i = 0; i < jp2_struct->numcomps; i++) - cio_write(jp2_struct->comps[i].bpcc, 1); + for (i = 0; i < jp2->numcomps; i++) { + cio_write(cio, jp2->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); + box.length = cio_tell(cio) - box.init_pos; + cio_seek(cio, box.init_pos); + cio_write(cio, box.length, 4); /* L */ + cio_seek(cio, box.init_pos + box.length); } -int jp2_read_bpcc(jp2_struct_t * jp2_struct) -{ +static bool jp2_read_bpcc(opj_jp2_t *jp2, opj_cio_t *cio) { unsigned int i; - jp2_box_t box; + opj_jp2_box_t box; - jp2_read_boxhdr(&box); + opj_common_ptr cinfo = jp2->cinfo; + + jp2_read_boxhdr(cinfo, cio, &box); if (JP2_BPCC != box.type) { - fprintf(stderr, "Error: Expected BPCC Marker\n"); - return 1; + opg_event_msg(cinfo, EVT_ERROR, "Expected BPCC Marker\n"); + return false; } - 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; + for (i = 0; i < jp2->numcomps; i++) { + jp2->comps[i].bpcc = cio_read(cio, 1); } - return 0; + + if (cio_tell(cio) - box.init_pos != box.length) { + opg_event_msg(cinfo, EVT_ERROR, "Error with BPCC Box\n"); + return false; + } + + return true; } -void jp2_write_colr(jp2_struct_t * jp2_struct) -{ - jp2_box_t box; +static void jp2_write_colr(opj_jp2_t *jp2, opj_cio_t *cio) { + opj_jp2_box_t box; - box.init_pos = cio_tell(); - cio_skip(4); - cio_write(JP2_COLR, 4); /* COLR*/ + box.init_pos = cio_tell(cio); + cio_skip(cio, 4); + cio_write(cio, 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*/ + cio_write(cio, jp2->meth, 1); /* METH */ + cio_write(cio, jp2->precedence, 1); /* PRECEDENCE */ + cio_write(cio, jp2->approx, 1); /* APPROX */ - if (jp2_struct->meth == 1) - cio_write(jp2_struct->enumcs, 4); /* EnumCS*/ - else - cio_write(0, 1); /* PROFILE (??)*/ + if (jp2->meth == 1) { + cio_write(cio, jp2->enumcs, 4); /* EnumCS */ + } else { + cio_write(cio, 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); + box.length = cio_tell(cio) - box.init_pos; + cio_seek(cio, box.init_pos); + cio_write(cio, box.length, 4); /* L */ + cio_seek(cio, box.init_pos + box.length); } -int jp2_read_colr(jp2_struct_t * jp2_struct) -{ - jp2_box_t box; +static bool jp2_read_colr(opj_jp2_t *jp2, opj_cio_t *cio) { + opj_jp2_box_t box; int skip_len; - jp2_read_boxhdr(&box); + opj_common_ptr cinfo = jp2->cinfo; + + jp2_read_boxhdr(cinfo, cio, &box); do { if (JP2_COLR != box.type) { - cio_skip(box.length - 8); - jp2_read_boxhdr(&box); + cio_skip(cio, box.length - 8); + jp2_read_boxhdr(cinfo, cio, &box); } - } while (JP2_COLR != box.type); + } while(JP2_COLR != box.type); - jp2_struct->meth = cio_read(1); /* METH*/ - jp2_struct->precedence = cio_read(1); /* PRECEDENCE*/ - jp2_struct->approx = cio_read(1); /* APPROX*/ + jp2->meth = cio_read(cio, 1); /* METH */ + jp2->precedence = cio_read(cio, 1); /* PRECEDENCE */ + jp2->approx = cio_read(cio, 1); /* APPROX */ - if (jp2_struct->meth == 1) - jp2_struct->enumcs = cio_read(4); /* EnumCS*/ - else { - /* SKIP PROFILE */ - skip_len = box.init_pos + box.length - cio_tell(); + if (jp2->meth == 1) { + jp2->enumcs = cio_read(cio, 4); /* EnumCS */ + } else { + /* skip PROFILE */ + skip_len = box.init_pos + box.length - cio_tell(cio); if (skip_len < 0) { - fprintf(stderr, "Error with JP2H box size\n"); - return 1; + opg_event_msg(cinfo, EVT_ERROR, "Error with JP2H box size\n"); + return false; } - cio_skip(box.init_pos + box.length - cio_tell()); + cio_skip(cio, box.init_pos + box.length - cio_tell(cio)); } - if (cio_tell() - box.init_pos != box.length) { - fprintf(stderr, "Error with BPCC Box\n"); - return 1; + if (cio_tell(cio) - box.init_pos != box.length) { + opg_event_msg(cinfo, EVT_ERROR, "Error with BPCC Box\n"); + return false; } - return 0; + return true; } -/* -* Write the JP2H box -* -* JP2 Header box -* -*/ -void jp2_write_jp2h(jp2_struct_t * jp2_struct) -{ - jp2_box_t box; +static void jp2_write_jp2h(opj_jp2_t *jp2, opj_cio_t *cio) { + opj_jp2_box_t box; - box.init_pos = cio_tell(); - cio_skip(4);; - cio_write(JP2_JP2H, 4); /* JP2H */ + box.init_pos = cio_tell(cio); + cio_skip(cio, 4); + cio_write(cio, JP2_JP2H, 4); /* JP2H */ - jp2_write_ihdr(jp2_struct); + jp2_write_ihdr(jp2, cio); - if (jp2_struct->bpc == 255) - jp2_write_bpcc(jp2_struct); - jp2_write_colr(jp2_struct); + if (jp2->bpc == 255) { + jp2_write_bpcc(jp2, cio); + } + jp2_write_colr(jp2, cio); - 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); + box.length = cio_tell(cio) - box.init_pos; + cio_seek(cio, box.init_pos); + cio_write(cio, box.length, 4); /* L */ + cio_seek(cio, 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; +static bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio) { + opj_jp2_box_t box; int skip_len; - jp2_read_boxhdr(&box); + opj_common_ptr cinfo = jp2->cinfo; + + jp2_read_boxhdr(cinfo, cio, &box); do { if (JP2_JP2H != box.type) { if (box.type == JP2_JP2C) { - fprintf(stderr, "Error: Expected JP2H Marker\n"); - return 1; + opg_event_msg(cinfo, EVT_ERROR, "Expected JP2H Marker\n"); + return false; } - cio_skip(box.length - 8); - jp2_read_boxhdr(&box); + cio_skip(cio, box.length - 8); + jp2_read_boxhdr(cinfo, cio, &box); } - } while (JP2_JP2H != box.type); + } while(JP2_JP2H != box.type); - if (jp2_read_ihdr(jp2_struct)) - return 1; + if (!jp2_read_ihdr(jp2, cio)) + return false; - if (jp2_struct->bpc == 255) { - if (jp2_read_bpcc(jp2_struct)) - return 1; + if (jp2->bpc == 255) { + if (!jp2_read_bpcc(jp2, cio)) + return false; } + if (!jp2_read_colr(jp2, cio)) + return false; - if (jp2_read_colr(jp2_struct)) - return 1; - - skip_len = box.init_pos + box.length - cio_tell(); + skip_len = box.init_pos + box.length - cio_tell(cio); if (skip_len < 0) { - fprintf(stderr, "Error with JP2H box size\n"); - return 1; + opg_event_msg(cinfo, EVT_ERROR, "Error with JP2H Box\n"); + return false; } - cio_skip(box.init_pos + box.length - cio_tell()); + cio_skip(cio, box.init_pos + box.length - cio_tell(cio)); - return 0; + return true; } -/* -* Write the FTYP box -* -* File type box -* -*/ -void jp2_write_ftyp(jp2_struct_t * jp2_struct) -{ +static void jp2_write_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) { unsigned int i; - jp2_box_t box; + opj_jp2_box_t box; - box.init_pos = cio_tell(); - cio_skip(4); - cio_write(JP2_FTYP, 4); /* FTYP */ + box.init_pos = cio_tell(cio); + cio_skip(cio, 4); + cio_write(cio, JP2_FTYP, 4); /* FTYP */ - cio_write(jp2_struct->brand, 4); /* BR */ - cio_write(jp2_struct->minversion, 4); /* MinV */ + cio_write(cio, jp2->brand, 4); /* BR */ + cio_write(cio, jp2->minversion, 4); /* MinV */ - for (i = 0; i < jp2_struct->numcl; i++) - cio_write(jp2_struct->cl[i], 4); /* CL */ + for (i = 0; i < jp2->numcl; i++) { + cio_write(cio, jp2->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); + box.length = cio_tell(cio) - box.init_pos; + cio_seek(cio, box.init_pos); + cio_write(cio, box.length, 4); /* L */ + cio_seek(cio, box.init_pos + box.length); } -/* -* Read the FTYP box -* -* File type box -* -*/ -int jp2_read_ftyp(jp2_struct_t * jp2_struct) -{ +static bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) { int i; - jp2_box_t box; + opj_jp2_box_t box; - jp2_read_boxhdr(&box); + opj_common_ptr cinfo = jp2->cinfo; + + jp2_read_boxhdr(cinfo, cio, &box); if (JP2_FTYP != box.type) { - fprintf(stderr, "Error: Excpected FTYP Marker\n"); - return 1; + opg_event_msg(cinfo, EVT_ERROR, "Expected FTYP Marker\n"); + return false; } - 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)); + jp2->brand = cio_read(cio, 4); /* BR */ + jp2->minversion = cio_read(cio, 4); /* MinV */ + jp2->numcl = (box.length - 16) / 4; + jp2->cl = (unsigned int *) opj_malloc(jp2->numcl * sizeof(unsigned int)); - for (i = 0; i < (int) jp2_struct->numcl; 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; + for (i = 0; i < (int)jp2->numcl; i++) { + jp2->cl[i] = cio_read(cio, 4); /* CLi */ } - return 0; + + if (cio_tell(cio) - box.init_pos != box.length) { + opg_event_msg(cinfo, EVT_ERROR, "Error with FTYP Box\n"); + return false; + } + + return true; } -int jp2_write_jp2c(int j2k_codestream_len, int *j2k_codestream_offset, - char *j2k_codestream) -{ - jp2_box_t box; +static int jp2_write_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, char *index) { + unsigned int j2k_codestream_offset, j2k_codestream_length; + opj_jp2_box_t box; - box.init_pos = cio_tell(); - cio_skip(4); - cio_write(JP2_JP2C, 4); /* JP2C*/ + opj_j2k_t *j2k = jp2->j2k; + opj_image_t *image = jp2->image; - *j2k_codestream_offset = cio_tell(); - memcpy(cio_getbp(), j2k_codestream, j2k_codestream_len); + box.init_pos = cio_tell(cio); + cio_skip(cio, 4); + cio_write(cio, JP2_JP2C, 4); /* JP2C */ - box.length = 8 + j2k_codestream_len; - cio_seek(box.init_pos); - cio_write(box.length, 4); /* L */ - cio_seek(box.init_pos + box.length); + /* J2K encoding */ + j2k_codestream_offset = cio_tell(cio); + if(!j2k_encode(j2k, cio, image, index)) { + opg_event_msg(j2k->cinfo, EVT_ERROR, "Failed to encode image\n"); + return 0; + } + j2k_codestream_length = cio_tell(cio) - j2k_codestream_offset; + + jp2->j2k_codestream_offset = j2k_codestream_offset; + jp2->j2k_codestream_length = j2k_codestream_length; + + box.length = 8 + jp2->j2k_codestream_length; + cio_seek(cio, box.init_pos); + cio_write(cio, box.length, 4); /* L */ + cio_seek(cio, box.init_pos + box.length); return box.length; } +static bool jp2_read_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, unsigned int *j2k_codestream_length, unsigned int *j2k_codestream_offset) { + opj_jp2_box_t box; -int jp2_read_jp2c(unsigned int *j2k_codestream_len, - unsigned int *j2k_codestream_offset) -{ - jp2_box_t box; + opj_common_ptr cinfo = jp2->cinfo; - jp2_read_boxhdr(&box); + jp2_read_boxhdr(cinfo, cio, &box); do { - if (JP2_JP2C != box.type) { - cio_skip(box.length - 8); - jp2_read_boxhdr(&box); + if(JP2_JP2C != box.type) { + cio_skip(cio, box.length - 8); + jp2_read_boxhdr(cinfo, cio, &box); } - } while (JP2_JP2C != box.type); + } while(JP2_JP2C != box.type); - *j2k_codestream_offset = cio_tell(); - *j2k_codestream_len = box.length - 8; + *j2k_codestream_offset = cio_tell(cio); + *j2k_codestream_length = box.length - 8; - return 0; + return true; } -void jp2_write_jp() -{ - jp2_box_t box; +static void jp2_write_jp(opj_cio_t *cio) { + opj_jp2_box_t box; - box.init_pos = cio_tell(); - cio_skip(4); - cio_write(JP2_JP, 4); /* JP*/ - cio_write(0x0d0a870a, 4); + box.init_pos = cio_tell(cio); + cio_skip(cio, 4); + cio_write(cio, JP2_JP, 4); /* JP2 signature */ + cio_write(cio, 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); + box.length = cio_tell(cio) - box.init_pos; + cio_seek(cio, box.init_pos); + cio_write(cio, box.length, 4); /* L */ + cio_seek(cio, 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; +static bool jp2_read_jp(opj_jp2_t *jp2, opj_cio_t *cio) { + opj_jp2_box_t box; - jp2_read_boxhdr(&box); + opj_common_ptr cinfo = jp2->cinfo; + + jp2_read_boxhdr(cinfo, cio, &box); if (JP2_JP != box.type) { - fprintf(stderr, "Error: Expected JP Marker\n"); - return 1; + opg_event_msg(cinfo, EVT_ERROR, "Expected JP Marker\n"); + return false; } - if (0x0d0a870a != cio_read(4)) { - fprintf(stderr, "Error with JP Marker\n"); - return 1; + if (0x0d0a870a != cio_read(cio, 4)) { + opg_event_msg(cinfo, EVT_ERROR, "Error with JP Marker\n"); + return false; } - if (cio_tell() - box.init_pos != box.length) { - fprintf(stderr, "Error with JP Box size\n"); - return 1; + if (cio_tell(cio) - box.init_pos != box.length) { + opg_event_msg(cinfo, EVT_ERROR, "Error with JP Box size\n"); + return false; } - return 0; + return true; } -int jp2_read_struct(unsigned char *src, jp2_struct_t * jp2_struct, int len) -{ - 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 - (&jp2_struct->j2k_codestream_len, - &jp2_struct->j2k_codestream_offset)) - return 1; - return 0; +static bool jp2_read_struct(opj_jp2_t *jp2, opj_cio_t *cio) { + if (!jp2_read_jp(jp2, cio)) + return false; + if (!jp2_read_ftyp(jp2, cio)) + return false; + if (!jp2_read_jp2h(jp2, cio)) + return false; + if (!jp2_read_jp2c(jp2, cio, &jp2->j2k_codestream_length, &jp2->j2k_codestream_offset)) + return false; + + return true; } -int jp2_wrap_j2k(jp2_struct_t * jp2_struct, char *j2k_codestream, - char *output) -{ - (void)output; - jp2_write_jp(); - jp2_write_ftyp(jp2_struct); - jp2_write_jp2h(jp2_struct); +/* ----------------------------------------------------------------------- */ +/* JP2 decoder interface */ +/* ----------------------------------------------------------------------- */ - jp2_write_jp2c(jp2_struct->j2k_codestream_len, - &jp2_struct->j2k_codestream_offset, j2k_codestream); - - return cio_tell(); +opj_jp2_t* jp2_create_decompress(opj_common_ptr cinfo) { + opj_jp2_t *jp2 = (opj_jp2_t*)opj_malloc(sizeof(opj_jp2_t)); + if(jp2) { + jp2->cinfo = cinfo; + /* create the J2K codec */ + jp2->j2k = j2k_create_decompress(cinfo); + if(jp2->j2k == NULL) { + jp2_destroy_decompress(jp2); + return NULL; + } + } + return jp2; } + +void jp2_destroy_decompress(opj_jp2_t *jp2) { + if(jp2) { + /* destroy the J2K codec */ + j2k_destroy_decompress(jp2->j2k); + + if(jp2->comps) { + opj_free(jp2->comps); + } + if(jp2->cl) { + opj_free(jp2->cl); + } + opj_free(jp2); + } +} + +void jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters) { + /* setup the J2K codec */ + j2k_setup_decoder(jp2->j2k, parameters); + /* further JP2 initializations go here */ +} + +opj_image_t* jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio) { + opj_common_ptr cinfo; + opj_image_t *image = NULL; + + if(!jp2 || !cio) { + return NULL; + } + + cinfo = jp2->cinfo; + + /* JP2 decoding */ + if(!jp2_read_struct(jp2, cio)) { + opg_event_msg(cinfo, EVT_ERROR, "Failed to decode jp2 structure\n"); + return NULL; + } + + /* J2K decoding */ + image = j2k_decode(jp2->j2k, cio); + if(!image) { + opg_event_msg(cinfo, EVT_ERROR, "Failed to decode J2K image\n"); + } + + return image; +} + +/* ----------------------------------------------------------------------- */ +/* JP2 encoder interface */ +/* ----------------------------------------------------------------------- */ + +opj_jp2_t* jp2_create_compress(opj_common_ptr cinfo) { + opj_jp2_t *jp2 = (opj_jp2_t*)opj_malloc(sizeof(opj_jp2_t)); + if(jp2) { + jp2->cinfo = cinfo; + /* create the J2K codec */ + jp2->j2k = j2k_create_compress(cinfo); + if(jp2->j2k == NULL) { + jp2_destroy_compress(jp2); + return NULL; + } + } + return jp2; +} + +void jp2_destroy_compress(opj_jp2_t *jp2) { + if(jp2) { + /* destroy the J2K codec */ + j2k_destroy_compress(jp2->j2k); + + if(jp2->comps) { + opj_free(jp2->comps); + } + if(jp2->cl) { + opj_free(jp2->cl); + } + opj_free(jp2); + } +} + +void jp2_setup_encoder(opj_jp2_t *jp2, opj_cparameters_t *parameters, opj_image_t *image) { + int i; + int depth_0, sign; + + if(!jp2 || !parameters || !image) + return; + + /* setup the J2K codec */ + /* ------------------- */ + + j2k_setup_encoder(jp2->j2k, parameters, image); + + /* setup the JP2 codec */ + /* ------------------- */ + + /* Profile box */ + + jp2->brand = JP2_JP2; /* BR */ + jp2->minversion = 0; /* MinV */ + jp2->numcl = 1; + jp2->cl = (unsigned int*) opj_malloc(jp2->numcl * sizeof(unsigned int)); + jp2->cl[0] = JP2_JP2; /* CL0 : JP2 */ + + /* Image Header box */ + + jp2->image = image; + + jp2->numcomps = image->numcomps; /* NC */ + jp2->comps = (opj_jp2_comps_t*) opj_malloc(jp2->numcomps * sizeof(opj_jp2_comps_t)); + jp2->h = image->y1 - image->y0; /* HEIGHT */ + jp2->w = image->x1 - image->x0; /* WIDTH */ + /* BPC */ + depth_0 = image->comps[0].prec - 1; + sign = image->comps[0].sgnd; + jp2->bpc = depth_0 + (sign << 7); + for (i = 1; i < image->numcomps; i++) { + int depth = image->comps[i].prec - 1; + sign = image->comps[i].sgnd; + if (depth_0 != depth) + jp2->bpc = 255; + } + jp2->C = 7; /* C : Always 7 */ + jp2->UnkC = 0; /* UnkC, colorspace specified in colr box */ + jp2->IPR = 0; /* IPR, no intellectual property */ + + /* BitsPerComponent box */ + + for (i = 0; i < image->numcomps; i++) { + jp2->comps[i].bpcc = image->comps[i].prec - 1 + (image->comps[i].sgnd << 7); + } + + /* Colour Specification box */ + + if ((image->numcomps == 1 || image->numcomps == 3) && (jp2->bpc != 255)) { + jp2->meth = 1; /* METH: Enumerated colourspace */ + } else { + jp2->meth = 2; /* METH: Restricted ICC profile */ + } + if (jp2->meth == 1) { + if (image->color_space == 1) + jp2->enumcs = 16; /* sRGB as defined by IEC 61966–2–1 */ + else if (image->color_space == 2) + jp2->enumcs = 17; /* greyscale */ + else if (image->color_space == 3) + jp2->enumcs = 18; /* YUV */ + } else { + jp2->enumcs = 0; /* PROFILE (??) */ + } + jp2->precedence = 0; /* PRECEDENCE */ + jp2->approx = 0; /* APPROX */ + +} + +bool jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, char *index) { + + /* JP2 encoding */ + + /* JPEG 2000 Signature box */ + jp2_write_jp(cio); + /* File Type box */ + jp2_write_ftyp(jp2, cio); + /* JP2 Header box */ + jp2_write_jp2h(jp2, cio); + + /* J2K encoding */ + + if(!jp2_write_jp2c(jp2, cio, index)) { + opg_event_msg(jp2->cinfo, EVT_ERROR, "Failed to encode image\n"); + return false; + } + + return true; +} + + diff --git a/libopenjpeg/jp2.h b/libopenjpeg/jp2.h index 5d20ae61..ea7c09bd 100644 --- a/libopenjpeg/jp2.h +++ b/libopenjpeg/jp2.h @@ -1,6 +1,7 @@ /* - * Copyright (c) 2003, Yannick Verschueren - * Copyright (c) 2003, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * Copyright (c) 2004, Yannick Verschueren + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,16 +27,47 @@ */ #ifndef __JP2_H #define __JP2_H +/** +@file jp2.h +@brief The JPEG-2000 file format Reader/Writer (JP2) -#include "j2k.h" +*/ -typedef struct { - int depth; - int sgnd; +/** @defgroup JP2 JP2 - JPEG-2000 file format reader/writer */ +/*@{*/ + +#define JPIP_JPIP 0x6a706970 + +#define JP2_JP 0x6a502020 /**< JPEG 2000 signature box */ +#define JP2_FTYP 0x66747970 /**< File type box */ +#define JP2_JP2H 0x6a703268 /**< JP2 header box */ +#define JP2_IHDR 0x69686472 /**< Image header box */ +#define JP2_COLR 0x636f6c72 /**< Colour specification box */ +#define JP2_JP2C 0x6a703263 /**< Contiguous codestream box */ +#define JP2_URL 0x75726c20 /**< URL box */ +#define JP2_DBTL 0x6474626c /**< ??? */ +#define JP2_BPCC 0x62706363 /**< Bits per component box */ +#define JP2_JP2 0x6a703220 /**< File type fields */ + +/* ----------------------------------------------------------------------- */ + +/** +JP2 component +*/ +typedef struct opj_jp2_comps { + int depth; + int sgnd; int bpcc; -} jp2_comps_t; +} opj_jp2_comps_t; -typedef struct { +/** +JPEG-2000 file format reader/writer +*/ +typedef struct opj_jp2 { + /** codec context */ + opj_common_ptr cinfo; + /** handle to the J2K codec */ + opj_j2k_t *j2k; unsigned int w; unsigned int h; unsigned int numcomps; @@ -51,68 +83,151 @@ typedef struct { unsigned int minversion; unsigned int numcl; unsigned int *cl; - jp2_comps_t *comps; - j2k_image_t *image; + opj_jp2_comps_t *comps; + opj_image_t *image; unsigned int j2k_codestream_offset; - unsigned int j2k_codestream_len; -} jp2_struct_t; + unsigned int j2k_codestream_length; +} opj_jp2_t; -typedef struct { +/** +JP2 Box +*/ +typedef struct opj_jp2_box { int length; int type; int init_pos; -} jp2_box_t; +} opj_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); +/** @name Local static functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Read box headers +@param cinfo Codec context info +@param cio Input stream +@param box +@return Returns true if successful, returns false otherwise +*/ +static bool jp2_read_boxhdr(opj_common_ptr cinfo, opj_cio_t *cio, opj_jp2_box_t *box); +static void jp2_write_url(opj_cio_t *cio, char *Idx_file); +/** +Read the IHDR box - Image Header box +@param jp2 JP2 handle +@param cio Input buffer stream +@return Returns true if successful, returns false otherwise +*/ +static bool jp2_read_ihdr(opj_jp2_t *jp2, opj_cio_t *cio); +static void jp2_write_ihdr(opj_jp2_t *jp2, opj_cio_t *cio); +static void jp2_write_bpcc(opj_jp2_t *jp2, opj_cio_t *cio); +static bool jp2_read_bpcc(opj_jp2_t *jp2, opj_cio_t *cio); +static void jp2_write_colr(opj_jp2_t *jp2, opj_cio_t *cio); +static bool jp2_read_colr(opj_jp2_t *jp2, opj_cio_t *cio); +/** +Write the JP2H box - JP2 Header box +@param jp2 JP2 handle +@param cio Output buffer stream +*/ +static void jp2_write_jp2h(opj_jp2_t *jp2, opj_cio_t *cio); +/** +Read the JP2H box - JP2 Header box +@param jp2 JP2 handle +@param cio Input buffer stream +@return Returns true if successful, returns false otherwise +*/ +static bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio); +/** +Write the FTYP box - File type box +@param jp2 JP2 handle +@param cio Output buffer stream +*/ +static void jp2_write_ftyp(opj_jp2_t *jp2, opj_cio_t *cio); +/** +Read the FTYP box - File type box +@param jp2 JP2 handle +@param cio Input buffer stream +@return Returns true if successful, returns false otherwise +*/ +static bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio); +static int jp2_write_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, char *index); +static bool jp2_read_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, unsigned int *j2k_codestream_length, unsigned int *j2k_codestream_offset); +static void jp2_write_jp(opj_cio_t *cio); +/** +Read the JP box - JPEG 2000 signature +@param jp2 JP2 handle +@param cio Input buffer stream +@return Returns true if successful, returns false otherwise +*/ +static bool jp2_read_jp(opj_jp2_t *jp2, opj_cio_t *cio); +/** +Decode the structure of a JP2 file +@param jp2 JP2 handle +@param cio Input buffer stream +@return Returns true if successful, returns false otherwise +*/ +static bool jp2_read_struct(opj_jp2_t *jp2, opj_cio_t *cio); +/* ----------------------------------------------------------------------- */ +/*@}*/ -/* int jp2_write_jp2c(int j2k_len, int *j2k_codestream_offset, char *j2k_codestream) - * - * Write the jp2c codestream box - * j2k_len: the j2k codestream length - * j2k_codestream_offset: the function will return the j2k codestream offset - * j2k_codestream: the j2k codestream to include in jp2 file - */ -int jp2_write_jp2c(int j2k_len, int *j2k_codestream_offset, char *j2k_codestream); +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Creates a JP2 decompression structure +@param cinfo Codec context info +@return Returns a handle to a JP2 decompressor if successful, returns NULL otherwise +*/ +opj_jp2_t* jp2_create_decompress(opj_common_ptr cinfo); +/** +Destroy a JP2 decompressor handle +@param jp2 JP2 decompressor handle to destroy +*/ +void jp2_destroy_decompress(opj_jp2_t *jp2); +/** +Setup the decoder decoding parameters using user parameters. +Decoding parameters are returned in jp2->j2k->cp. +@param jp2 JP2 decompressor handle +@param parameters decompression parameters +*/ +void jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters); +/** +Decode an image from a JPEG-2000 file stream +@param jp2 JP2 decompressor handle +@param cio Input buffer stream +@return Returns a decoded image if successful, returns NULL otherwise +*/ +opj_image_t* jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio); +/** +Creates a JP2 compression structure +@param cinfo Codec context info +@return Returns a handle to a JP2 compressor if successful, returns NULL otherwise +*/ +opj_jp2_t* jp2_create_compress(opj_common_ptr cinfo); +/** +Destroy a JP2 compressor handle +@param jp2 JP2 compressor handle to destroy +*/ +void jp2_destroy_compress(opj_jp2_t *jp2); +/** +Setup the encoder parameters using the current image and using user parameters. +Coding parameters are returned in jp2->j2k->cp. +@param jp2 JP2 compressor handle +@param parameters compression parameters +@param image input filled image +*/ +void jp2_setup_encoder(opj_jp2_t *jp2, opj_cparameters_t *parameters, opj_image_t *image); +/** +Encode an image into a JPEG-2000 file stream +@param jp2 JP2 compressor handle +@param cio Output buffer stream +@param image Image to encode +@param index Name of the index file if required, NULL otherwise +@return Returns true if successful, returns false otherwise +*/ +bool jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, 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); +#endif /* __JP2_H */ -/* int jp2_wrap_j2k(jp2_struct_t * jp2_struct, char *j2k_codestream, - int j2k_len, char *output) - * - * Wrap a J2K codestream in a JP2 file - * jp2_struct: the jp2 structure used to create jp2 boxes - * j2k_codestream: the j2k codestream to include in jp2 file - * output: pointer to jp2 codestream that will be created - */ -int jp2_wrap_j2k(jp2_struct_t * jp2_struct, char *j2k_codestream, - char *output); - - -/* int jp2_read_struct(unsigned char *src, jp2_struct_t * jp2_struct); - * - * Decode the structure of a JP2 file - * src: pointer to memory where compressed data is stored - * jp2_struct: the jp2 structure that will be created - * len: length of jp2 codestream - */ -int jp2_read_struct(unsigned char *src, jp2_struct_t * jp2_struct, int len); - -#endif diff --git a/libopenjpeg/jpt.c b/libopenjpeg/jpt.c index 1d4713dc..08323e13 100644 --- a/libopenjpeg/jpt.c +++ b/libopenjpeg/jpt.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2004, Yannick Verschueren - * Copyright (c) 2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,28 +26,22 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include -#include - -#include "jpt.h" -#include "j2k.h" -#include "cio.h" +#include "opj_includes.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 int jpt_read_VBAS_info(opj_cio_t *cio, unsigned int value) { unsigned char elmt; - elmt = cio_read(1); + elmt = cio_read(cio, 1); while ((elmt >> 7) == 1) { value = (value << 7); value |= (elmt & 0x7f); - elmt = cio_read(1); + elmt = cio_read(cio, 1); } value = (value << 7); value |= (elmt & 0x7f); @@ -58,15 +53,14 @@ unsigned int jpt_read_VBAS_info(unsigned int 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 */ +void jpt_init_msg_header(opj_jpt_msg_header_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 */ } /* @@ -75,47 +69,45 @@ void jpt_init_Msg_Header(jpt_msg_header_struct_t * header) * 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 */ +void jpt_reinit_msg_header(opj_jpt_msg_header_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) -{ +void jpt_read_msg_header(opj_common_ptr cinfo, opj_cio_t *cio, opj_jpt_msg_header_t *header) { unsigned char elmt, Class = 0, CSn = 0; - jpt_reinit_Msg_Header(header); + jpt_reinit_msg_header(header); /* ------------- */ /* VBAS : Bin-ID */ /* ------------- */ - elmt = cio_read(1); + elmt = cio_read(cio, 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; + case 0: + opg_event_msg(cinfo, EVT_ERROR, "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] */ @@ -125,14 +117,14 @@ void jpt_read_Msg_Header(jpt_msg_header_struct_t * header) /* In-class identifier */ header->Id |= (elmt & 0x0f); if ((elmt >> 7) == 1) - header->Id = jpt_read_VBAS_info(header->Id); + header->Id = jpt_read_VBAS_info(cio, header->Id); /* ------------ */ /* VBAS : Class */ /* ------------ */ if (Class == 1) { header->Class_Id = 0; - header->Class_Id = jpt_read_VBAS_info(header->Class_Id); + header->Class_Id = jpt_read_VBAS_info(cio, header->Class_Id); } /* ---------- */ @@ -140,24 +132,24 @@ void jpt_read_Msg_Header(jpt_msg_header_struct_t * header) /* ---------- */ if (CSn == 1) { header->CSn_Id = 0; - header->CSn_Id = jpt_read_VBAS_info(header->CSn_Id); + header->CSn_Id = jpt_read_VBAS_info(cio, header->CSn_Id); } /* ----------------- */ /* VBAS : Msg_offset */ /* ----------------- */ - header->Msg_offset = jpt_read_VBAS_info(header->Msg_offset); + header->Msg_offset = jpt_read_VBAS_info(cio, header->Msg_offset); /* ----------------- */ /* VBAS : Msg_length */ /* ----------------- */ - header->Msg_length = jpt_read_VBAS_info(header->Msg_length); + header->Msg_length = jpt_read_VBAS_info(cio, header->Msg_length); /* ---------- */ /* VBAS : Aux */ /* ---------- */ if ((header->Class_Id & 0x01) == 1) { header->Layer_nb = 0; - header->Layer_nb = jpt_read_VBAS_info(header->Layer_nb); + header->Layer_nb = jpt_read_VBAS_info(cio, header->Layer_nb); } } diff --git a/libopenjpeg/jpt.h b/libopenjpeg/jpt.h index ea784e0e..9f65ff11 100644 --- a/libopenjpeg/jpt.h +++ b/libopenjpeg/jpt.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2004, Yannick Verschueren - * Copyright (c) 2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,32 +26,49 @@ * 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; +#ifndef __JPT_H +#define __JPT_H +/** +@file jpt.h +@brief JPT-stream reader (JPEG 2000, JPIP) -/* - * Initialize the value of the message header structure - * - * header : Message header structure - * - */ -void jpt_init_Msg_Header(jpt_msg_header_struct_t * header); +JPT-stream functions are implemented in J2K.C. +*/ -/* - * Read the message header for a JPP/JPT - stream - * - * header : Message header structure - * - */ -void jpt_read_Msg_Header(jpt_msg_header_struct_t * header); +/** +Message Header JPT stream structure +*/ +typedef struct opj_jpt_msg_header { + /** In-class Identifier */ + unsigned int Id; + /** Last byte information */ + unsigned int last_byte; + /** Class Identifier */ + unsigned int Class_Id; + /** CSn : index identifier */ + unsigned int CSn_Id; + /** Message offset */ + unsigned int Msg_offset; + /** Message length */ + unsigned int Msg_length; + /** Auxiliary for JPP case */ + unsigned int Layer_nb; +} opj_jpt_msg_header_t; + +/* ----------------------------------------------------------------------- */ + +/** +Initialize the value of the message header structure +@param header Message header structure +*/ +void jpt_init_msg_header(opj_jpt_msg_header_t * header); + +/** +Read the message header for a JPP/JPT - stream +@param cinfo Codec context info +@param cio CIO handle +@param header Message header structure +*/ +void jpt_read_msg_header(opj_common_ptr cinfo, opj_cio_t *cio, opj_jpt_msg_header_t *header); + +#endif diff --git a/libopenjpeg/mct.c b/libopenjpeg/mct.c index 185c1b66..d015ae1f 100644 --- a/libopenjpeg/mct.c +++ b/libopenjpeg/mct.c @@ -1,5 +1,9 @@ /* - * Copyright (c) 2001-2002, David Janssens + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,24 +28,22 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "mct.h" -#include "fix.h" +#include "opj_includes.h" /* */ /* This table contains the norms of the basis function of the reversible MCT. */ /* */ -double mct_norms[3] = { 1.732, .8292, .8292 }; +static const 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 }; +static const 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) -{ +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; @@ -60,8 +62,7 @@ void mct_encode(int *c0, int *c1, int *c2, int n) /* */ /* Inverse reversible MCT. */ /* */ -void mct_decode(int *c0, int *c1, int *c2, int n) -{ +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; @@ -80,16 +81,14 @@ void mct_decode(int *c0, int *c1, int *c2, int n) /* */ /* Get norm of basis function of reversible MCT. */ /* */ -double mct_getnorm(int compno) -{ +double mct_getnorm(int compno) { return mct_norms[compno]; } /* */ /* Foward irreversible MCT. */ /* */ -void mct_encode_real(int *c0, int *c1, int *c2, int n) -{ +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; @@ -108,8 +107,7 @@ void mct_encode_real(int *c0, int *c1, int *c2, int n) /* */ /* Inverse irreversible MCT. */ /* */ -void mct_decode_real(int *c0, int *c1, int *c2, int n) -{ +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; @@ -128,7 +126,6 @@ void mct_decode_real(int *c0, int *c1, int *c2, int n) /* */ /* Get norm of basis function of irreversible MCT. */ /* */ -double mct_getnorm_real(int compno) -{ +double mct_getnorm_real(int compno) { return mct_norms_real[compno]; } diff --git a/libopenjpeg/mct.h b/libopenjpeg/mct.h index 196dc6d3..8848c014 100644 --- a/libopenjpeg/mct.h +++ b/libopenjpeg/mct.h @@ -1,5 +1,9 @@ /* - * Copyright (c) 2001-2002, David Janssens + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,51 +28,71 @@ * POSSIBILITY OF SUCH DAMAGE. */ + #ifndef __MCT_H #define __MCT_H +/** +@file mct.h +@brief Implementation of a multi-component transforms (MCT) -/* - * 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) - */ +The functions in MCT.C have for goal to realize reversible and irreversible multicomponent +transform. The functions in MCT.C are used by some function in TCD.C. +*/ + +/** @defgroup MCT MCT - Implementation of a multi-component transform */ +/*@{*/ + +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Apply a reversible multi-component transform to an image +@param c0 Samples for red component +@param c1 Samples for green component +@param c2 Samples blue component +@param n Number of samples for each component +*/ +void mct_encode(int *c0, int *c1, int *c2, int n); +/** +Apply a reversible multi-component inverse transform to an image +@param c0 Samples for luminance component +@param c1 Samples for red chrominance component +@param c2 Samples for blue chrominance component +@param n Number of samples for each component +*/ +void mct_decode(int *c0, int *c1, int *c2, int n); +/** +Get norm of the basis function used for the reversible multi-component transform +@param compno Number of the component (0->Y, 1->U, 2->V) +@return +*/ double mct_getnorm(int compno); -/* - * Apply an irreversible multi-component transform to an image - * R: samples for red component - * G: samples for green component - * B: samples blue component - * n: number of samples for each component - */ +/** +Apply an irreversible multi-component transform to an image +@param c0 Samples for red component +@param c1 Samples for green component +@param c2 Samples blue component +@param n Number of samples for each component +*/ void mct_encode_real(int *c0, int *c1, int *c2, int n); -/* - * Apply an irreversible multi-component inverse transform to an image - * Y: samples for luminance component - * U: samples for red chrominance component - * V: samples for blue chrominance component - * n: number of samples for each component - */ +/** +Apply an irreversible multi-component inverse transform to an image +@param c0 Samples for luminance component +@param c1 Samples for red chrominance component +@param c2 Samples for blue chrominance component +@param n Number of samples for each component +*/ void mct_decode_real(int *c0, int *c1, int *c2, int n); -/* - * Get norm of the basis function used for the irreversible multi-component transform - * compno: number of the component (0->Y, 1->U, 2->V) - */ +/** +Get norm of the basis function used for the irreversible multi-component transform +@param compno Number of the component (0->Y, 1->U, 2->V) +@return +*/ double mct_getnorm_real(int compno); +/* ----------------------------------------------------------------------- */ +/*@}*/ -#endif +/*@}*/ + +#endif /* __MCT_H */ diff --git a/libopenjpeg/mqc.c b/libopenjpeg/mqc.c index 727b8742..e32c2209 100644 --- a/libopenjpeg/mqc.c +++ b/libopenjpeg/mqc.c @@ -1,7 +1,9 @@ /* - * Copyright (c) 2001-2002, David Janssens + * 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 + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,23 +28,12 @@ * 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; +#include "opj_includes.h" /* */ /* This array defines all the possible states for a context. */ /* */ -mqc_state_t mqc_states[47 * 2] = { +static opj_mqc_state_t mqc_states[47 * 2] = { {0x5601, 0, &mqc_states[2], &mqc_states[3]}, {0x5601, 1, &mqc_states[3], &mqc_states[2]}, {0x3401, 0, &mqc_states[4], &mqc_states[12]}, @@ -139,453 +130,353 @@ mqc_state_t mqc_states[47 * 2] = { {0x5601, 1, &mqc_states[93], &mqc_states[93]}, }; -#define MQC_NUMCTXS 32 +/* +========================================================== + local functions +========================================================== +*/ -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; +static void mqc_byteout(opj_mqc_t *mqc) { + if (*mqc->bp == 0xff) { + mqc->bp++; + *mqc->bp = mqc->c >> 20; + mqc->c &= 0xfffff; + mqc->ct = 7; } else { - if ((mqc_c & 0x8000000) == 0) { /* ((mqc_c&0x8000000)==0) CHANGE */ - mqc_bp++; - *mqc_bp = mqc_c >> 19; - mqc_c &= 0x7ffff; - mqc_ct = 8; + 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; + (*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; + 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() -{ +static void mqc_renorme(opj_mqc_t *mqc) { do { - mqc_a <<= 1; - mqc_c <<= 1; - mqc_ct--; - if (mqc_ct == 0) { - mqc_byteout(); + mqc->a <<= 1; + mqc->c <<= 1; + mqc->ct--; + if (mqc->ct == 0) { + mqc_byteout(mqc); } - } while ((mqc_a & 0x8000) == 0); + } 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; +static void mqc_codemps(opj_mqc_t *mqc) { + mqc->a -= (*mqc->curctx)->qeval; + if ((mqc->a & 0x8000) == 0) { + if (mqc->a < (*mqc->curctx)->qeval) { + mqc->a = (*mqc->curctx)->qeval; } else { - mqc_c += (*mqc_curctx)->qeval; + mqc->c += (*mqc->curctx)->qeval; } - *mqc_curctx = (*mqc_curctx)->nmps; - mqc_renorme(); + *mqc->curctx = (*mqc->curctx)->nmps; + mqc_renorme(mqc); } else { - mqc_c += (*mqc_curctx)->qeval; + 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; +static void mqc_codelps(opj_mqc_t *mqc) { + mqc->a -= (*mqc->curctx)->qeval; + if (mqc->a < (*mqc->curctx)->qeval) { + mqc->c += (*mqc->curctx)->qeval; } else { - mqc_a = (*mqc_curctx)->qeval; + mqc->a = (*mqc->curctx)->qeval; } - *mqc_curctx = (*mqc_curctx)->nlps; - mqc_renorme(); + *mqc->curctx = (*mqc->curctx)->nlps; + mqc_renorme(mqc); } -/* */ -/* 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(); +static void mqc_setbits(opj_mqc_t *mqc) { + unsigned int tempc = mqc->c + mqc->a; + mqc->c |= 0xffff; + if (mqc->c >= tempc) { + mqc->c -= 0x8000; } } -/* */ -/* 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() -{ +static int mqc_mpsexchange(opj_mqc_t *mqc) { int d; - if (mqc_a < (*mqc_curctx)->qeval) { - d = 1 - (*mqc_curctx)->mps; - *mqc_curctx = (*mqc_curctx)->nlps; + 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; + d = (*mqc->curctx)->mps; + *mqc->curctx = (*mqc->curctx)->nmps; } + return d; } -/* */ -/* */ -int mqc_lpsexchange() -{ +static int mqc_lpsexchange(opj_mqc_t *mqc) { int d; - if (mqc_a < (*mqc_curctx)->qeval) { - mqc_a = (*mqc_curctx)->qeval; - d = (*mqc_curctx)->mps; - *mqc_curctx = (*mqc_curctx)->nmps; + 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; + 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) { +static void mqc_bytein(opj_mqc_t *mqc) { + if (mqc->bp != mqc->end) { unsigned int c; - if (mqc_bp + 1 != mqc_end) { - c = *(mqc_bp + 1); + if (mqc->bp + 1 != mqc->end) { + c = *(mqc->bp + 1); } else { c = 0xff; } - if (*mqc_bp == 0xff) { + if (*mqc->bp == 0xff) { if (c > 0x8f) { - mqc_c += 0xff00; - mqc_ct = 8; + mqc->c += 0xff00; + mqc->ct = 8; } else { - mqc_bp++; - mqc_c += c << 9; - mqc_ct = 7; + mqc->bp++; + mqc->c += c << 9; + mqc->ct = 7; } } else { - mqc_bp++; - mqc_c += c << 8; - mqc_ct = 8; + mqc->bp++; + mqc->c += c << 8; + mqc->ct = 8; } } else { - mqc_c += 0xff00; - mqc_ct = 8; + mqc->c += 0xff00; + mqc->ct = 8; } } -/* */ -/* Renormalize mqc_a and mqc_c while decoding. */ -/* */ -void mqc_renormd() -{ +static void mqc_renormd(opj_mqc_t *mqc) { do { - if (mqc_ct == 0) { - mqc_bytein(); + if (mqc->ct == 0) { + mqc_bytein(mqc); } - mqc_a <<= 1; - mqc_c <<= 1; - mqc_ct--; - } while (mqc_a < 0x8000); + 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; +/* +========================================================== + MQ-Coder interface +========================================================== +*/ + +opj_mqc_t* mqc_create() { + opj_mqc_t *mqc = (opj_mqc_t*)opj_malloc(sizeof(opj_mqc_t)); + return mqc; } -/* */ -/* 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(); +void mqc_destroy(opj_mqc_t *mqc) { + if(mqc) { + opj_free(mqc); + } +} + +int mqc_numbytes(opj_mqc_t *mqc) { + return mqc->bp - mqc->start; +} + +void mqc_init_enc(opj_mqc_t *mqc, unsigned char *bp) { + mqc_setcurctx(mqc, 0); + mqc->a = 0x8000; + mqc->c = 0; + mqc->bp = bp - 1; + mqc->ct = 12; + if (*mqc->bp == 0xff) { + mqc->ct = 13; + } + mqc->start = bp; +} + +void mqc_setcurctx(opj_mqc_t *mqc, int ctxno) { + mqc->curctx = &mqc->ctxs[ctxno]; +} + +void mqc_encode(opj_mqc_t *mqc, int d) { + if ((*mqc->curctx)->mps == d) { + mqc_codemps(mqc); } else { - mqc_c -= (*mqc_curctx)->qeval << 16; - if ((mqc_a & 0x8000) == 0) { - d = mqc_mpsexchange(); - mqc_renormd(); + mqc_codelps(mqc); + } +} + +void mqc_flush(opj_mqc_t *mqc) { + mqc_setbits(mqc); + mqc->c <<= mqc->ct; + mqc_byteout(mqc); + mqc->c <<= mqc->ct; + mqc_byteout(mqc); + + if (*mqc->bp != 0xff) { + mqc->bp++; + } +} + +void mqc_bypass_init_enc(opj_mqc_t *mqc) { + mqc->c = 0; + mqc->ct = 8; + /*if (*mqc->bp == 0xff) { + mqc->ct = 7; + } */ +} + +void mqc_bypass_enc(opj_mqc_t *mqc, int d) { + mqc->ct--; + mqc->c = mqc->c + (d << mqc->ct); + if (mqc->ct == 0) { + mqc->bp++; + *mqc->bp = mqc->c; + mqc->ct = 8; + if (*mqc->bp == 0xff) { + mqc->ct = 7; + } + mqc->c = 0; + } +} + +int mqc_bypass_flush_enc(opj_mqc_t *mqc) { + unsigned char bit_padding; + + bit_padding = 0; + + if (mqc->ct != 0) { + while (mqc->ct > 0) { + mqc->ct--; + mqc->c += bit_padding << mqc->ct; + bit_padding = (bit_padding + 1) & 0x01; + } + mqc->bp++; + *mqc->bp = mqc->c; + mqc->ct = 8; + mqc->c = 0; + } + + return 1; +} + +void mqc_reset_enc(opj_mqc_t *mqc) { + mqc_resetstates(mqc); + mqc_setstate(mqc, 18, 0, 46); + mqc_setstate(mqc, 0, 0, 3); + mqc_setstate(mqc, 1, 0, 4); +} + +int mqc_restart_enc(opj_mqc_t *mqc) { + int correction = 1; + + /* */ + int n = 27 - 15 - mqc->ct; + mqc->c <<= mqc->ct; + while (n > 0) { + mqc_byteout(mqc); + n -= mqc->ct; + mqc->c <<= mqc->ct; + } + mqc_byteout(mqc); + + return correction; +} + +void mqc_restart_init_enc(opj_mqc_t *mqc) { + /* */ + mqc_setcurctx(mqc, 0); + mqc->a = 0x8000; + mqc->c = 0; + mqc->ct = 12; + mqc->bp--; + if (*mqc->bp == 0xff) { + mqc->ct = 13; + } +} + +void mqc_erterm_enc(opj_mqc_t *mqc) { + int k = 11 - mqc->ct + 1; + + while (k > 0) { + mqc->c <<= mqc->ct; + mqc->ct = 0; + mqc_byteout(mqc); + k -= mqc->ct; + } + + if (*mqc->bp != 0xff) { + mqc_byteout(mqc); + } +} + +void mqc_segmark_enc(opj_mqc_t *mqc) { + int i; + mqc_setcurctx(mqc, 18); + + for (i = 1; i < 5; i++) { + mqc_encode(mqc, i % 2); + } +} + +void mqc_init_dec(opj_mqc_t *mqc, unsigned char *bp, int len) { + mqc_setcurctx(mqc, 0); + mqc->start = bp; + mqc->end = bp + len; + mqc->bp = bp; + if (len==0) mqc->c = 0xff << 16; + else mqc->c = *mqc->bp << 16; + mqc_bytein(mqc); + mqc->c <<= 7; + mqc->ct -= 7; + mqc->a = 0x8000; +} + +int mqc_decode(opj_mqc_t *mqc) { + int d; + mqc->a -= (*mqc->curctx)->qeval; + if ((mqc->c >> 16) < (*mqc->curctx)->qeval) { + d = mqc_lpsexchange(mqc); + mqc_renormd(mqc); + } else { + mqc->c -= (*mqc->curctx)->qeval << 16; + if ((mqc->a & 0x8000) == 0) { + d = mqc_mpsexchange(mqc); + mqc_renormd(mqc); } else { - d = (*mqc_curctx)->mps; + d = (*mqc->curctx)->mps; } } + return d; } -/* */ -/* Reset states of all contexts. */ -/* */ -void mqc_resetstates() -{ +void mqc_resetstates(opj_mqc_t *mqc) { int i; for (i = 0; i < MQC_NUMCTXS; i++) { - mqc_ctxs[i] = mqc_states; + 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)]; +void mqc_setstate(opj_mqc_t *mqc, int ctxno, int msb, int prob) { + mqc->ctxs[ctxno] = &mqc_states[msb + (prob << 1)]; } + + diff --git a/libopenjpeg/mqc.h b/libopenjpeg/mqc.h index ea01d809..7c601b03 100644 --- a/libopenjpeg/mqc.h +++ b/libopenjpeg/mqc.h @@ -1,7 +1,9 @@ /* - * Copyright (c) 2001-2002, David Janssens + * 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 + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,100 +30,221 @@ #ifndef __MQC_H #define __MQC_H +/** +@file mqc.h +@brief Implementation of an MQ-Coder (MQC) -/* - * Return the number of bytes written/read since initialisation - */ -int mqc_numbytes(); +The functions in MQC.C have for goal to realize the MQ-coder operations. The functions +in MQC.C are used by some function in T1.C. +*/ -/* - * 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(); +/** @defgroup MQC MQC - Implementation of an MQ-Coder */ +/*@{*/ -/* - * 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); +/** +This struct defines the state of a context. +*/ +typedef struct opj_mqc_state { + /** the probability of the Least Probable Symbol (0.75->0x8000, 1.5->0xffff) */ + unsigned int qeval; + /** the Most Probable Symbol (0 or 1) */ + int mps; + /** next state if the next encoded symbol is the MPS */ + struct opj_mqc_state *nmps; + /** next state if the next encoded symbol is the LPS */ + struct opj_mqc_state *nlps; +} opj_mqc_state_t; -/* - * Initialize the encoder - * bp: pointer to the start of the buffer where the bytes will be written - */ -void mqc_init_enc(unsigned char *bp); +#define MQC_NUMCTXS 32 -/* - * Set the current context used for coding/decoding - * ctxno: number that identifies the context - */ -void mqc_setcurctx(int ctxno); +/** +MQ coder +*/ +typedef struct opj_mqc { + unsigned int c; + unsigned int a; + unsigned int ct; + unsigned char *bp; + unsigned char *start; + unsigned char *end; + opj_mqc_state_t *ctxs[MQC_NUMCTXS]; + opj_mqc_state_t **curctx; +} opj_mqc_t; -/* - * Encode a bit - * d: bit to encode (0 or 1) - */ -void mqc_encode(int d); +/** @name Local static functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Output a byte, doing bit-stuffing if necessary. +After a 0xff byte, the next byte must be smaller than 0x90. +@param mqc MQC handle +*/ +static void mqc_byteout(opj_mqc_t *mqc); +/** +Renormalize mqc->a and mqc->c while encoding, so that mqc->a stays between 0x8000 and 0x10000 +@param mqc MQC handle +*/ +static void mqc_renorme(opj_mqc_t *mqc); +/** +Encode the most probable symbol +@param mqc MQC handle +*/ +static void mqc_codemps(opj_mqc_t *mqc); +/** +Encode the most least symbol +@param mqc MQC handle +*/ +static void mqc_codelps(opj_mqc_t *mqc); +/** +Fill mqc->c with 1's for flushing +@param mqc MQC handle +*/ +static void mqc_setbits(opj_mqc_t *mqc); +/** +FIXME: documentation ??? +@param mqc MQC handle +@return +*/ +static int mqc_mpsexchange(opj_mqc_t *mqc); +/** +FIXME: documentation ??? +@param mqc MQC handle +@return +*/ +static int mqc_lpsexchange(opj_mqc_t *mqc); +/** +Input a byte +@param mqc MQC handle +*/ +static void mqc_bytein(opj_mqc_t *mqc); +/** +Renormalize mqc->a and mqc->c while decoding +@param mqc MQC handle +*/ +static void mqc_renormd(opj_mqc_t *mqc); +/* ----------------------------------------------------------------------- */ +/*@}*/ -/* - * Flush the encoder, so that all remaining data is written - */ -void mqc_flush(); +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Create a new MQC handle +@return Returns a new MQC handle if successful, returns NULL otherwise +*/ +opj_mqc_t* mqc_create(); +/** +Destroy a previously created MQC handle +@param mqc MQC handle to destroy +*/ +void mqc_destroy(opj_mqc_t *mqc); +/** +Return the number of bytes written/read since initialisation +@param mqc MQC handle +@return Returns the number of bytes already encoded +*/ +int mqc_numbytes(opj_mqc_t *mqc); +/** +Reset the states of all the context of the coder/decoder +(each context is set to a state where 0 and 1 are more or less equiprobable) +@param mqc MQC handle +*/ +void mqc_resetstates(opj_mqc_t *mqc); +/** +Set the state of a particular context +@param mqc MQC handle +@param ctxno Number that identifies the context +@param msb The MSB of the new state of the context +@param prob Number that identifies the probability of the symbols for the new state of the context +*/ +void mqc_setstate(opj_mqc_t *mqc, int ctxno, int msb, int prob); +/** +Initialize the encoder +@param mqc MQC handle +@param bp Pointer to the start of the buffer where the bytes will be written +*/ +void mqc_init_enc(opj_mqc_t *mqc, unsigned char *bp); +/** +Set the current context used for coding/decoding +@param mqc MQC handle +@param ctxno Number that identifies the context +*/ +void mqc_setcurctx(opj_mqc_t *mqc, int ctxno); +/** +Encode a symbol using the MQ-coder +@param mqc MQC handle +@param d The symbol to be encoded (0 or 1) +*/ +void mqc_encode(opj_mqc_t *mqc, int d); +/** +Flush the encoder, so that all remaining data is written +@param mqc MQC handle +*/ +void mqc_flush(opj_mqc_t *mqc); +/** +BYPASS mode switch, initialization operation. +JPEG 2000 p 505. +

Not fully implemented and tested !!

+@param mqc MQC handle +*/ +void mqc_bypass_init_enc(opj_mqc_t *mqc); +/** +BYPASS mode switch, coding operation. +JPEG 2000 p 505. +

Not fully implemented and tested !!

+@param mqc MQC handle +@param d The symbol to be encoded (0 or 1) +*/ +void mqc_bypass_enc(opj_mqc_t *mqc, int d); +/** +BYPASS mode switch, flush operation +

Not fully implemented and tested !!

+@param mqc MQC handle +@return Returns 1 (always) +*/ +int mqc_bypass_flush_enc(opj_mqc_t *mqc); +/** +RESET mode switch +@param mqc MQC handle +*/ +void mqc_reset_enc(opj_mqc_t *mqc); +/** +RESTART mode switch (TERMALL) +@param mqc MQC handle +@return Returns 1 (always) +*/ +int mqc_restart_enc(opj_mqc_t *mqc); +/** +RESTART mode switch (TERMALL) reinitialisation +@param mqc MQC handle +*/ +void mqc_restart_init_enc(opj_mqc_t *mqc); +/** +ERTERM mode switch (PTERM) +@param mqc MQC handle +*/ +void mqc_erterm_enc(opj_mqc_t *mqc); +/** +SEGMARK mode switch (SEGSYM) +@param mqc MQC handle +*/ +void mqc_segmark_enc(opj_mqc_t *mqc); +/** +Initialize the decoder +@param mqc MQC handle +@param bp Pointer to the start of the buffer from which the bytes will be read +@param len Length of the input buffer +*/ +void mqc_init_dec(opj_mqc_t *mqc, unsigned char *bp, int len); +/** +Decode a symbol +@param mqc MQC handle +@return Returns the decoded symbol (0 or 1) +*/ +int mqc_decode(opj_mqc_t *mqc); +/* ----------------------------------------------------------------------- */ +/*@}*/ -/* - * 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 +#endif /* __MQC_H */ diff --git a/libopenjpeg/openjpeg.c b/libopenjpeg/openjpeg.c new file mode 100644 index 00000000..4cfe3769 --- /dev/null +++ b/libopenjpeg/openjpeg.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2005, Hervé Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "opj_includes.h" + +opj_dinfo_t* opj_create_decompress(OPJ_CODEC_FORMAT format) { + opj_dinfo_t *dinfo = (opj_dinfo_t*)opj_malloc(sizeof(opj_dinfo_t)); + if(!dinfo) return NULL; + dinfo->is_decompressor = true; + switch(format) { + case CODEC_J2K: + case CODEC_JPT: + /* get a J2K decoder handle */ + dinfo->j2k_handle = (void*)j2k_create_decompress((opj_common_ptr)dinfo); + if(!dinfo->j2k_handle) { + opj_free(dinfo); + return NULL; + } + break; + case CODEC_JP2: + /* get a JP2 decoder handle */ + dinfo->jp2_handle = (void*)jp2_create_decompress((opj_common_ptr)dinfo); + if(!dinfo->jp2_handle) { + opj_free(dinfo); + return NULL; + } + break; + default: + opj_free(dinfo); + return NULL; + } + + dinfo->codec_format = format; + + return dinfo; +} + +void opj_destroy_decompress(opj_dinfo_t *dinfo) { + if(dinfo) { + /* destroy the codec */ + switch(dinfo->codec_format) { + case CODEC_J2K: + case CODEC_JPT: + j2k_destroy_decompress((opj_j2k_t*)dinfo->j2k_handle); + break; + case CODEC_JP2: + jp2_destroy_decompress((opj_jp2_t*)dinfo->jp2_handle); + break; + } + /* destroy the decompressor */ + opj_free(dinfo); + } +} + +void opj_set_default_decoder_parameters(opj_dparameters_t *parameters) { + if(parameters) { + memset(parameters, 0, sizeof(opj_dparameters_t)); + /* default decoding parameters */ + parameters->cp_layer = 0; + parameters->cp_reduce = 0; + + parameters->decod_format = -1; + parameters->cod_format = -1; + } +} + +void opj_setup_decoder(opj_dinfo_t *dinfo, opj_dparameters_t *parameters) { + if(dinfo && parameters) { + switch(dinfo->codec_format) { + case CODEC_J2K: + case CODEC_JPT: + j2k_setup_decoder((opj_j2k_t*)dinfo->j2k_handle, parameters); + break; + case CODEC_JP2: + jp2_setup_decoder((opj_jp2_t*)dinfo->jp2_handle, parameters); + break; + } + } +} + +opj_image_t* opj_decode(opj_dinfo_t *dinfo, opj_cio_t *cio) { + if(dinfo && cio) { + switch(dinfo->codec_format) { + case CODEC_J2K: + return j2k_decode((opj_j2k_t*)dinfo->j2k_handle, cio); + case CODEC_JPT: + return j2k_decode_jpt_stream((opj_j2k_t*)dinfo->j2k_handle, cio); + case CODEC_JP2: + return jp2_decode((opj_jp2_t*)dinfo->jp2_handle, cio); + } + } + + return NULL; +} + +opj_cinfo_t* opj_create_compress(OPJ_CODEC_FORMAT format) { + opj_cinfo_t *cinfo = (opj_cinfo_t*)opj_malloc(sizeof(opj_cinfo_t)); + if(!cinfo) return NULL; + cinfo->is_decompressor = false; + switch(format) { + case CODEC_J2K: + /* get a J2K coder handle */ + cinfo->j2k_handle = (void*)j2k_create_compress((opj_common_ptr)cinfo); + if(!cinfo->j2k_handle) { + opj_free(cinfo); + return NULL; + } + break; + case CODEC_JP2: + /* get a JP2 coder handle */ + cinfo->jp2_handle = (void*)jp2_create_compress((opj_common_ptr)cinfo); + if(!cinfo->jp2_handle) { + opj_free(cinfo); + return NULL; + } + break; + default: + opj_free(cinfo); + return NULL; + } + + cinfo->codec_format = format; + + return cinfo; +} + +void opj_destroy_compress(opj_cinfo_t *cinfo) { + if(cinfo) { + /* destroy the codec */ + switch(cinfo->codec_format) { + case CODEC_J2K: + j2k_destroy_decompress((opj_j2k_t*)cinfo->j2k_handle); + break; + case CODEC_JP2: + jp2_destroy_decompress((opj_jp2_t*)cinfo->jp2_handle); + break; + } + /* destroy the decompressor */ + opj_free(cinfo); + } +} + +void opj_set_default_encoder_parameters(opj_cparameters_t *parameters) { + if(parameters) { + memset(parameters, 0, sizeof(opj_cparameters_t)); + /* default coding parameters */ + parameters->numresolution = 6; + parameters->cblockw_init = 64; + parameters->cblockh_init = 64; + parameters->prog_order = LRCP; + parameters->roi_compno = -1; /* no ROI */ + parameters->subsampling_dx = 1; + parameters->subsampling_dy = 1; + + parameters->decod_format = -1; + parameters->cod_format = -1; + } +} + +void opj_setup_encoder(opj_cinfo_t *cinfo, opj_cparameters_t *parameters, opj_image_t *image) { + if(cinfo && parameters && image) { + switch(cinfo->codec_format) { + case CODEC_J2K: + j2k_setup_encoder((opj_j2k_t*)cinfo->j2k_handle, parameters, image); + break; + case CODEC_JP2: + jp2_setup_encoder((opj_jp2_t*)cinfo->jp2_handle, parameters, image); + break; + } + } +} + +bool opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, char *index) { + if(cinfo && cio && image) { + switch(cinfo->codec_format) { + case CODEC_J2K: + return j2k_encode((opj_j2k_t*)cinfo->j2k_handle, cio, image, index); + case CODEC_JP2: + return jp2_encode((opj_jp2_t*)cinfo->jp2_handle, cio, image, index); + } + } + + return false; +} + + diff --git a/libopenjpeg/openjpeg.h b/libopenjpeg/openjpeg.h index a2543e64..5bae6beb 100644 --- a/libopenjpeg/openjpeg.h +++ b/libopenjpeg/openjpeg.h @@ -1,7 +1,9 @@ /* - * Copyright (c) 2001-2002, David Janssens - * Copyright (c) 2003, Yannick Verschueren - * Copyright (c) 2003, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,24 +28,571 @@ * 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 +#ifndef OPENJPEG_H +#define OPENJPEG_H +/* +========================================================== + Compiler directives +========================================================== +*/ +#ifndef __cplusplus +#if defined(HAVE_STDBOOL_H) +/* +The C language implementation does correctly provide the standard header +file "stdbool.h". + */ +#include +#else +/* +The C language implementation does not provide the standard header file +"stdbool.h" as required by ISO/IEC 9899:1999. Try to compensate for this +braindamage below. +*/ +#if !defined(bool) +#define bool int #endif +#if !defined(true) +#define true 1 +#endif +#if !defined(false) +#define false 0 +#endif +#endif +#endif /* __cplusplus */ + +/* +========================================================== + Useful constant definitions +========================================================== +*/ + +#ifndef MAX_PATH +#define MAX_PATH 260 /**< Maximum allowed size for filenames */ +#endif /* MAX_PATH */ + +#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 */ + +/* +========================================================== + enum definitions +========================================================== +*/ + +/** Progression order */ +typedef enum PROG_ORDER { + PROG_UNKNOWN = -1, /**< place-holder */ + LRCP = 0, /**< layer-resolution-component-precinct order */ + RLCP = 1, /**< resolution-layer-component-precinct order */ + RPCL = 2, /**< resolution-precinct-component-layer order */ + PCRL = 3, /**< precinct-component-resolution-layer order */ + CPRL = 4 /**< component-precinct-resolution-layer order */ +} OPJ_PROG_ORDER; + +/** +Supported image color spaces +*/ +typedef enum COLOR_SPACE { + CLRSPC_UNKNOWN = -1, /**< place-holder */ + CLRSPC_SRGB = 1, /**< sRGB */ + CLRSPC_GRAY = 2, /**< grayscale */ + CLRSPC_SYCC = 3 /**< YUV */ +} OPJ_COLOR_SPACE; + +/** +Supported codec +*/ +typedef enum CODEC_FORMAT { + CODEC_UNKNOWN = -1, /**< place-holder */ + CODEC_J2K = 0, /**< JPEG-2000 codestream : read/write */ + CODEC_JPT = 1, /**< JPT-stream (JPEG 2000, JPIP) : read only */ + CODEC_JP2 = 2 /**< JPEG-2000 file format : read/write */ +} OPJ_CODEC_FORMAT; + +/* +========================================================== + event manager typedef definitions +========================================================== +*/ + +/** +Callback function prototype for events +@param msg Event message +@param client_data +*/ +typedef void (*opj_msg_callback) (const char *msg, void *client_data); + +/** +Message handler object +used for +
    +
  • Error messages +
  • Warning messages +
  • Debugging messages +
+*/ +typedef struct opj_event_mgr { + /** Error message callback if available, NULL otherwise */ + opj_msg_callback error_handler; + /** Warning message callback if available, NULL otherwise */ + opj_msg_callback warning_handler; + /** Debug message callback if available, NULL otherwise */ + opj_msg_callback info_handler; +} opj_event_mgr_t; + + +/* +========================================================== + codec typedef definitions +========================================================== +*/ + +/** +Progression order changes +*/ +typedef struct opj_poc { + int resno0, compno0; + int layno1, resno1, compno1; + OPJ_PROG_ORDER prg; + int tile; + char progorder[4]; +} opj_poc_t; + +/** +Compression parameters +*/ +typedef struct opj_cparameters { + /** size of tile: tile_size_on = false (not in argument) or = true (in argument) */ + bool tile_size_on; + /** XTOsiz */ + int cp_tx0; + /** YTOsiz */ + int cp_ty0; + /** XTsiz */ + int cp_tdx; + /** YTsiz */ + int cp_tdy; + /** allocation by rate/distortion */ + int cp_disto_alloc; + /** allocation by fixed layer */ + int cp_fixed_alloc; + /** add fixed_quality */ + int cp_fixed_quality; + /** fixed layer */ + int *cp_matrice; + /** comment for coding */ + char *cp_comment; + /** csty : coding style */ + int csty; + /** progression order (default LRCP) */ + OPJ_PROG_ORDER prog_order; + /** progression order changes */ + opj_poc_t POC[32]; + /** number of progression order changes (POC), default to 0 */ + int numpocs; + /** number of layers */ + int tcp_numlayers; + /** rates of layers */ + int tcp_rates[100]; + /** different psnr for successive layers */ + float tcp_distoratio[100]; + /** number of resolutions */ + int numresolution; + /** initial code block width, default to 64 */ + int cblockw_init; + /** initial code block height, default to 64 */ + int cblockh_init; + /** mode switch (cblk_style) */ + int mode; + /** 1 : use the irreversible DWT 9-7, 0 : use lossless compression (default) */ + int irreversible; + /** region of interest: affected component in [0..3], -1 means no ROI */ + int roi_compno; + /** region of interest: upshift value */ + int roi_shift; + /* number of precinct size specifications */ + int res_spec; + /** initial precinct width */ + int prcw_init[J2K_MAXRLVLS]; + /** initial precinct height */ + int prch_init[J2K_MAXRLVLS]; + + /**@name command line encoder parameters (not used inside the library) */ + /*@{*/ + /** input file name */ + char infile[MAX_PATH]; + /** output file name */ + char outfile[MAX_PATH]; + /** creation of an index file, default to 0 (false) */ + int index_on; + /** index file name */ + char index[MAX_PATH]; + /** subimage encoding: origin image offset in x direction */ + int image_offset_x0; + /** subimage encoding: origin image offset in y direction */ + int image_offset_y0; + /** subsampling value for dx */ + int subsampling_dx; + /** subsampling value for dy */ + int subsampling_dy; + /** input file format 0: PGX, 1: PxM, 2: BMP */ + int decod_format; + /** output file format 0: J2K, 1: JP2, 2: JPT */ + int cod_format; + /*@}*/ +} opj_cparameters_t; + +/** +Decompression parameters +*/ +typedef struct opj_dparameters { + /** + Set the number of highest resolution levels to be discarded. + The image resolution is effectively divided by 2 to the power of the number of discarded levels. + The reduce factor is limited by the smallest total number of decomposition levels among tiles. + if != 0, then original dimension divided by 2^(reduce); + if == 0 or not used, image is decoded to the full resolution + */ + int cp_reduce; + /** + Set the maximum number of quality layers to decode. + If there are less quality layers than the specified number, all the quality layers are decoded. + if != 0, then only the first "layer" layers are decoded; + if == 0 or not used, all the quality layers are decoded + */ + int cp_layer; + + /**@name command line encoder parameters (not used inside the library) */ + /*@{*/ + /** input file name */ + char infile[MAX_PATH]; + /** output file name */ + char outfile[MAX_PATH]; + /** input file format 0: J2K, 1: JP2, 2: JPT */ + int decod_format; + /** output file format 0: PGX, 1: PxM, 2: BMP */ + int cod_format; + /*@}*/ +} opj_dparameters_t; + +/** Common fields between JPEG-2000 compression and decompression master structs. */ + +#define opj_common_fields \ + opj_event_mgr_t *event_mgr; /**< pointer to the event manager */\ + void * client_data; /**< Available for use by application */\ + bool is_decompressor; /**< So common code can tell which is which */\ + OPJ_CODEC_FORMAT codec_format; /**< selected codec */\ + void *j2k_handle; /**< pointer to the J2K codec */\ + void *jp2_handle /**< pointer to the JP2 codec */ + +/* Routines that are to be used by both halves of the library are declared + * to receive a pointer to this structure. There are no actual instances of + * opj_common_struct_t, only of opj_cinfo_t and opj_dinfo_t. + */ +typedef struct opj_common_struct { + opj_common_fields; /* Fields common to both master struct types */ + /* Additional fields follow in an actual opj_cinfo_t or + * opj_dinfo_t. All three structs must agree on these + * initial fields! (This would be a lot cleaner in C++.) + */ +} opj_common_struct_t; + +typedef opj_common_struct_t * opj_common_ptr; + +/** +Compression context info +*/ +typedef struct opj_cinfo { + /** Fields shared with opj_dinfo_t */ + opj_common_fields; + /* other specific fields go here */ +} opj_cinfo_t; + +/** +Decompression context info +*/ +typedef struct opj_dinfo { + /** Fields shared with opj_cinfo_t */ + opj_common_fields; + /* other specific fields go here */ +} opj_dinfo_t; + +/* +========================================================== + I/O stream typedef definitions +========================================================== +*/ + +/* + * Stream open flags. + */ +/** The stream was opened for reading. */ +#define OPJ_STREAM_READ 0x0001 +/** The stream was opened for writing. */ +#define OPJ_STREAM_WRITE 0x0002 + +/** +Byte input-output stream (CIO) +*/ +typedef struct opj_cio { + /** codec context */ + opj_common_ptr cinfo; + + /** open mode (read/write) either OPJ_STREAM_READ or OPJ_STREAM_WRITE */ + int openmode; + /** pointer to the start of the buffer */ + unsigned char *buffer; + /** buffer size in bytes */ + int length; + + /** pointer to the start of the stream */ + unsigned char *start; + /** pointer to the end of the stream */ + unsigned char *end; + /** pointer to the current position */ + unsigned char *bp; +} opj_cio_t; + +/* +========================================================== + image typedef definitions +========================================================== +*/ + +/** +Defines a single image component +*/ +typedef struct opj_image_comp { + /** XRsiz: horizontal separation of a sample of ith component with respect to the reference grid */ + int dx; + /** YRsiz: vertical separation of a sample of ith component with respect to the reference grid */ + int dy; + /** data width */ + int w; + /** data height */ + int h; + /** x component offset compared to the whole image */ + int x0; + /** y component offset compared to the whole image */ + int y0; + /** precision */ + int prec; + /** image depth in bits */ + int bpp; + /** signed (1) / unsigned (0) */ + int sgnd; + /** number of decoded resolution */ + int resno_decoded; + /** number of division by 2 of the out image compared to the original size of image */ + int factor; + /** image component data */ + int *data; +} opj_image_comp_t; + +/** +Defines image data and characteristics +*/ +typedef struct opj_image { + /** XOsiz: horizontal offset from the origin of the reference grid to the left side of the image area */ + int x0; + /** YOsiz: vertical offset from the origin of the reference grid to the top side of the image area */ + int y0; + /** Xsiz: width of the reference grid */ + int x1; + /** Ysiz: height of the reference grid */ + int y1; + /** number of components in the image */ + int numcomps; + /** color space: sRGB, Greyscale or YUV */ + OPJ_COLOR_SPACE color_space; + /** image components */ + opj_image_comp_t *comps; +} opj_image_t; + +/** +Component parameters structure used by the opj_image_create function +*/ +typedef struct opj_image_comptparm { + /** XRsiz: horizontal separation of a sample of ith component with respect to the reference grid */ + int dx; + /** YRsiz: vertical separation of a sample of ith component with respect to the reference grid */ + int dy; + /** data width */ + int w; + /** data height */ + int h; + /** x component offset compared to the whole image */ + int x0; + /** y component offset compared to the whole image */ + int y0; + /** precision */ + int prec; + /** image depth in bits */ + int bpp; + /** signed (1) / unsigned (0) */ + int sgnd; +} opj_image_cmptparm_t; + +#ifdef __cplusplus +extern "C" { +#endif + +/* +========================================================== + image functions definitions +========================================================== +*/ + +/** +Create an image +@param numcmpts number of components +@param cmptparms components parameters +@param clrspc image color space +@return returns a new image structure if successful, returns NULL otherwise +*/ +opj_image_t *opj_image_create(int numcmpts, opj_image_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc); + +/** +Deallocate any resources associated with an image +@param image image to be destroyed +*/ +void opj_image_destroy(opj_image_t *image); + +/* +========================================================== + stream functions definitions +========================================================== +*/ + +/** +Open and allocate a memory stream for read / write. +On reading, the user must provide a buffer containing encoded data. The buffer will be +wrapped by the returned CIO handle. +On writing, buffer parameters must be set to 0: a buffer will be allocated by the library +to contain encoded data. +@param cinfo Codec context info +@param buffer Reading: buffer address. Writing: NULL +@param length Reading: buffer length. Writing: 0 +@return Returns a CIO handle if successful, returns NULL otherwise +*/ +opj_cio_t* opj_cio_open(opj_common_ptr cinfo, unsigned char *buffer, int length); + +/** +Close and free a CIO handle +@param cio CIO handle to free +*/ +void opj_cio_close(opj_cio_t *cio); + +/** +Get position in byte stream +@param cio CIO handle +@return Returns the position in bytes +*/ +int cio_tell(opj_cio_t *cio); +/** +Set position in byte stream +@param cio CIO handle +@param pos Position, in number of bytes, from the beginning of the stream +*/ +void cio_seek(opj_cio_t *cio, int pos); + +/* +========================================================== + event manager functions definitions +========================================================== +*/ + +opj_event_mgr_t* opj_set_event_mgr(opj_common_ptr cinfo, opj_event_mgr_t *event_mgr, void *context); + +/* +========================================================== + codec functions definitions +========================================================== +*/ +/** +Creates a J2K/JPT/JP2 decompression structure +@param format Decoder to select +@return Returns a handle to a decompressor if successful, returns NULL otherwise +*/ +opj_dinfo_t* opj_create_decompress(OPJ_CODEC_FORMAT format); +/** +Destroy a decompressor handle +@param dinfo decompressor handle to destroy +*/ +void opj_destroy_decompress(opj_dinfo_t *dinfo); +/** +Set decoding parameters to default values +@param parameters Decompression parameters +*/ +void opj_set_default_decoder_parameters(opj_dparameters_t *parameters); +/** +Setup the decoder decoding parameters using user parameters. +Decoding parameters are returned in j2k->cp. +@param dinfo decompressor handle +@param parameters decompression parameters +*/ +void opj_setup_decoder(opj_dinfo_t *dinfo, opj_dparameters_t *parameters); +/** +Decode an image from a JPEG-2000 codestream +@param dinfo decompressor handle +@param cio Input buffer stream +@return Returns a decoded image if successful, returns NULL otherwise +*/ +opj_image_t* opj_decode(opj_dinfo_t *dinfo, opj_cio_t *cio); +/** +Creates a J2K/JP2 compression structure +@param format Coder to select +@return Returns a handle to a compressor if successful, returns NULL otherwise +*/ +opj_cinfo_t* opj_create_compress(OPJ_CODEC_FORMAT format); +/** +Destroy a compressor handle +@param cinfo compressor handle to destroy +*/ +void opj_destroy_compress(opj_cinfo_t *cinfo); +/** +Set encoding parameters to default values, that means : +
    +
  • Lossless +
  • 1 tile +
  • Size of precinct : 2^15 x 2^15 (means 1 precinct) +
  • Size of code-block : 64 x 64 +
  • Number of resolutions: 6 +
  • No SOP marker in the codestream +
  • No EPH marker in the codestream +
  • No sub-sampling in x or 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 +
+@param parameters Compression parameters +*/ +void opj_set_default_encoder_parameters(opj_cparameters_t *parameters); +/** +Setup the encoder parameters using the current image and using user parameters. +@param cinfo compressor handle +@param parameters compression parameters +@param image input filled image +*/ +void opj_setup_encoder(opj_cinfo_t *cinfo, opj_cparameters_t *parameters, opj_image_t *image); +/** +Encode an image into a JPEG-2000 codestream +@param cinfo compressor handle +@param cio Output buffer stream +@param image Image to encode +@param index Name of the index file if required, NULL otherwise +@return Returns true if successful, returns false otherwise +*/ +bool opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, char *index); + +#ifdef __cplusplus +} +#endif + +#endif /* OPENJPEG_H */ diff --git a/libopenjpeg/opj_includes.h b/libopenjpeg/opj_includes.h new file mode 100644 index 00000000..2a78fca1 --- /dev/null +++ b/libopenjpeg/opj_includes.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2005, Hervé Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef OPJ_INCLUDES_H +#define OPJ_INCLUDES_H + +/* + ========================================================== + Standard includes used by the library + ========================================================== +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + ========================================================== + OpenJPEG interface + ========================================================== + */ +#include "openjpeg.h" + +/* + ========================================================== + OpenJPEG modules + ========================================================== +*/ + +#include "j2k_lib.h" +#include "event.h" +#include "cio.h" + +#include "image.h" +#include "j2k.h" +#include "jp2.h" +#include "jpt.h" + +#include "mqc.h" +#include "raw.h" +#include "bio.h" +#include "tgt.h" +#include "tcd.h" +#include "t1.h" +#include "dwt.h" +#include "pi.h" +#include "t2.h" +#include "mct.h" +#include "int.h" +#include "fix.h" + + +#endif /* OPJ_INCLUDES_H */ diff --git a/libopenjpeg/pi.c b/libopenjpeg/pi.c index 285da3bd..87bd2635 100644 --- a/libopenjpeg/pi.c +++ b/libopenjpeg/pi.c @@ -1,7 +1,9 @@ /* - * 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 + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,221 +28,94 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "pi.h" -#include "int.h" -#include -#include +#include "opj_includes.h" -/* - * 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; +/* +========================================================== + local functions +========================================================== +*/ +static bool pi_next_lrcp(opj_pi_iterator_t * pi) { + opj_pi_comp_t *comp = NULL; + opj_pi_resolution_t *res = NULL; + long index = 0; + if (!pi->first) { comp = &pi->comps[pi->compno]; res = &comp->resolutions[pi->resno]; - goto skip; + goto LABEL_SKIP; } else { pi->first = 0; } + for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) { for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; - pi->resno++) { - for (pi->compno = pi->poc.compno0; - pi->compno < pi->poc.compno1; pi->compno++) { - comp = &pi->comps[pi->compno]; - if (pi->resno >= comp->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:; - } + 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++) { + index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; + if (!pi->include[index]) { + pi->include[index] = 1; + return true; + } +LABEL_SKIP:; + } } } } - return 0; + + return false; } -/* - * 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; +static bool pi_next_rlcp(opj_pi_iterator_t * pi) { + opj_pi_comp_t *comp = NULL; + opj_pi_resolution_t *res = NULL; + long index = 0; + if (!pi->first) { comp = &pi->comps[pi->compno]; res = &comp->resolutions[pi->resno]; - goto skip; + goto LABEL_SKIP; } else { pi->first = 0; } + for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) { for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) { - for (pi->compno = pi->poc.compno0; - pi->compno < pi->poc.compno1; pi->compno++) { - comp = &pi->comps[pi->compno]; - if (pi->resno >= comp->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:; - } + 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++) { + index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; + if (!pi->include[index]) { + pi->include[index] = 1; + return true; + } +LABEL_SKIP:; + } } } } - return 0; + + return false; } -/* - * 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; +static bool pi_next_rpcl(opj_pi_iterator_t * pi) { + opj_pi_comp_t *comp = NULL; + opj_pi_resolution_t *res = NULL; + long index = 0; + if (!pi->first) { - goto skip; + goto LABEL_SKIP; } else { int compno, resno; pi->first = 0; @@ -249,102 +124,77 @@ int pi_next_rpcl(pi_iterator_t * pi) 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); + 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:; - } - } + 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; + 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); + try1 = int_ceildiv(pi->ty1, comp->dy << levelno); + rpx = res->pdx + levelno; + rpy = res->pdy + levelno; + if ((!(pi->x % (comp->dx << rpx) == 0) || (pi->x == pi->tx0 && (trx0 << levelno) % (1 << rpx)))) { + continue; + } + if ((!(pi->y % (comp->dy << rpy) == 0) || (pi->y == pi->ty0 && (try0 << levelno) % (1 << rpx)))) { + continue; + } + + if ((res->pw==0)||(res->pw==0)) continue; + + if ((trx0==trx1)||(try0==try1)) continue; + + prci = int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelno), res->pdx) + - int_floordivpow2(trx0, res->pdx); + prcj = int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelno), res->pdy) + - int_floordivpow2(try0, res->pdy); + pi->precno = prci + prcj * res->pw; + for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) { + index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; + if (!pi->include[index]) { + pi->include[index] = 1; + return true; + } +LABEL_SKIP:; + } + } } } } - return 0; + + return false; } -/* - * 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; +static bool pi_next_pcrl(opj_pi_iterator_t * pi) { + opj_pi_comp_t *comp = NULL; + opj_pi_resolution_t *res = NULL; + long index = 0; + if (!pi->first) { comp = &pi->comps[pi->compno]; - goto skip; + goto LABEL_SKIP; } else { int compno, resno; pi->first = 0; @@ -353,106 +203,79 @@ int pi_next_pcrl(pi_iterator_t * pi) 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); + 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:; - } - } + 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; + 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); + try1 = int_ceildiv(pi->ty1, comp->dy << levelno); + rpx = res->pdx + levelno; + rpy = res->pdy + levelno; + if ((!(pi->x % (comp->dx << rpx) == 0) || (pi->x == pi->tx0 && (trx0 << levelno) % (1 << rpx)))) { + continue; + } + if ((!(pi->y % (comp->dy << rpy) == 0) || (pi->y == pi->ty0 && (try0 << levelno) % (1 << rpx)))) { + continue; + } + + if ((res->pw==0)||(res->pw==0)) continue; + + if ((trx0==trx1)||(try0==try1)) continue; + + prci = int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelno), res->pdx) + - int_floordivpow2(trx0, res->pdx); + prcj = int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelno), res->pdy) + - int_floordivpow2(try0, res->pdy); + pi->precno = prci + prcj * res->pw; + for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) { + index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; + if (!pi->include[index]) { + pi->include[index] = 1; + return true; + } +LABEL_SKIP:; + } + } } } } - return 0; + + return false; } -/* - * 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; +static bool pi_next_cprl(opj_pi_iterator_t * pi) { + opj_pi_comp_t *comp = NULL; + opj_pi_resolution_t *res = NULL; + long index = 0; + if (!pi->first) { comp = &pi->comps[pi->compno]; - goto skip; + goto LABEL_SKIP; } else { pi->first = 0; } - for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; - pi->compno++) { + + for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) { int resno; comp = &pi->comps[pi->compno]; pi->dx = 0; @@ -465,93 +288,224 @@ int pi_next_cprl(pi_iterator_t * pi) 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:; - } - } + 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; + 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); + try1 = int_ceildiv(pi->ty1, comp->dy << levelno); + rpx = res->pdx + levelno; + rpy = res->pdy + levelno; + if ((!(pi->x % (comp->dx << rpx) == 0) || (pi->x == pi->tx0 && (trx0 << levelno) % (1 << rpx)))) { + continue; + } + if ((!(pi->y % (comp->dy << rpy) == 0) || (pi->y == pi->ty0 && (try0 << levelno) % (1 << rpx)))) { + continue; + } + + if ((res->pw==0)||(res->pw==0)) continue; + + if ((trx0==trx1)||(try0==try1)) continue; + + prci = int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelno), res->pdx) + - int_floordivpow2(trx0, res->pdx); + prcj = int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelno), res->pdy) + - int_floordivpow2(try0, res->pdy); + pi->precno = prci + prcj * res->pw; + for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) { + index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; + if (!pi->include[index]) { + pi->include[index] = 1; + return true; + } +LABEL_SKIP:; + } + } } } } - return 0; + + return false; } -/* - * 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); +/* +========================================================== + Packet iterator interface +========================================================== +*/ + +opj_pi_iterator_t *pi_create(opj_image_t *image, opj_cp_t *cp, int tileno) { + int p, q; + int compno, resno, pino; + int maxres = 0; + opj_pi_iterator_t *pi = NULL; + opj_tcp_t *tcp = NULL; + opj_tccp_t *tccp = NULL; + size_t array_size; + + tcp = &cp->tcps[tileno]; + + array_size = (tcp->numpocs + 1) * sizeof(opj_pi_iterator_t); + pi = (opj_pi_iterator_t *) opj_malloc(array_size); + if(!pi) { + /* TODO: throw an error */ + return NULL; } - return 0; + + 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, image->x0); + pi[pino].ty0 = int_max(cp->ty0 + q * cp->tdy, image->y0); + pi[pino].tx1 = int_min(cp->tx0 + (p + 1) * cp->tdx, image->x1); + pi[pino].ty1 = int_min(cp->ty0 + (q + 1) * cp->tdy, image->y1); + pi[pino].numcomps = image->numcomps; + + array_size = image->numcomps * sizeof(opj_pi_comp_t); + pi[pino].comps = (opj_pi_comp_t *) opj_malloc(array_size); + if(!pi[pino].comps) { + /* TODO: throw an error */ + pi_destroy(pi, cp, tileno); + return NULL; + } + memset(pi[pino].comps, 0, array_size); + + for (compno = 0; compno < pi->numcomps; compno++) { + int tcx0, tcy0, tcx1, tcy1; + opj_pi_comp_t *comp = &pi[pino].comps[compno]; + tccp = &tcp->tccps[compno]; + comp->dx = image->comps[compno].dx; + comp->dy = image->comps[compno].dy; + comp->numresolutions = tccp->numresolutions; + + array_size = comp->numresolutions * sizeof(opj_pi_resolution_t); + comp->resolutions = (opj_pi_resolution_t *) opj_malloc(array_size); + if(!comp->resolutions) { + /* TODO: throw an error */ + pi_destroy(pi, cp, tileno); + return NULL; + } + + 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; + opj_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); + res->ph = (ry0==ry1)?0:((py1 - py0) >> res->pdy); + } + } + + tccp = &tcp->tccps[0]; + pi[pino].step_p = 1; + pi[pino].step_c = 100 * pi[pino].step_p; + pi[pino].step_r = image->numcomps * pi[pino].step_c; + pi[pino].step_l = maxres * pi[pino].step_r; + + if (pino == 0) { + array_size = image->numcomps * maxres * tcp->numlayers * 100 * sizeof(short int); + pi[pino].include = (short int *) opj_malloc(array_size); + if(!pi[pino].include) { + /* TODO: throw an error */ + pi_destroy(pi, cp, tileno); + return NULL; + } + } + else { + pi[pino].include = pi[pino - 1].include; + } + + if (tcp->POC == 0) { + pi[pino].first = 1; + pi[pino].poc.resno0 = 0; + pi[pino].poc.compno0 = 0; + pi[pino].poc.layno1 = tcp->numlayers; + pi[pino].poc.resno1 = maxres; + pi[pino].poc.compno1 = image->numcomps; + pi[pino].poc.prg = tcp->prg; + } else { + pi[pino].first = 1; + pi[pino].poc.resno0 = tcp->pocs[pino].resno0; + pi[pino].poc.compno0 = tcp->pocs[pino].compno0; + pi[pino].poc.layno1 = tcp->pocs[pino].layno1; + pi[pino].poc.resno1 = tcp->pocs[pino].resno1; + pi[pino].poc.compno1 = tcp->pocs[pino].compno1; + pi[pino].poc.prg = tcp->pocs[pino].prg; + } + } + + return pi; } + +void pi_destroy(opj_pi_iterator_t *pi, opj_cp_t *cp, int tileno) { + int compno, pino; + opj_tcp_t *tcp = &cp->tcps[tileno]; + if(pi) { + for (pino = 0; pino < tcp->numpocs + 1; pino++) { + if(pi[pino].comps) { + for (compno = 0; compno < pi->numcomps; compno++) { + opj_pi_comp_t *comp = &pi[pino].comps[compno]; + if(comp->resolutions) { + opj_free(comp->resolutions); + } + } + opj_free(pi[pino].comps); + } + } + if(pi->include) { + opj_free(pi->include); + } + opj_free(pi); + } +} + +bool pi_next(opj_pi_iterator_t * pi) { + switch (pi->poc.prg) { + case LRCP: + return pi_next_lrcp(pi); + case RLCP: + return pi_next_rlcp(pi); + case RPCL: + return pi_next_rpcl(pi); + case PCRL: + return pi_next_pcrl(pi); + case CPRL: + return pi_next_cprl(pi); + } + + return false; +} + diff --git a/libopenjpeg/pi.h b/libopenjpeg/pi.h index acfe201a..5e39276b 100644 --- a/libopenjpeg/pi.h +++ b/libopenjpeg/pi.h @@ -1,5 +1,9 @@ /* - * Copyright (c) 2001-2002, David Janssens + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,47 +30,137 @@ #ifndef __PI_H #define __PI_H +/** +@file pi.h +@brief Implementation of a packet iterator (PI) -#include "j2k.h" -#include "tcd.h" +The functions in PI.C have for goal to realize a packet iterator that permits to get the next +packet following the progression order and change of it. The functions in PI.C are used +by some function in T2.C. +*/ -typedef struct { +/** @defgroup PI PI - Implementation of a packet iterator */ +/*@{*/ + +/** +FIXME: documentation +*/ +typedef struct opj_pi_resolution { int pdx, pdy; int pw, ph; -} pi_resolution_t; +} opj_pi_resolution_t; -typedef struct { +/** +FIXME: documentation +*/ +typedef struct opj_pi_comp { int dx, dy; + /** number of resolution levels */ int numresolutions; - pi_resolution_t *resolutions; -} pi_comp_t; + opj_pi_resolution_t *resolutions; +} opj_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; +/** +Packet iterator +*/ +typedef struct opj_pi_iterator { + /** precise if the packet has been already used (usefull for progression order change) */ + short int *include; + /** layer step used to localize the packet in the include vector */ + int step_l; + /** resolution step used to localize the packet in the include vector */ + int step_r; + /** component step used to localize the packet in the include vector */ + int step_c; + /** precinct step used to localize the packet in the include vector */ + int step_p; + /** component that identify the packet */ + int compno; + /** resolution that identify the packet */ + int resno; + /** precinct that identify the packet */ + int precno; + /** layer that identify the packet */ + int layno; + /** 0 if the first packet */ + int first; + /** progression order change information */ + opj_poc_t poc; + /** */ int numcomps; - pi_comp_t *comps; + /** */ + opj_pi_comp_t *comps; int tx0, ty0, tx1, ty1; int x, y, dx, dy; -} pi_iterator_t; /* packet iterator */ +} opj_pi_iterator_t; -/* - * 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); +/** @name Local static functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Get next packet in layer-resolution-component-precinct order. +@param pi packet iterator to modify +@return returns false if pi pointed to the last packet or else returns true +*/ +static bool pi_next_lrcp(opj_pi_iterator_t * pi); +/** +Get next packet in resolution-layer-component-precinct order. +@param pi packet iterator to modify +@return returns false if pi pointed to the last packet or else returns true +*/ +static bool pi_next_rlcp(opj_pi_iterator_t * pi); +/** +Get next packet in resolution-precinct-component-layer order. +@param pi packet iterator to modify +@return returns false if pi pointed to the last packet or else returns true +*/ +static bool pi_next_rpcl(opj_pi_iterator_t * pi); +/** +Get next packet in precinct-component-resolution-layer order. +@param pi packet iterator to modify +@return returns false if pi pointed to the last packet or else returns true +*/ +static bool pi_next_pcrl(opj_pi_iterator_t * pi); +/** +Get next packet in component-precinct-resolution-layer order. +@param pi packet iterator to modify +@return returns false if pi pointed to the last packet or else returns true +*/ +static bool pi_next_cprl(opj_pi_iterator_t * pi); +/* ----------------------------------------------------------------------- */ +/*@}*/ -/* - * 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); +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Create a packet iterator +@param image Raw image for which the packets will be listed +@param cp Coding parameters +@param tileno Number that identifies the tile for which to list the packets +@return Returns a packet iterator that points to the first packet of the tile +@see pi_destroy +*/ +opj_pi_iterator_t *pi_create(opj_image_t * image, opj_cp_t * cp, int tileno); -#endif +/** +Destroy a packet iterator +@param pi Previously created packet iterator +@param cp Coding parameters +@param tileno Number that identifies the tile for which the packets were listed +@see pi_create +*/ +void pi_destroy(opj_pi_iterator_t *pi, opj_cp_t *cp, int tileno); + +/** +Modify the packet iterator to point to the next packet +@param pi Packet iterator to modify +@return Returns false if pi pointed to the last packet or else returns true +*/ +bool pi_next(opj_pi_iterator_t * pi); +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __PI_H */ diff --git a/libopenjpeg/raw.c b/libopenjpeg/raw.c index bae2e899..7e7326d1 100644 --- a/libopenjpeg/raw.c +++ b/libopenjpeg/raw.c @@ -1,5 +1,7 @@ /* - * Copyright (c) 2002-2003, Antonin Descampe + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,58 +26,61 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "raw.h" +#include "opj_includes.h" + +/* +========================================================== + local functions +========================================================== +*/ -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 */ +/* +========================================================== + RAW encoding interface +========================================================== +*/ -/* - * Return the number of bytes already encoded. - */ -int raw_numbytes() -{ - return raw_bp - raw_start; +opj_raw_t* raw_create() { + opj_raw_t *raw = (opj_raw_t*)opj_malloc(sizeof(opj_raw_t)); + return raw; } -/* - * 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; +void raw_destroy(opj_raw_t *raw) { + if(raw) { + opj_free(raw); + } } -/* - * Decode a symbol using raw-decoder. Cfr p.506 TAUBMAN - */ -int raw_decode() -{ +int raw_numbytes(opj_raw_t *raw) { + return raw->bp - raw->start; +} + +void raw_init_dec(opj_raw_t *raw, unsigned char *bp, int len) { + raw->start = bp; + raw->lenmax = len; + raw->len = 0; + raw->c = 0; + raw->ct = 0; +} + +int raw_decode(opj_raw_t *raw) { int d; - if (raw_ct == 0) { - raw_ct = 8; - if (raw_len == raw_lenmax) - raw_c = 0xff; - else { - if (raw_c == 0xff) - raw_ct = 7; - raw_c = *(raw_start + raw_len); - raw_len++; + 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; + raw->ct--; + d = (raw->c >> raw->ct) & 0x01; + return d; } + diff --git a/libopenjpeg/raw.h b/libopenjpeg/raw.h index 08b20bc6..0a45ecd9 100644 --- a/libopenjpeg/raw.h +++ b/libopenjpeg/raw.h @@ -1,6 +1,7 @@ /* - * Copyright (c) 2002-2003, Antonin Descampe - * Copyright (c) 2002-2003, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,22 +28,72 @@ #ifndef __RAW_H #define __RAW_H +/** +@file raw.h +@brief Implementation of operations for raw encoding (RAW) -/* - * Return the number of bytes written/read since initialisation - */ -int raw_numbytes(); +The functions in RAW.C have for goal to realize the operation of raw encoding linked +with the corresponding mode switch. +*/ -/* - * 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); +/** @defgroup RAW RAW - Implementation of operations for raw encoding */ +/*@{*/ -/* - * Decode a bit (returns 0 or 1) - */ -int raw_decode(); +/** +RAW encoding operations +*/ +typedef struct opj_raw { + /** temporary buffer where bits are coded or decoded */ + unsigned char c; + /** number of bits already read or free to write */ + unsigned int ct; + /** maximum length to decode */ + unsigned int lenmax; + /** length decoded */ + unsigned int len; + /** pointer to the current position in the buffer */ + unsigned char *bp; + /** pointer to the start of the buffer */ + unsigned char *start; + /** pointer to the end of the buffer */ + unsigned char *end; +} opj_raw_t; -#endif +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Create a new RAW handle +@return Returns a new RAW handle if successful, returns NULL otherwise +*/ +opj_raw_t* raw_create(); +/** +Destroy a previously created RAW handle +@param raw RAW handle to destroy +*/ +void raw_destroy(opj_raw_t *raw); +/** +Return the number of bytes written/read since initialisation +@param raw RAW handle to destroy +@return Returns the number of bytes already encoded +*/ +int raw_numbytes(opj_raw_t *raw); +/** +Initialize the decoder +@param raw RAW handle +@param bp Pointer to the start of the buffer from which the bytes will be read +@param len Length of the input buffer +*/ +void raw_init_dec(opj_raw_t *raw, unsigned char *bp, int len); +/** +Decode a symbol using raw-decoder. Cfr p.506 TAUBMAN +@param raw RAW handle +@return Returns the decoded symbol (0 or 1) +*/ +int raw_decode(opj_raw_t *raw); +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __RAW_H */ diff --git a/libopenjpeg/t1.c b/libopenjpeg/t1.c index 52e34f86..2770c4d1 100644 --- a/libopenjpeg/t1.c +++ b/libopenjpeg/t1.c @@ -1,7 +1,9 @@ /* - * Copyright (c) 2001-2002, David Janssens + * 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 + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,116 +28,43 @@ * 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 +#include "opj_includes.h" -#define T1_MAXCBLKW 1024 -#define T1_MAXCBLKH 1024 +/* ----------------------------------------------------------------------- */ -#define T1_SIG_NE 0x0001 -#define T1_SIG_SE 0x0002 -#define T1_SIG_SW 0x0004 -#define T1_SIG_NW 0x0008 -#define T1_SIG_N 0x0010 -#define T1_SIG_E 0x0020 -#define T1_SIG_S 0x0040 -#define T1_SIG_W 0x0080 -#define T1_SIG_OTH (T1_SIG_N|T1_SIG_NE|T1_SIG_E|T1_SIG_SE|T1_SIG_S|T1_SIG_SW|T1_SIG_W|T1_SIG_NW) -#define T1_SIG_PRIM (T1_SIG_N|T1_SIG_E|T1_SIG_S|T1_SIG_W) - -#define T1_SGN_N 0x0100 -#define T1_SGN_E 0x0200 -#define T1_SGN_S 0x0400 -#define T1_SGN_W 0x0800 -#define T1_SGN (T1_SGN_N|T1_SGN_E|T1_SGN_S|T1_SGN_W) - -#define T1_SIG 0x1000 -#define T1_REFINE 0x2000 -#define T1_VISIT 0x4000 - -#define T1_NUMCTXS_AGG 1 -#define T1_NUMCTXS_ZC 9 -#define T1_NUMCTXS_MAG 3 -#define T1_NUMCTXS_SC 5 -#define T1_NUMCTXS_UNI 1 - -#define T1_CTXNO_AGG 0 -#define T1_CTXNO_ZC (T1_CTXNO_AGG+T1_NUMCTXS_AGG) -#define T1_CTXNO_MAG (T1_CTXNO_ZC+T1_NUMCTXS_ZC) -#define T1_CTXNO_SC (T1_CTXNO_MAG+T1_NUMCTXS_MAG) -#define T1_CTXNO_UNI (T1_CTXNO_SC+T1_NUMCTXS_SC) -#define T1_NUMCTXS (T1_CTXNO_UNI+T1_NUMCTXS_UNI) - -#define T1_NMSEDEC_BITS 7 -#define T1_NMSEDEC_FRACBITS (T1_NMSEDEC_BITS-1) - -/* add TONY */ -#define T1_TYPE_MQ 0 -#define T1_TYPE_RAW 1 -/* dda */ - -static int t1_lut_ctxno_zc[1024]; -static int t1_lut_ctxno_sc[256]; -static int t1_lut_ctxno_mag[4096]; -static int t1_lut_spb[256]; -static int t1_lut_nmsedec_sig[1 << T1_NMSEDEC_BITS]; -static int t1_lut_nmsedec_sig0[1 << T1_NMSEDEC_BITS]; -static int t1_lut_nmsedec_ref[1 << T1_NMSEDEC_BITS]; -static int t1_lut_nmsedec_ref0[1 << T1_NMSEDEC_BITS]; - -static int t1_data[T1_MAXCBLKH][T1_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)]; +static int t1_getctxno_zc(opj_t1_t *t1, 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]; +static int t1_getctxno_sc(opj_t1_t *t1, 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)]; +static int t1_getctxno_mag(opj_t1_t *t1, int f) { + return t1->lut_ctxno_mag[(f & T1_SIG_OTH) | (((f & T1_REFINE) != 0) << 11)]; } -int t1_getspb(int f) -{ - return t1_lut_spb[(f & (T1_SIG_PRIM | T1_SGN)) >> 4]; +static int t1_getspb(opj_t1_t *t1, 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)]; +static int t1_getnmsedec_sig(opj_t1_t *t1, int x, int bitpos) { + if (bitpos > T1_NMSEDEC_FRACBITS) { + return t1->lut_nmsedec_sig[(x >> (bitpos - T1_NMSEDEC_FRACBITS)) & ((1 << T1_NMSEDEC_BITS) - 1)]; + } + + return t1->lut_nmsedec_sig0[x & ((1 << T1_NMSEDEC_BITS) - 1)]; } -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)]; +static int t1_getnmsedec_ref(opj_t1_t *t1, int x, int bitpos) { + if (bitpos > T1_NMSEDEC_FRACBITS) { + return t1->lut_nmsedec_ref[(x >> (bitpos - T1_NMSEDEC_FRACBITS)) & ((1 << T1_NMSEDEC_BITS) - 1)]; + } + + return t1->lut_nmsedec_ref0[x & ((1 << T1_NMSEDEC_BITS) - 1)]; } -void t1_updateflags(int *fp, int s) -{ +static void t1_updateflags(int *fp, int s) { int *np = fp - (T1_MAXCBLKW + 2); int *sp = fp + (T1_MAXCBLKW + 2); np[-1] |= T1_SIG_SE; @@ -154,31 +83,30 @@ void t1_updateflags(int *fp, int s) } } -void t1_enc_sigpass_step(int *fp, int *dp, int orient, int bpno, int one, - int *nmsedec, char type, int vsc) -{ +static void t1_enc_sigpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int bpno, int one, int *nmsedec, char type, int vsc) { int v, flag; - flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) - : (*fp); + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*fp); if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) { v = int_abs(*dp) & one ? 1 : 0; - if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */ - mqc_setcurctx(t1_getctxno_zc(flag, orient)); /* ESSAI */ - mqc_bypass_enc(v); + if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */ + mqc_setcurctx(mqc, t1_getctxno_zc(t1, flag, orient)); /* ESSAI */ + mqc_bypass_enc(mqc, v); } else { - mqc_setcurctx(t1_getctxno_zc(flag, orient)); - mqc_encode(v); + mqc_setcurctx(mqc, t1_getctxno_zc(t1, flag, orient)); + mqc_encode(mqc, 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); + *nmsedec += t1_getnmsedec_sig(t1, int_abs(*dp), bpno + T1_NMSEDEC_FRACBITS); + if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */ + mqc_setcurctx(mqc, t1_getctxno_sc(t1, flag)); /* ESSAI */ + mqc_bypass_enc(mqc, v); } else { - mqc_setcurctx(t1_getctxno_sc(flag)); - mqc_encode(v ^ t1_getspb(flag)); + mqc_setcurctx(mqc, t1_getctxno_sc(t1, flag)); + mqc_encode(mqc, v ^ t1_getspb(t1, flag)); } t1_updateflags(fp, v); *fp |= T1_SIG; @@ -187,58 +115,50 @@ void t1_enc_sigpass_step(int *fp, int *dp, int orient, int bpno, int one, } } - - -void t1_dec_sigpass_step(int *fp, int *dp, int orient, int oneplushalf, - char type, int vsc) -{ +static void t1_dec_sigpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int oneplushalf, char type, int vsc) { int v, flag; - flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) - : (*fp); + + opj_raw_t *raw = t1->raw; /* RAW component */ + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*fp); if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) { if (type == T1_TYPE_RAW) { - if (raw_decode()) { - v = raw_decode(); /* ESSAI */ - *dp = v ? -oneplushalf : oneplushalf; - t1_updateflags(fp, v); - *fp |= T1_SIG; + if (raw_decode(raw)) { + v = raw_decode(raw); /* 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; + mqc_setcurctx(mqc, t1_getctxno_zc(t1, flag, orient)); + if (mqc_decode(mqc)) { + mqc_setcurctx(mqc, t1_getctxno_sc(t1, flag)); + v = mqc_decode(mqc) ^ t1_getspb(t1, flag); + *dp = v ? -oneplushalf : oneplushalf; + t1_updateflags(fp, v); + *fp |= T1_SIG; } } *fp |= T1_VISIT; } -} /* VSC and BYPASS by Antonin */ +} /* VSC and BYPASS by Antonin */ -void t1_enc_sigpass(int w, int h, int bpno, int orient, int *nmsedec, - char type, int cblksty) -{ +static void t1_enc_sigpass(opj_t1_t *t1, 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); + vsc = ((cblksty & J2K_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; + t1_enc_sigpass_step(t1, &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) -{ +static void t1_dec_sigpass(opj_t1_t *t1, 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; @@ -246,83 +166,69 @@ void t1_dec_sigpass(int w, int h, int bpno, int orient, char type, 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 = ((cblksty & J2K_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; + t1_dec_sigpass_step(t1, &t1->flags[1 + j][1 + i], &t1->data[j][i], orient, oneplushalf, type, vsc); } } } -} /* VSC and BYPASS by Antonin */ +} /* VSC and BYPASS by Antonin */ -void t1_enc_refpass_step(int *fp, int *dp, int bpno, int one, int *nmsedec, - char type, int vsc) -{ +static void t1_enc_refpass_step(opj_t1_t *t1, int *fp, int *dp, int bpno, int one, int *nmsedec, char type, int vsc) { int v, flag; - flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) - : (*fp); + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*fp); if ((flag & (T1_SIG | T1_VISIT)) == T1_SIG) { - *nmsedec += - t1_getnmsedec_ref(int_abs(*dp), bpno + T1_NMSEDEC_FRACBITS); + *nmsedec += t1_getnmsedec_ref(t1, int_abs(*dp), bpno + T1_NMSEDEC_FRACBITS); v = int_abs(*dp) & one ? 1 : 0; - if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */ - mqc_setcurctx(t1_getctxno_mag(flag)); /* ESSAI */ - mqc_bypass_enc(v); + if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */ + mqc_setcurctx(mqc, t1_getctxno_mag(t1, flag)); /* ESSAI */ + mqc_bypass_enc(mqc, v); } else { - mqc_setcurctx(t1_getctxno_mag(flag)); - mqc_encode(v); + mqc_setcurctx(mqc, t1_getctxno_mag(t1, flag)); + mqc_encode(mqc, v); } *fp |= T1_REFINE; } } - - -void t1_dec_refpass_step(int *fp, int *dp, int poshalf, int neghalf, - char type, int vsc) -{ +static void t1_dec_refpass_step(opj_t1_t *t1, int *fp, int *dp, int poshalf, int neghalf, char type, int vsc) { int v, t, flag; - flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) - : (*fp); + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + opj_raw_t *raw = t1->raw; /* RAW component */ + + flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*fp); if ((flag & (T1_SIG | T1_VISIT)) == T1_SIG) { if (type == T1_TYPE_RAW) { - mqc_setcurctx(t1_getctxno_mag(flag)); /* ESSAI */ - v = raw_decode(); + mqc_setcurctx(mqc, t1_getctxno_mag(t1, flag)); /* ESSAI */ + v = raw_decode(raw); } else { - mqc_setcurctx(t1_getctxno_mag(flag)); - v = mqc_decode(); + mqc_setcurctx(mqc, t1_getctxno_mag(t1, flag)); + v = mqc_decode(mqc); } t = v ? poshalf : neghalf; *dp += *dp < 0 ? -t : t; *fp |= T1_REFINE; } -} /* VSC and BYPASS by Antonin */ +} /* VSC and BYPASS by Antonin */ -void t1_enc_refpass(int w, int h, int bpno, int *nmsedec, char type, - int cblksty) -{ +static void t1_enc_refpass(opj_t1_t *t1, 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); + vsc = ((cblksty & J2K_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; + t1_enc_refpass_step(t1, &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) -{ +static void t1_dec_refpass(opj_t1_t *t1, int w, int h, int bpno, char type, int cblksty) { int i, j, k, one, poshalf, neghalf; int vsc; one = 1 << bpno; @@ -331,40 +237,32 @@ void t1_dec_refpass(int w, int h, int bpno, char type, int cblksty) 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 = ((cblksty & J2K_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; + t1_dec_refpass_step(t1, &t1->flags[1 + j][1 + i], &t1->data[j][i], poshalf, neghalf, type, vsc); } } } -} /* VSC and BYPASS by Antonin */ +} /* 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) -{ +static void t1_enc_clnpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int bpno, int one, int *nmsedec, int partial, int vsc) { int v, flag; - flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) - : (*fp); - if (partial) - goto label_partial; + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*fp); + if (partial) { + goto LABEL_PARTIAL; + } if (!(*fp & (T1_SIG | T1_VISIT))) { - mqc_setcurctx(t1_getctxno_zc(flag, orient)); + mqc_setcurctx(mqc, t1_getctxno_zc(t1, flag, orient)); v = int_abs(*dp) & one ? 1 : 0; - mqc_encode(v); + mqc_encode(mqc, v); if (v) { - label_partial: - *nmsedec += - t1_getnmsedec_sig(int_abs(*dp), bpno + T1_NMSEDEC_FRACBITS); - mqc_setcurctx(t1_getctxno_sc(flag)); +LABEL_PARTIAL: + *nmsedec += t1_getnmsedec_sig(t1, int_abs(*dp), bpno + T1_NMSEDEC_FRACBITS); + mqc_setcurctx(mqc, t1_getctxno_sc(t1, flag)); v = *dp < 0 ? 1 : 0; - mqc_encode(v ^ t1_getspb(flag)); + mqc_encode(mqc, v ^ t1_getspb(t1, flag)); t1_updateflags(fp, v); *fp |= T1_SIG; } @@ -372,186 +270,156 @@ void t1_enc_clnpass_step(int *fp, int *dp, int orient, int bpno, int one, *fp &= ~T1_VISIT; } - - - -void t1_dec_clnpass_step(int *fp, int *dp, int orient, int oneplushalf, - int partial, int vsc) -{ +static void t1_dec_clnpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int oneplushalf, int partial, int vsc) { int v, flag; - flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) - : (*fp); - if (partial) - goto label_partial; + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*fp); + if (partial) { + goto LABEL_PARTIAL; + } if (!(flag & (T1_SIG | T1_VISIT))) { - mqc_setcurctx(t1_getctxno_zc(flag, orient)); - if (mqc_decode()) { - label_partial: - mqc_setcurctx(t1_getctxno_sc(flag)); - v = mqc_decode() ^ t1_getspb(flag); + mqc_setcurctx(mqc, t1_getctxno_zc(t1, flag, orient)); + if (mqc_decode(mqc)) { +LABEL_PARTIAL: + mqc_setcurctx(mqc, t1_getctxno_sc(t1, flag)); + v = mqc_decode(mqc) ^ t1_getspb(t1, flag); *dp = v ? -oneplushalf : oneplushalf; t1_updateflags(fp, v); *fp |= T1_SIG; } } *fp &= ~T1_VISIT; -} /* VSC and BYPASS by Antonin */ +} /* VSC and BYPASS by Antonin */ -void t1_enc_clnpass(int w, int h, int bpno, int orient, int *nmsedec, - int cblksty) -{ +static void t1_enc_clnpass(opj_t1_t *t1, int w, int h, int bpno, int orient, int *nmsedec, int cblksty) { int i, j, k, one, agg, runlen, vsc; + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + *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)); - } + 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; + 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); + for (runlen = 0; runlen < 4; runlen++) { + if (int_abs(t1->data[k + runlen][i]) & one) + break; + } + mqc_setcurctx(mqc, T1_CTXNO_AGG); + mqc_encode(mqc, runlen != 4); + if (runlen == 4) { + continue; + } + mqc_setcurctx(mqc, T1_CTXNO_UNI); + mqc_encode(mqc, runlen >> 1); + mqc_encode(mqc, runlen & 1); } else { - runlen = 0; + 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); + vsc = ((cblksty & J2K_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; + t1_enc_clnpass_step(t1, &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) -{ +static void t1_dec_clnpass(opj_t1_t *t1, 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; + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + 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)); - } + 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; + 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(); + mqc_setcurctx(mqc, T1_CTXNO_AGG); + if (!mqc_decode(mqc)) { + continue; + } + mqc_setcurctx(mqc, T1_CTXNO_UNI); + runlen = mqc_decode(mqc); + runlen = (runlen << 1) | mqc_decode(mqc); } else { - runlen = 0; + 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); + vsc = ((cblksty & J2K_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; + t1_dec_clnpass_step(t1, &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); - } */ + mqc_setcurctx(mqc, T1_CTXNO_UNI); + v = mqc_decode(mqc); + v = (v << 1) | mqc_decode(mqc); + v = (v << 1) | mqc_decode(mqc); + v = (v << 1) | mqc_decode(mqc); + /* + if (v!=0xa) { + opg_event_msg(t1->cinfo, EVT_WARNING, "Bad segmentation symbol %x\n", v); + } + */ } -} /* VSC and BYPASS by Antonin */ +} /* VSC and BYPASS by Antonin */ -double t1_getwmsedec(int nmsedec, int compno, int level, int orient, int bpno, int qmfbid, float stepsize, int numcomps) /*mod fixed_quality*/ -{ + +/** mod fixed_quality */ +static double t1_getwmsedec(opj_t1_t *t1, int nmsedec, int compno, int level, int orient, int bpno, int qmfbid, double stepsize, int numcomps) { double w1, w2, wmsedec; if (qmfbid == 1) { w1 = (numcomps > 1) ? mct_getnorm(compno) : 1; w2 = dwt_getnorm(level, orient); - } else { /* if (qmfbid == 0) */ + } 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, float stepsize, int cblksty, int numcomps, tcd_tile_t * tile) /*mod fixed_quality*/ -{ +/** mod fixed_quality */ +static void t1_encode_cblk(opj_t1_t *t1, opj_tcd_cblk_t * cblk, int orient, int compno, int level, int qmfbid, double stepsize, int cblksty, int numcomps, opj_tcd_tile_t * tile) { int i, j; int w, h; int passno; @@ -560,450 +428,282 @@ void t1_encode_cblk(tcd_cblk_t * cblk, int orient, int compno, int level, int qm int nmsedec; double cumwmsedec = 0; char type = T1_TYPE_MQ; - + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + w = cblk->x1 - cblk->x0; h = cblk->y1 - cblk->y0; - + max = 0; for (j = 0; j < h; j++) { for (i = 0; i < w; i++) { - max = int_max(max, int_abs(t1_data[j][i])); + max = int_max(max, int_abs(t1->data[j][i])); } } - + cblk->numbps = max ? (int_floorlog2(max) + 1) - T1_NMSEDEC_FRACBITS : 0; - + /* Changed by Dmitry Kolyadin */ - for (i = 0; i <= w; i++) - for (j = 0; j <= h; j++){ - t1_flags[j][i] = 0; + for (i = 0; i <= w; i++) { + for (j = 0; j <= h; j++) { + t1->flags[j][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); - + + mqc_resetstates(mqc); + mqc_setstate(mqc, T1_CTXNO_UNI, 0, 46); + mqc_setstate(mqc, T1_CTXNO_AGG, 0, 3); + mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4); + mqc_init_enc(mqc, cblk->data); + for (passno = 0; bpno >= 0; passno++) { - tcd_pass_t *pass = &cblk->passes[passno]; + opj_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; - + 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; + case 0: + t1_enc_sigpass(t1, w, h, bpno, orient, &nmsedec, type, cblksty); + break; + case 1: + t1_enc_refpass(t1, w, h, bpno, &nmsedec, type, cblksty); + break; + case 2: + t1_enc_clnpass(t1, w, h, bpno, orient, &nmsedec, cblksty); + /* code switch SEGMARK (i.e. SEGSYM) */ + if (cblksty & J2K_CCP_CBLKSTY_SEGSYM) + mqc_segmark_enc(mqc); + 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*/ - - + + /* fixed_quality */ + cumwmsedec += t1_getwmsedec(t1, nmsedec, compno, level, orient, bpno, qmfbid, stepsize, numcomps); + tile->distotile += t1_getwmsedec(t1, nmsedec, compno, level, orient, bpno, qmfbid, stepsize, numcomps); + /* Code switch "RESTART" (i.e. TERMALL) */ - if ((cblksty & J2K_CCP_CBLKSTY_TERMALL) - && !((passtype == 2) && (bpno - 1 < 0))) { + 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; + mqc_flush(mqc); + correction = 1; + /* correction = mqc_bypass_flush_enc(); */ + } else { /* correction = mqc_restart_enc(); */ + mqc_flush(mqc); + correction = 1; } pass->term = 1; } else { - if (((bpno < (cblk->numbps - 4) && (passtype > 0)) - || ((bpno == (cblk->numbps - 4)) && (passtype == 2))) - && (cblksty & 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; + 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(mqc); + correction = 1; + /* correction = mqc_bypass_flush_enc(); */ + } else { /* correction = mqc_restart_enc(); */ + mqc_flush(mqc); + correction = 1; + } + pass->term = 1; } else { - pass->term = 0; + 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; + 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(); + mqc_bypass_init_enc(mqc); else - mqc_restart_init_enc(); + mqc_restart_init_enc(mqc); } - + pass->distortiondec = cumwmsedec; - pass->rate = mqc_numbytes() + correction; /* FIXME */ - pass->len = - pass->rate - (passno == 0 ? 0 : cblk->passes[passno - 1].rate); - + pass->rate = mqc_numbytes(mqc) + 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(); + mqc_reset_enc(mqc); } - + /* Code switch "ERTERM" (i.e. PTERM) */ if (cblksty & J2K_CCP_CBLKSTY_PTERM) - mqc_erterm_enc(); + mqc_erterm_enc(mqc); else /* Default coding */ if (!(cblksty & J2K_CCP_CBLKSTY_LAZY)) - mqc_flush(); - + mqc_flush(mqc); + cblk->totalpasses = passno; } -void t1_decode_cblk(tcd_cblk_t * cblk, int orient, int roishift, - int cblksty) -{ +static void t1_decode_cblk(opj_t1_t *t1, opj_tcd_cblk_t * cblk, int orient, int roishift, int cblksty) { int i, j, w, h; int bpno, passtype; int segno, passno; - char type = T1_TYPE_MQ; /*BYPASS mode*/ + char type = T1_TYPE_MQ; /* BYPASS mode */ + + opj_raw_t *raw = t1->raw; /* RAW component */ + opj_mqc_t *mqc = t1->mqc; /* MQC component */ w = cblk->x1 - cblk->x0; h = cblk->y1 - cblk->y0; /* Changed by Dmitry Kolyadin */ - for (j = 0; j <= h; j++){ + for (j = 0; j <= h; j++) { for (i = 0; i <= w; i++) { - t1_flags[j][i] = 0; + t1->flags[j][i] = 0; + } } - } - + /* Changed by Dmitry Kolyadin */ for (i = 0; i < w; i++) { - for (j = 0; j < h; j++){ - t1_data[j][i] = 0; - } + for (j = 0; j < h; j++){ + t1->data[j][i] = 0; + } } - + 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); - + + mqc_resetstates(mqc); + mqc_setstate(mqc, T1_CTXNO_UNI, 0, 46); + mqc_setstate(mqc, T1_CTXNO_AGG, 0, 3); + mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4); + for (segno = 0; segno < cblk->numsegs; segno++) { - tcd_seg_t *seg = &cblk->segs[segno]; + opj_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 */ + /* 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(raw, seg->data, seg->len); + } else { + mqc_init_dec(mqc, seg->data, seg->len); + } for (passno = 0; passno < seg->numpasses; passno++) { switch (passtype) { - case 0: - t1_dec_sigpass(w, h, bpno+1, orient, type, cblksty); - break; - case 1: - t1_dec_refpass(w, h, bpno+1, type, cblksty); - break; - case 2: - t1_dec_clnpass(w, h, bpno+1, orient, cblksty); - break; + case 0: + t1_dec_sigpass(t1, w, h, bpno+1, orient, type, cblksty); + break; + case 1: + t1_dec_refpass(t1, w, h, bpno+1, type, cblksty); + break; + case 2: + t1_dec_clnpass(t1, w, h, bpno+1, 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); - + mqc_resetstates(mqc); + mqc_setstate(mqc, T1_CTXNO_UNI, 0, 46); + mqc_setstate(mqc, T1_CTXNO_AGG, 0, 3); + mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4); } - if (++passtype == 3) { - passtype = 0; - bpno--; + 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 / - ((int) floor(band->stepsize * 8192))) >> (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++) { - int tmp=t1_data[j][i]; - if (tmp>>1==0) tilec->data[x + i + (y + j) * (tilec->x1 - tilec->x0)] = 0; - else tilec->data[x + i + (y + j) * (tilec->x1 - tilec->x0)] = tmp<0?(tmp>>1)+1:(tmp>>1); - } - } - } 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++) { - double tmp=t1_data[j][i] * band->stepsize * 4096.0; - int tmp2; - if (t1_data[j][i]>>1 == 0) { - tilec->data[x + i + (y + j) * (tilec->x1 - tilec->x0)] = 0; - } else { - tmp2=((int) (floor(fabs(tmp)))) + ((int) floor(fabs(tmp*2))%2); - tilec->data[x + i + (y + j) * (tilec->x1 - tilec->x0)] = ((tmp<0)?-tmp2:tmp2); - } - } - } - } - } - } - } - } - } -} - -int t1_init_ctxno_zc(int f, int orient) -{ +static int t1_init_ctxno_zc(int f, int orient) { int h, v, d, n, t, hv; n = 0; h = ((f & T1_SIG_W) != 0) + ((f & T1_SIG_E) != 0); v = ((f & T1_SIG_N) != 0) + ((f & T1_SIG_S) != 0); - d = ((f & T1_SIG_NW) != 0) + ((f & T1_SIG_NE) != - 0) + ((f & T1_SIG_SE) != - 0) + ((f & T1_SIG_SW) != 0); + 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; + 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 = 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; + 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; + + return (T1_CTXNO_ZC + n); } -int t1_init_ctxno_sc(int f) -{ +static int t1_init_ctxno_sc(int f) { int hc, vc, n; n = 0; + hc = int_min(((f & (T1_SIG_E | T1_SGN_E)) == - T1_SIG_E) + ((f & (T1_SIG_W | T1_SGN_W)) == T1_SIG_W), - 1) - int_min(((f & (T1_SIG_E | T1_SGN_E)) == - (T1_SIG_E | T1_SGN_E)) + - ((f & (T1_SIG_W | T1_SGN_W)) == - (T1_SIG_W | T1_SGN_W)), 1); + 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); + 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; @@ -1023,61 +723,63 @@ int t1_init_ctxno_sc(int f) else n = 4; } - return T1_CTXNO_SC + n; + + return (T1_CTXNO_SC + n); } -int t1_init_ctxno_mag(int f) -{ +static int t1_init_ctxno_mag(int f) { int n; if (!(f & T1_REFINE)) n = (f & (T1_SIG_OTH)) ? 1 : 0; else n = 2; - return T1_CTXNO_MAG + n; + + return (T1_CTXNO_MAG + n); } -int t1_init_spb(int f) -{ +static int t1_init_spb(int f) { int hc, vc, n; + hc = int_min(((f & (T1_SIG_E | T1_SGN_E)) == - T1_SIG_E) + ((f & (T1_SIG_W | T1_SGN_W)) == T1_SIG_W), - 1) - int_min(((f & (T1_SIG_E | T1_SGN_E)) == - (T1_SIG_E | T1_SGN_E)) + - ((f & (T1_SIG_W | T1_SGN_W)) == - (T1_SIG_W | T1_SGN_W)), 1); + 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); + 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() -{ +static void t1_init_luts(opj_t1_t *t1) { int i, j; double u, v, t; for (j = 0; j < 4; j++) { for (i = 0; i < 256; ++i) { - t1_lut_ctxno_zc[(j << 8) | i] = t1_init_ctxno_zc(i, j); + 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); + 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); + 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); + t1->lut_spb[i] = t1_init_spb(i << 4); } /* FIXME FIXME FIXME */ /* fprintf(stdout,"nmsedec luts:\n"); */ @@ -1085,33 +787,210 @@ void t1_init_luts() t = i / pow(2, T1_NMSEDEC_FRACBITS); u = t; v = t - 1.5; - t1_lut_nmsedec_sig[i] = + 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 - 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)); + (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] = + 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) (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)); + (int) (floor((u * u) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0)); } } + +/* ----------------------------------------------------------------------- */ + +opj_t1_t* t1_create(opj_common_ptr cinfo) { + opj_t1_t *t1 = (opj_t1_t*)opj_malloc(sizeof(opj_t1_t)); + if(t1) { + t1->cinfo = cinfo; + /* create MQC and RAW handles */ + t1->mqc = mqc_create(); + t1->raw = raw_create(); + /* initialize the look-up tables of the Tier-1 coder/decoder */ + t1_init_luts(t1); + } + return t1; +} + +void t1_destroy(opj_t1_t *t1) { + if(t1) { + /* destroy MQC and RAW handles */ + mqc_destroy(t1->mqc); + raw_destroy(t1->raw); + opj_free(t1); + } +} + +void t1_encode_cblks(opj_t1_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp) { + int compno, resno, bandno, precno, cblkno; + int x, y, i, j, orient; + + tile->distotile = 0; /* fixed_quality */ + + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + + for (resno = 0; resno < tilec->numresolutions; resno++) { + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + + for (precno = 0; precno < res->pw * res->ph; precno++) { + opj_tcd_precinct_t *prc = &band->precincts[precno]; + + for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { + opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; + + if (band->bandno == 0) { + x = cblk->x0 - band->x0; + y = cblk->y0 - band->y0; + } else if (band->bandno == 1) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = pres->x1 - pres->x0 + cblk->x0 - band->x0; + y = cblk->y0 - band->y0; + } else if (band->bandno == 2) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = cblk->x0 - band->x0; + y = pres->y1 - pres->y0 + cblk->y0 - band->y0; + } else { /* if (band->bandno == 3) */ + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = pres->x1 - pres->x0 + cblk->x0 - band->x0; + y = pres->y1 - pres->y0 + cblk->y0 - band->y0; + } + + 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 / ((int) floor(band->stepsize * 8192))) >> (13 - T1_NMSEDEC_FRACBITS); + } + } + } + orient = band->bandno; /* FIXME */ + if (orient == 2) { + orient = 1; + } else if (orient == 1) { + orient = 2; + } + + t1_encode_cblk(t1, cblk, orient, compno, tilec->numresolutions - 1 - resno, tcp->tccps[compno].qmfbid, band->stepsize, tcp->tccps[compno].cblksty, tile->numcomps, tile); + + } /* cblkno */ + } /* precno */ + } /* bandno */ + } /* resno */ + } /* compno */ +} + +void t1_decode_cblks(opj_t1_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp) { + int compno, resno, bandno, precno, cblkno; + + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + + for (resno = 0; resno < tilec->numresolutions; resno++) { + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + + for (precno = 0; precno < res->pw * res->ph; precno++) { + opj_tcd_precinct_t *prc = &band->precincts[precno]; + + for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { + int x, y, i, j, orient; + opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; + + orient = band->bandno; /* FIXME */ + if (orient == 2) { + orient = 1; + } else if (orient == 1) { + orient = 2; + } + + t1_decode_cblk(t1, cblk, orient, tcp->tccps[compno].roishift, tcp->tccps[compno].cblksty); + + if (band->bandno == 0) { + x = cblk->x0 - band->x0; + y = cblk->y0 - band->y0; + } else if (band->bandno == 1) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = pres->x1 - pres->x0 + cblk->x0 - band->x0; + y = cblk->y0 - band->y0; + } else if (band->bandno == 2) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = cblk->x0 - band->x0; + y = pres->y1 - pres->y0 + cblk->y0 - band->y0; + } else { /* if (band->bandno == 3) */ + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = pres->x1 - pres->x0 + cblk->x0 - band->x0; + y = pres->y1 - pres->y0 + cblk->y0 - band->y0; + } + + 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++) { + int tmp = t1->data[j][i]; + if(tmp >> 1 == 0) { + tilec->data[x + i + (y + j) * (tilec->x1 - tilec->x0)] = 0; + } else { + tilec->data[x + i + (y + j) * (tilec->x1 - tilec->x0)] = tmp<0?(tmp>>1)+1:(tmp>>1); + } + } + } + } 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++) { + double tmp = (double)(t1->data[j][i] * band->stepsize * 4096.0); + if (t1->data[j][i] >> 1 == 0) { + tilec->data[x + i + (y + j) * (tilec->x1 - tilec->x0)] = 0; + } else { + int tmp2 = ((int) (floor(fabs(tmp)))) + ((int) floor(fabs(tmp*2))%2); + tilec->data[x + i + (y + j) * (tilec->x1 - tilec->x0)] = ((tmp<0)?-tmp2:tmp2); + } + } + } + } + } /* cblkno */ + } /* precno */ + } /* bandno */ + } /* resno */ + } /* compno */ +} + diff --git a/libopenjpeg/t1.h b/libopenjpeg/t1.h index 5e98bc09..6fd4f4cf 100644 --- a/libopenjpeg/t1.h +++ b/libopenjpeg/t1.h @@ -1,5 +1,9 @@ /* - * Copyright (c) 2001-2002, David Janssens + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,27 +30,217 @@ #ifndef __T1_H #define __T1_H +/** +@file t1.h +@brief Implementation of the tier-1 coding (coding of code-block coefficients) (T1) -#include "tcd.h" -#include "j2k.h" +The functions in T1.C have for goal to realize the tier-1 coding operation. The functions +in T1.C are used by some function in TCD.C. +*/ -/* - * Initialize the look-up tables of the Tier-1 coder/decoder - */ -void t1_init_luts(); +/** @defgroup T1 T1 - Implementation of the tier-1 coding */ +/*@{*/ -/* - * 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); +/* ----------------------------------------------------------------------- */ +#define T1_NMSEDEC_BITS 7 -/* - * 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); +#define T1_MAXCBLKW 1024 /**< Maximum size of code-block (width) */ +#define T1_MAXCBLKH 1024 /**< Maximum size of code-block (heigth) */ -#endif +#define T1_SIG_NE 0x0001 /**< Context orientation : North-East direction */ +#define T1_SIG_SE 0x0002 /**< Context orientation : South-East direction */ +#define T1_SIG_SW 0x0004 /**< Context orientation : South-West direction */ +#define T1_SIG_NW 0x0008 /**< Context orientation : North-West direction */ +#define T1_SIG_N 0x0010 /**< Context orientation : North direction */ +#define T1_SIG_E 0x0020 /**< Context orientation : East direction */ +#define T1_SIG_S 0x0040 /**< Context orientation : South direction */ +#define T1_SIG_W 0x0080 /**< Context orientation : West direction */ +#define T1_SIG_OTH (T1_SIG_N|T1_SIG_NE|T1_SIG_E|T1_SIG_SE|T1_SIG_S|T1_SIG_SW|T1_SIG_W|T1_SIG_NW) +#define T1_SIG_PRIM (T1_SIG_N|T1_SIG_E|T1_SIG_S|T1_SIG_W) + +#define T1_SGN_N 0x0100 +#define T1_SGN_E 0x0200 +#define T1_SGN_S 0x0400 +#define T1_SGN_W 0x0800 +#define T1_SGN (T1_SGN_N|T1_SGN_E|T1_SGN_S|T1_SGN_W) + +#define T1_SIG 0x1000 +#define T1_REFINE 0x2000 +#define T1_VISIT 0x4000 + +#define T1_NUMCTXS_AGG 1 +#define T1_NUMCTXS_ZC 9 +#define T1_NUMCTXS_MAG 3 +#define T1_NUMCTXS_SC 5 +#define T1_NUMCTXS_UNI 1 + +#define T1_CTXNO_AGG 0 +#define T1_CTXNO_ZC (T1_CTXNO_AGG+T1_NUMCTXS_AGG) +#define T1_CTXNO_MAG (T1_CTXNO_ZC+T1_NUMCTXS_ZC) +#define T1_CTXNO_SC (T1_CTXNO_MAG+T1_NUMCTXS_MAG) +#define T1_CTXNO_UNI (T1_CTXNO_SC+T1_NUMCTXS_SC) +#define T1_NUMCTXS (T1_CTXNO_UNI+T1_NUMCTXS_UNI) + +#define T1_NMSEDEC_FRACBITS (T1_NMSEDEC_BITS-1) + +#define T1_TYPE_MQ 0 /**< Normal coding using entropy coder */ +#define T1_TYPE_RAW 1 /**< No encoding the information is store under raw format in codestream (mode switch RAW)*/ + +/* ----------------------------------------------------------------------- */ + +/** +Tier-1 coding (coding of code-block coefficients) +*/ +typedef struct opj_t1 { + /** codec context */ + opj_common_ptr cinfo; + + /** MQC component */ + opj_mqc_t *mqc; + /** RAW component */ + opj_raw_t *raw; + + int lut_ctxno_zc[1024]; + int lut_ctxno_sc[256]; + int lut_ctxno_mag[4096]; + int lut_spb[256]; + int lut_nmsedec_sig[1 << T1_NMSEDEC_BITS]; + int lut_nmsedec_sig0[1 << T1_NMSEDEC_BITS]; + int lut_nmsedec_ref[1 << T1_NMSEDEC_BITS]; + int lut_nmsedec_ref0[1 << T1_NMSEDEC_BITS]; + + int data[T1_MAXCBLKH][T1_MAXCBLKW]; + int flags[T1_MAXCBLKH + 2][T1_MAXCBLKH + 2]; + +} opj_t1_t; + +/** @name Local static functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +static int t1_getctxno_zc(opj_t1_t *t1, int f, int orient); +static int t1_getctxno_sc(opj_t1_t *t1, int f); +static int t1_getctxno_mag(opj_t1_t *t1, int f); +static int t1_getspb(opj_t1_t *t1, int f); +static int t1_getnmsedec_sig(opj_t1_t *t1, int x, int bitpos); +static int t1_getnmsedec_ref(opj_t1_t *t1, int x, int bitpos); +static void t1_updateflags(int *fp, int s); +/** +Encode significant pass +*/ +static void t1_enc_sigpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int bpno, int one, int *nmsedec, char type, int vsc); +/** +Decode significant pass +*/ +static void t1_dec_sigpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int oneplushalf, char type, int vsc); +/** +Encode significant pass +*/ +static void t1_enc_sigpass(opj_t1_t *t1, int w, int h, int bpno, int orient, int *nmsedec, char type, int cblksty); +/** +Decode significant pass +*/ +static void t1_dec_sigpass(opj_t1_t *t1, int w, int h, int bpno, int orient, char type, int cblksty); +/** +Encode refinement pass +*/ +static void t1_enc_refpass_step(opj_t1_t *t1, int *fp, int *dp, int bpno, int one, int *nmsedec, char type, int vsc); +/** +Decode refinement pass +*/ +static void t1_dec_refpass_step(opj_t1_t *t1, int *fp, int *dp, int poshalf, int neghalf, char type, int vsc); +/** +Encode refinement pass +*/ +static void t1_enc_refpass(opj_t1_t *t1, int w, int h, int bpno, int *nmsedec, char type, int cblksty); +/** +Decode refinement pass +*/ +static void t1_dec_refpass(opj_t1_t *t1, int w, int h, int bpno, char type, int cblksty); +/** +Encode clean-up pass +*/ +static void t1_enc_clnpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int bpno, int one, int *nmsedec, int partial, int vsc); +/** +Decode clean-up pass +*/ +static void t1_dec_clnpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int oneplushalf, int partial, int vsc); +/** +Encode clean-up pass +*/ +static void t1_enc_clnpass(opj_t1_t *t1, int w, int h, int bpno, int orient, int *nmsedec, int cblksty); +/** +Decode clean-up pass +*/ +static void t1_dec_clnpass(opj_t1_t *t1, int w, int h, int bpno, int orient, int cblksty); +static double t1_getwmsedec(opj_t1_t *t1, int nmsedec, int compno, int level, int orient, int bpno, int qmfbid, double stepsize, int numcomps); +/** +Encode 1 code-block +@param t1 T1 handle +@param cblk Code-block coding parameters +@param orient +@param compno Component number +@param level +@param qmfbid +@param stepsize +@param cblksty Code-block style +@param numcomps +@param tile +*/ +static void t1_encode_cblk(opj_t1_t *t1, opj_tcd_cblk_t * cblk, int orient, int compno, int level, int qmfbid, double stepsize, int cblksty, int numcomps, opj_tcd_tile_t * tile); +/** +Decode 1 code-block +@param t1 T1 handle +@param cblk Code-block coding parameters +@param orient +@param roishift Region of interest shifting value +@param cblksty Code-block style +*/ +static void t1_decode_cblk(opj_t1_t *t1, opj_tcd_cblk_t * cblk, int orient, int roishift, int cblksty); +static int t1_init_ctxno_zc(int f, int orient); +static int t1_init_ctxno_sc(int f); +static int t1_init_ctxno_mag(int f); +static int t1_init_spb(int f); +/** +Initialize the look-up tables of the Tier-1 coder/decoder +@param t1 T1 handle +*/ +static void t1_init_luts(opj_t1_t *t1); + +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Create a new T1 handle +and initialize the look-up tables of the Tier-1 coder/decoder +@return Returns a new T1 handle if successful, returns NULL otherwise +@see t1_init_luts +*/ +opj_t1_t* t1_create(opj_common_ptr cinfo); +/** +Destroy a previously created T1 handle +@param t1 T1 handle to destroy +*/ +void t1_destroy(opj_t1_t *t1); +/** +Encode the code-blocks of a tile +@param t1 T1 handle +@param tile The tile to encode +@param tcp Tile coding parameters +*/ +void t1_encode_cblks(opj_t1_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp); +/** +Decode the code-blocks of a tile +@param t1 T1 handle +@param tile The tile to decode +@param tcp Tile coding parameters +*/ +void t1_decode_cblks(opj_t1_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp); +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __T1_H */ diff --git a/libopenjpeg/t2.c b/libopenjpeg/t2.c index 82eae95c..2fb739e9 100644 --- a/libopenjpeg/t2.c +++ b/libopenjpeg/t2.c @@ -1,7 +1,9 @@ /* - * 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 + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,682 +28,591 @@ * 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 +#include "opj_includes.h" -#define RESTART 0x04 -extern jmp_buf j2k_error; +/* #define RESTART 0x04 */ -void t2_putcommacode(int n) -{ +static void t2_putcommacode(opj_bio_t *bio, int n) { while (--n >= 0) { - bio_write(1, 1); + bio_write(bio, 1, 1); } - bio_write(0, 1); + bio_write(bio, 0, 1); } -int t2_getcommacode() -{ +static int t2_getcommacode(opj_bio_t *bio) { int n; - for (n = 0; bio_read(1); n++) { + for (n = 0; bio_read(bio, 1); n++) { + ; } return n; } -/* */ -/* Variable length code for signalling delta Zil (truncation point) */ -/* n : delta Zil */ -/* <\summary> */ -void t2_putnumpasses(int n) -{ +static void t2_putnumpasses(opj_bio_t *bio, int n) { if (n == 1) { - bio_write(0, 1); + bio_write(bio, 0, 1); } else if (n == 2) { - bio_write(2, 2); + bio_write(bio, 2, 2); } else if (n <= 5) { - bio_write(0xc | (n - 3), 4); + bio_write(bio, 0xc | (n - 3), 4); } else if (n <= 36) { - bio_write(0x1e0 | (n - 6), 9); + bio_write(bio, 0x1e0 | (n - 6), 9); } else if (n <= 164) { - bio_write(0xff80 | (n - 37), 16); + bio_write(bio, 0xff80 | (n - 37), 16); } } -int t2_getnumpasses() -{ +static int t2_getnumpasses(opj_bio_t *bio) { int n; - if (!bio_read(1)) + if (!bio_read(bio, 1)) return 1; - if (!bio_read(1)) + if (!bio_read(bio, 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); + if ((n = bio_read(bio, 2)) != 3) + return (3 + n); + if ((n = bio_read(bio, 5)) != 31) + return (6 + n); + return (37 + bio_read(bio, 7)); } -/* - * 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) -{ +static int t2_encode_packet(opj_t2_t* t2, opj_tcd_tile_t * tile, opj_tcp_t * tcp, opj_pi_iterator_t *pi, unsigned char *dest, int len, opj_image_info_t * image_info, int tileno) { int bandno, cblkno; unsigned char *sop = 0, *eph = 0; - tcd_tilecomp_t *tilec = &tile->comps[compno]; - tcd_resolution_t *res = &tilec->resolutions[resno]; unsigned char *c = dest; + int compno = pi->compno; /* component value */ + int resno = pi->resno; /* resolution level value */ + int precno = pi->precno; /* precinct value */ + int layno = pi->layno; /* quality layer value */ + + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + + opj_bio_t *bio = NULL; /* BIO component */ + /* */ if (tcp->csty & J2K_CP_CSTY_SOP) { - sop = (unsigned char *) malloc(6 * sizeof(unsigned char)); + sop = (unsigned char *) opj_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; + sop[4] = (image_info->num % 65536) / 256; + sop[5] = (image_info->num % 65536) % 256; memcpy(c, sop, 6); - free(sop); + opj_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]; + opj_tcd_band_t *band = &res->bands[bandno]; + opj_tcd_precinct_t *prc = &band->precincts[precno]; tgt_reset(prc->incltree); tgt_reset(prc->imsbtree); for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { - tcd_cblk_t *cblk = &prc->cblks[cblkno]; - cblk->numpasses = 0; - tgt_setvalue(prc->imsbtree, cblkno, band->numbps - cblk->numbps); + opj_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 */ - + + bio = bio_create(); + bio_init_enc(bio, c, len); + bio_write(bio, 1, 1); /* Empty header bit */ + /* Writing Packet header */ for (bandno = 0; bandno < res->numbands; bandno++) { - tcd_band_t *band = &res->bands[bandno]; - tcd_precinct_t *prc = &band->precincts[precno]; + opj_tcd_band_t *band = &res->bands[bandno]; + opj_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]; + opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; + opj_tcd_layer_t *layer = &cblk->layers[layno]; if (!cblk->numpasses && layer->numpasses) { - tgt_setvalue(prc->incltree, cblkno, layno); + 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]; + opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; + opj_tcd_layer_t *layer = &cblk->layers[layno]; int increment = 0; int nump = 0; int len = 0, passno; /* cblk inclusion bits */ if (!cblk->numpasses) { - tgt_encode(prc->incltree, cblkno, layno + 1); + tgt_encode(bio, prc->incltree, cblkno, layno + 1); } else { - bio_write(layer->numpasses != 0, 1); + bio_write(bio, layer->numpasses != 0, 1); } /* if cblk not included, go to the next cblk */ if (!layer->numpasses) { - continue; + continue; } /* if first instance of cblk --> zero bit-planes information */ if (!cblk->numpasses) { - cblk->numlenbits = 3; - tgt_encode(prc->imsbtree, cblkno, 999); + cblk->numlenbits = 3; + tgt_encode(bio, prc->imsbtree, cblkno, 999); } /* number of coding passes included */ - t2_putnumpasses(layer->numpasses); - + t2_putnumpasses(bio, layer->numpasses); + /* computation of the increase of the length indicator and insertion in the header */ - for (passno = cblk->numpasses; - passno < cblk->numpasses + layer->numpasses; passno++) { - 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; - } + for (passno = cblk->numpasses; passno < cblk->numpasses + layer->numpasses; passno++) { + opj_tcd_pass_t *pass = &cblk->passes[passno]; + nump++; + len += pass->len; + if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) { + increment = int_max(increment, int_floorlog2(len) + 1 - (cblk->numlenbits + int_floorlog2(nump))); + len = 0; + nump = 0; + } } - t2_putcommacode(increment); + t2_putcommacode(bio, increment); + /* computation of the new Length indicator */ cblk->numlenbits += increment; - /* insertion of the codeword segment length */ - for (passno = cblk->numpasses; - passno < cblk->numpasses + layer->numpasses; passno++) { - 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; - } + /* insertion of the codeword segment length */ + for (passno = cblk->numpasses; passno < cblk->numpasses + layer->numpasses; passno++) { + opj_tcd_pass_t *pass = &cblk->passes[passno]; + nump++; + len += pass->len; + if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) { + bio_write(bio, len, cblk->numlenbits + int_floorlog2(nump)); + len = 0; + nump = 0; + } } } } + + if (bio_flush(bio)) { + return -999; /* modified to eliminate longjmp !! */ + } + + c += bio_numbytes(bio); - if (bio_flush()) - return -999; /* modified to eliminate longjmp !! */ - - c += bio_numbytes(); - + bio_destroy(bio); + /* */ if (tcp->csty & J2K_CP_CSTY_EPH) { - eph = (unsigned char *) malloc(2 * sizeof(unsigned char)); + eph = (unsigned char *) opj_malloc(2 * sizeof(unsigned char)); eph[0] = 255; eph[1] = 146; memcpy(c, eph, 2); - free(eph); + opj_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]; + opj_tcd_band_t *band = &res->bands[bandno]; + opj_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]; + opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; + opj_tcd_layer_t *layer = &cblk->layers[layno]; if (!layer->numpasses) { - continue; + continue; } if (c + layer->len > dest + len) { - return -999; + 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; - } /* */ + if(image_info && image_info->index_write && image_info->index_on) { + opj_tile_info_t *info_TL = &image_info->tile[tileno]; + opj_packet_info_t *info_PK = &info_TL->packet[image_info->num]; + info_PK->disto += layer->disto; + if (image_info->D_max < info_PK->disto) { + image_info->D_max = info_PK->disto; + } + } + /* */ } } - return c - dest; + + return (c - dest); } -void t2_init_seg(tcd_seg_t * seg, int cblksty, int first) -{ +static void t2_init_seg(opj_tcd_seg_t * seg, int cblksty, int first) { seg->numpasses = 0; seg->len = 0; - if (cblksty & J2K_CCP_CBLKSTY_TERMALL) + if (cblksty & J2K_CCP_CBLKSTY_TERMALL) { seg->maxpasses = 1; + } else if (cblksty & J2K_CCP_CBLKSTY_LAZY) { - if (first) + if (first) { seg->maxpasses = 10; - else - seg->maxpasses = (((seg - 1)->maxpasses == 1) - || ((seg - 1)->maxpasses == 10)) ? 2 : 1; - } else + } 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 t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile, opj_tcp_t *tcp, opj_pi_iterator_t *pi) { int bandno, cblkno; - tcd_tilecomp_t *tilec = &tile->comps[compno]; - tcd_resolution_t *res = &tilec->resolutions[resno]; unsigned char *c = src; + opj_cp_t *cp = t2->cp; + + int compno = pi->compno; /* component value */ + int resno = pi->resno; /* resolution level value */ + int precno = pi->precno; /* precinct value */ + int layno = pi->layno; /* quality layer value */ + + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + unsigned char *hd = NULL; int present; - + + opj_bio_t *bio = NULL; /* BIO component */ + if (layno == 0) { for (bandno = 0; bandno < res->numbands; bandno++) { - tcd_band_t *band = &res->bands[bandno]; - tcd_precinct_t *prc = &band->precincts[precno]; - + opj_tcd_band_t *band = &res->bands[bandno]; + opj_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; + opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; + cblk->numsegs = 0; } } } - - - /* SOP markers*/ - + /* SOP markers */ + if (tcp->csty & J2K_CP_CSTY_SOP) { - if ((*c) != 0xff || (*(c + 1) != 0x91)) { - - fprintf(stderr,"Warning : expected SOP marker\n"); - + opg_event_msg(t2->cinfo, EVT_WARNING, "Expected SOP marker\n"); } else { - c += 6; - } - - /*TODO : check the Nsop value*/ - + + /** TODO : check the Nsop value */ } - - /* When the marker PPT/PPM is used the packet header are store in PPT/PPM marker + + /* + 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 */ + step 2: Return to codestream for decoding + */ - - if (cp->ppm == 1) { /* PPM */ + bio = bio_create(); + + 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 */ + bio_init_dec(bio, hd, cp->ppm_len); + } else if (tcp->ppt == 1) { /* PPT */ hd = tcp->ppt_data; - bio_init_dec(hd, tcp->ppt_len); /*Mod Antonin : ppmbug1*/ - } else { /* Normal Case */ - + bio_init_dec(bio, hd, tcp->ppt_len); + } else { /* Normal Case */ hd = c; - - bio_init_dec(hd, src+len-hd); - + bio_init_dec(bio, hd, src+len-hd); } - present = bio_read(1); - + present = bio_read(bio, 1); + if (!present) { - bio_inalign(); - - hd += bio_numbytes(); - - - - /* EPH markers*/ - + bio_inalign(bio); + hd += bio_numbytes(bio); + bio_destroy(bio); + + /* EPH markers */ + if (tcp->csty & J2K_CP_CSTY_EPH) { - if ((*hd) != 0xff || (*(hd + 1) != 0x92)) { - - printf("Error : expected EPH marker\n"); - + printf("Error : expected EPH marker\n"); } else { - - hd += 2; - + hd += 2; } - } - - if (cp->ppm == 1) { /* PPM case */ - - cp->ppm_len+=cp->ppm_data-hd; + + if (cp->ppm == 1) { /* PPM case */ + cp->ppm_len += cp->ppm_data-hd; cp->ppm_data = hd; - return c - src; + return (c - src); } - if (tcp->ppt == 1) { /* PPT case */ - + if (tcp->ppt == 1) { /* PPT case */ tcp->ppt_len+=tcp->ppt_data-hd; tcp->ppt_data = hd; - return c - src; + return (c - src); } - - - return hd - 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*/ - + opj_tcd_band_t *band = &res->bands[bandno]; + opj_tcd_precinct_t *prc = &band->precincts[precno]; + if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)) 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; + opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; + opj_tcd_seg_t *seg = NULL; /* if cblk not yet included before --> inclusion tagtree */ if (!cblk->numsegs) { - included = tgt_decode(prc->incltree, cblkno, layno + 1); - /* else one bit */ + included = tgt_decode(bio, prc->incltree, cblkno, layno + 1); + /* else one bit */ } else { - included = bio_read(1); + included = bio_read(bio, 1); } /* if cblk not included */ if (!included) { - cblk->numnewpasses = 0; - continue; + 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; + int i, numimsbs; + for (i = 0; !tgt_decode(bio, prc->imsbtree, cblkno, i); i++) { + ; + } + numimsbs = i - 1; + cblk->numbps = band->numbps - numimsbs; + cblk->numlenbits = 3; } /* number of coding passes */ - cblk->numnewpasses = t2_getnumpasses(); - increment = t2_getcommacode(); + cblk->numnewpasses = t2_getnumpasses(bio); + increment = t2_getcommacode(bio); /* length indicator increment */ cblk->numlenbits += increment; if (!cblk->numsegs) { - seg = &cblk->segs[0]; - t2_init_seg(seg, tcp->tccps[compno].cblksty, 1); + 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); - } + 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); - } + seg->numnewpasses = int_min(seg->maxpasses - seg->numpasses, n); + seg->newlen = bio_read(bio, cblk->numlenbits + int_floorlog2(seg->numnewpasses)); + n -= seg->numnewpasses; + if (n > 0) { + t2_init_seg(++seg, tcp->tccps[compno].cblksty, 0); + } } while (n > 0); } } - if (bio_inalign()) + + if (bio_inalign(bio)) { + bio_destroy(bio); return -999; - - hd += bio_numbytes(); - - - /* EPH markers*/ + } + + hd += bio_numbytes(bio); + bio_destroy(bio); + + /* EPH markers */ if (tcp->csty & J2K_CP_CSTY_EPH) { if ((*hd) != 0xff || (*(hd + 1) != 0x92)) { - fprintf(stderr,"Error : expected EPH marker\n"); + opg_event_msg(t2->cinfo, EVT_ERROR, "Expected EPH marker\n"); } else { hd += 2; - } } - - - + if (cp->ppm==1) { - cp->ppm_len+=cp->ppm_data-hd; - cp->ppm_data = hd; - } else if (tcp->ppt == 1) { - tcp->ppt_len+=tcp->ppt_data-hd; - tcp->ppt_data = hd; - } else { - c=hd; - } - + for (bandno = 0; bandno < res->numbands; bandno++) { - tcd_band_t *band = &res->bands[bandno]; - tcd_precinct_t *prc = &band->precincts[precno]; - - - - /*Add Antonin : sizebug1*/ - + opj_tcd_band_t *band = &res->bands[bandno]; + opj_tcd_precinct_t *prc = &band->precincts[precno]; + if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)) continue; - - /*ddA*/ - - + for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { - tcd_cblk_t *cblk = &prc->cblks[cblkno]; - tcd_seg_t *seg; + opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; + opj_tcd_seg_t *seg = NULL; if (!cblk->numnewpasses) - continue; + continue; if (!cblk->numsegs) { - seg = &cblk->segs[0]; - - cblk->numsegs++; - cblk->len = 0; + seg = &cblk->segs[0]; + cblk->numsegs++; + cblk->len = 0; } else { - seg = &cblk->segs[cblk->numsegs - 1]; - if (seg->numpasses == seg->maxpasses) { - seg++; - cblk->numsegs++; - } + 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++; - } + 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; + + 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) -{ +int t2_encode_packets(opj_t2_t* t2, int tileno, opj_tcd_tile_t *tile, int maxlayers, unsigned char *dest, int len, opj_image_info_t *image_info) { unsigned char *c = dest; int e = 0; - pi_iterator_t *pi; - int pino, compno; - - pi = pi_create(img, cp, tileno); + opj_pi_iterator_t *pi = NULL; + int pino; + opj_image_t *image = t2->image; + opj_cp_t *cp = t2->cp; + + /* create a packet iterator */ + pi = pi_create(image, cp, tileno); + if(!pi) { + /* TODO: throw an error */ + return -999; + } + for (pino = 0; pino <= cp->tcps[tileno].numpocs; pino++) { while (pi_next(&pi[pino])) { if (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; + e = t2_encode_packet(t2, tile, &cp->tcps[tileno], &pi[pino], c, dest + len - c, image_info, tileno); + if (e == -999) { + break; + } else { + c += e; + } + + /* INDEX >> */ + if(image_info && image_info->index_on) { + if(image_info->index_write) { + opj_tile_info_t *info_TL = &image_info->tile[tileno]; + opj_packet_info_t *info_PK = &info_TL->packet[image_info->num]; + if (!image_info->num) { + info_PK->start_pos = info_TL->end_header + 1; + } else { + info_PK->start_pos = info_TL->packet[image_info->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++; - } + image_info->num++; + } + /* << INDEX */ } - } - - /* 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) + + /* don't forget to release pi */ + pi_destroy(pi, cp, tileno); + + if (e == -999) { return e; - else - return c - dest; + } + + 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) -{ +int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj_tcd_tile_t *tile) { unsigned char *c = src; - pi_iterator_t *pi; - int pino, compno, e = 0; + opj_pi_iterator_t *pi; + int pino, e = 0; int n = 0; - pi = pi_create(img, cp, tileno); - + opj_image_t *image = t2->image; + opj_cp_t *cp = t2->cp; + + /* create a packet iterator */ + pi = pi_create(image, cp, tileno); + if(!pi) { + /* TODO: throw an error */ + return -999; + } + for (pino = 0; pino <= cp->tcps[tileno].numpocs; pino++) { while (pi_next(&pi[pino])) { - if ((cp->layer==0) || (cp->layer>=((pi[pino].layno)+1))) { - e = t2_decode_packet(c, src + len - c, tile, cp, - &cp->tcps[tileno], pi[pino].compno, - pi[pino].resno, pi[pino].precno, - pi[pino].layno); + e = t2_decode_packet(t2, c, src + len - c, tile, &cp->tcps[tileno], &pi[pino]); } else { - e = 0; + e = 0; } /* 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; + image->comps[pi[pino].compno].resno_decoded = + (e > 0) ? + int_max(pi[pino].resno, image->comps[pi[pino].compno].resno_decoded) + : image->comps[pi[pino].compno].resno_decoded; n++; - if (e == -999) { /* ADD */ - break; + if (e == -999) { /* ADD */ + break; } else { - c += e; + 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) + /* don't forget to release pi */ + pi_destroy(pi, cp, tileno); + + if (e == -999) { return e; - else - return c - src; + } + + return (c - src); } + +/* ----------------------------------------------------------------------- */ + +opj_t2_t* t2_create(opj_common_ptr cinfo, opj_image_t *image, opj_cp_t *cp) { + /* create the tcd structure */ + opj_t2_t *t2 = (opj_t2_t*)opj_malloc(sizeof(opj_t2_t)); + if(!t2) return NULL; + t2->cinfo = cinfo; + t2->image = image; + t2->cp = cp; + + return t2; +} + +void t2_destroy(opj_t2_t *t2) { + if(t2) { + opj_free(t2); + } +} + diff --git a/libopenjpeg/t2.h b/libopenjpeg/t2.h index 795fb53f..3576b253 100644 --- a/libopenjpeg/t2.h +++ b/libopenjpeg/t2.h @@ -1,7 +1,9 @@ /* - * Copyright (c) 2001-2002, David Janssens + * 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 + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,37 +30,118 @@ #ifndef __T2_H #define __T2_H +/** +@file t2.h +@brief Implementation of a tier-2 coding (packetization of code-block data) (T2) -#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 +/** @defgroup T2 T2 - Implementation of a tier-2 coding */ +/*@{*/ + +/** +Tier-2 coding +*/ +typedef struct opj_t2 { + /** codec context */ + opj_common_ptr cinfo; + + /** Encoding: pointer to the src image. Decoding: pointer to the dst image. */ + opj_image_t *image; + /** pointer to the image coding parameters */ + opj_cp_t *cp; +} opj_t2_t; + +/** @name Local static functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ + +static void t2_putcommacode(opj_bio_t *bio, int n); +static int t2_getcommacode(opj_bio_t *bio); +/** +Variable length code for signalling delta Zil (truncation point) +@param bio Bit Input/Output component +@param n delta Zil +*/ +static void t2_putnumpasses(opj_bio_t *bio, int n); +static int t2_getnumpasses(opj_bio_t *bio); +/** +Encode a packet of a tile to a destination buffer +@param t2 T2 handle +@param tile Tile for which to write the packets +@param tcp Tile coding parameters +@param pi Packet identity +@param dest Destination buffer +@param len Length of the destination buffer +@param image_info Structure to create an index file +@param tileno Number of the tile encoded +@return +*/ +static int t2_encode_packet(opj_t2_t* t2, opj_tcd_tile_t *tile, opj_tcp_t *tcp, opj_pi_iterator_t *pi, unsigned char *dest, int len, opj_image_info_t *image_info, int tileno); +/** +@param seg +@param cblksty +@param first +*/ +static void t2_init_seg(opj_tcd_seg_t *seg, int cblksty, int first); +/** +Decode a packet of a tile from a source buffer +@param t2 T2 handle +@param src Source buffer +@param len Length of the source buffer +@param tile Tile for which to write the packets +@param tcp Tile coding parameters +@param pi Packet identity +@return +*/ +int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile, opj_tcp_t *tcp, opj_pi_iterator_t *pi); + +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ + +/** +Encode the packets of a tile to a destination buffer +@param t2 T2 handle +@param tileno number of the tile encoded +@param tile the tile for which to write the packets +@param maxlayers maximum number of layers +@param dest the destination buffer +@param len the length of the destination buffer +@param image_info structure to create an index file +*/ +int t2_encode_packets(opj_t2_t* t2, int tileno, opj_tcd_tile_t *tile, int maxlayers, unsigned char *dest, int len, opj_image_info_t *image_info); + +/** +Decode the packets of a tile from a source buffer +@param t2 T2 handle +@param src the source buffer +@param len length of the source buffer +@param tileno number that identifies the tile for which to decode the packets +@param tile tile for which to decode the packets */ -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); +int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj_tcd_tile_t *tile); -/* - * 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); +/** +Create a T2 handle +@param cinfo Codec context info +@param image Source or destination image +@param cp Image coding parameters +@return Returns a new T2 handle if successful, returns NULL otherwise +*/ +opj_t2_t* t2_create(opj_common_ptr cinfo, opj_image_t *image, opj_cp_t *cp); +/** +Destroy a T2 handle +@param t2 T2 handle to destroy +*/ +void t2_destroy(opj_t2_t *t2); -#endif +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __T2_H */ diff --git a/libopenjpeg/tcd.c b/libopenjpeg/tcd.c index f6429f09..be35f203 100644 --- a/libopenjpeg/tcd.c +++ b/libopenjpeg/tcd.c @@ -1,7 +1,9 @@ /* - * 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 + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,1631 +28,1392 @@ * 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 +#include "opj_includes.h" -static tcd_image_t tcd_image; - -static j2k_image_t *tcd_img; -static j2k_cp_t *tcd_cp; - -static tcd_tile_t *tcd_tile; -static j2k_tcp_t *tcd_tcp; -static int tcd_tileno; - -static tcd_tile_t *tile; -static tcd_tilecomp_t *tilec; -static tcd_resolution_t *res; -static tcd_band_t *band; -static tcd_precinct_t *prc; -static tcd_cblk_t *cblk; - -extern jmp_buf j2k_error; - -void tcd_dump(tcd_image_t * img, int curtileno) -{ +void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_image_t * img, int curtileno) { int tileno, compno, resno, bandno, precno, cblkno; - (void)curtileno; - fprintf(stdout, "image {\n"); - fprintf(stdout, " 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); + + fprintf(fd, "image {\n"); + fprintf(fd, " tw=%d, th=%d x0=%d x1=%d y0=%d y1=%d\n", + img->tw, img->th, tcd->image->x0, tcd->image->x1, tcd->image->y0, tcd->image->y1); + for (tileno = 0; tileno < img->th * img->tw; tileno++) { - tcd_tile_t *tile = &tcd_image.tiles[tileno]; - fprintf(stdout, " tile {\n"); - fprintf(stdout, " x0=%d, y0=%d, x1=%d, y1=%d, numcomps=%d\n", - tile->x0, tile->y0, tile->x1, tile->y1, tile->numcomps); + opj_tcd_tile_t *tile = &tcd->tcd_image->tiles[tileno]; + fprintf(fd, " tile {\n"); + fprintf(fd, " 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(stdout, " tilec {\n"); - fprintf(stdout, - " x0=%d, y0=%d, x1=%d, y1=%d, numresolutions=%d\n", - tilec->x0, tilec->y0, tilec->x1, tilec->y1, - tilec->numresolutions); + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + fprintf(fd, " tilec {\n"); + fprintf(fd, + " 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(stdout, "\n res {\n"); - fprintf(stdout, - " 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(stdout, " band {\n"); - fprintf(stdout, - " x0=%d, y0=%d, x1=%d, y1=%d, stepsize=%f, 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(stdout, " prec {\n"); - fprintf(stdout, - " 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(stdout, " cblk {\n"); - fprintf(stdout, - " x0=%d, y0=%d, x1=%d, y1=%d\n", - cblk->x0, cblk->y0, cblk->x1, cblk->y1); - fprintf(stdout, " }\n"); - } - fprintf(stdout, " }\n"); - } - fprintf(stdout, " }\n"); - } - fprintf(stdout, " }\n"); + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + fprintf(fd, "\n res {\n"); + fprintf(fd, + " 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++) { + opj_tcd_band_t *band = &res->bands[bandno]; + fprintf(fd, " band {\n"); + fprintf(fd, + " 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++) { + opj_tcd_precinct_t *prec = &band->precincts[precno]; + fprintf(fd, " prec {\n"); + fprintf(fd, + " 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++) { + opj_tcd_cblk_t *cblk = &prec->cblks[cblkno]; + fprintf(fd, " cblk {\n"); + fprintf(fd, + " x0=%d, y0=%d, x1=%d, y1=%d\n", + cblk->x0, cblk->y0, cblk->x1, cblk->y1); + fprintf(fd, " }\n"); + } + fprintf(fd, " }\n"); + } + fprintf(fd, " }\n"); + } + fprintf(fd, " }\n"); } - fprintf(stdout, " }\n"); + fprintf(fd, " }\n"); } - fprintf(stdout, " }\n"); + fprintf(fd, " }\n"); } - fprintf(stdout, "}\n"); + fprintf(fd, "}\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] = 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)) : 0; /*Mod antonin losslessbug*/ - if (tcp->rates[j]) { - if (j && tcp->rates[j] < tcp->rates[j - 1] + 10) { - tcp->rates[j] = tcp->rates[j - 1] + 20; - } else { - if (!j && tcp->rates[j] < 30) - tcp->rates[j] = 30; - } - } - } - /* << Modification of the RATE */ - - tile->comps = - (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 = (float)((1.0 + ss->mant / 2048.0) * pow(2.0, numbps - ss->expn)); - 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); - } - } - } - } - } +/** +Create a new TCD handle +*/ +opj_tcd_t* tcd_create(opj_common_ptr cinfo) { + /* create the tcd structure */ + opj_tcd_t *tcd = (opj_tcd_t*)opj_malloc(sizeof(opj_tcd_t)); + if(!tcd) return NULL; + tcd->cinfo = cinfo; + tcd->tcd_image = (opj_tcd_image_t*)opj_malloc(sizeof(opj_tcd_image_t)); + if(!tcd->tcd_image) { + opj_free(tcd); + return NULL; } - /* tcd_dump(&tcd_image,curtileno); */ + + return tcd; } -void tcd_free_encode(j2k_image_t * img, j2k_cp_t * cp, int curtileno) -{ - int tileno, compno, resno, bandno, precno; - (void)curtileno; - 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); +/** +Destroy a previously created TCD handle +*/ +void tcd_destroy(opj_tcd_t *tcd) { + if(tcd) { + opj_free(tcd->tcd_image); + opj_free(tcd); + } } -void tcd_init_encode(j2k_image_t * img, j2k_cp_t * cp, int curtileno) -{ +/* ----------------------------------------------------------------------- */ + +void tcd_malloc_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int curtileno) { int tileno, compno, resno, bandno, precno, cblkno; + opj_tcd_tile_t *tile = NULL; /* pointer to tcd->tile */ + opj_tcd_tilecomp_t *tilec = NULL; /* pointer to tcd->tilec */ + opj_tcd_resolution_t *res = NULL; /* pointer to tcd->res */ + opj_tcd_band_t *band = NULL; /* pointer to tcd->band */ + opj_tcd_precinct_t *prc = NULL; /* pointer to tcd->prc */ + opj_tcd_cblk_t *cblk = NULL; /* pointer to tcd->cblk */ + + tcd->image = image; + tcd->cp = cp; + tcd->tcd_image->tw = cp->tw; + tcd->tcd_image->th = cp->th; + tcd->tcd_image->tiles = (opj_tcd_tile_t *) opj_malloc(sizeof(opj_tcd_tile_t)); + for (tileno = 0; tileno < 1; tileno++) { - j2k_tcp_t *tcp = &cp->tcps[curtileno]; + opj_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; + 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 */ + + /* opj_tcd_tile_t *tile=&tcd->tcd_image->tiles[tileno]; */ + tcd->tile = tcd->tcd_image->tiles; + tile = tcd->tile; /* 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->x0 = int_max(cp->tx0 + p * cp->tdx, image->x0); + tile->y0 = int_max(cp->ty0 + q * cp->tdy, image->y0); + tile->x1 = int_min(cp->tx0 + (p + 1) * cp->tdx, image->x1); + tile->y1 = int_min(cp->ty0 + (q + 1) * cp->tdy, image->y1); + tile->numcomps = image->numcomps; + /* tile->PPT=image->PPT; */ - tile->numcomps = img->numcomps; - /* tile->PPT=img->PPT; */ /* Modification of the RATE >> */ for (j = 0; j < tcp->numlayers; j++) { - tcp->rates[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)) : 0; /*Mod antonin losslessbug*/ + tcp->rates[j] = tcp->rates[j] ? + int_ceildiv(tile->numcomps + * (tile->x1 - tile->x0) + * (tile->y1 - tile->y0) + * image->comps[0].prec, + (tcp->rates[j] * 8 * image->comps[0].dx * image->comps[0].dy)) + : 0; + if (tcp->rates[j]) { - if (j && tcp->rates[j] < tcp->rates[j - 1] + 10) { - tcp->rates[j] = tcp->rates[j - 1] + 20; - } else { - if (!j && tcp->rates[j] < 30) - tcp->rates[j] = 30; - } - } - } - /* << Modification of the RATE */ - /* tile->comps=(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 = (float)((1.0 + ss->mant / 2048.0) * pow(2.0, numbps - ss->expn)); - band->numbps = ss->expn + tccp->numgbits - 1; /* WHY -1 ? */ - - for (precno = 0; precno < res->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, p, q; - unsigned int x0 = 0, y0 = 0, x1 = 0, y1 = 0, w, h; - 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 = (float)((1.0 + ss->mant / 2048.0) * pow(2.0, numbps - ss->expn)); - band->numbps = ss->expn + tccp->numgbits - 1; /* WHY -1 ? */ - - band->precincts = - (tcd_precinct_t *) malloc(res->pw * res->ph * - sizeof(tcd_precinct_t)); - - for (precno = 0; precno < res->pw * res->ph; precno++) { - int tlcblkxstart, tlcblkystart, brcblkxend, brcblkyend; - int cbgxstart = - tlcbgxstart + (precno % res->pw) * (1 << cbgwidthexpn); - int cbgystart = - tlcbgystart + (precno / res->pw) * (1 << cbgheightexpn); - int cbgxend = cbgxstart + (1 << cbgwidthexpn); - int cbgyend = cbgystart + (1 << cbgheightexpn); - tcd_precinct_t *prc = &band->precincts[precno]; - /* precinct size (global) */ - prc->x0 = int_max(cbgxstart, band->x0); - prc->y0 = int_max(cbgystart, band->y0); - prc->x1 = int_min(cbgxend, band->x1); - prc->y1 = int_min(cbgyend, band->y1); - - tlcblkxstart = - int_floordivpow2(prc->x0, cblkwidthexpn) << cblkwidthexpn; - tlcblkystart = - int_floordivpow2(prc->y0, cblkheightexpn) << cblkheightexpn; - brcblkxend = - int_ceildivpow2(prc->x1, cblkwidthexpn) << cblkwidthexpn; - brcblkyend = - int_ceildivpow2(prc->y1, cblkheightexpn) << cblkheightexpn; - prc->cw = (brcblkxend - tlcblkxstart) >> cblkwidthexpn; - prc->ch = (brcblkyend - tlcblkystart) >> cblkheightexpn; - - prc->cblks = - (tcd_cblk_t *) malloc(prc->cw * prc->ch * - sizeof(tcd_cblk_t)); - - prc->incltree = tgt_create(prc->cw, prc->ch); - prc->imsbtree = tgt_create(prc->cw, prc->ch); - - for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { - int cblkxstart = - tlcblkxstart + (cblkno % prc->cw) * (1 << cblkwidthexpn); - int cblkystart = - tlcblkystart + (cblkno / prc->cw) * (1 << cblkheightexpn); - int cblkxend = cblkxstart + (1 << cblkwidthexpn); - int cblkyend = cblkystart + (1 << cblkheightexpn); - tcd_cblk_t *cblk = &prc->cblks[cblkno]; - /* code-block size (global) */ - cblk->x0 = int_max(cblkxstart, prc->x0); - cblk->y0 = int_max(cblkystart, prc->y0); - cblk->x1 = int_min(cblkxend, prc->x1); - cblk->y1 = int_min(cblkyend, prc->y1); - } - } - } - } - } - } - /*tcd_dump(&tcd_image,0);*/ - - - /* 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, - (unsigned int) - tcd_image. - tiles - [tileno]. - comps - [i].x0); - y0 = - j == 0 ? tcd_image.tiles[tileno].comps[i].y0 : int_min(y0, - (unsigned int) - tcd_image. - tiles - [tileno]. - comps[i]. - y0); - x1 = - j == 0 ? tcd_image.tiles[tileno].comps[i].x1 : int_max(x1, - (unsigned int) - tcd_image. - tiles - [tileno]. - comps[i]. - x1); - y1 = - j == 0 ? tcd_image.tiles[tileno].comps[i].y1 : int_max(y1, - (unsigned int) - tcd_image. - tiles - [tileno]. - comps[i]. - y1); - } - - 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)); + if (j && tcp->rates[j] < tcp->rates[j - 1] + 10) { + tcp->rates[j] = tcp->rates[j - 1] + 20; + } else { + if (!j && tcp->rates[j] < 30) + tcp->rates[j] = 30; } } } + /* << Modification of the RATE */ + + tile->comps = (opj_tcd_tilecomp_t *) opj_malloc(image->numcomps * sizeof(opj_tcd_tilecomp_t)); + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tccp_t *tccp = &tcp->tccps[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; - 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 */ + /* opj_tcd_tilecomp_t *tilec=&tile->comps[compno]; */ + tcd->tilec = &tile->comps[compno]; + tilec = tcd->tilec; - 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; - } - } + /* border of each tile component (global) */ + tilec->x0 = int_ceildiv(tile->x0, image->comps[compno].dx); + tilec->y0 = int_ceildiv(tile->y0, image->comps[compno].dy); + tilec->x1 = int_ceildiv(tile->x1, image->comps[compno].dx); + tilec->y1 = int_ceildiv(tile->y1, image->comps[compno].dy); + + tilec->data = (int *) opj_malloc((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0) * sizeof(int)); + tilec->numresolutions = tccp->numresolutions; - if (layno == 0) - cblk->numpassesinlayers = 0; + tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(tilec->numresolutions * sizeof(opj_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; - 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; + /* opj_tcd_resolution_t *res=&tilec->resolutions[resno]; */ + tcd->res = &tilec->resolutions[resno]; + res = tcd->res; + + /* 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; + opj_stepsize_t *ss = NULL; - layer->numpasses = n - cblk->numpassesinlayers; + tcd->band = &res->bands[bandno]; + band = tcd->band; - if (!layer->numpasses) - continue; + 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 = image->comps[compno].prec + gain; + + band->stepsize = (float)((1.0 + ss->mant / 2048.0) * pow(2.0, numbps - ss->expn)); + band->numbps = ss->expn + tccp->numgbits - 1; /* WHY -1 ? */ + + band->precincts = (opj_tcd_precinct_t *) opj_malloc(3 * res->pw * res->ph * sizeof(opj_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; - 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; - } - } + 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); + + /* opj_tcd_precinct_t *prc=&band->precincts[precno]; */ + tcd->prc = &band->precincts[precno]; + prc = tcd->prc; + + /* precinct size (global) */ + prc->x0 = int_max(cbgxstart, band->x0); + prc->y0 = int_max(cbgystart, band->y0); + prc->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 = (opj_tcd_cblk_t *) opj_malloc((prc->cw * prc->ch) * sizeof(opj_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 = &prc->cblks[cblkno]; + cblk = tcd->cblk; + + /* code-block size (global) */ + cblk->x0 = int_max(cblkxstart, prc->x0); + cblk->y0 = int_max(cblkystart, prc->y0); + cblk->x1 = int_min(cblkxend, prc->x1); + cblk->y1 = int_min(cblkyend, prc->y1); + } + } + } } } } + + /* tcd_dump(stdout, tcd, &tcd->tcd_image, curtileno); */ } -void tcd_rateallocate_fixed() -{ - int layno; +void tcd_free_encode(opj_tcd_t *tcd) { + int tileno, compno, resno, bandno, precno; - for (layno = 0; layno < tcd_tcp->numlayers; layno++) { - tcd_makelayer_fixed(layno, 1); + opj_tcd_tile_t *tile = NULL; /* pointer to tcd->tile */ + opj_tcd_tilecomp_t *tilec = NULL; /* pointer to tcd->tilec */ + opj_tcd_resolution_t *res = NULL; /* pointer to tcd->res */ + opj_tcd_band_t *band = NULL; /* pointer to tcd->band */ + opj_tcd_precinct_t *prc = NULL; /* pointer to tcd->prc */ + + for (tileno = 0; tileno < 1; tileno++) { + tcd->tile = tcd->tcd_image->tiles; + tile = tcd->tile; + + for (compno = 0; compno < tile->numcomps; compno++) { + tcd->tilec = &tile->comps[compno]; + tilec = tcd->tilec; + + for (resno = 0; resno < tilec->numresolutions; resno++) { + tcd->res = &tilec->resolutions[resno]; + res = tcd->res; + + for (bandno = 0; bandno < res->numbands; bandno++) { + tcd->band = &res->bands[bandno]; + band = tcd->band; + + for (precno = 0; precno < res->pw * res->ph; precno++) { + tcd->prc = &band->precincts[precno]; + prc = tcd->prc; + + if (prc->incltree != NULL) { + tgt_destroy(prc->incltree); + prc->incltree = NULL; + } + if (prc->imsbtree != NULL) { + tgt_destroy(prc->imsbtree); + prc->imsbtree = NULL; + } + opj_free(prc->cblks); + prc->cblks = NULL; + } /* for (precno */ + opj_free(band->precincts); + band->precincts = NULL; + } /* for (bandno */ + } /* for (resno */ + opj_free(tilec->resolutions); + tilec->resolutions = NULL; + } /* for (compno */ + opj_free(tile->comps); + tile->comps = NULL; + } /* for (tileno */ + opj_free(tcd->tcd_image->tiles); + tcd->tcd_image->tiles = NULL; +} + +void tcd_init_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int curtileno) { + int tileno, compno, resno, bandno, precno, cblkno; + + opj_tcd_tile_t *tile = NULL; /* pointer to tcd->tile */ + opj_tcd_tilecomp_t *tilec = NULL; /* pointer to tcd->tilec */ + opj_tcd_resolution_t *res = NULL; /* pointer to tcd->res */ + opj_tcd_band_t *band = NULL; /* pointer to tcd->band */ + opj_tcd_precinct_t *prc = NULL; /* pointer to tcd->prc */ + opj_tcd_cblk_t *cblk = NULL; /* pointer to tcd->cblk */ + + for (tileno = 0; tileno < 1; tileno++) { + opj_tcp_t *tcp = &cp->tcps[curtileno]; + int j; + /* cfr p59 ISO/IEC FDIS15444-1 : 2000 (18 august 2000) */ + int p = curtileno % cp->tw; + int q = curtileno / cp->tw; + + tcd->tile = tcd->tcd_image->tiles; + tile = tcd->tile; + + /* 4 borders of the tile rescale on the image if necessary */ + tile->x0 = int_max(cp->tx0 + p * cp->tdx, image->x0); + tile->y0 = int_max(cp->ty0 + q * cp->tdy, image->y0); + tile->x1 = int_min(cp->tx0 + (p + 1) * cp->tdx, image->x1); + tile->y1 = int_min(cp->ty0 + (q + 1) * cp->tdy, image->y1); + + tile->numcomps = image->numcomps; + /* tile->PPT=image->PPT; */ + + /* Modification of the RATE >> */ + for (j = 0; j < tcp->numlayers; j++) { + tcp->rates[j] = tcp->rates[j] ? + int_ceildiv(tile->numcomps + * (tile->x1 - tile->x0) + * (tile->y1 - tile->y0) + * image->comps[0].prec, + (tcp->rates[j] * 8 * image->comps[0].dx * image->comps[0].dy)) + : 0; + + if (tcp->rates[j]) { + if (j && tcp->rates[j] < tcp->rates[j - 1] + 10) { + tcp->rates[j] = tcp->rates[j - 1] + 20; + } else { + if (!j && tcp->rates[j] < 30) + tcp->rates[j] = 30; + } + } + } + /* << Modification of the RATE */ + + /* tile->comps=(opj_tcd_tilecomp_t*)j2k_realloc(tile->comps,image->numcomps*sizeof(opj_tcd_tilecomp_t)); */ + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tccp_t *tccp = &tcp->tccps[compno]; + + tcd->tilec = &tile->comps[compno]; + tilec = tcd->tilec; + + /* border of each tile component (global) */ + tilec->x0 = int_ceildiv(tile->x0, image->comps[compno].dx); + tilec->y0 = int_ceildiv(tile->y0, image->comps[compno].dy); + tilec->x1 = int_ceildiv(tile->x1, image->comps[compno].dx); + tilec->y1 = int_ceildiv(tile->y1, image->comps[compno].dy); + + tilec->data = (int *) opj_malloc((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0) * sizeof(int)); + tilec->numresolutions = tccp->numresolutions; + /* tilec->resolutions=(opj_tcd_resolution_t*)j2k_realloc(tilec->resolutions,tilec->numresolutions*sizeof(opj_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->res = &tilec->resolutions[resno]; + res = tcd->res; + + /* 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; + opj_stepsize_t *ss = NULL; + + tcd->band = &res->bands[bandno]; + band = tcd->band; + + 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 = image->comps[compno].prec + gain; + band->stepsize = (float)((1.0 + ss->mant / 2048.0) * pow(2.0, numbps - ss->expn)); + band->numbps = ss->expn + tccp->numgbits - 1; /* WHY -1 ? */ + + for (precno = 0; precno < res->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->prc = &band->precincts[precno]; + prc = tcd->prc; + + /* precinct size (global) */ + prc->x0 = int_max(cbgxstart, band->x0); + prc->y0 = int_max(cbgystart, band->y0); + prc->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; + + opj_free(prc->cblks); + prc->cblks = (opj_tcd_cblk_t *) opj_malloc(prc->cw * prc->ch * sizeof(opj_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); + + tcd->cblk = &prc->cblks[cblkno]; + cblk = tcd->cblk; + + /* code-block size (global) */ + cblk->x0 = int_max(cblkxstart, prc->x0); + cblk->y0 = int_max(cblkystart, prc->y0); + cblk->x1 = int_min(cblkxend, prc->x1); + cblk->y1 = int_min(cblkyend, prc->y1); + } + } /* precno */ + } /* bandno */ + } /* resno */ + } /* compno */ + } /* tileno */ + + /* tcd_dump(stdout, tcd, &tcd->tcd_image,0); */ +} + +void tcd_malloc_decode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp) { + int tileno, compno, resno, bandno, precno, cblkno, i, j, p, q; + unsigned int x0 = 0, y0 = 0, x1 = 0, y1 = 0, w, h; + + tcd->image = image; + tcd->cp = cp; + tcd->tcd_image->tw = cp->tw; + tcd->tcd_image->th = cp->th; + tcd->tcd_image->tiles = (opj_tcd_tile_t *) opj_malloc(cp->tw * cp->th * sizeof(opj_tcd_tile_t)); + + for (i = 0; i < cp->tileno_size; i++) { + opj_tcp_t *tcp = &(cp->tcps[cp->tileno[i]]); + opj_tcd_tile_t *tile = &(tcd->tcd_image->tiles[cp->tileno[i]]); + + /* cfr p59 ISO/IEC FDIS15444-1 : 2000 (18 august 2000) */ + tileno = cp->tileno[i]; + 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, image->x0); + tile->y0 = int_max(cp->ty0 + q * cp->tdy, image->y0); + tile->x1 = int_min(cp->tx0 + (p + 1) * cp->tdx, image->x1); + tile->y1 = int_min(cp->ty0 + (q + 1) * cp->tdy, image->y1); + + tile->numcomps = image->numcomps; + tile->comps = (opj_tcd_tilecomp_t *) opj_malloc(image->numcomps * sizeof(opj_tcd_tilecomp_t)); + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tccp_t *tccp = &tcp->tccps[compno]; + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + + /* border of each tile component (global) */ + tilec->x0 = int_ceildiv(tile->x0, image->comps[compno].dx); + tilec->y0 = int_ceildiv(tile->y0, image->comps[compno].dy); + tilec->x1 = int_ceildiv(tile->x1, image->comps[compno].dx); + tilec->y1 = int_ceildiv(tile->y1, image->comps[compno].dy); + + tilec->data = (int *) opj_malloc((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0) * sizeof(int)); + tilec->numresolutions = tccp->numresolutions; + tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(tilec->numresolutions * sizeof(opj_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; + + opj_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); + res->ph = (res->y0 == res->y1) ? 0 : ((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; + opj_stepsize_t *ss = NULL; + + opj_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 = image->comps[compno].prec + gain; + band->stepsize = (float)((1.0 + ss->mant / 2048.0) * pow(2.0, numbps - ss->expn)); + band->numbps = ss->expn + tccp->numgbits - 1; /* WHY -1 ? */ + + band->precincts = (opj_tcd_precinct_t *) opj_malloc(res->pw * res->ph * sizeof(opj_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); + + opj_tcd_precinct_t *prc = &band->precincts[precno]; + /* precinct size (global) */ + prc->x0 = int_max(cbgxstart, band->x0); + prc->y0 = int_max(cbgystart, band->y0); + prc->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 = (opj_tcd_cblk_t *) opj_malloc(prc->cw * prc->ch * sizeof(opj_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); + + /* code-block size (global) */ + opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; + 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); + } + } /* precno */ + } /* bandno */ + } /* resno */ + } /* compno */ + } /* i = 0..cp->tileno_size */ + + /* tcd_dump(stdout, tcd, &tcd->tcd_image, 0); */ + + /* + Allocate place to store the decoded data = final image + Place limited by the tile really present in the codestream + */ + + for (i = 0; i < image->numcomps; i++) { + for (j = 0; j < cp->tileno_size; j++) { + tileno = cp->tileno[j]; + x0 = j == 0 ? tcd->tcd_image->tiles[tileno].comps[i].x0 : int_min(x0, + (unsigned int) tcd->tcd_image->tiles[tileno].comps[i].x0); + y0 = j == 0 ? tcd->tcd_image->tiles[tileno].comps[i].y0 : int_min(y0, + (unsigned int) tcd->tcd_image->tiles[tileno].comps[i].y0); + x1 = j == 0 ? tcd->tcd_image->tiles[tileno].comps[i].x1 : int_max(x1, + (unsigned int) tcd->tcd_image->tiles[tileno].comps[i].x1); + y1 = j == 0 ? tcd->tcd_image->tiles[tileno].comps[i].y1 : int_max(y1, + (unsigned int) tcd->tcd_image->tiles[tileno].comps[i].y1); + } + + w = x1 - x0; + h = y1 - y0; + + image->comps[i].data = (int *) opj_malloc(w * h * sizeof(int)); + image->comps[i].w = w; + image->comps[i].h = h; + image->comps[i].x0 = x0; + image->comps[i].y0 = y0; } } -void tcd_makelayer(int layno, double thresh, int final) -{ - int compno, resno, bandno, precno, cblkno, passno; +void tcd_makelayer_fixed(opj_tcd_t *tcd, int layno, int final) { + int compno, resno, bandno, precno, cblkno; + int value; /*, matrice[tcd_tcp->numlayers][tcd_tile->comps[0].numresolutions][3]; */ + int matrice[10][10][3]; + int i, j, k; - tcd_tile->distolayer[layno] = 0; /*add fixed_quality*/ + opj_cp_t *cp = tcd->cp; + opj_tcd_tile_t *tcd_tile = tcd->tcd_tile; + opj_tcp_t *tcd_tcp = tcd->tcp; + /*matrice=(int*)opj_malloc(tcd_tcp->numlayers*tcd_tile->comps[0].numresolutions*3*sizeof(int)); */ + for (compno = 0; compno < tcd_tile->numcomps; compno++) { - tcd_tilecomp_t *tilec = &tcd_tile->comps[compno]; + opj_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) (cp->matrice[i * tilec->numresolutions * 3 + j * 3 + k] + * (float) (tcd->image->comps[compno].prec / 16.0)); + } + } + } + for (resno = 0; resno < tilec->numresolutions; resno++) { - tcd_resolution_t *res = &tilec->resolutions[resno]; + opj_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) { - if (dd) - n = passno + 1; - continue; - } - - if (dd / dr >= thresh) - n = passno + 1; - } - layer->numpasses = n - cblk->numpassesinlayers; - - if (!layer->numpasses) { - layer->disto = 0; - continue; - } - - if (cblk->numpassesinlayers == 0) { - layer->len = cblk->passes[n - 1].rate; - layer->data = cblk->data; - layer->disto = cblk->passes[n - 1].distortiondec; - } else { - layer->len = cblk->passes[n - 1].rate - - cblk->passes[cblk->numpassesinlayers - 1].rate; - layer->data = - cblk->data + - cblk->passes[cblk->numpassesinlayers - 1].rate; - layer->disto = - cblk->passes[n - 1].distortiondec - - cblk->passes[cblk->numpassesinlayers - 1].distortiondec; - } - - tcd_tile->distolayer[layno] += layer->disto; /*add fixed_quality*/ - - if (final) - cblk->numpassesinlayers = n; - } - } + opj_tcd_band_t *band = &res->bands[bandno]; + for (precno = 0; precno < res->pw * res->ph; precno++) { + opj_tcd_precinct_t *prc = &band->precincts[precno]; + for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { + opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; + opj_tcd_layer_t *layer = &cblk->layers[layno]; + int n; + int imsb = tcd->image->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(unsigned char *dest, int len, info_image * info_IM) -{ +void tcd_rateallocate_fixed(opj_tcd_t *tcd) { + int layno; + for (layno = 0; layno < tcd->tcp->numlayers; layno++) { + tcd_makelayer_fixed(tcd, layno, 1); + } +} + +void tcd_makelayer(opj_tcd_t *tcd, int layno, double thresh, int final) { + int compno, resno, bandno, precno, cblkno, passno; + + opj_tcd_tile_t *tcd_tile = tcd->tcd_tile; + + tcd_tile->distolayer[layno] = 0; /* fixed_quality */ + + for (compno = 0; compno < tcd_tile->numcomps; compno++) { + opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno]; + for (resno = 0; resno < tilec->numresolutions; resno++) { + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + for (precno = 0; precno < res->pw * res->ph; precno++) { + opj_tcd_precinct_t *prc = &band->precincts[precno]; + for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { + opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; + opj_tcd_layer_t *layer = &cblk->layers[layno]; + + int n; + if (layno == 0) { + cblk->numpassesinlayers = 0; + } + n = cblk->numpassesinlayers; + for (passno = cblk->numpassesinlayers; passno < cblk->totalpasses; passno++) { + int dr; + double dd; + opj_tcd_pass_t *pass = &cblk->passes[passno]; + if (n == 0) { + dr = pass->rate; + dd = pass->distortiondec; + } else { + dr = pass->rate - cblk->passes[n - 1].rate; + dd = pass->distortiondec - cblk->passes[n - 1].distortiondec; + } + if (!dr) { + if (dd) + n = passno + 1; + continue; + } + if (dd / dr >= thresh) + n = passno + 1; + } + layer->numpasses = n - cblk->numpassesinlayers; + + if (!layer->numpasses) { + layer->disto = 0; + continue; + } + if (cblk->numpassesinlayers == 0) { + layer->len = cblk->passes[n - 1].rate; + layer->data = cblk->data; + layer->disto = cblk->passes[n - 1].distortiondec; + } else { + layer->len = cblk->passes[n - 1].rate - cblk->passes[cblk->numpassesinlayers - 1].rate; + layer->data = cblk->data + cblk->passes[cblk->numpassesinlayers - 1].rate; + layer->disto = cblk->passes[n - 1].distortiondec - cblk->passes[cblk->numpassesinlayers - 1].distortiondec; + } + + tcd_tile->distolayer[layno] += layer->disto; /* fixed_quality */ + + if (final) + cblk->numpassesinlayers = n; + } + } + } + } + } +} + +bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_image_info_t * image_info) { 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 cumdisto[100]; /* fixed_quality */ + const double K = 1; /* 1.1; // fixed_quality */ double maxSE = 0; + + opj_t2_t *t2 = NULL; /* T2 component */ + + opj_cp_t *cp = tcd->cp; + opj_tcd_tile_t *tcd_tile = tcd->tcd_tile; + opj_tcp_t *tcd_tcp = tcd->tcp; + min = DBL_MAX; max = 0; - - tcd_tile->nbpix = 0; /*add fixed_quality*/ - + + tcd_tile->nbpix = 0; /* fixed_quality */ + for (compno = 0; compno < tcd_tile->numcomps; compno++) { - tcd_tilecomp_t *tilec = &tcd_tile->comps[compno]; - + opj_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]; + opj_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 << tcd_img->comps[compno].prec) - 1.0) * ((double)(1 << tcd_img->comps[compno].prec) -1.0)) * ((double)(tilec->nbpix)); - } /* compno */ - + opj_tcd_band_t *band = &res->bands[bandno]; + for (precno = 0; precno < res->pw * res->ph; precno++) { + opj_tcd_precinct_t *prc = &band->precincts[precno]; + for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { + opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; + for (passno = 0; passno < cblk->totalpasses; passno++) { + opj_tcd_pass_t *pass = &cblk->passes[passno]; + int dr; + double dd, rdslope; + if (passno == 0) { + dr = pass->rate; + dd = pass->distortiondec; + } else { + dr = pass->rate - cblk->passes[passno - 1].rate; + dd = pass->distortiondec - cblk->passes[passno - 1].distortiondec; + } + if (dr == 0) { + continue; + } + rdslope = dd / dr; + if (rdslope < min) { + min = rdslope; + } + if (rdslope > max) { + max = rdslope; + } + } /* passno */ + + /* fixed_quality */ + tcd_tile->nbpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0)); + tilec->nbpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0)); + } /* cbklno */ + } /* precno */ + } /* bandno */ + } /* resno */ + + maxSE += (((double)(1 << tcd->image->comps[compno].prec) - 1.0) + * ((double)(1 << tcd->image->comps[compno].prec) -1.0)) + * ((double)(tilec->nbpix)); + } /* compno */ + /* add antonin index */ - if (info_IM->index_on) { - info_tile *info_TL = &info_IM->tile[tcd_tileno]; + if(image_info && image_info->index_on) { + opj_tile_info_t *info_TL = &image_info->tile[tcd->tcd_tileno]; info_TL->nbpix = tcd_tile->nbpix; info_TL->distotile = tcd_tile->distotile; - info_TL->thresh = - (double *) malloc(tcd_tcp->numlayers * sizeof(double)); + info_TL->thresh = (double *) opj_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 = tcd_tcp->rates[layno] ? int_min(tcd_tcp->rates[layno], len) : len; /*Mod antonin losslessbug*/ - volatile double goodthresh; - volatile int i; - double distotarget; /*add fixed_quality*/ - - distotarget = tcd_tile->distotile - ((K * maxSE) / pow(10, tcd_tcp->distoratio[layno] / 10)); /* add fixed_quality*/ + double lo = min; + double hi = max; + int success = 0; + int maxlen = tcd_tcp->rates[layno] ? int_min(tcd_tcp->rates[layno], len) : len; + double goodthresh; + int i; + double distotarget; /* fixed_quality */ - if ((tcd_tcp->rates[layno]) || (tcd_cp->disto_alloc==0)) { + /* fixed_quality */ + distotarget = tcd_tile->distotile - ((K * maxSE) / pow((float)10, tcd_tcp->distoratio[layno] / 10)); + + if ((tcd_tcp->rates[layno]) || (cp->disto_alloc==0)) { + opj_t2_t *t2 = t2_create(tcd->cinfo, tcd->image, cp); + 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; + double thresh = (lo + hi) / 2; + int l = 0; + double distoachieved = 0; /* fixed_quality */ + + tcd_makelayer(tcd, layno, thresh, 0); + + if (cp->fixed_quality) { /* 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(t2, tcd->tcd_tileno, tcd_tile, layno + 1, dest, maxlen, image_info); + opg_event_msg(tcd->cinfo, EVT_INFO, "rate alloc: len=%d, max=%d\n", l, maxlen); + if (l == -999) { + lo = thresh; + continue; + } + hi = thresh; + } + + success = 1; + goodthresh = thresh; } + t2_destroy(t2); } else { success = 1; goodthresh = min; } - + if (!success) { - longjmp(j2k_error, 1); + return false; } - - if (info_IM->index_on) { /* Threshold for Marcela Index */ - info_IM->tile[tcd_tileno].thresh[layno] = goodthresh; + + if(image_info && image_info->index_on) { /* Threshold for Marcela Index */ + image_info->tile[tcd->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*/ + tcd_makelayer(tcd, layno, goodthresh, 1); + + /* fixed_quality */ + cumdisto[layno] = layno == 0 ? tcd_tile->distolayer[0] : cumdisto[layno - 1] + tcd_tile->distolayer[layno]; } + + return true; } -int -tcd_encode_tile_pxm(int tileno, unsigned char *dest, int len, - info_image * info_IM) -{ +int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, opj_image_info_t * image_info) { int compno; - int l, i, npck=0; - clock_t time7; - tcd_tile_t *tile; - j2k_tcp_t *tcp = &tcd_cp->tcps[0]; - j2k_tccp_t *tccp = &tcp->tccps[0]; + int l, i, npck = 0; + double encoding_time; + opj_tcd_tile_t *tile = NULL; + opj_tcp_t *tcd_tcp = NULL; + opj_cp_t *cp = NULL; + + opj_tcp_t *tcp = &tcd->cp->tcps[0]; + opj_tccp_t *tccp = &tcp->tccps[0]; + opj_image_t *image = tcd->image; - tcd_tileno = tileno; - tcd_tile = tcd_image.tiles; - tcd_tcp = &tcd_cp->tcps[tileno]; - tile = tcd_tile; + opj_t1_t *t1 = NULL; /* T1 component */ + opj_t2_t *t2 = NULL; /* T2 component */ + + tcd->tcd_tileno = tileno; + tcd->tcd_tile = tcd->tcd_image->tiles; + tcd->tcp = &tcd->cp->tcps[tileno]; + + tile = tcd->tcd_tile; + tcd_tcp = tcd->tcp; + cp = tcd->cp; + /* 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*/ - + if(image_info && image_info->index_on) { + opj_tcd_tilecomp_t *tilec_idx = &tile->comps[0]; /* based on component 0 */ for (i = 0; i < tilec_idx->numresolutions; 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; - - npck+=res_idx->pw * res_idx->ph; - - info_IM->tile[tileno].pdx[i] = tccp->prcw[i]; - info_IM->tile[tileno].pdy[i] = tccp->prch[i]; - + opj_tcd_resolution_t *res_idx = &tilec_idx->resolutions[i]; + + image_info->tile[tileno].pw[i] = res_idx->pw; + image_info->tile[tileno].ph[i] = res_idx->ph; + + npck += res_idx->pw * res_idx->ph; + + image_info->tile[tileno].pdx[i] = tccp->prcw[i]; + image_info->tile[tileno].pdy[i] = tccp->prch[i]; } - info_IM->tile[tileno].packet = (info_packet *) calloc(info_IM->Comp * info_IM->Layer * npck, sizeof(info_packet)); + image_info->tile[tileno].packet = (opj_packet_info_t *) opj_malloc(image_info->comp * image_info->layer * npck * sizeof(opj_packet_info_t)); } /* << INDEX */ + + /*---------------TILE-------------------*/ + encoding_time = opj_clock(); /* time needed to encode a tile */ + + for (compno = 0; compno < tile->numcomps; compno++) { + int x, y; -/*---------------TILE-------------------*/ + int adjust = image->comps[compno].sgnd ? 0 : 1 << (image->comps[compno].prec - 1); + int offset_x = int_ceildiv(image->x0, image->comps[compno].dx); + int offset_y = int_ceildiv(image->y0, image->comps[compno].dy); + + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + int tw = tilec->x1 - tilec->x0; + int w = int_ceildiv(image->x1 - image->x0, image->comps[compno].dx); - time7 = clock(); + /* extract tile data */ + + if (tcd_tcp->tccps[compno].qmfbid == 1) { + for (y = tilec->y0; y < tilec->y1; y++) { + /* start of the src tile scanline */ + int *data = &image->comps[compno].data[(tilec->x0 - offset_x) + (y - offset_y) * w]; + /* start of the dst tile scanline */ + int *tile_data = &tilec->data[(y - tilec->y0) * tw]; + for (x = tilec->x0; x < tilec->x1; x++) { + *tile_data++ = *data++ - adjust; + } + } + } else if (tcd_tcp->tccps[compno].qmfbid == 0) { + for (y = tilec->y0; y < tilec->y1; y++) { + /* start of the src tile scanline */ + int *data = &image->comps[compno].data[(tilec->x0 - offset_x) + (y - offset_y) * w]; + /* start of the dst tile scanline */ + int *tile_data = &tilec->data[(y - tilec->y0) * tw]; + for (x = tilec->x0; x < tilec->x1; x++) { + *tile_data++ = (*data++ - adjust) << 13; + } + } + } + } + + /*----------------MCT-------------------*/ + if (tcd_tcp->mct) { + int samples = (tile->comps[0].x1 - tile->comps[0].x0) * (tile->comps[0].y1 - tile->comps[0].y0); + if (tcd_tcp->tccps[0].qmfbid == 0) { + mct_encode_real(tile->comps[0].data, tile->comps[1].data, tile->comps[2].data, samples); + } else { + mct_encode(tile->comps[0].data, tile->comps[1].data, tile->comps[2].data, samples); + } + } + + /*----------------DWT---------------------*/ 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)); + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + if (tcd_tcp->tccps[compno].qmfbid == 1) { + dwt_encode(tilec); + } else if (tcd_tcp->tccps[compno].qmfbid == 0) { + dwt_encode_real(tilec); } } -/*----------------DWT---------------------*/ -/* mod Ive*/ -for (compno = 0; compno < tile->numcomps; compno++) { - tcd_tilecomp_t *tilec = &tile->comps[compno]; - if (tcd_tcp->tccps[compno].qmfbid == 1) { - dwt_encode(tilec); - } else if (tcd_tcp->tccps[compno].qmfbid == 0) { - dwt_encode_real(tilec); + /*------------------TIER1-----------------*/ + t1 = t1_create(tcd->cinfo); + t1_encode_cblks(t1, tile, tcd_tcp); + t1_destroy(t1); + + /*-----------RATE-ALLOCATE------------------*/ + + /* INDEX */ + if(image_info) { + image_info->index_write = 0; } -} -/* /mod Ive*/ -/*------------------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*/ + if (cp->disto_alloc || cp->fixed_quality) { /* fixed_quality */ /* Normal Rate/distortion allocation */ - tcd_rateallocate(dest, len, info_IM); - else + tcd_rateallocate(tcd, dest, len, image_info); + } else { /* Fixed layer allocation */ - tcd_rateallocate_fixed(); + tcd_rateallocate_fixed(tcd); + } + + /*--------------TIER2------------------*/ -/*--------------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-------------------*/ + /* INDEX */ + if(image_info) { + image_info->index_write = 1; + } - time7 = clock() - time7; - fprintf(stdout,"total: %ld.%.3ld s\n", time7 / CLOCKS_PER_SEC, - (time7 % (int)CLOCKS_PER_SEC) * 1000 / CLOCKS_PER_SEC); + t2 = t2_create(tcd->cinfo, image, cp); + l = t2_encode_packets(t2, tileno, tile, tcd_tcp->numlayers, dest, len, image_info); + t2_destroy(t2); + + /*---------------CLEAN-------------------*/ + encoding_time = opj_clock() - encoding_time; + opg_event_msg(tcd->cinfo, EVT_INFO, "- tile encoded in %f s\n", encoding_time); + /* cleaning memory */ for (compno = 0; compno < tile->numcomps; compno++) { - tilec = &tile->comps[compno]; - free(tilec->data); + tcd->tilec = &tile->comps[compno]; + opj_free(tcd->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, npck=0; - 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; i < tilec_idx->numresolutions; 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; - - npck+=res_idx->pw * res_idx->ph; - - info_IM->tile[tileno].pdx[i] = tccp->prcw[i]; - info_IM->tile[tileno].pdy[i] = tccp->prch[i]; - - } - info_IM->tile[tileno].packet = (info_packet *) calloc(info_IM->Comp * info_IM->Layer * npck, sizeof(info_packet)); - } - /* << 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---------------------*/ - -/* mod Ive*/ -for (compno = 0; compno < tile->numcomps; compno++) { - tcd_tilecomp_t *tilec = &tile->comps[compno]; - if (tcd_tcp->tccps[compno].qmfbid == 1) { - dwt_encode(tilec); - } else if (tcd_tcp->tccps[compno].qmfbid == 0) { - dwt_encode_real(tilec); - } -} -/* /mod Ive*/ - -/*------------------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; - fprintf(stdout,"total: %ld.%.3ld s\n", time / CLOCKS_PER_SEC, - (time % (int)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) -{ +bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno) { int l; int compno; int eof = 0; - clock_t time; - tcd_tile_t *tile; + double tile_time, t1_time, dwt_time; + opj_tcd_tile_t *tile = NULL; - tcd_tileno = tileno; - tcd_tile = &tcd_image.tiles[tileno]; - tcd_tcp = &tcd_cp->tcps[tileno]; - tile = tcd_tile; - - time = clock(); - - fprintf(stdout, "Tile %d of %d decoded in ", tileno + 1, - tcd_cp->tw * tcd_cp->th); - - /*--------------TIER2------------------*/ - - l = t2_decode_packets(src, len, tcd_img, tcd_cp, tileno, tile); + opj_t1_t *t1 = NULL; /* T1 component */ + opj_t2_t *t2 = NULL; /* T2 component */ + + tcd->tcd_tileno = tileno; + tcd->tcd_tile = &(tcd->tcd_image->tiles[tileno]); + tcd->tcp = &(tcd->cp->tcps[tileno]); + tile = tcd->tcd_tile; + + tile_time = opj_clock(); /* time needed to decode a tile */ + opg_event_msg(tcd->cinfo, EVT_INFO, "tile %d of %d\n", tileno + 1, tcd->cp->tw * tcd->cp->th); + + /*--------------TIER2------------------*/ + + t2 = t2_create(tcd->cinfo, tcd->image, tcd->cp); + l = t2_decode_packets(t2, src, len, tileno, tile); + t2_destroy(t2); if (l == -999) { eof = 1; - fprintf(stderr, "tcd_decode: incomplete bistream\n"); + opg_event_msg(tcd->cinfo, EVT_ERROR, "tcd_decode: incomplete bistream\n"); } + + /*------------------TIER1-----------------*/ + + t1_time = opj_clock(); /* time needed to decode a tile */ + t1 = t1_create(tcd->cinfo); + t1_decode_cblks(t1, tile, tcd->tcp); + t1_destroy(t1); + t1_time = opj_clock() - t1_time; + opg_event_msg(tcd->cinfo, EVT_INFO, "- tiers-1 took %f s\n", t1_time); + + /*----------------DWT---------------------*/ - /*------------------TIER1-----------------*/ - t1_init_luts(); - t1_decode_cblks(tile, tcd_tcp); - - /*----------------DWT---------------------*/ - + dwt_time = opj_clock(); /* time needed to decode a tile */ for (compno = 0; compno < tile->numcomps; compno++) { - tcd_tilecomp_t *tilec = &tile->comps[compno]; - if (tcd_cp->reduce != 0) { - tcd_img->comps[compno].resno_decoded = - tile->comps[compno].numresolutions - tcd_cp->reduce - 1; + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + if (tcd->cp->reduce != 0) { + tcd->image->comps[compno].resno_decoded = + tile->comps[compno].numresolutions - tcd->cp->reduce - 1; } - - - /* mod Ive */ - if (tcd_tcp->tccps[compno].qmfbid == 1) { - dwt_decode(tilec, - tilec->numresolutions - 1 - - tcd_img->comps[compno].resno_decoded); + + if (tcd->tcp->tccps[compno].qmfbid == 1) { + dwt_decode(tilec, tilec->numresolutions - 1 - tcd->image->comps[compno].resno_decoded); } else { - dwt_decode_real(tilec, - tilec->numresolutions - 1 - - tcd_img->comps[compno].resno_decoded); + dwt_decode_real(tilec, tilec->numresolutions - 1 - tcd->image->comps[compno].resno_decoded); } - /* /mod Ive*/ + + if (tile->comps[compno].numresolutions > 0) { + tcd->image->comps[compno].factor = tile->comps[compno].numresolutions - (tcd->image->comps[compno].resno_decoded + 1); + } + } + dwt_time = opj_clock() - dwt_time; + opg_event_msg(tcd->cinfo, EVT_INFO, "- dwt took %f s\n", dwt_time); + + /*----------------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++) { + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + opj_tcd_resolution_t *res = &tilec->resolutions[tcd->image->comps[compno].resno_decoded]; + int adjust = tcd->image->comps[compno].sgnd ? 0 : 1 << (tcd->image->comps[compno].prec - 1); + int min = tcd->image->comps[compno].sgnd ? + -(1 << (tcd->image->comps[compno].prec - 1)) : 0; + int max = tcd->image->comps[compno].sgnd ? + (1 << (tcd->image->comps[compno].prec - 1)) - 1 : (1 << tcd->image->comps[compno].prec) - 1; - 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 w = tcd->image->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); - + int offset_x = int_ceildivpow2(tcd->image->comps[compno].x0, tcd->image->comps[compno].factor); + int offset_y = int_ceildivpow2(tcd->image->comps[compno].y0, tcd->image->comps[compno].factor); + for (j = res->y0; j < res->y1; j++) { for (i = res->x0; i < res->x1; i++) { + int v; + float tmp = (float)((tilec->data[i - res->x0 + (j - res->y0) * tw]) / 8192.0); - int v; - double tmp = (tilec->data[i - res->x0 + (j - res->y0) * tw])/8192.0; - int tmp2; - - if (tcd_tcp->tccps[compno].qmfbid == 1) { - v = tilec->data[i - res->x0 + (j - res->y0) * tw]; - } else { - tmp2=((int) (floor(fabs(tmp)))) + ((int) floor(fabs(tmp*2))%2); - v = ((tmp<0)?-tmp2:tmp2); + if (tcd->tcp->tccps[compno].qmfbid == 1) { + v = tilec->data[i - res->x0 + (j - res->y0) * tw]; + } else { + int tmp2 = ((int) (floor(fabs(tmp)))) + ((int) floor(fabs(tmp*2))%2); + v = ((tmp < 0) ? -tmp2:tmp2); } + v += adjust; - v += adjust; - - tcd_img->comps[compno].data[(i - offset_x) + - (j - offset_y) * w] = - int_clamp(v, min, max); + tcd->image->comps[compno].data[(i - offset_x) + (j - offset_y) * w] = int_clamp(v, min, max); } } } - - time = clock() - time; - fprintf(stdout, "%ld.%.3ld s\n", time / CLOCKS_PER_SEC, - (time % (int)CLOCKS_PER_SEC) * 1000 / CLOCKS_PER_SEC); - - - + + tile_time = opj_clock() - tile_time; /* time needed to decode a tile */ + opg_event_msg(tcd->cinfo, EVT_INFO, "- tile decoded in %f s\n", tile_time); + for (compno = 0; compno < tile->numcomps; compno++) { - free(tcd_image.tiles[tileno].comps[compno].data); + opj_free(tcd->tcd_image->tiles[tileno].comps[compno].data); + tcd->tcd_image->tiles[tileno].comps[compno].data = NULL; } - + if (eof) { - longjmp(j2k_error, 1); + return false; } - - return l; + + return true; } - - -void tcd_dec_release() - -{ - +void tcd_free_decode(opj_tcd_t *tcd) { int tileno,compno,resno,bandno,precno; - for (tileno=0;tilenotcd_image; + + for (tileno = 0; tileno < tcd_image->tw * tcd_image->th; tileno++) { + opj_tcd_tile_t *tile = &tcd_image->tiles[tileno]; + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + for (resno = 0; resno < tilec->numresolutions; resno++) { + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + for (precno = 0; precno < res->ph * res->pw; precno++) { + opj_tcd_precinct_t *prec = &band->precincts[precno]; + if (prec->cblks != NULL) opj_free(prec->cblks); + if (prec->imsbtree != NULL) tgt_destroy(prec->imsbtree); + if (prec->incltree != NULL) tgt_destroy(prec->incltree); + } + if (band->precincts != NULL) opj_free(band->precincts); + } } - - if (tilec.resolutions!=NULL) free(tilec.resolutions); - + if (tilec->resolutions != NULL) opj_free(tilec->resolutions); } - - if (tile.comps!=NULL) free(tile.comps); - + if (tile->comps != NULL) opj_free(tile->comps); } - if (tcd_image.tiles!=NULL) free(tcd_image.tiles); - + if (tcd_image->tiles != NULL) opj_free(tcd_image->tiles); } + diff --git a/libopenjpeg/tcd.h b/libopenjpeg/tcd.h index 714d5ea4..538361b6 100644 --- a/libopenjpeg/tcd.h +++ b/libopenjpeg/tcd.h @@ -1,7 +1,9 @@ /* - * Copyright (c) 2001-2002, David Janssens + * 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 + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,156 +30,238 @@ #ifndef __TCD_H #define __TCD_H +/** +@file tcd.h +@brief Implementation of a tile coder/decoder (TCD) -#include "j2k.h" -#include "tgt.h" +The functions in TCD.C have for goal to encode or decode each tile independently from +each other. The functions in TCD.C are used by some function in J2K.C. +*/ -typedef struct { +/** @defgroup TCD TCD - Implementation of a tile coder/decoder */ +/*@{*/ + +/** +FIXME: documentation +*/ +typedef struct opj_tcd_seg { int numpasses; int len; unsigned char *data; int maxpasses; int numnewpasses; int newlen; -} tcd_seg_t; +} opj_tcd_seg_t; -typedef struct { +/** +FIXME: documentation +*/ +typedef struct opj_tcd_pass { int rate; double distortiondec; int term, len; -} tcd_pass_t; +} opj_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; +/** +FIXME: documentation +*/ +typedef struct opj_tcd_layer { + int numpasses; /* Number of passes in the layer */ + int len; /* len of information */ + double disto; /* add for index (Cfr. Marcela) */ + unsigned char *data; /* data */ +} opj_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) */ +/** +FIXME: documentation +*/ +typedef struct opj_tcd_cblk { + int x0, y0, x1, y1; /* dimension of the code-blocks : left upper corner (x0, y0) right low corner (x1,y1) */ int numbps; 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; + 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 */ + opj_tcd_seg_t segs[100]; /* segments informations */ + unsigned char data[8192]; /* Data */ + int numpassesinlayers; /* number of passes in the layer */ + opj_tcd_layer_t layers[100]; /* layer information */ + int totalpasses; /* total number of passes */ + opj_tcd_pass_t passes[100]; /* information about the passes */ +} opj_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; +/** +FIXME: documentation +*/ +typedef struct opj_tcd_precinct { + 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 */ + opj_tcd_cblk_t *cblks; /* code-blocks informations */ + opj_tgt_tree_t *incltree; /* inclusion tree */ + opj_tgt_tree_t *imsbtree; /* IMSB tree */ +} opj_tcd_precinct_t; -typedef struct { - int x0, y0, x1, y1; /* dimension of the subband : left upper corner (x0, y0) right low corner (x1,y1) */ +/** +FIXME: documentation +*/ +typedef struct opj_tcd_band { + 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 */ + opj_tcd_precinct_t *precincts; /* precinct information */ int numbps; float stepsize; -} tcd_band_t; +} opj_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) */ +/** +FIXME: documentation +*/ +typedef struct opj_tcd_resolution { + 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; + int numbands; /* number sub-band for the resolution level */ + opj_tcd_band_t bands[3]; /* subband information */ +} opj_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; +/** +FIXME: documentation +*/ +typedef struct opj_tcd_tilecomp { + int x0, y0, x1, y1; /* dimension of component : left upper corner (x0, y0) right low corner (x1,y1) */ + int numresolutions; /* number of resolutions level */ + opj_tcd_resolution_t *resolutions; /* resolutions information */ + int *data; /* data of the component */ + int nbpix; /* add fixed_quality */ +} opj_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; +/** +FIXME: documentation +*/ +typedef struct opj_tcd_tile { + 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 */ + opj_tcd_tilecomp_t *comps; /* Components information */ + int nbpix; /* add fixed_quality */ + double distotile; /* add fixed_quality */ + double distolayer[100]; /* add fixed_quality */ +} opj_tcd_tile_t; -typedef struct { - int tw, th; /* number of tiles in width and heigth */ - tcd_tile_t *tiles; /* Tiles information */ -} tcd_image_t; +/** +FIXME: documentation +*/ +typedef struct opj_tcd_image { + int tw, th; /* number of tiles in width and heigth */ + opj_tcd_tile_t *tiles; /* Tiles information */ +} opj_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); +/** +Tile coder/decoder +*/ +typedef struct opj_tcd { + /** codec context */ + opj_common_ptr cinfo; + /** info on each image tile */ + opj_tcd_image_t *tcd_image; + /** image */ + opj_image_t *image; + /** coding parameters */ + opj_cp_t *cp; + /** pointer to the current encoded/decoded tile */ + opj_tcd_tile_t *tcd_tile; + /** coding/decoding parameters common to all tiles */ + opj_tcp_t *tcp; + /** current encoded/decoded tile */ + int tcd_tileno; + /**@name working variables */ + /*@{*/ + opj_tcd_tile_t *tile; + opj_tcd_tilecomp_t *tilec; + opj_tcd_resolution_t *res; + opj_tcd_band_t *band; + opj_tcd_precinct_t *prc; + opj_tcd_cblk_t *cblk; + /*@}*/ +} opj_tcd_t; -/* - * 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); +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Dump the content of a tcd structure +*/ +void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_image_t * img, int curtileno); +/** +Create a new TCD handle +@param cinfo Codec context info +@return Returns a new TCD handle if successful returns NULL otherwise +*/ +opj_tcd_t* tcd_create(opj_common_ptr cinfo); +/** +Destroy a previously created TCD handle +@param tcd TCD handle to destroy +*/ +void tcd_destroy(opj_tcd_t *tcd); +/** +Initialize the tile coder (allocate the memory) +@param tcd TCD handle +@param image Raw image +@param cp Coding parameters +@param curtileno Number that identifies the tile that will be encoded +*/ +void tcd_malloc_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int curtileno); +/** +Free the memory allocated for encoding +@param tcd TCD handle +*/ +void tcd_free_encode(opj_tcd_t *tcd); +/** +Initialize the tile coder (reuses the memory allocated by tcd_malloc_encode) +@param tcd TCD handle +@param image Raw image +@param cp Coding parameters +@param curtileno Number that identifies the tile that will be encoded +*/ +void tcd_init_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int curtileno); +/** +Initialize the tile decoder +@param tcd TCD handle +@param image Raw image +@param cp Coding parameters +*/ +void tcd_malloc_decode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp); +void tcd_makelayer_fixed(opj_tcd_t *tcd, int layno, int final); +void tcd_rateallocate_fixed(opj_tcd_t *tcd); +void tcd_makelayer(opj_tcd_t *tcd, int layno, double thresh, int final); +bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_image_info_t * image_info); +/** +Encode a tile from the raw image into a buffer +@param tcd TCD handle +@param tileno Number that identifies one of the tiles to be encoded +@param dest Destination buffer +@param len Length of destination buffer +@param image_info Creation of index file +@return +*/ +int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, opj_image_info_t * image_info); +/** +Decode a tile from a buffer into a raw image +@param tcd TCD handle +@param src Source buffer +@param len Length of source buffer +@param tileno Number that identifies one of the tiles to be decoded +*/ +bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno); +/** +Free the memory allocated for decoding +@param tcd TCD handle +*/ +void tcd_free_decode(opj_tcd_t *tcd); -/* - * 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); - -void tcd_dec_release(); - -#endif +#endif /* __TCD_H */ diff --git a/libopenjpeg/tgt.c b/libopenjpeg/tgt.c index 0dfe9089..ef053ea4 100644 --- a/libopenjpeg/tgt.c +++ b/libopenjpeg/tgt.c @@ -1,5 +1,9 @@ /* - * Copyright (c) 2001-2002, David Janssens + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,44 +28,27 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "tgt.h" -#include "bio.h" -#include -#include +#include "opj_includes.h" -/* */ -/* Reset tag-tree. */ -/* */ -void tgt_reset(tgt_tree_t * tree) -{ - int i; - /* new */ - if (!tree || tree == NULL) - return; +/* +========================================================== + Tag-tree coder interface +========================================================== +*/ - 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) -{ +opj_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; + opj_tgt_node_t *node = NULL; + opj_tgt_node_t *parentnode = NULL; + opj_tgt_node_t *parentnode0 = NULL; + opj_tgt_tree_t *tree = NULL; int i, j, k; int numlvls; int n; - tree = (tgt_tree_t *) malloc(sizeof(tgt_tree_t)); + tree = (opj_tgt_tree_t *) opj_malloc(sizeof(opj_tgt_tree_t)); + if(!tree) return NULL; tree->numleafsh = numleafsh; tree->numleafsv = numleafsv; @@ -76,61 +63,70 @@ tgt_tree_t *tgt_create(int numleafsh, int numleafsv) tree->numnodes += n; ++numlvls; } while (n > 1); - + /* ADD */ if (tree->numnodes == 0) { - free(tree); + opj_free(tree); return NULL; } - tree->nodes = (tgt_node_t *) malloc(tree->numnodes * sizeof(tgt_node_t)); + tree->nodes = (opj_tgt_node_t *) opj_malloc(tree->numnodes * sizeof(opj_tgt_node_t)); + if(!tree->nodes) { + opj_free(tree); + return NULL; + } node = tree->nodes; parentnode = &tree->nodes[tree->numleafsh * tree->numleafsv]; 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; + node->parent = parentnode; + ++node; + if (--k >= 0) { + node->parent = parentnode; + ++node; + } + ++parentnode; } if ((j & 1) || j == nplv[i] - 1) { - parentnode0 = parentnode; + parentnode0 = parentnode; } else { - parentnode = parentnode0; - parentnode0 += nplh[i]; + 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); +void tgt_destroy(opj_tgt_tree_t *tree) { + opj_free(tree->nodes); + opj_free(tree); } -/* */ -/* 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; +void tgt_reset(opj_tgt_tree_t *tree) { + int i; + + if (NULL == tree) + return; + + for (i = 0; i < tree->numnodes; i++) { + tree->nodes[i].value = 999; + tree->nodes[i].low = 0; + tree->nodes[i].known = 0; + } +} + +void tgt_setvalue(opj_tgt_tree_t *tree, int leafno, int value) { + opj_tgt_node_t *node; node = &tree->nodes[leafno]; while (node && node->value > value) { node->value = value; @@ -138,14 +134,10 @@ void tgt_setvalue(tgt_tree_t * tree, int leafno, int value) } } -/* */ -/* 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; +void tgt_encode(opj_bio_t *bio, opj_tgt_tree_t *tree, int leafno, int threshold) { + opj_tgt_node_t *stk[31]; + opj_tgt_node_t **stkptr; + opj_tgt_node_t *node; int low; stkptr = stk; @@ -154,7 +146,7 @@ void tgt_encode(tgt_tree_t * tree, int leafno, int threshold) *stkptr++ = node; node = node->parent; } - + low = 0; for (;;) { if (low > node->low) { @@ -162,35 +154,30 @@ void tgt_encode(tgt_tree_t * tree, int leafno, int threshold) } else { low = node->low; } - + while (low < threshold) { if (low >= node->value) { - if (!node->known) { - bio_write(1, 1); - node->known = 1; - } - break; + if (!node->known) { + bio_write(bio, 1, 1); + node->known = 1; + } + break; } - bio_write(0, 1); + bio_write(bio, 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 tgt_decode(opj_bio_t *bio, opj_tgt_tree_t *tree, int leafno, int threshold) { + opj_tgt_node_t *stk[31]; + opj_tgt_node_t **stkptr; + opj_tgt_node_t *node; int low; stkptr = stk; @@ -199,7 +186,7 @@ int tgt_decode(tgt_tree_t * tree, int leafno, int threshold) *stkptr++ = node; node = node->parent; } - + low = 0; for (;;) { if (low > node->low) { @@ -208,10 +195,10 @@ int tgt_decode(tgt_tree_t * tree, int leafno, int threshold) low = node->low; } while (low < threshold && low < node->value) { - if (bio_read(1)) { - node->value = low; + if (bio_read(bio, 1)) { + node->value = low; } else { - ++low; + ++low; } } node->low = low; @@ -220,6 +207,6 @@ int tgt_decode(tgt_tree_t * tree, int leafno, int threshold) } node = *--stkptr; } - + return (node->value < threshold) ? 1 : 0; } diff --git a/libopenjpeg/tgt.h b/libopenjpeg/tgt.h index d7b5ab7e..28fc99dd 100644 --- a/libopenjpeg/tgt.h +++ b/libopenjpeg/tgt.h @@ -1,5 +1,9 @@ /* - * Copyright (c) 2001-2002, David Janssens + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, HervŽ Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,62 +30,84 @@ #ifndef __TGT_H #define __TGT_H +/** +@file tgt.h +@brief Implementation of a tag-tree coder (TGT) -typedef struct tgt_node { - struct tgt_node *parent; +The functions in TGT.C have for goal to realize a tag-tree coder. The functions in TGT.C +are used by some function in T2.C. +*/ + +/** @defgroup TGT TGT - Implementation of a tag-tree coder */ +/*@{*/ + +/** +Tag node +*/ +typedef struct opj_tgt_node { + struct opj_tgt_node *parent; int value; int low; int known; -} tgt_node_t; +} opj_tgt_node_t; -typedef struct { +/** +Tag tree +*/ +typedef struct opj_tgt_tree { int numleafsh; int numleafsv; int numnodes; - tgt_node_t *nodes; -} tgt_tree_t; + opj_tgt_node_t *nodes; +} opj_tgt_tree_t; +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Create a tag-tree +@param numleafsh Width of the array of leafs of the tree +@param numleafsv Height of the array of leafs of the tree +@return Returns a new tag-tree if successful, returns NULL otherwise +*/ +opj_tgt_tree_t *tgt_create(int numleafsh, int numleafsv); +/** +Destroy a tag-tree, liberating memory +@param tree Tag-tree to destroy +*/ +void tgt_destroy(opj_tgt_tree_t *tree); +/** +Reset a tag-tree (set all leaves to 0) +@param tree Tag-tree to reset +*/ +void tgt_reset(opj_tgt_tree_t *tree); +/** +Set the value of a leaf of a tag-tree +@param tree Tag-tree to modify +@param leafno Number that identifies the leaf to modify +@param value New value of the leaf +*/ +void tgt_setvalue(opj_tgt_tree_t *tree, int leafno, int value); +/** +Encode the value of a leaf of the tag-tree up to a given threshold +@param bio Pointer to a BIO handle +@param tree Tag-tree to modify +@param leafno Number that identifies the leaf to encode +@param threshold Threshold to use when encoding value of the leaf +*/ +void tgt_encode(opj_bio_t *bio, opj_tgt_tree_t *tree, int leafno, int threshold); +/** +Decode the value of a leaf of the tag-tree up to a given threshold +@param bio Pointer to a BIO handle +@param tree Tag-tree to decode +@param leafno Number that identifies the leaf to decode +@param threshold Threshold to use when decoding value of the leaf +@return Returns 1 if the node's value < threshold, returns 0 otherwise +*/ +int tgt_decode(opj_bio_t *bio, opj_tgt_tree_t *tree, int leafno, int threshold); +/* ----------------------------------------------------------------------- */ +/*@}*/ +/*@}*/ -/* - * 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 +#endif /* __TGT_H */