diff options
author | Alon Zakai <azakai@mozilla.com> | 2011-02-27 16:55:53 -0800 |
---|---|---|
committer | Alon Zakai <azakai@mozilla.com> | 2011-02-27 16:55:53 -0800 |
commit | 6b7f4ffa844bd3e1f2690af2501807e1da161034 (patch) | |
tree | 49ac3a5e35a09b09a1a2ad7aebbb8e9a6c86f263 /tests/openjpeg/libopenjpeg/j2k.c | |
parent | e932e70792a50786dedc0461697ed31c7ffa4bb2 (diff) |
openjpeg test
Diffstat (limited to 'tests/openjpeg/libopenjpeg/j2k.c')
-rw-r--r-- | tests/openjpeg/libopenjpeg/j2k.c | 2434 |
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; + } + } +} |