aboutsummaryrefslogtreecommitdiff
path: root/tests/openjpeg/libopenjpeg/j2k.c
diff options
context:
space:
mode:
authorAlon Zakai <azakai@mozilla.com>2011-02-27 16:55:53 -0800
committerAlon Zakai <azakai@mozilla.com>2011-02-27 16:55:53 -0800
commit6b7f4ffa844bd3e1f2690af2501807e1da161034 (patch)
tree49ac3a5e35a09b09a1a2ad7aebbb8e9a6c86f263 /tests/openjpeg/libopenjpeg/j2k.c
parente932e70792a50786dedc0461697ed31c7ffa4bb2 (diff)
openjpeg test
Diffstat (limited to 'tests/openjpeg/libopenjpeg/j2k.c')
-rw-r--r--tests/openjpeg/libopenjpeg/j2k.c2434
1 files changed, 2434 insertions, 0 deletions
diff --git a/tests/openjpeg/libopenjpeg/j2k.c b/tests/openjpeg/libopenjpeg/j2k.c
new file mode 100644
index 00000000..de1c2067
--- /dev/null
+++ b/tests/openjpeg/libopenjpeg/j2k.c
@@ -0,0 +1,2434 @@
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2006-2007, Parvatha Elangovan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opj_includes.h"
+
+/** @defgroup J2K J2K - JPEG-2000 codestream reader/writer */
+/*@{*/
+
+/** @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 TLM marker (Mainheader)
+@param j2k J2K handle
+*/
+static void j2k_write_tlm(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);
+
+/*@}*/
+
+/*@}*/
+
+/* ----------------------------------------------------------------------- */
+typedef struct j2k_prog_order{
+ OPJ_PROG_ORDER enum_prog;
+ char str_prog[4];
+}j2k_prog_order_t;
+
+j2k_prog_order_t j2k_prog_order_list[] = {
+ {CPRL, "CPRL"},
+ {LRCP, "LRCP"},
+ {PCRL, "PCRL"},
+ {RLCP, "RLCP"},
+ {RPCL, "RPCL"},
+ {(OPJ_PROG_ORDER)-1, ""}
+};
+
+char *j2k_convert_progression_order(OPJ_PROG_ORDER prg_order){
+ j2k_prog_order_t *po;
+ for(po = j2k_prog_order_list; po->enum_prog != -1; po++ ){
+ if(po->enum_prog == prg_order){
+ break;
+ }
+ }
+ return po->str_prog;
+}
+
+/* ----------------------------------------------------------------------- */
+static int j2k_get_num_tp(opj_cp_t *cp,int pino,int tileno){
+ char *prog;
+ int i;
+ int tpnum=1,tpend=0;
+ opj_tcp_t *tcp = &cp->tcps[tileno];
+ prog = j2k_convert_progression_order(tcp->prg);
+
+ if(cp->tp_on == 1){
+ for(i=0;i<4;i++){
+ if(tpend!=1){
+ if( cp->tp_flag == prog[i] ){
+ tpend=1;cp->tp_pos=i;
+ }
+ switch(prog[i]){
+ case 'C':
+ tpnum= tpnum * tcp->pocs[pino].compE;
+ break;
+ case 'R':
+ tpnum= tpnum * tcp->pocs[pino].resE;
+ break;
+ case 'P':
+ tpnum= tpnum * tcp->pocs[pino].prcE;
+ break;
+ case 'L':
+ tpnum= tpnum * tcp->pocs[pino].layE;
+ break;
+ }
+ }
+ }
+ }else{
+ tpnum=1;
+ }
+ return tpnum;
+}
+
+/** mem allocation for TLM marker*/
+int j2k_calculate_tp(opj_cp_t *cp,int img_numcomp,opj_image_t *image,opj_j2k_t *j2k ){
+ int pino,tileno,totnum_tp=0;
+ j2k->cur_totnum_tp = (int *) opj_malloc(cp->tw * cp->th * sizeof(int));
+ for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
+ int cur_totnum_tp = 0;
+ opj_tcp_t *tcp = &cp->tcps[tileno];
+ for(pino = 0; pino <= tcp->numpocs; pino++) {
+ int tp_num=0;
+ opj_pi_iterator_t *pi = pi_initialise_encode(image, cp, tileno,FINAL_PASS);
+ if(!pi) { return -1;}
+ tp_num = j2k_get_num_tp(cp,pino,tileno);
+ totnum_tp = totnum_tp + tp_num;
+ cur_totnum_tp = cur_totnum_tp + tp_num;
+ pi_destroy(pi, cp, tileno);
+ }
+ j2k->cur_totnum_tp[tileno] = cur_totnum_tp;
+ /* INDEX >> */
+ if (j2k->cstr_info) {
+ j2k->cstr_info->tile[tileno].num_tps = cur_totnum_tp;
+ j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_malloc(cur_totnum_tp * sizeof(opj_tp_info_t));
+ }
+ /* << INDEX */
+ }
+ return totnum_tp;
+}
+
+static void j2k_write_soc(opj_j2k_t *j2k) {
+ opj_cio_t *cio = j2k->cio;
+ cio_write(cio, J2K_MS_SOC, 2);
+
+/* UniPG>> */
+#ifdef USE_JPWL
+
+ /* update markers struct */
+ j2k_add_marker(j2k->cstr_info, J2K_MS_SOC, cio_tell(cio) - 2, 2);
+
+#endif /* USE_JPWL */
+/* <<UniPG */
+}
+
+static void j2k_read_soc(opj_j2k_t *j2k) {
+ j2k->state = J2K_STATE_MHSIZ;
+ /* Index */
+ if (j2k->cstr_info) {
+ j2k->cstr_info->main_head_start = cio_tell(j2k->cio) - 2;
+ j2k->cstr_info->codestream_size = cio_numbytesleft(j2k->cio) + 2 - j2k->cstr_info->main_head_start;
+ }
+}
+
+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(cio, J2K_MS_SIZ, 2); /* SIZ */
+ lenp = cio_tell(cio);
+ cio_skip(cio, 2);
+ cio_write(cio, cp->rsiz, 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(cio) - lenp;
+ cio_seek(cio, lenp);
+ cio_write(cio, len, 2); /* Lsiz */
+ cio_seek(cio, lenp + len);
+}
+
+static void j2k_read_siz(opj_j2k_t *j2k) {
+ int len, i;
+
+ opj_cio_t *cio = j2k->cio;
+ opj_image_t *image = j2k->image;
+ opj_cp_t *cp = j2k->cp;
+
+ 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 */
+
+ if ((image->x0<0)||(image->x1<0)||(image->y0<0)||(image->y1<0)) {
+ opj_event_msg(j2k->cinfo, EVT_ERROR,
+ "%s: invalid image size (x0:%d, x1:%d, y0:%d, y1:%d)\n",
+ image->x0,image->x1,image->y0,image->y1);
+ return;
+ }
+
+ image->numcomps = cio_read(cio, 2); /* Csiz */
+
+#ifdef USE_JPWL
+ if (j2k->cp->correct) {
+ /* if JPWL is on, we check whether TX errors have damaged
+ too much the SIZ parameters */
+ if (!(image->x1 * image->y1)) {
+ opj_event_msg(j2k->cinfo, EVT_ERROR,
+ "JPWL: bad image size (%d x %d)\n",
+ image->x1, image->y1);
+ if (!JPWL_ASSUME || JPWL_ASSUME) {
+ opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
+ return;
+ }
+ }
+ if (image->numcomps != ((len - 38) / 3)) {
+ opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
+ "JPWL: Csiz is %d => space in SIZ only for %d comps.!!!\n",
+ image->numcomps, ((len - 38) / 3));
+ if (!JPWL_ASSUME) {
+ opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
+ return;
+ }
+ /* we try to correct */
+ opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust this\n");
+ if (image->numcomps < ((len - 38) / 3)) {
+ len = 38 + 3 * image->numcomps;
+ opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting Lsiz to %d => HYPOTHESIS!!!\n",
+ len);
+ } else {
+ image->numcomps = ((len - 38) / 3);
+ opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting Csiz to %d => HYPOTHESIS!!!\n",
+ image->numcomps);
+ }
+ }
+
+ /* update components number in the jpwl_exp_comps filed */
+ cp->exp_comps = image->numcomps;
+ }
+#endif /* USE_JPWL */
+
+ image->comps = (opj_image_comp_t*) opj_calloc(image->numcomps, sizeof(opj_image_comp_t));
+ for (i = 0; i < image->numcomps; i++) {
+ int tmp, w, h;
+ 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 */
+
+#ifdef USE_JPWL
+ if (j2k->cp->correct) {
+ /* if JPWL is on, we check whether TX errors have damaged
+ too much the SIZ parameters, again */
+ if (!(image->comps[i].dx * image->comps[i].dy)) {
+ opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
+ "JPWL: bad XRsiz_%d/YRsiz_%d (%d x %d)\n",
+ i, i, image->comps[i].dx, image->comps[i].dy);
+ if (!JPWL_ASSUME) {
+ opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
+ return;
+ }
+ /* we try to correct */
+ opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust them\n");
+ if (!image->comps[i].dx) {
+ image->comps[i].dx = 1;
+ opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting XRsiz_%d to %d => HYPOTHESIS!!!\n",
+ i, image->comps[i].dx);
+ }
+ if (!image->comps[i].dy) {
+ image->comps[i].dy = 1;
+ opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting YRsiz_%d to %d => HYPOTHESIS!!!\n",
+ i, image->comps[i].dy);
+ }
+ }
+
+ }
+#endif /* USE_JPWL */
+
+ /* 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 = cp->reduce; /* reducing factor per component */
+ }
+
+ cp->tw = int_ceildiv(image->x1 - cp->tx0, cp->tdx);
+ cp->th = int_ceildiv(image->y1 - cp->ty0, cp->tdy);
+
+#ifdef USE_JPWL
+ if (j2k->cp->correct) {
+ /* if JPWL is on, we check whether TX errors have damaged
+ too much the SIZ parameters */
+ if ((cp->tw < 1) || (cp->th < 1) || (cp->tw > cp->max_tiles) || (cp->th > cp->max_tiles)) {
+ opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
+ "JPWL: bad number of tiles (%d x %d)\n",
+ cp->tw, cp->th);
+ if (!JPWL_ASSUME) {
+ opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
+ return;
+ }
+ /* we try to correct */
+ opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust them\n");
+ if (cp->tw < 1) {
+ cp->tw= 1;
+ opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting %d tiles in x => HYPOTHESIS!!!\n",
+ cp->tw);
+ }
+ if (cp->tw > cp->max_tiles) {
+ cp->tw= 1;
+ opj_event_msg(j2k->cinfo, EVT_WARNING, "- too large x, increase expectance of %d\n"
+ "- setting %d tiles in x => HYPOTHESIS!!!\n",
+ cp->max_tiles, cp->tw);
+ }
+ if (cp->th < 1) {
+ cp->th= 1;
+ opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting %d tiles in y => HYPOTHESIS!!!\n",
+ cp->th);
+ }
+ if (cp->th > cp->max_tiles) {
+ cp->th= 1;
+ opj_event_msg(j2k->cinfo, EVT_WARNING, "- too large y, increase expectance of %d to continue\n",
+ "- setting %d tiles in y => HYPOTHESIS!!!\n",
+ cp->max_tiles, cp->th);
+ }
+ }
+ }
+#endif /* USE_JPWL */
+
+ cp->tcps = (opj_tcp_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tcp_t));
+ cp->tileno = (int*) opj_malloc(cp->tw * cp->th * sizeof(int));
+ cp->tileno_size = 0;
+
+#ifdef USE_JPWL
+ if (j2k->cp->correct) {
+ if (!cp->tcps) {
+ opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
+ "JPWL: could not alloc tcps field of cp\n");
+ if (!JPWL_ASSUME || JPWL_ASSUME) {
+ opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
+ return;
+ }
+ }
+ }
+#endif /* USE_JPWL */
+
+ 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 */
+ cp->ppm = 0;
+ cp->ppm_data = NULL;
+ cp->ppm_data_first = NULL;
+ cp->ppm_previous = 0;
+ cp->ppm_store = 0;
+
+ j2k->default_tcp->tccps = (opj_tccp_t*) opj_calloc(image->numcomps, sizeof(opj_tccp_t));
+ for (i = 0; i < cp->tw * cp->th; i++) {
+ cp->tcps[i].tccps = (opj_tccp_t*) opj_malloc(image->numcomps * sizeof(opj_tccp_t));
+ }
+ j2k->tile_data = (unsigned char**) opj_calloc(cp->tw * cp->th, sizeof(unsigned char*));
+ j2k->tile_len = (int*) opj_calloc(cp->tw * cp->th, sizeof(int));
+ j2k->state = J2K_STATE_MH;
+
+ /* Index */
+ if (j2k->cstr_info) {
+ opj_codestream_info_t *cstr_info = j2k->cstr_info;
+ cstr_info->image_w = image->x1 - image->x0;
+ cstr_info->image_h = image->y1 - image->y0;
+ cstr_info->numcomps = image->numcomps;
+ cstr_info->tw = cp->tw;
+ cstr_info->th = cp->th;
+ cstr_info->tile_x = cp->tdx;
+ cstr_info->tile_y = cp->tdy;
+ cstr_info->tile_Ox = cp->tx0;
+ cstr_info->tile_Oy = cp->ty0;
+ cstr_info->tile = (opj_tile_info_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tile_info_t));
+ }
+}
+
+static void j2k_write_com(opj_j2k_t *j2k) {
+ unsigned int i;
+ int lenp, len;
+
+ 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, 1, 2); /* General use (IS 8859-15:1999 (Latin) values) */
+ for (i = 0; i < strlen(comment); i++) {
+ cio_write(cio, comment[i], 1);
+ }
+ len = cio_tell(cio) - lenp;
+ cio_seek(cio, lenp);
+ cio_write(cio, len, 2);
+ cio_seek(cio, lenp + len);
+ }
+}
+
+static void j2k_read_com(opj_j2k_t *j2k) {
+ int len;
+
+ opj_cio_t *cio = j2k->cio;
+
+ len = cio_read(cio, 2);
+ cio_skip(cio, len - 2);
+}
+
+static void j2k_write_cox(opj_j2k_t *j2k, int compno) {
+ int i;
+
+ 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(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(cio, tccp->prcw[i] + (tccp->prch[i] << 4), 1); /* SPcox (I_i) */
+ }
+ }
+}
+
+static void j2k_read_cox(opj_j2k_t *j2k, int compno) {
+ int i;
+
+ 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) */
+
+ // If user wants to remove more resolutions than the codestream contains, return error
+ if (cp->reduce >= tccp->numresolutions) {
+ opj_event_msg(j2k->cinfo, EVT_ERROR, "Error decoding component %d.\nThe number of resolutions to remove is higher than the number "
+ "of resolutions of this component\nModify the cp_reduce parameter.\n\n", compno);
+ j2k->state |= J2K_STATE_ERR;
+ }
+
+ 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(cio, 1); /* SPcox (I_i) */
+ tccp->prcw[i] = tmp & 0xf;
+ tccp->prch[i] = tmp >> 4;
+ }
+ }
+
+ /* INDEX >> */
+ if(j2k->cstr_info && compno == 0) {
+ for (i = 0; i < tccp->numresolutions; i++) {
+ if (tccp->csty & J2K_CP_CSTY_PRT) {
+ j2k->cstr_info->tile[j2k->curtileno].pdx[i] = tccp->prcw[i];
+ j2k->cstr_info->tile[j2k->curtileno].pdy[i] = tccp->prch[i];
+ }
+ else {
+ j2k->cstr_info->tile[j2k->curtileno].pdx[i] = 15;
+ j2k->cstr_info->tile[j2k->curtileno].pdx[i] = 15;
+ }
+ }
+ }
+ /* << INDEX */
+}
+
+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(cio, J2K_MS_COD, 2); /* COD */
+
+ lenp = cio_tell(cio);
+ cio_skip(cio, 2);
+
+ 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(j2k, 0);
+ len = cio_tell(cio) - lenp;
+ cio_seek(cio, lenp);
+ cio_write(cio, len, 2); /* Lcod */
+ cio_seek(cio, lenp + len);
+}
+
+static void j2k_read_cod(opj_j2k_t *j2k) {
+ int len, i, pos;
+
+ 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;
+
+ 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(cio, pos);
+ j2k_read_cox(j2k, i);
+ }
+
+ /* Index */
+ if (j2k->cstr_info) {
+ opj_codestream_info_t *cstr_info = j2k->cstr_info;
+ cstr_info->prog = tcp->prg;
+ cstr_info->numlayers = tcp->numlayers;
+ cstr_info->numdecompos = (int*) opj_malloc(image->numcomps * sizeof(int));
+ for (i = 0; i < image->numcomps; i++) {
+ cstr_info->numdecompos[i] = tcp->tccps[i].numresolutions - 1;
+ }
+ }
+}
+
+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(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);
+}
+
+static void j2k_read_coc(opj_j2k_t *j2k) {
+ int len, compno;
+
+ 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;
+
+ 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);
+}
+
+static void j2k_write_qcx(opj_j2k_t *j2k, int compno) {
+ int bandno, numbands;
+ int expn, mant;
+
+ 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(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(cio, expn << 3, 1); /* SPqcx_i */
+ } else {
+ cio_write(cio, (expn << 11) + mant, 2); /* SPqcx_i */
+ }
+ }
+}
+
+static void j2k_read_qcx(opj_j2k_t *j2k, int compno, int len) {
+ int tmp;
+ int bandno, numbands;
+
+ 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);
+
+#ifdef USE_JPWL
+ if (j2k->cp->correct) {
+
+ /* if JPWL is on, we check whether there are too many subbands */
+ if ((numbands < 0) || (numbands >= J2K_MAXBANDS)) {
+ opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
+ "JPWL: bad number of subbands in Sqcx (%d)\n",
+ numbands);
+ if (!JPWL_ASSUME) {
+ opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
+ return;
+ }
+ /* we try to correct */
+ numbands = 1;
+ opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust them\n"
+ "- setting number of bands to %d => HYPOTHESIS!!!\n",
+ numbands);
+ };
+
+ };
+#endif /* USE_JPWL */
+
+ for (bandno = 0; bandno < numbands; bandno++) {
+ int expn, mant;
+ if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) {
+ expn = cio_read(cio, 1) >> 3; /* SPqcx_i */
+ mant = 0;
+ } else {
+ tmp = cio_read(cio, 2); /* SPqcx_i */
+ expn = tmp >> 11;
+ mant = tmp & 0x7ff;
+ }
+ tccp->stepsizes[bandno].expn = expn;
+ tccp->stepsizes[bandno].mant = mant;
+ }
+
+ /* Add Antonin : if scalar_derived -> compute other stepsizes */
+ if (tccp->qntsty == 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].mant = tccp->stepsizes[0].mant;
+ }
+ }
+ /* ddA */
+}
+
+static void j2k_write_qcd(opj_j2k_t *j2k) {
+ int lenp, len;
+
+ opj_cio_t *cio = j2k->cio;
+
+ 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);
+}
+
+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(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);
+ }
+}
+
+static void j2k_write_qcc(opj_j2k_t *j2k, int compno) {
+ int lenp, len;
+
+ opj_cio_t *cio = j2k->cio;
+
+ 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);
+}
+
+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(cio, 2); /* Lqcc */
+ compno = cio_read(cio, numcomp <= 256 ? 1 : 2); /* Cqcc */
+
+#ifdef USE_JPWL
+ if (j2k->cp->correct) {
+
+ static int backup_compno = 0;
+
+ /* compno is negative or larger than the number of components!!! */
+ if ((compno < 0) || (compno >= numcomp)) {
+ opj_event_msg(j2k->cinfo, EVT_ERROR,
+ "JPWL: bad component number in QCC (%d out of a maximum of %d)\n",
+ compno, numcomp);
+ if (!JPWL_ASSUME) {
+ opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
+ return;
+ }
+ /* we try to correct */
+ compno = backup_compno % numcomp;
+ opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust this\n"
+ "- setting component number to %d\n",
+ compno);
+ }
+
+ /* keep your private count of tiles */
+ backup_compno++;
+ };
+#endif /* USE_JPWL */
+
+ j2k_read_qcx(j2k, compno, len - 2 - (numcomp <= 256 ? 1 : 2));
+}
+
+static void j2k_write_poc(opj_j2k_t *j2k) {
+ int len, numpchgs, i;
+
+ int numcomps = j2k->image->numcomps;
+
+ 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 = 1 + tcp->numpocs;
+ 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++) {
+ opj_poc_t *poc = &tcp->pocs[i];
+ cio_write(cio, poc->resno0, 1); /* RSpoc_i */
+ cio_write(cio, poc->compno0, (numcomps <= 256 ? 1 : 2)); /* CSpoc_i */
+ cio_write(cio, poc->layno1, 2); /* LYEpoc_i */
+ poc->layno1 = int_min(poc->layno1, tcp->numlayers);
+ cio_write(cio, poc->resno1, 1); /* REpoc_i */
+ poc->resno1 = int_min(poc->resno1, tccp->numresolutions);
+ cio_write(cio, poc->compno1, (numcomps <= 256 ? 1 : 2)); /* CEpoc_i */
+ poc->compno1 = int_min(poc->compno1, numcomps);
+ cio_write(cio, poc->prg, 1); /* Ppoc_i */
+ }
+}
+
+static void j2k_read_poc(opj_j2k_t *j2k) {
+ int len, numpchgs, i, old_poc;
+
+ int numcomps = j2k->image->numcomps;
+
+ 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;
+
+ old_poc = tcp->POC ? tcp->numpocs + 1 : 0;
+ tcp->POC = 1;
+ len = cio_read(cio, 2); /* Lpoc */
+ numpchgs = (len - 2) / (5 + 2 * (numcomps <= 256 ? 1 : 2));
+
+ for (i = old_poc; i < numpchgs + old_poc; i++) {
+ opj_poc_t *poc;
+ poc = &tcp->pocs[i];
+ poc->resno0 = cio_read(cio, 1); /* RSpoc_i */
+ poc->compno0 = cio_read(cio, numcomps <= 256 ? 1 : 2); /* CSpoc_i */
+ poc->layno1 = cio_read(cio, 2); /* LYEpoc_i */
+ poc->resno1 = cio_read(cio, 1); /* REpoc_i */
+ poc->compno1 = int_min(
+ cio_read(cio, numcomps <= 256 ? 1 : 2), (unsigned int) numcomps); /* CEpoc_i */
+ poc->prg = (OPJ_PROG_ORDER)cio_read(cio, 1); /* Ppoc_i */
+ }
+
+ tcp->numpocs = numpchgs + old_poc - 1;
+}
+
+static void j2k_read_crg(opj_j2k_t *j2k) {
+ int len, i, Xcrg_i, 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 */
+ }
+}
+
+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(cio, 2); /* Ltlm */
+ Ztlm = cio_read(cio, 1); /* Ztlm */
+ Stlm = cio_read(cio, 1); /* Stlm */
+ ST = ((Stlm >> 4) & 0x01) + ((Stlm >> 4) & 0x02);
+ SP = (Stlm >> 6) & 0x01;
+ tile_tlm = (len - 4) / ((SP + 1) * 2 + ST);
+ for (i = 0; i < tile_tlm; i++) {
+ Ttlm_i = cio_read(cio, ST); /* Ttlm_i */
+ Ptlm_i = cio_read(cio, SP ? 4 : 2); /* Ptlm_i */
+ }
+}
+
+static void j2k_read_plm(opj_j2k_t *j2k) {
+ int len, i, Zplm, Nplm, add, packet_len = 0;
+
+ 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(cio, 4); /* Nplm */
+ len -= 4;
+ for (i = Nplm; i > 0; i--) {
+ add = cio_read(cio, 1);
+ len--;
+ packet_len = (packet_len << 7) + add; /* Iplm_ij */
+ if ((add & 0x80) == 0) {
+ /* New packet */
+ packet_len = 0;
+ }
+ if (len <= 0)
+ break;
+ }
+ }
+}
+
+static void j2k_read_plt(opj_j2k_t *j2k) {
+ int len, i, Zplt, packet_len = 0, add;
+
+ 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(cio, 1);
+ packet_len = (packet_len << 7) + add; /* Iplt_i */
+ if ((add & 0x80) == 0) {
+ /* New packet */
+ packet_len = 0;
+ }
+ }
+}