PageRenderTime 223ms CodeModel.GetById 37ms app.highlight 167ms RepoModel.GetById 1ms app.codeStats 0ms

/src/FreeImage/Source/LibOpenJPEG/j2k.c

https://bitbucket.org/cabalistic/ogredeps/
C | 2534 lines | 1799 code | 348 blank | 387 comment | 376 complexity | 7c3951d52c2de93f0d3640ef51d5ada6 MD5 | raw file
   1/*
   2 * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
   3 * Copyright (c) 2002-2007, Professor Benoit Macq
   4 * Copyright (c) 2001-2003, David Janssens
   5 * Copyright (c) 2002-2003, Yannick Verschueren
   6 * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
   7 * Copyright (c) 2005, Herve Drolon, FreeImage Team
   8 * Copyright (c) 2006-2007, Parvatha Elangovan
   9 * Copyright (c) 2010-2011, Kaori Hagihara
  10 * All rights reserved.
  11 *
  12 * Redistribution and use in source and binary forms, with or without
  13 * modification, are permitted provided that the following conditions
  14 * are met:
  15 * 1. Redistributions of source code must retain the above copyright
  16 *    notice, this list of conditions and the following disclaimer.
  17 * 2. Redistributions in binary form must reproduce the above copyright
  18 *    notice, this list of conditions and the following disclaimer in the
  19 *    documentation and/or other materials provided with the distribution.
  20 *
  21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
  22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  31 * POSSIBILITY OF SUCH DAMAGE.
  32 */
  33
  34#include "opj_includes.h"
  35
  36/** @defgroup J2K J2K - JPEG-2000 codestream reader/writer */
  37/*@{*/
  38
  39/** @name Local static functions */
  40/*@{*/
  41
  42/**
  43Write the SOC marker (Start Of Codestream)
  44@param j2k J2K handle
  45*/
  46static void j2k_write_soc(opj_j2k_t *j2k);
  47/**
  48Read the SOC marker (Start of Codestream)
  49@param j2k J2K handle
  50*/
  51static void j2k_read_soc(opj_j2k_t *j2k);
  52/**
  53Write the SIZ marker (image and tile size)
  54@param j2k J2K handle
  55*/
  56static void j2k_write_siz(opj_j2k_t *j2k);
  57/**
  58Read the SIZ marker (image and tile size)
  59@param j2k J2K handle
  60*/
  61static void j2k_read_siz(opj_j2k_t *j2k);
  62/**
  63Write the COM marker (comment)
  64@param j2k J2K handle
  65*/
  66static void j2k_write_com(opj_j2k_t *j2k);
  67/**
  68Read the COM marker (comment)
  69@param j2k J2K handle
  70*/
  71static void j2k_read_com(opj_j2k_t *j2k);
  72/**
  73Write the value concerning the specified component in the marker COD and COC
  74@param j2k J2K handle
  75@param compno Number of the component concerned by the information written
  76*/
  77static void j2k_write_cox(opj_j2k_t *j2k, int compno);
  78/**
  79Read the value concerning the specified component in the marker COD and COC
  80@param j2k J2K handle
  81@param compno Number of the component concerned by the information read
  82*/
  83static void j2k_read_cox(opj_j2k_t *j2k, int compno);
  84/**
  85Write the COD marker (coding style default)
  86@param j2k J2K handle
  87*/
  88static void j2k_write_cod(opj_j2k_t *j2k);
  89/**
  90Read the COD marker (coding style default)
  91@param j2k J2K handle
  92*/
  93static void j2k_read_cod(opj_j2k_t *j2k);
  94/**
  95Write the COC marker (coding style component)
  96@param j2k J2K handle
  97@param compno Number of the component concerned by the information written
  98*/
  99static void j2k_write_coc(opj_j2k_t *j2k, int compno);
 100/**
 101Read the COC marker (coding style component)
 102@param j2k J2K handle
 103*/
 104static void j2k_read_coc(opj_j2k_t *j2k);
 105/**
 106Write the value concerning the specified component in the marker QCD and QCC
 107@param j2k J2K handle
 108@param compno Number of the component concerned by the information written
 109*/
 110static void j2k_write_qcx(opj_j2k_t *j2k, int compno);
 111/**
 112Read the value concerning the specified component in the marker QCD and QCC
 113@param j2k J2K handle
 114@param compno Number of the component concern by the information read
 115@param len Length of the information in the QCX part of the marker QCD/QCC
 116*/
 117static void j2k_read_qcx(opj_j2k_t *j2k, int compno, int len);
 118/**
 119Write the QCD marker (quantization default)
 120@param j2k J2K handle
 121*/
 122static void j2k_write_qcd(opj_j2k_t *j2k);
 123/**
 124Read the QCD marker (quantization default)
 125@param j2k J2K handle
 126*/
 127static void j2k_read_qcd(opj_j2k_t *j2k);
 128/**
 129Write the QCC marker (quantization component)
 130@param j2k J2K handle
 131@param compno Number of the component concerned by the information written
 132*/
 133static void j2k_write_qcc(opj_j2k_t *j2k, int compno);
 134/**
 135Read the QCC marker (quantization component)
 136@param j2k J2K handle
 137*/
 138static void j2k_read_qcc(opj_j2k_t *j2k);
 139/**
 140Write the POC marker (progression order change)
 141@param j2k J2K handle
 142*/
 143static void j2k_write_poc(opj_j2k_t *j2k);
 144/**
 145Read the POC marker (progression order change)
 146@param j2k J2K handle
 147*/
 148static void j2k_read_poc(opj_j2k_t *j2k);
 149/**
 150Read the CRG marker (component registration)
 151@param j2k J2K handle
 152*/
 153static void j2k_read_crg(opj_j2k_t *j2k);
 154/**
 155Read the TLM marker (tile-part lengths)
 156@param j2k J2K handle
 157*/
 158static void j2k_read_tlm(opj_j2k_t *j2k);
 159/**
 160Read the PLM marker (packet length, main header)
 161@param j2k J2K handle
 162*/
 163static void j2k_read_plm(opj_j2k_t *j2k);
 164/**
 165Read the PLT marker (packet length, tile-part header)
 166@param j2k J2K handle
 167*/
 168static void j2k_read_plt(opj_j2k_t *j2k);
 169/**
 170Read the PPM marker (packet packet headers, main header)
 171@param j2k J2K handle
 172*/
 173static void j2k_read_ppm(opj_j2k_t *j2k);
 174/**
 175Read the PPT marker (packet packet headers, tile-part header)
 176@param j2k J2K handle
 177*/
 178static void j2k_read_ppt(opj_j2k_t *j2k);
 179/**
 180Write the TLM marker (Mainheader)
 181@param j2k J2K handle
 182*/
 183static void j2k_write_tlm(opj_j2k_t *j2k);
 184/**
 185Write the SOT marker (start of tile-part)
 186@param j2k J2K handle
 187*/
 188static void j2k_write_sot(opj_j2k_t *j2k);
 189/**
 190Read the SOT marker (start of tile-part)
 191@param j2k J2K handle
 192*/
 193static void j2k_read_sot(opj_j2k_t *j2k);
 194/**
 195Write the SOD marker (start of data)
 196@param j2k J2K handle
 197@param tile_coder Pointer to a TCD handle
 198*/
 199static void j2k_write_sod(opj_j2k_t *j2k, void *tile_coder);
 200/**
 201Read the SOD marker (start of data)
 202@param j2k J2K handle
 203*/
 204static void j2k_read_sod(opj_j2k_t *j2k);
 205/**
 206Write the RGN marker (region-of-interest)
 207@param j2k J2K handle
 208@param compno Number of the component concerned by the information written
 209@param tileno Number of the tile concerned by the information written
 210*/
 211static void j2k_write_rgn(opj_j2k_t *j2k, int compno, int tileno);
 212/**
 213Read the RGN marker (region-of-interest)
 214@param j2k J2K handle
 215*/
 216static void j2k_read_rgn(opj_j2k_t *j2k);
 217/**
 218Write the EOC marker (end of codestream)
 219@param j2k J2K handle
 220*/
 221static void j2k_write_eoc(opj_j2k_t *j2k);
 222/**
 223Read the EOC marker (end of codestream)
 224@param j2k J2K handle
 225*/
 226static void j2k_read_eoc(opj_j2k_t *j2k);
 227/**
 228Read an unknown marker
 229@param j2k J2K handle
 230*/
 231static void j2k_read_unk(opj_j2k_t *j2k);
 232/**
 233Add main header marker information
 234@param cstr_info Codestream information structure
 235@param type marker type
 236@param pos byte offset of marker segment
 237@param len length of marker segment
 238 */
 239static void j2k_add_mhmarker(opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len);
 240/**
 241Add tile header marker information
 242@param tileno tile index number
 243@param cstr_info Codestream information structure
 244@param type marker type
 245@param pos byte offset of marker segment
 246@param len length of marker segment
 247 */
 248static void j2k_add_tlmarker( int tileno, opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len);
 249
 250/*@}*/
 251
 252/*@}*/
 253
 254/* ----------------------------------------------------------------------- */
 255typedef struct j2k_prog_order{
 256	OPJ_PROG_ORDER enum_prog;
 257	char str_prog[5];
 258}j2k_prog_order_t;
 259
 260j2k_prog_order_t j2k_prog_order_list[] = {
 261	{CPRL, "CPRL"},
 262	{LRCP, "LRCP"},
 263	{PCRL, "PCRL"},
 264	{RLCP, "RLCP"},
 265	{RPCL, "RPCL"},
 266	{(OPJ_PROG_ORDER)-1, ""}
 267};
 268
 269char *j2k_convert_progression_order(OPJ_PROG_ORDER prg_order){
 270	j2k_prog_order_t *po;
 271	for(po = j2k_prog_order_list; po->enum_prog != -1; po++ ){
 272		if(po->enum_prog == prg_order){
 273			break;
 274		}
 275	}
 276	return po->str_prog;
 277}
 278
 279/* ----------------------------------------------------------------------- */
 280static int j2k_get_num_tp(opj_cp_t *cp,int pino,int tileno){
 281	char *prog;
 282	int i;
 283	int tpnum=1,tpend=0;
 284	opj_tcp_t *tcp = &cp->tcps[tileno];
 285	prog = j2k_convert_progression_order(tcp->prg);
 286	
 287	if(cp->tp_on == 1){
 288		for(i=0;i<4;i++){
 289			if(tpend!=1){
 290				if( cp->tp_flag == prog[i] ){
 291					tpend=1;cp->tp_pos=i;
 292				}
 293				switch(prog[i]){
 294				case 'C':
 295					tpnum= tpnum * tcp->pocs[pino].compE;
 296					break;
 297				case 'R':
 298					tpnum= tpnum * tcp->pocs[pino].resE;
 299					break;
 300				case 'P':
 301					tpnum= tpnum * tcp->pocs[pino].prcE;
 302					break;
 303				case 'L':
 304					tpnum= tpnum * tcp->pocs[pino].layE;
 305					break;
 306				}
 307			}
 308		}
 309	}else{
 310		tpnum=1;
 311	}
 312	return tpnum;
 313}
 314
 315/**	mem allocation for TLM marker*/
 316int j2k_calculate_tp(opj_cp_t *cp,int img_numcomp,opj_image_t *image,opj_j2k_t *j2k ){
 317	int pino,tileno,totnum_tp=0;
 318
 319	OPJ_ARG_NOT_USED(img_numcomp);
 320
 321	j2k->cur_totnum_tp = (int *) opj_malloc(cp->tw * cp->th * sizeof(int));
 322	for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
 323		int cur_totnum_tp = 0;
 324		opj_tcp_t *tcp = &cp->tcps[tileno];
 325		for(pino = 0; pino <= tcp->numpocs; pino++) {
 326			int tp_num=0;
 327			opj_pi_iterator_t *pi = pi_initialise_encode(image, cp, tileno,FINAL_PASS);
 328			if(!pi) { return -1;}
 329			tp_num = j2k_get_num_tp(cp,pino,tileno);
 330			totnum_tp = totnum_tp + tp_num;
 331			cur_totnum_tp = cur_totnum_tp + tp_num;
 332			pi_destroy(pi, cp, tileno);
 333		}
 334		j2k->cur_totnum_tp[tileno] = cur_totnum_tp;
 335		/* INDEX >> */
 336		if (j2k->cstr_info) {
 337			j2k->cstr_info->tile[tileno].num_tps = cur_totnum_tp;
 338			j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_malloc(cur_totnum_tp * sizeof(opj_tp_info_t));
 339		}
 340		/* << INDEX */
 341	}
 342	return totnum_tp;
 343}
 344
 345static void j2k_write_soc(opj_j2k_t *j2k) {
 346	opj_cio_t *cio = j2k->cio;
 347	cio_write(cio, J2K_MS_SOC, 2);
 348
 349	if(j2k->cstr_info)
 350	  j2k_add_mhmarker(j2k->cstr_info, J2K_MS_SOC, cio_tell(cio), 0);
 351
 352/* UniPG>> */
 353#ifdef USE_JPWL
 354
 355	/* update markers struct */
 356	j2k_add_marker(j2k->cstr_info, J2K_MS_SOC, cio_tell(cio) - 2, 2);
 357#endif /* USE_JPWL */
 358/* <<UniPG */
 359}
 360
 361static void j2k_read_soc(opj_j2k_t *j2k) {	
 362	j2k->state = J2K_STATE_MHSIZ;
 363	/* Index */
 364	if (j2k->cstr_info) {
 365		j2k->cstr_info->main_head_start = cio_tell(j2k->cio) - 2;
 366		j2k->cstr_info->codestream_size = cio_numbytesleft(j2k->cio) + 2 - j2k->cstr_info->main_head_start;
 367	}
 368}
 369
 370static void j2k_write_siz(opj_j2k_t *j2k) {
 371	int i;
 372	int lenp, len;
 373
 374	opj_cio_t *cio = j2k->cio;
 375	opj_image_t *image = j2k->image;
 376	opj_cp_t *cp = j2k->cp;
 377
 378	cio_write(cio, J2K_MS_SIZ, 2);	/* SIZ */
 379	lenp = cio_tell(cio);
 380	cio_skip(cio, 2);
 381	cio_write(cio, cp->rsiz, 2);			/* Rsiz (capabilities) */
 382	cio_write(cio, image->x1, 4);	/* Xsiz */
 383	cio_write(cio, image->y1, 4);	/* Ysiz */
 384	cio_write(cio, image->x0, 4);	/* X0siz */
 385	cio_write(cio, image->y0, 4);	/* Y0siz */
 386	cio_write(cio, cp->tdx, 4);		/* XTsiz */
 387	cio_write(cio, cp->tdy, 4);		/* YTsiz */
 388	cio_write(cio, cp->tx0, 4);		/* XT0siz */
 389	cio_write(cio, cp->ty0, 4);		/* YT0siz */
 390	cio_write(cio, image->numcomps, 2);	/* Csiz */
 391	for (i = 0; i < image->numcomps; i++) {
 392		cio_write(cio, image->comps[i].prec - 1 + (image->comps[i].sgnd << 7), 1);	/* Ssiz_i */
 393		cio_write(cio, image->comps[i].dx, 1);	/* XRsiz_i */
 394		cio_write(cio, image->comps[i].dy, 1);	/* YRsiz_i */
 395	}
 396	len = cio_tell(cio) - lenp;
 397	cio_seek(cio, lenp);
 398	cio_write(cio, len, 2);		/* Lsiz */
 399	cio_seek(cio, lenp + len);
 400	
 401	if(j2k->cstr_info)
 402	  j2k_add_mhmarker(j2k->cstr_info, J2K_MS_SIZ, lenp, len);
 403}
 404
 405static void j2k_read_siz(opj_j2k_t *j2k) {
 406	int len, i;
 407	
 408	opj_cio_t *cio = j2k->cio;
 409	opj_image_t *image = j2k->image;
 410	opj_cp_t *cp = j2k->cp;
 411	
 412	len = cio_read(cio, 2);			/* Lsiz */
 413	cio_read(cio, 2);				/* Rsiz (capabilities) */
 414	image->x1 = cio_read(cio, 4);	/* Xsiz */
 415	image->y1 = cio_read(cio, 4);	/* Ysiz */
 416	image->x0 = cio_read(cio, 4);	/* X0siz */
 417	image->y0 = cio_read(cio, 4);	/* Y0siz */
 418	cp->tdx = cio_read(cio, 4);		/* XTsiz */
 419	cp->tdy = cio_read(cio, 4);		/* YTsiz */
 420	cp->tx0 = cio_read(cio, 4);		/* XT0siz */
 421	cp->ty0 = cio_read(cio, 4);		/* YT0siz */
 422	
 423	if ((image->x0<0)||(image->x1<0)||(image->y0<0)||(image->y1<0)) {
 424		opj_event_msg(j2k->cinfo, EVT_ERROR,
 425									"%s: invalid image size (x0:%d, x1:%d, y0:%d, y1:%d)\n",
 426									image->x0,image->x1,image->y0,image->y1);
 427		return;
 428	}
 429	
 430	image->numcomps = cio_read(cio, 2);	/* Csiz */
 431
 432#ifdef USE_JPWL
 433	if (j2k->cp->correct) {
 434		/* if JPWL is on, we check whether TX errors have damaged
 435		  too much the SIZ parameters */
 436		if (!(image->x1 * image->y1)) {
 437			opj_event_msg(j2k->cinfo, EVT_ERROR,
 438				"JPWL: bad image size (%d x %d)\n",
 439				image->x1, image->y1);
 440			if (!JPWL_ASSUME || JPWL_ASSUME) {
 441				opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
 442				return;
 443			}
 444		}
 445		if (image->numcomps != ((len - 38) / 3)) {
 446			opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
 447				"JPWL: Csiz is %d => space in SIZ only for %d comps.!!!\n",
 448				image->numcomps, ((len - 38) / 3));
 449			if (!JPWL_ASSUME) {
 450				opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
 451				return;
 452			}
 453			/* we try to correct */
 454			opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust this\n");
 455			if (image->numcomps < ((len - 38) / 3)) {
 456				len = 38 + 3 * image->numcomps;
 457				opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting Lsiz to %d => HYPOTHESIS!!!\n",
 458					len);				
 459			} else {
 460				image->numcomps = ((len - 38) / 3);
 461				opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting Csiz to %d => HYPOTHESIS!!!\n",
 462					image->numcomps);				
 463			}
 464		}
 465
 466		/* update components number in the jpwl_exp_comps filed */
 467		cp->exp_comps = image->numcomps;
 468	}
 469#endif /* USE_JPWL */
 470
 471	image->comps = (opj_image_comp_t*) opj_calloc(image->numcomps, sizeof(opj_image_comp_t));
 472	for (i = 0; i < image->numcomps; i++) {
 473		int tmp, w, h;
 474		tmp = cio_read(cio, 1);		/* Ssiz_i */
 475		image->comps[i].prec = (tmp & 0x7f) + 1;
 476		image->comps[i].sgnd = tmp >> 7;
 477		image->comps[i].dx = cio_read(cio, 1);	/* XRsiz_i */
 478		image->comps[i].dy = cio_read(cio, 1);	/* YRsiz_i */
 479		
 480#ifdef USE_JPWL
 481		if (j2k->cp->correct) {
 482		/* if JPWL is on, we check whether TX errors have damaged
 483			too much the SIZ parameters, again */
 484			if (!(image->comps[i].dx * image->comps[i].dy)) {
 485				opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
 486					"JPWL: bad XRsiz_%d/YRsiz_%d (%d x %d)\n",
 487					i, i, image->comps[i].dx, image->comps[i].dy);
 488				if (!JPWL_ASSUME) {
 489					opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
 490					return;
 491				}
 492				/* we try to correct */
 493				opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust them\n");
 494				if (!image->comps[i].dx) {
 495					image->comps[i].dx = 1;
 496					opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting XRsiz_%d to %d => HYPOTHESIS!!!\n",
 497						i, image->comps[i].dx);
 498				}
 499				if (!image->comps[i].dy) {
 500					image->comps[i].dy = 1;
 501					opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting YRsiz_%d to %d => HYPOTHESIS!!!\n",
 502						i, image->comps[i].dy);
 503				}
 504			}
 505			
 506		}
 507#endif /* USE_JPWL */
 508
 509		/* TODO: unused ? */
 510		w = int_ceildiv(image->x1 - image->x0, image->comps[i].dx);
 511		h = int_ceildiv(image->y1 - image->y0, image->comps[i].dy);
 512
 513		image->comps[i].resno_decoded = 0;	/* number of resolution decoded */
 514		image->comps[i].factor = cp->reduce; /* reducing factor per component */
 515	}
 516	
 517	cp->tw = int_ceildiv(image->x1 - cp->tx0, cp->tdx);
 518	cp->th = int_ceildiv(image->y1 - cp->ty0, cp->tdy);
 519
 520#ifdef USE_JPWL
 521	if (j2k->cp->correct) {
 522		/* if JPWL is on, we check whether TX errors have damaged
 523		  too much the SIZ parameters */
 524		if ((cp->tw < 1) || (cp->th < 1) || (cp->tw > cp->max_tiles) || (cp->th > cp->max_tiles)) {
 525			opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
 526				"JPWL: bad number of tiles (%d x %d)\n",
 527				cp->tw, cp->th);
 528			if (!JPWL_ASSUME) {
 529				opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
 530				return;
 531			}
 532			/* we try to correct */
 533			opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust them\n");
 534			if (cp->tw < 1) {
 535				cp->tw= 1;
 536				opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting %d tiles in x => HYPOTHESIS!!!\n",
 537					cp->tw);
 538			}
 539			if (cp->tw > cp->max_tiles) {
 540				cp->tw= 1;
 541				opj_event_msg(j2k->cinfo, EVT_WARNING, "- too large x, increase expectance of %d\n"
 542					"- setting %d tiles in x => HYPOTHESIS!!!\n",
 543					cp->max_tiles, cp->tw);
 544			}
 545			if (cp->th < 1) {
 546				cp->th= 1;
 547				opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting %d tiles in y => HYPOTHESIS!!!\n",
 548					cp->th);
 549			}
 550			if (cp->th > cp->max_tiles) {
 551				cp->th= 1;
 552				opj_event_msg(j2k->cinfo, EVT_WARNING, "- too large y, increase expectance of %d to continue\n",
 553					"- setting %d tiles in y => HYPOTHESIS!!!\n",
 554					cp->max_tiles, cp->th);
 555			}
 556		}
 557	}
 558#endif /* USE_JPWL */
 559
 560	cp->tcps = (opj_tcp_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tcp_t));
 561	cp->tileno = (int*) opj_malloc(cp->tw * cp->th * sizeof(int));
 562	cp->tileno_size = 0;
 563	
 564#ifdef USE_JPWL
 565	if (j2k->cp->correct) {
 566		if (!cp->tcps) {
 567			opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
 568				"JPWL: could not alloc tcps field of cp\n");
 569			if (!JPWL_ASSUME || JPWL_ASSUME) {
 570				opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
 571				return;
 572			}
 573		}
 574	}
 575#endif /* USE_JPWL */
 576
 577	for (i = 0; i < cp->tw * cp->th; i++) {
 578		cp->tcps[i].POC = 0;
 579		cp->tcps[i].numpocs = 0;
 580		cp->tcps[i].first = 1;
 581	}
 582	
 583	/* Initialization for PPM marker */
 584	cp->ppm = 0;
 585	cp->ppm_data = NULL;
 586	cp->ppm_data_first = NULL;
 587	cp->ppm_previous = 0;
 588	cp->ppm_store = 0;
 589
 590	j2k->default_tcp->tccps = (opj_tccp_t*) opj_calloc(image->numcomps, sizeof(opj_tccp_t));
 591	for (i = 0; i < cp->tw * cp->th; i++) {
 592		cp->tcps[i].tccps = (opj_tccp_t*) opj_malloc(image->numcomps * sizeof(opj_tccp_t));
 593	}	
 594	j2k->tile_data = (unsigned char**) opj_calloc(cp->tw * cp->th, sizeof(unsigned char*));
 595	j2k->tile_len = (int*) opj_calloc(cp->tw * cp->th, sizeof(int));
 596	j2k->state = J2K_STATE_MH;
 597
 598	/* Index */
 599	if (j2k->cstr_info) {
 600		opj_codestream_info_t *cstr_info = j2k->cstr_info;
 601		cstr_info->image_w = image->x1 - image->x0;
 602		cstr_info->image_h = image->y1 - image->y0;
 603		cstr_info->numcomps = image->numcomps;
 604		cstr_info->tw = cp->tw;
 605		cstr_info->th = cp->th;
 606		cstr_info->tile_x = cp->tdx;	
 607		cstr_info->tile_y = cp->tdy;	
 608		cstr_info->tile_Ox = cp->tx0;	
 609		cstr_info->tile_Oy = cp->ty0;			
 610		cstr_info->tile = (opj_tile_info_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tile_info_t));		
 611	}
 612}
 613
 614static void j2k_write_com(opj_j2k_t *j2k) {
 615	unsigned int i;
 616	int lenp, len;
 617
 618	if(j2k->cp->comment) {
 619		opj_cio_t *cio = j2k->cio;
 620		char *comment = j2k->cp->comment;
 621
 622		cio_write(cio, J2K_MS_COM, 2);
 623		lenp = cio_tell(cio);
 624		cio_skip(cio, 2);
 625		cio_write(cio, 1, 2);		/* General use (IS 8859-15:1999 (Latin) values) */
 626		for (i = 0; i < strlen(comment); i++) {
 627			cio_write(cio, comment[i], 1);
 628		}
 629		len = cio_tell(cio) - lenp;
 630		cio_seek(cio, lenp);
 631		cio_write(cio, len, 2);
 632		cio_seek(cio, lenp + len);
 633
 634		
 635		if(j2k->cstr_info)
 636		  j2k_add_mhmarker(j2k->cstr_info, J2K_MS_COM, lenp, len);
 637
 638	}
 639}
 640
 641static void j2k_read_com(opj_j2k_t *j2k) {
 642	int len;
 643	
 644	opj_cio_t *cio = j2k->cio;
 645
 646	len = cio_read(cio, 2);
 647	cio_skip(cio, len - 2);  
 648}
 649
 650static void j2k_write_cox(opj_j2k_t *j2k, int compno) {
 651	int i;
 652
 653	opj_cp_t *cp = j2k->cp;
 654	opj_tcp_t *tcp = &cp->tcps[j2k->curtileno];
 655	opj_tccp_t *tccp = &tcp->tccps[compno];
 656	opj_cio_t *cio = j2k->cio;
 657	
 658	cio_write(cio, tccp->numresolutions - 1, 1);	/* SPcox (D) */
 659	cio_write(cio, tccp->cblkw - 2, 1);				/* SPcox (E) */
 660	cio_write(cio, tccp->cblkh - 2, 1);				/* SPcox (F) */
 661	cio_write(cio, tccp->cblksty, 1);				/* SPcox (G) */
 662	cio_write(cio, tccp->qmfbid, 1);				/* SPcox (H) */
 663	
 664	if (tccp->csty & J2K_CCP_CSTY_PRT) {
 665		for (i = 0; i < tccp->numresolutions; i++) {
 666			cio_write(cio, tccp->prcw[i] + (tccp->prch[i] << 4), 1);	/* SPcox (I_i) */
 667		}
 668	}
 669}
 670
 671static void j2k_read_cox(opj_j2k_t *j2k, int compno) {
 672	int i;
 673
 674	opj_cp_t *cp = j2k->cp;
 675	opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp;
 676	opj_tccp_t *tccp = &tcp->tccps[compno];
 677	opj_cio_t *cio = j2k->cio;
 678
 679	tccp->numresolutions = cio_read(cio, 1) + 1;	/* SPcox (D) */
 680
 681	/* If user wants to remove more resolutions than the codestream contains, return error*/
 682	if (cp->reduce >= tccp->numresolutions) {
 683		opj_event_msg(j2k->cinfo, EVT_ERROR, "Error decoding component %d.\nThe number of resolutions to remove is higher than the number "
 684					"of resolutions of this component\nModify the cp_reduce parameter.\n\n", compno);
 685		j2k->state |= J2K_STATE_ERR;
 686	}
 687
 688	tccp->cblkw = cio_read(cio, 1) + 2;	/* SPcox (E) */
 689	tccp->cblkh = cio_read(cio, 1) + 2;	/* SPcox (F) */
 690	tccp->cblksty = cio_read(cio, 1);	/* SPcox (G) */
 691	tccp->qmfbid = cio_read(cio, 1);	/* SPcox (H) */
 692	if (tccp->csty & J2K_CP_CSTY_PRT) {
 693		for (i = 0; i < tccp->numresolutions; i++) {
 694			int tmp = cio_read(cio, 1);	/* SPcox (I_i) */
 695			tccp->prcw[i] = tmp & 0xf;
 696			tccp->prch[i] = tmp >> 4;
 697		}
 698	}
 699
 700	/* INDEX >> */
 701	if(j2k->cstr_info && compno == 0) {
 702		for (i = 0; i < tccp->numresolutions; i++) {
 703			if (tccp->csty & J2K_CP_CSTY_PRT) {
 704				j2k->cstr_info->tile[j2k->curtileno].pdx[i] = tccp->prcw[i];
 705				j2k->cstr_info->tile[j2k->curtileno].pdy[i] = tccp->prch[i];
 706			}
 707			else {
 708				j2k->cstr_info->tile[j2k->curtileno].pdx[i] = 15;
 709				j2k->cstr_info->tile[j2k->curtileno].pdx[i] = 15;
 710			}
 711		}
 712	}
 713	/* << INDEX */
 714}
 715
 716static void j2k_write_cod(opj_j2k_t *j2k) {
 717	opj_cp_t *cp = NULL;
 718	opj_tcp_t *tcp = NULL;
 719	int lenp, len;
 720
 721	opj_cio_t *cio = j2k->cio;
 722	
 723	cio_write(cio, J2K_MS_COD, 2);	/* COD */
 724	
 725	lenp = cio_tell(cio);
 726	cio_skip(cio, 2);
 727	
 728	cp = j2k->cp;
 729	tcp = &cp->tcps[j2k->curtileno];
 730
 731	cio_write(cio, tcp->csty, 1);		/* Scod */
 732	cio_write(cio, tcp->prg, 1);		/* SGcod (A) */
 733	cio_write(cio, tcp->numlayers, 2);	/* SGcod (B) */
 734	cio_write(cio, tcp->mct, 1);		/* SGcod (C) */
 735	
 736	j2k_write_cox(j2k, 0);
 737	len = cio_tell(cio) - lenp;
 738	cio_seek(cio, lenp);
 739	cio_write(cio, len, 2);		/* Lcod */
 740	cio_seek(cio, lenp + len);
 741
 742	if(j2k->cstr_info)
 743	  j2k_add_mhmarker(j2k->cstr_info, J2K_MS_COD, lenp, len);
 744
 745}
 746
 747static void j2k_read_cod(opj_j2k_t *j2k) {
 748	int len, i, pos;
 749	
 750	opj_cio_t *cio = j2k->cio;
 751	opj_cp_t *cp = j2k->cp;
 752	opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp;
 753	opj_image_t *image = j2k->image;
 754	
 755	len = cio_read(cio, 2);				/* Lcod */
 756	tcp->csty = cio_read(cio, 1);		/* Scod */
 757	tcp->prg = (OPJ_PROG_ORDER)cio_read(cio, 1);		/* SGcod (A) */
 758	tcp->numlayers = cio_read(cio, 2);	/* SGcod (B) */
 759	tcp->mct = cio_read(cio, 1);		/* SGcod (C) */
 760	
 761	pos = cio_tell(cio);
 762	for (i = 0; i < image->numcomps; i++) {
 763		tcp->tccps[i].csty = tcp->csty & J2K_CP_CSTY_PRT;
 764		cio_seek(cio, pos);
 765		j2k_read_cox(j2k, i);
 766	}
 767
 768	/* Index */
 769	if (j2k->cstr_info) {
 770		opj_codestream_info_t *cstr_info = j2k->cstr_info;
 771		cstr_info->prog = tcp->prg;
 772		cstr_info->numlayers = tcp->numlayers;
 773		cstr_info->numdecompos = (int*) opj_malloc(image->numcomps * sizeof(int));
 774		for (i = 0; i < image->numcomps; i++) {
 775			cstr_info->numdecompos[i] = tcp->tccps[i].numresolutions - 1;
 776		}
 777	}
 778}
 779
 780static void j2k_write_coc(opj_j2k_t *j2k, int compno) {
 781	int lenp, len;
 782
 783	opj_cp_t *cp = j2k->cp;
 784	opj_tcp_t *tcp = &cp->tcps[j2k->curtileno];
 785	opj_image_t *image = j2k->image;
 786	opj_cio_t *cio = j2k->cio;
 787	
 788	cio_write(cio, J2K_MS_COC, 2);	/* COC */
 789	lenp = cio_tell(cio);
 790	cio_skip(cio, 2);
 791	cio_write(cio, compno, image->numcomps <= 256 ? 1 : 2);	/* Ccoc */
 792	cio_write(cio, tcp->tccps[compno].csty, 1);	/* Scoc */
 793	j2k_write_cox(j2k, compno);
 794	len = cio_tell(cio) - lenp;
 795	cio_seek(cio, lenp);
 796	cio_write(cio, len, 2);			/* Lcoc */
 797	cio_seek(cio, lenp + len);
 798}
 799
 800static void j2k_read_coc(opj_j2k_t *j2k) {
 801	int len, compno;
 802
 803	opj_cp_t *cp = j2k->cp;
 804	opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp;
 805	opj_image_t *image = j2k->image;
 806	opj_cio_t *cio = j2k->cio;
 807	
 808	len = cio_read(cio, 2);		/* Lcoc */
 809	compno = cio_read(cio, image->numcomps <= 256 ? 1 : 2);	/* Ccoc */
 810	tcp->tccps[compno].csty = cio_read(cio, 1);	/* Scoc */
 811	j2k_read_cox(j2k, compno);
 812}
 813
 814static void j2k_write_qcx(opj_j2k_t *j2k, int compno) {
 815	int bandno, numbands;
 816	int expn, mant;
 817	
 818	opj_cp_t *cp = j2k->cp;
 819	opj_tcp_t *tcp = &cp->tcps[j2k->curtileno];
 820	opj_tccp_t *tccp = &tcp->tccps[compno];
 821	opj_cio_t *cio = j2k->cio;
 822	
 823	cio_write(cio, tccp->qntsty + (tccp->numgbits << 5), 1);	/* Sqcx */
 824	numbands = tccp->qntsty == J2K_CCP_QNTSTY_SIQNT ? 1 : tccp->numresolutions * 3 - 2;
 825	
 826	for (bandno = 0; bandno < numbands; bandno++) {
 827		expn = tccp->stepsizes[bandno].expn;
 828		mant = tccp->stepsizes[bandno].mant;
 829		
 830		if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) {
 831			cio_write(cio, expn << 3, 1);	/* SPqcx_i */
 832		} else {
 833			cio_write(cio, (expn << 11) + mant, 2);	/* SPqcx_i */
 834		}
 835	}
 836}
 837
 838static void j2k_read_qcx(opj_j2k_t *j2k, int compno, int len) {
 839	int tmp;
 840	int bandno, numbands;
 841
 842	opj_cp_t *cp = j2k->cp;
 843	opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp;
 844	opj_tccp_t *tccp = &tcp->tccps[compno];
 845	opj_cio_t *cio = j2k->cio;
 846
 847	tmp = cio_read(cio, 1);		/* Sqcx */
 848	tccp->qntsty = tmp & 0x1f;
 849	tccp->numgbits = tmp >> 5;
 850	numbands = (tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? 
 851		1 : ((tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) ? len - 1 : (len - 1) / 2);
 852
 853#ifdef USE_JPWL
 854	if (j2k->cp->correct) {
 855
 856		/* if JPWL is on, we check whether there are too many subbands */
 857		if ((numbands < 0) || (numbands >= J2K_MAXBANDS)) {
 858			opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
 859				"JPWL: bad number of subbands in Sqcx (%d)\n",
 860				numbands);
 861			if (!JPWL_ASSUME) {
 862				opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
 863				return;
 864			}
 865			/* we try to correct */
 866			numbands = 1;
 867			opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust them\n"
 868				"- setting number of bands to %d => HYPOTHESIS!!!\n",
 869				numbands);
 870		};
 871
 872	};
 873
 874#else
 875	/* We check whether there are too many subbands */
 876	if ((numbands < 0) || (numbands >= J2K_MAXBANDS)) {
 877		opj_event_msg(j2k->cinfo, EVT_WARNING ,
 878					"bad number of subbands in Sqcx (%d) regarding to J2K_MAXBANDS (%d) \n"
 879				    "- limiting number of bands to J2K_MAXBANDS and try to move to the next markers\n", numbands, J2K_MAXBANDS);
 880	}
 881
 882#endif /* USE_JPWL */
 883
 884	for (bandno = 0; bandno < numbands; bandno++) {
 885		int expn, mant;
 886		if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) {
 887			expn = cio_read(cio, 1) >> 3;	/* SPqcx_i */
 888			mant = 0;
 889		} else {
 890			tmp = cio_read(cio, 2);	/* SPqcx_i */
 891			expn = tmp >> 11;
 892			mant = tmp & 0x7ff;
 893		}
 894		if (bandno < J2K_MAXBANDS){
 895			tccp->stepsizes[bandno].expn = expn;
 896			tccp->stepsizes[bandno].mant = mant;
 897		}
 898	}
 899	
 900	/* Add Antonin : if scalar_derived -> compute other stepsizes */
 901	if (tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) {
 902		for (bandno = 1; bandno < J2K_MAXBANDS; bandno++) {
 903			tccp->stepsizes[bandno].expn = 
 904				((tccp->stepsizes[0].expn) - ((bandno - 1) / 3) > 0) ? 
 905					(tccp->stepsizes[0].expn) - ((bandno - 1) / 3) : 0;
 906			tccp->stepsizes[bandno].mant = tccp->stepsizes[0].mant;
 907		}
 908	}
 909	/* ddA */
 910}
 911
 912static void j2k_write_qcd(opj_j2k_t *j2k) {
 913	int lenp, len;
 914
 915	opj_cio_t *cio = j2k->cio;
 916	
 917	cio_write(cio, J2K_MS_QCD, 2);	/* QCD */
 918	lenp = cio_tell(cio);
 919	cio_skip(cio, 2);
 920	j2k_write_qcx(j2k, 0);
 921	len = cio_tell(cio) - lenp;
 922	cio_seek(cio, lenp);
 923	cio_write(cio, len, 2);			/* Lqcd */
 924	cio_seek(cio, lenp + len);
 925
 926	if(j2k->cstr_info)
 927	  j2k_add_mhmarker(j2k->cstr_info, J2K_MS_QCD, lenp, len);
 928}
 929
 930static void j2k_read_qcd(opj_j2k_t *j2k) {
 931	int len, i, pos;
 932
 933	opj_cio_t *cio = j2k->cio;
 934	opj_image_t *image = j2k->image;
 935	
 936	len = cio_read(cio, 2);		/* Lqcd */
 937	pos = cio_tell(cio);
 938	for (i = 0; i < image->numcomps; i++) {
 939		cio_seek(cio, pos);
 940		j2k_read_qcx(j2k, i, len - 2);
 941	}
 942}
 943
 944static void j2k_write_qcc(opj_j2k_t *j2k, int compno) {
 945	int lenp, len;
 946
 947	opj_cio_t *cio = j2k->cio;
 948	
 949	cio_write(cio, J2K_MS_QCC, 2);	/* QCC */
 950	lenp = cio_tell(cio);
 951	cio_skip(cio, 2);
 952	cio_write(cio, compno, j2k->image->numcomps <= 256 ? 1 : 2);	/* Cqcc */
 953	j2k_write_qcx(j2k, compno);
 954	len = cio_tell(cio) - lenp;
 955	cio_seek(cio, lenp);
 956	cio_write(cio, len, 2);			/* Lqcc */
 957	cio_seek(cio, lenp + len);
 958}
 959
 960static void j2k_read_qcc(opj_j2k_t *j2k) {
 961	int len, compno;
 962	int numcomp = j2k->image->numcomps;
 963	opj_cio_t *cio = j2k->cio;
 964
 965	len = cio_read(cio, 2);	/* Lqcc */
 966	compno = cio_read(cio, numcomp <= 256 ? 1 : 2);	/* Cqcc */
 967
 968#ifdef USE_JPWL
 969	if (j2k->cp->correct) {
 970
 971		static int backup_compno = 0;
 972
 973		/* compno is negative or larger than the number of components!!! */
 974		if ((compno < 0) || (compno >= numcomp)) {
 975			opj_event_msg(j2k->cinfo, EVT_ERROR,
 976				"JPWL: bad component number in QCC (%d out of a maximum of %d)\n",
 977				compno, numcomp);
 978			if (!JPWL_ASSUME) {
 979				opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
 980				return;
 981			}
 982			/* we try to correct */
 983			compno = backup_compno % numcomp;
 984			opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust this\n"
 985				"- setting component number to %d\n",
 986				compno);
 987		}
 988
 989		/* keep your private count of tiles */
 990		backup_compno++;
 991	};
 992#endif /* USE_JPWL */
 993
 994	j2k_read_qcx(j2k, compno, len - 2 - (numcomp <= 256 ? 1 : 2));
 995}
 996
 997static void j2k_write_poc(opj_j2k_t *j2k) {
 998	int len, numpchgs, i;
 999
1000	int numcomps = j2k->image->numcomps;
1001	
1002	opj_cp_t *cp = j2k->cp;
1003	opj_tcp_t *tcp = &cp->tcps[j2k->curtileno];
1004	opj_tccp_t *tccp = &tcp->tccps[0];
1005	opj_cio_t *cio = j2k->cio;
1006
1007	numpchgs = 1 + tcp->numpocs;
1008	cio_write(cio, J2K_MS_POC, 2);	/* POC  */
1009	len = 2 + (5 + 2 * (numcomps <= 256 ? 1 : 2)) * numpchgs;
1010	cio_write(cio, len, 2);		/* Lpoc */
1011	for (i = 0; i < numpchgs; i++) {
1012		opj_poc_t *poc = &tcp->pocs[i];
1013		cio_write(cio, poc->resno0, 1);	/* RSpoc_i */
1014		cio_write(cio, poc->compno0, (numcomps <= 256 ? 1 : 2));	/* CSpoc_i */
1015		cio_write(cio, poc->layno1, 2);	/* LYEpoc_i */
1016		poc->layno1 = int_min(poc->layno1, tcp->numlayers);
1017		cio_write(cio, poc->resno1, 1);	/* REpoc_i */
1018		poc->resno1 = int_min(poc->resno1, tccp->numresolutions);
1019		cio_write(cio, poc->compno1, (numcomps <= 256 ? 1 : 2));	/* CEpoc_i */
1020		poc->compno1 = int_min(poc->compno1, numcomps);
1021		cio_write(cio, poc->prg, 1);	/* Ppoc_i */
1022	}
1023}
1024
1025static void j2k_read_poc(opj_j2k_t *j2k) {
1026	int len, numpchgs, i, old_poc;
1027
1028	int numcomps = j2k->image->numcomps;
1029	
1030	opj_cp_t *cp = j2k->cp;
1031	opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp;
1032	opj_cio_t *cio = j2k->cio;
1033	
1034	old_poc = tcp->POC ? tcp->numpocs + 1 : 0;
1035	tcp->POC = 1;
1036	len = cio_read(cio, 2);		/* Lpoc */
1037	numpchgs = (len - 2) / (5 + 2 * (numcomps <= 256 ? 1 : 2));
1038	
1039	for (i = old_poc; i < numpchgs + old_poc; i++) {
1040		opj_poc_t *poc;
1041		poc = &tcp->pocs[i];
1042		poc->resno0 = cio_read(cio, 1);	/* RSpoc_i */
1043		poc->compno0 = cio_read(cio, numcomps <= 256 ? 1 : 2);	/* CSpoc_i */
1044		poc->layno1 = cio_read(cio, 2);    /* LYEpoc_i */
1045		poc->resno1 = cio_read(cio, 1);    /* REpoc_i */
1046		poc->compno1 = int_min(
1047			cio_read(cio, numcomps <= 256 ? 1 : 2), (unsigned int) numcomps);	/* CEpoc_i */
1048		poc->prg = (OPJ_PROG_ORDER)cio_read(cio, 1);	/* Ppoc_i */
1049	}
1050	
1051	tcp->numpocs = numpchgs + old_poc - 1;
1052}
1053
1054static void j2k_read_crg(opj_j2k_t *j2k) {
1055	int len, i, Xcrg_i, Ycrg_i;
1056	
1057	opj_cio_t *cio = j2k->cio;
1058	int numcomps = j2k->image->numcomps;
1059	
1060	len = cio_read(cio, 2);			/* Lcrg */
1061	for (i = 0; i < numcomps; i++) {
1062		Xcrg_i = cio_read(cio, 2);	/* Xcrg_i */
1063		Ycrg_i = cio_read(cio, 2);	/* Ycrg_i */
1064	}
1065}
1066
1067static void j2k_read_tlm(opj_j2k_t *j2k) {
1068	int len, Ztlm, Stlm, ST, SP, tile_tlm, i;
1069	long int Ttlm_i, Ptlm_i;
1070
1071	opj_cio_t *cio = j2k->cio;
1072	
1073	len = cio_read(cio, 2);		/* Ltlm */
1074	Ztlm = cio_read(cio, 1);	/* Ztlm */
1075	Stlm = cio_read(cio, 1);	/* Stlm */
1076	ST = ((Stlm >> 4) & 0x01) + ((Stlm >> 4) & 0x02);
1077	SP = (Stlm >> 6) & 0x01;
1078	tile_tlm = (len - 4) / ((SP + 1) * 2 + ST);
1079	for (i = 0; i < tile_tlm; i++) {
1080		Ttlm_i = cio_read(cio, ST);	/* Ttlm_i */
1081		Ptlm_i = cio_read(cio, SP ? 4 : 2);	/* Ptlm_i */
1082	}
1083}
1084
1085static void j2k_read_plm(opj_j2k_t *j2k) {
1086	int len, i, Zplm, Nplm, add, packet_len = 0;
1087	
1088	opj_cio_t *cio = j2k->cio;
1089
1090	len = cio_read(cio, 2);		/* Lplm */
1091	Zplm = cio_read(cio, 1);	/* Zplm */
1092	len -= 3;
1093	while (len > 0) {
1094		Nplm = cio_read(cio, 4);		/* Nplm */
1095		len -= 4;
1096		for (i = Nplm; i > 0; i--) {
1097			add = cio_read(cio, 1);
1098			len--;
1099			packet_len = (packet_len << 7) + add;	/* Iplm_ij */
1100			if ((add & 0x80) == 0) {
1101				/* New packet */
1102				packet_len = 0;
1103			}
1104			if (len <= 0)
1105				break;
1106		}
1107	}
1108}
1109
1110static void j2k_read_plt(opj_j2k_t *j2k) {
1111	int len, i, Zplt, packet_len = 0, add;
1112	
1113	opj_cio_t *cio = j2k->cio;
1114	
1115	len = cio_read(cio, 2);		/* Lplt */
1116	Zplt = cio_read(cio, 1);	/* Zplt */
1117	for (i = len - 3; i > 0; i--) {
1118		add = cio_read(cio, 1);
1119		packet_len = (packet_len << 7) + add;	/* Iplt_i */
1120		if ((add & 0x80) == 0) {
1121			/* New packet */
1122			packet_len = 0;
1123		}
1124	}
1125}
1126
1127static void j2k_read_ppm(opj_j2k_t *j2k) {
1128	int len, Z_ppm, i, j;
1129	int N_ppm;
1130
1131	opj_cp_t *cp = j2k->cp;
1132	opj_cio_t *cio = j2k->cio;
1133	
1134	len = cio_read(cio, 2);
1135	cp->ppm = 1;
1136	
1137	Z_ppm = cio_read(cio, 1);	/* Z_ppm */
1138	len -= 3;
1139	while (len > 0) {
1140		if (cp->ppm_previous == 0) {
1141			N_ppm = cio_read(cio, 4);	/* N_ppm */
1142			len -= 4;
1143		} else {
1144			N_ppm = cp->ppm_previous;
1145		}
1146		j = cp->ppm_store;
1147		if (Z_ppm == 0) {	/* First PPM marker */
1148			cp->ppm_data = (unsigned char *) opj_malloc(N_ppm * sizeof(unsigned char));
1149			cp->ppm_data_first = cp->ppm_data;
1150			cp->ppm_len = N_ppm;
1151		} else {			/* NON-first PPM marker */
1152			cp->ppm_data = (unsigned char *) opj_realloc(cp->ppm_data, (N_ppm +	cp->ppm_store) * sizeof(unsigned char));
1153
1154#ifdef USE_JPWL
1155			/* this memory allocation check could be done even in non-JPWL cases */
1156			if (cp->correct) {
1157				if (!cp->ppm_data) {
1158					opj_event_msg(j2k->cinfo, EVT_ERROR,
1159						"JPWL: failed memory allocation during PPM marker parsing (pos. %x)\n",
1160						cio_tell(cio));
1161					if (!JPWL_ASSUME || JPWL_ASSUME) {
1162						opj_free(cp->ppm_data);
1163						opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
1164						return;
1165					}
1166				}
1167			}
1168#endif
1169
1170			cp->ppm_data_first = cp->ppm_data;
1171			cp->ppm_len = N_ppm + cp->ppm_store;
1172		}
1173		for (i = N_ppm; i > 0; i--) {	/* Read packet header */
1174			cp->ppm_data[j] = cio_read(cio, 1);
1175			j++;
1176			len--;
1177			if (len == 0)
1178				break;			/* Case of non-finished packet header in present marker but finished in next one */
1179		}
1180		cp->ppm_previous = i - 1;
1181		cp->ppm_store = j;
1182	}
1183}
1184
1185static void j2k_read_ppt(opj_j2k_t *j2k) {
1186	int len, Z_ppt, i, j = 0;
1187
1188	opj_cp_t *cp = j2k->cp;
1189	opj_tcp_t *tcp = cp->tcps + j2k->curtileno;
1190	opj_cio_t *cio = j2k->cio;
1191
1192	len = cio_read(cio, 2);
1193	Z_ppt = cio_read(cio, 1);
1194	tcp->ppt = 1;
1195	if (Z_ppt == 0) {		/* First PPT marker */
1196		tcp->ppt_data = (unsigned char *) opj_malloc((len - 3) * sizeof(unsigned char));
1197		tcp->ppt_data_first = tcp->ppt_data;
1198		tcp->ppt_store = 0;
1199		tcp->ppt_len = len - 3;
1200	} else {			/* NON-first PPT marker */
1201		tcp->ppt_data =	(unsigned char *) opj_realloc(tcp->ppt_data, (len - 3 + tcp->ppt_store) * sizeof(unsigned char));
1202		tcp->ppt_data_first = tcp->ppt_data;
1203		tcp->ppt_len = len - 3 + tcp->ppt_store;
1204	}
1205	j = tcp->ppt_store;
1206	for (i = len - 3; i > 0; i--) {
1207		tcp->ppt_data[j] = cio_read(cio, 1);
1208		j++;
1209	}
1210	tcp->ppt_store = j;
1211}
1212
1213static void j2k_write_tlm(opj_j2k_t *j2k){
1214	int lenp;
1215	opj_cio_t *cio = j2k->cio;
1216	j2k->tlm_start = cio_tell(cio);
1217	cio_write(cio, J2K_MS_TLM, 2);/* TLM */
1218	lenp = 4 + (5*j2k->totnum_tp);
1219	cio_write(cio,lenp,2);				/* Ltlm */
1220	cio_write(cio, 0,1);					/* Ztlm=0*/
1221	cio_write(cio,80,1);					/* Stlm ST=1(8bits-255 tiles max),SP=1(Ptlm=32bits) */
1222	cio_skip(cio,5*j2k->totnum_tp);
1223}
1224
1225static void j2k_write_sot(opj_j2k_t *j2k) {
1226	int lenp, len;
1227
1228	opj_cio_t *cio = j2k->cio;
1229
1230	j2k->sot_start = cio_tell(cio);
1231	cio_write(cio, J2K_MS_SOT, 2);		/* SOT */
1232	lenp = cio_tell(cio);
1233	cio_skip(cio, 2);					/* Lsot (further) */
1234	cio_write(cio, j2k->curtileno, 2);	/* Isot */
1235	cio_skip(cio, 4);					/* Psot (further in j2k_write_sod) */
1236	cio_write(cio, j2k->cur_tp_num , 1);	/* TPsot */
1237	cio_write(cio, j2k->cur_totnum_tp[j2k->curtileno], 1);		/* TNsot */
1238	len = cio_tell(cio) - lenp;
1239	cio_seek(cio, lenp);
1240	cio_write(cio, len, 2);				/* Lsot */
1241	cio_seek(cio, lenp + len);
1242
1243	/* UniPG>> */
1244#ifdef USE_JPWL
1245	/* update markers struct */
1246	j2k_add_marker(j2k->cstr_info, J2K_MS_SOT, j2k->sot_start, len + 2);
1247#endif /* USE_JPWL */
1248	/* <<UniPG */
1249
1250	if( j2k->cstr_info && j2k->cur_tp_num==0){
1251	  j2k_add_tlmarker( j2k->curtileno, j2k->cstr_info, J2K_MS_SOT, lenp, len);
1252	}
1253}
1254
1255static void j2k_read_sot(opj_j2k_t *j2k) {
1256	int len, tileno, totlen, partno, numparts, i;
1257	opj_tcp_t *tcp = NULL;
1258	char status = 0;
1259
1260	opj_cp_t *cp = j2k->cp;
1261	opj_cio_t *cio = j2k->cio;
1262
1263	len = cio_read(cio, 2);
1264	tileno = cio_read(cio, 2);
1265
1266#ifdef USE_JPWL
1267	if (j2k->cp->correct) {
1268
1269		static int backup_tileno = 0;
1270
1271		/* tileno is negative or larger than the number of tiles!!! */
1272		if ((tileno < 0) || (tileno > (cp->tw * cp->th))) {
1273			opj_event_msg(j2k->cinfo, EVT_ERROR,
1274				"JPWL: bad tile number (%d out of a maximum of %d)\n",
1275				tileno, (cp->tw * cp->th));
1276			if (!JPWL_ASSUME) {
1277				opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
1278				return;
1279			}
1280			/* we try to correct */
1281			tileno = backup_tileno;
1282			opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust this\n"
1283				"- setting tile number to %d\n",
1284				tileno);
1285		}
1286
1287		/* keep your private count of tiles */
1288		backup_tileno++;
1289	};
1290#endif /* USE_JPWL */
1291	
1292	if (cp->tileno_size == 0) {
1293		cp->tileno[cp->tileno_size] = tileno;
1294		cp->tileno_size++;
1295	} else {
1296		i = 0;
1297		while (i < cp->tileno_size && status == 0) {
1298			status = cp->tileno[i] == tileno ? 1 : 0;
1299			i++;
1300		}
1301		if (status == 0) {
1302			cp->tileno[cp->tileno_size] = tileno;
1303			cp->tileno_size++;
1304		}
1305	}
1306	
1307	totlen = cio_read(cio, 4);
1308
1309#ifdef USE_JPWL
1310	if (j2k->cp->correct) {
1311
1312		/* totlen is negative or larger than the bytes left!!! */
1313		if ((totlen < 0) || (totlen > (cio_numbytesleft(cio) + 8))) {
1314			opj_event_msg(j2k->cinfo, EVT_ERROR,
1315				"JPWL: bad tile byte size (%d bytes against %d bytes left)\n",
1316				totlen, cio_numbytesleft(cio) + 8);
1317			if (!JPWL_ASSUME) {
1318				opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
1319				return;
1320			}
1321			/* we try to correct */
1322			totlen = 0;
1323			opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust this\n"
1324				"- setting Psot to %d => assuming it is the last tile\n",
1325				totlen);
1326		}
1327
1328	};
1329#endif /* USE_JPWL */
1330
1331	if (!totlen)
1332		totlen = cio_numbytesleft(cio) + 8;
1333	
1334	partno = cio_read(cio, 1);
1335	numparts = cio_read(cio, 1);
1336  
1337  if (partno >= numparts) {
1338    opj_event_msg(j2k->cinfo, EVT_WARNING, "SOT marker inconsistency in tile %d: tile-part index greater (%d) than number of tile-parts (%d)\n", tileno, partno, numparts);
1339    numparts = partno+1;
1340  }
1341	
1342	j2k->curtileno = tileno;
1343	j2k->cur_tp_num = partno;
1344	j2k->eot = cio_getbp(cio) - 12 + totlen;
1345	j2k->state = J2K_STATE_TPH;
1346	tcp = &cp->tcps[j2k->curtileno];
1347
1348	/* Index */
1349	if (j2k->cstr_info) {
1350		if (tcp->first) {
1351			if (tileno == 0) 
1352				j2k->cstr_info->main_head_end = cio_tell(cio) - 13;
1353			j2k->cstr_info->tile[tileno].tileno = tileno;
1354			j2k->cstr_info->tile[tileno].start_pos = cio_tell(cio) - 12;
1355			j2k->cstr_info->tile[tileno].end_pos = j2k->cstr_info->tile[tileno].start_pos + totlen - 1;				
1356    } else {
1357			j2k->cstr_info->tile[tileno].end_pos += totlen;
1358		}
1359    j2k->cstr_info->tile[tileno].num_tps = numparts;
1360    if (numparts)
1361      j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_realloc(j2k->cstr_info->tile[tileno].tp, numparts * sizeof(opj_tp_info_t));
1362    else
1363      j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_realloc(j2k->cstr_info->tile[tileno].tp, 10 * sizeof(opj_tp_info_t)); /* Fixme (10)*/
1364		j2k->cstr_info->tile[tileno].tp[partno].tp_start_pos = cio_tell(cio) - 12;
1365		j2k->cstr_info->tile[tileno].tp[partno].tp_end_pos = 
1366			j2k->cstr_info->tile[tileno].tp[partno].tp_start_pos + totlen - 1;
1367	}
1368	
1369	if (tcp->first == 1) {		
1370		/* Initialization PPT */
1371		opj_tccp_t *tmp = tcp->tccps;
1372		memcpy(tcp, j2k->default_tcp, sizeof(opj_tcp_t));
1373		tcp->ppt = 0;
1374		tcp->ppt_data = NULL;
1375		tcp->ppt_data_first = NULL;
1376		tcp->tccps = tmp;
1377
1378		for (i = 0; i < j2k->image->numcomps; i++) {
1379			tcp->tccps[i] = j2k->default_tcp->tccps[i];
1380		}
1381		cp->tcps[j2k->curtileno].first = 0;
1382	}
1383}
1384
1385static void j2k_write_sod(opj_j2k_t *j2k, void *tile_coder) {
1386	int l, layno;
1387	int totlen;
1388	opj_tcp_t *tcp = NULL;
1389	opj_codestream_info_t *cstr_info = NULL;
1390	
1391	opj_tcd_t *tcd = (opj_tcd_t*)tile_coder;	/* cast is needed because of conflicts in header inclusions */
1392	opj_cp_t *cp = j2k->cp;
1393	opj_cio_t *cio = j2k->cio;
1394
1395	tcd->tp_num = j2k->tp_num ;
1396	tcd->cur_tp_num = j2k->cur_tp_num;
1397	
1398	cio_write(cio, J2K_MS_SOD, 2);
1399
1400	if( j2k->cstr_info && j2k->cur_tp_num==0){
1401	  j2k_add_tlmarker( j2k->curtileno, j2k->cstr_info, J2K_MS_SOD, cio_tell(cio), 0);
1402	}
1403
1404	if (j2k->curtileno == 0) {
1405		j2k->sod_start = cio_tell(cio) + j2k->pos_correction;
1406	}
1407
1408	/* INDEX >> */
1409	cstr_info = j2k->cstr_info;
1410	if (cstr_info) {
1411		if (!j2k->cur_tp_num ) {
1412			cstr_info->tile[j2k->curtileno].end_header = cio_tell(cio) + j2k->pos_correction - 1;
1413			j2k->cstr_info->tile[j2k->curtileno].tileno = j2k->curtileno;
1414		}
1415		else{
1416			if(cstr_info->tile[j2k->curtileno].packet[cstr_info->packno - 1].end_pos < cio_tell(cio))
1417				cstr_info->tile[j2k->curtileno].packet[cstr_info->packno].start_pos = cio_tell(cio);
1418		}
1419		/* UniPG>> */
1420#ifdef USE_JPWL
1421		/* update markers struct */
1422		j2k_add_marker(j2k->cstr_info, J2K_MS_SOD, j2k->sod_start, 2);
1423#endif /* USE_JPWL */
1424		/* <<UniPG */
1425	}
1426	/* << INDEX */
1427	
1428	tcp = &cp->tcps[j2k->curtileno];
1429	for (layno = 0; layno < tcp->numlayers; layno++) {
1430		if (tcp->rates[layno]>(j2k->sod_start / (cp->th * cp->tw))) {
1431			tcp->rates[layno]-=(j2k->sod_start / (cp->th * cp->tw));
1432		} else if (tcp->rates[layno]) {
1433			tcp->rates[layno]=1;
1434		}
1435	}
1436	if(j2k->cur_tp_num == 0){
1437		tcd->tcd_image->tiles->packno = 0;
1438		if(cstr_info)
1439			cstr_info->packno = 0;
1440	}
1441	
1442	l = tcd_encode_tile(tcd, j2k->curtileno, cio_getbp(cio), cio_numbytesleft(cio) - 2, cstr_info);
1443	
1444	/* Writing Psot in SOT marker */
1445	totlen = cio_tell(cio) + l - j2k->sot_start;
1446	cio_seek(cio, j2k->sot_start + 6);
1447	cio_write(cio, totlen, 4);
1448	cio_seek(cio, j2k->sot_start + totlen);
1449	/* Writing Ttlm and Ptlm in TLM marker */
1450	if(cp->cinema){
1451		cio_seek(cio, j2k->tlm_start + 6 + (5*j2k->cur_tp_num));
1452		cio_write(cio, j2k->curtileno, 1);
1453		cio_write(cio, totlen, 4);
1454	}
1455	cio_seek(cio, j2k->sot_start + totlen);
1456}
1457
1458static void j2k_read_sod(opj_j2k_t *j2k) {
1459	int len, truncate = 0, i;
1460	unsigned char *data = NULL, *data_ptr = NULL;
1461
1462	opj_cio_t *cio = j2k->cio;
1463	int curtileno = j2k->curtileno;
1464
1465	/* Index */
1466	if (j2k->cstr_info) {
1467		j2k->cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_end_header =
1468			cio_tell(cio) + j2k->pos_correction - 1;
1469		if (j2k->cur_tp_num == 0)
1470			j2k->cstr_info->tile[j2k->curtileno].end_header = cio_tell(cio) + j2k->pos_correction - 1;
1471		j2k->cstr_info->packno = 0;
1472	}
1473	
1474	len = int_min(j2k->eot - cio_getbp(cio), cio_numbytesleft(cio) + 1);
1475
1476	if (len == cio_numbytesleft(cio) + 1) {
1477		truncate = 1;		/* Case of a truncate codestream */
1478	}	
1479
1480	data = j2k->tile_data[curtileno];
1481	data = (unsigned char*) opj_realloc(data, (j2k->tile_len[curtileno] + len) * sizeof(unsigned char));
1482
1483	data_ptr = data + j2k->tile_len[curtileno];
1484	for (i = 0; i < len; i++) {
1485		data_ptr[i] = cio_read(cio, 1);
1486	}
1487
1488	j2k->tile_len[curtileno] += len;
1489	j2k->tile_data[curtileno] = data;
1490	
1491	if (!truncate) {
1492		j2k->state = J2K_STATE_TPHSOT;
1493	} else {
1494		j2k->state = J2K_STATE_NEOC;	/* RAJOUTE !! */
1495	}
1496	j2k->cur_tp_num++;
1497}
1498
1499static void j2k_write_rgn(opj_j2k_t *j2k, int compno, int tileno) {
1500	opj_cp_t *cp = j2k->cp;
1501	opj_tcp_t *tcp = &cp->tcps[tileno];
1502	opj_cio_t *cio = j2k->cio;
1503	int numcomps = j2k->image->numcomps;
1504	
1505	cio_write(cio, J2K_MS_RGN, 2);						/* RGN  */
1506	cio_write(cio, numcomps <= 256 ? 5 : 6, 2);			/* Lrgn */
1507	cio_write(cio, compno, numcomps <= 256 ? 1 : 2);	/* Crgn */
1508	cio_write(cio, 0, 1);								/* Srgn */
1509	cio_write(cio, tcp->tccps[compno].roishift, 1);		/* SPrgn */
1510}
1511
1512static void j2k_read_rgn(opj_j2k_t *j2k) {
1513	int len, compno, roisty;
1514
1515	opj_cp_t *cp = j2k->cp;
1516	opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp;
1517	opj_cio_t *cio = j2k->cio;
1518	int numcomps = j2k->image->numcomps;
1519
1520	len = cio_read(cio, 2);										/* Lrgn */
1521	compno = cio_read(cio, numcomps <= 256 ? 1 : 2);			/* Crgn */
1522	roisty = cio_read(cio, 1);									/* Srgn */
1523
1524#ifdef USE_JPWL
1525	if (j2k->cp->correct) {
1526		/* totlen is negative or larger than the bytes left!!! */
1527		if (compno >= numcomps) {
1528			opj_event_msg(j2k->cinfo, EVT_ERROR,
1529				"JPWL: bad component number in RGN (%d when there are only %d)\n",
1530				compno, numcomps);
1531			if (!JPWL_ASSUME || JPWL_ASSUME) {
1532				opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
1533				return;
1534			}
1535		}
1536	};
1537#endif /* USE_JPWL */
1538
1539	tcp->tccps[compno].roishift = cio_read(cio, 1);				/* SPrgn */
1540}
1541
1542static void j2k_write_eoc(opj_j2k_t *j2k) {
1543	opj_cio_t *cio = j2k->cio;
1544	/* opj_event_msg(j2k->cinfo, "%.8x: EOC\n", cio_tell(cio) + j2k->pos_correction); */
1545	cio_write(cio, J2K_MS_EOC, 2);
1546
1547/* UniPG>> */
1548#ifdef USE_JPWL
1549	/* update markers struct */
1550	j2k_add_marker(j2k->cstr_info, J2K_MS_EOC, cio_tell(cio) - 2, 2);
1551#endif /* USE_JPWL */
1552/* <<UniPG */
1553}
1554
1555static void j2k_read_eoc(opj_j2k_t *j2k) {
1556	int i, tileno;
1557	opj_bool success;
1558
1559	/* if packets should be decoded */
1560	if (j2k->cp->limit_decoding != DECODE_ALL_BUT_PACKETS) {
1561		opj_tcd_t *tcd = tcd_create(j2k->cinfo);
1562		tcd_malloc_decode(tcd, j2k->image, j2k->cp);
1563		for (i = 0; i < j2k->cp->tileno_size; i++) {
1564			tcd_malloc_decode_tile(tcd, j2k->image, j2k->cp, i, j2k->cstr_info);
1565			tileno = j2k->cp->tileno[i];
1566			success = tcd_decode_tile(tcd, j2k->tile_data[tileno], j2k->tile_len[tileno], tileno, j2k->cstr_info);
1567			opj_free(j2k->tile_data[tileno]);
1568			j2k->tile_data[tileno] = NULL;
1569			tcd_free_decode_tile(tcd, i);
1570			if (success == OPJ_FALSE) {
1571				j2k->state |= J2K_STATE_ERR;
1572				break;
1573			}
1574		}
1575		tcd_free_decode(tcd);
1576		tcd_destroy(tcd);
1577	}
1578	/* if packets should not be decoded  */
1579	else {
1580		for (i = 0; i < j2k->cp->tileno_size; i++) {
1581			tileno = j2k->cp->tileno[i];
1582			opj_free(j2k->tile_data[tileno]);
1583			j2k->tile_data[tileno] = NULL;
1584		}
1585	}	
1586	if (j2k->state & J2K_STATE_ERR)
1587		j2k->state = J2K_STATE_MT + J2K_STATE_ERR;
1588	else
1589		j2k->state = J2K_STATE_MT; 
1590}
1591
1592typedef struct opj_dec_mstabent {
1593	/** marker value */
1594	int id;
1595	/** value of the state when the marker can appear */
1596	int states;
1597	/** action linked to the marker */
1598	void (*handler) (opj_j2k_t *j2k);
1599} opj_dec_mstabent_t;
1600
1601opj_dec_mstabent_t j2k_dec_mstab[] = {
1602  {J2K_MS_SOC, J2K_STATE_MHSOC, j2k_read_soc},
1603  {J2K_MS_SOT, J2K_STATE_MH | J2K_STATE_TPHSOT, j2k_read_sot},
1604  {J2K_MS_SOD, J2K_STATE_TPH, j2k_read_sod},
1605  {J2K_MS_EOC, J2K_STATE_TPHSOT, j2k_read_eoc},
1606  {J2K_MS_SIZ, J2K_STATE_MHSIZ, j2k_read_siz},
1607  {J2K_MS_COD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_cod},
1608  {J2K_MS_COC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_coc},
1609  {J2K_MS_RGN, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_rgn},
1610  {J2K_MS_QCD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_qcd},
1611  {J2K_MS_QCC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_qcc},
1612  {J2K_MS_POC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_poc},
1613  {J2K_MS_TLM, J2K_STATE_MH, j2k_read_tlm},
1614  {J2K_MS_PLM, J2K_STATE_MH, j2k_read_plm},
1615  {J2K_MS_PLT, J2K_STATE_TPH, j2k_read_plt},
1616  {J2K_MS_PPM, J2K_STATE_MH, j2k_read_ppm},
1617  {J2K_MS_PPT, J2K_STATE_TPH, j2k_read_ppt},
1618  {J2K_MS_SOP, 0, 0},
1619  {J2K_MS_CRG, J2K_STATE_MH, j2k_read_crg},
1620  {J2K_MS_COM, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_com},
1621
1622#ifdef USE_JPWL
1623  {J2K_MS_EPC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_epc},
1624  {J2K_MS_EPB, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_epb},
1625  {J2K_MS_ESD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_esd},
1626  {J2K_MS_RED, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_red},
1627#endif /* USE_JPWL */
1628#ifdef USE_JPSEC
1629  {J2K_MS_SEC, J2K_STATE_MH, j2k_read_sec},
1630  {J2K_MS_INSEC, 0, j2k_read_insec},
1631#endif /* USE_JPSEC */
1632
1633  {0, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_unk}
1634};
1635
1636static void j2k_read_unk(opj_j2k_t *j2k) {
1637	opj_event_msg(j2k->cinfo, EVT_WARNING, "Unknown marker\n");
1638
1639#ifdef USE_JPWL
1640	if (j2k->cp->correct) {
1641		int m = 0, id, i;
1642		int min_id = 0, min_dist = 17, cur_dist = 0, tmp_id;
1643		cio_seek(j2k->cio, cio_tell(j2k->cio) - 2);
1644		id = cio_read(j2k->cio, 2);
1645		opj_event_msg(j2k->cinfo, EVT_ERROR,
1646			"JPWL: really don't know this marker %x\n",
1647			id);
1648		if (!JPWL_ASSUME) {
1649			opj_event_msg(j2k->cinfo, EVT_ERROR,
1650				"- possible synch loss due to uncorrectable codestream errors => giving up\n");
1651			return;
1652		}
1653		/* OK, activate this at your own risk!!! */
1654		/* we look for the marker at the minimum hamming distance from this */
1655		while (j2k_dec_mstab[m].id) {
1656			
1657			/* 1's where they differ */
1658			tmp_id = j2k_dec_mstab[m].id ^ id;
1659
1660			/* compute the hamming distance between our id and the current */
1661			cur_dist = 0;
1662			for (i = 0; i < 16; i++) {
1663				if ((tmp_id >> i) & 0x0001) {
1664					cur_dist++;
1665				}
1666			}
1667
1668			/* if current distance is smaller, set the minimum */
1669			if (cur_dist < min_dist) {
1670				min_dist = cur_dist;
1671				min_id = j2k_dec_mstab[m].id;
1672			}
1673			
1674			/* jump to the next marker */
1675			m++;
1676		}
1677
1678		/* do we substitute the marker? */
1679		if (min_dist < JPWL_MAXIMUM_HAMMING) {
1680			opj_event_msg(j2k->cinfo, EVT_ERROR,
1681				"- marker %x is at distance %d from the read %x\n",
1682				min_id, min_dist, id);
1683			opj_event_msg(j2k->cinfo, EVT_ERROR,
1684				"- trying to substitute in place and crossing fingers!\n");
1685			cio_seek(j2k->cio, cio_tell(j2k->cio) - 2);
1686			cio_write(j2k->cio, min_id, 2);
1687
1688			/* rewind */
1689			cio_seek(j2k->cio, cio_tell(j2k->cio) - 2);
1690
1691		}
1692
1693	};
1694#endif /* USE_JPWL */
1695
1696}
1697
1698/**
1699Read the lookup table containing all the marker, status and action
1700@param id Marker value
1701*/
1702static opj_dec_mstabent_t *j2k_dec_mstab_lookup(int id) {
1703	opj_dec_mstabent_t *e;
1704	for (e = j2k_dec_mstab; e->id != 0; e++) {
1705		if (e->id == id) {
1706			break;
1707		}
1708	}
1709	return e;
1710}
1711
1712/* ----------------------------------------------------------------------- */
1713/* J2K / JPT decoder interface                                             */
1714/* ----------------------------------------------------------------------- */
1715
1716opj_j2k_t* j2k_create_decompress(opj_common_ptr cinfo) {
1717	opj_j2k_t *j2k = (opj_j2k_t*) opj_calloc(1, sizeof(opj_j2k_t));
1718	if(!j2k)
1719		return NULL;
1720
1721	j2k->default_tcp = (opj_tcp_t*) opj_calloc(1, sizeof(opj_tcp_t));
1722	if(!j2k->default_tcp) {
1723		opj_free(j2k);
1724		return NULL;
1725	}
1726
1727	j2k->cinfo = cinfo;
1728	j2k->tile_data = NULL;
1729
1730	return j2k;
1731}
1732
1733void j2k_destroy_decompress(opj_j2k_t *j2k) {
1734	int i = 0;
1735
1736	if(j2k->tile_len != NULL) {
1737		opj_free(j2k->tile_len);
1738	}
1739	if(j2k->tile_data != NULL) {
1740		opj_free(j2k->tile_data);
1741	}
1742	if(j2k->default_tcp != NULL) {
1743		opj_tcp_t *default_tcp = j2k->default_tcp;
1744		if(default_tcp->ppt_data_first != NULL) {
1745			opj_free(default_tcp->ppt_data_first);
1746		}
1747		if(j2k->default_tcp->tccps != NULL) {
1748			opj_free(j2k->default_tcp->tccps);
1749		}
1750		opj_free(j2k->default_tcp);
1751	}
1752	if(j2k->cp != NULL) {
1753		opj_cp_t *cp = j2k->cp;
1754		if(cp->tcps != NULL) {
1755			for(i = 0; i < cp->tw * cp->th; i++) {
1756				if(cp->tcps[i].ppt_data_first != NULL) {
1757					opj_free(cp->tcps[i].ppt_data_first);
1758				}
1759				if(cp->tcps[i].tccps != NULL) {
1760					opj_free(cp->tcps[i].tccps);
1761				}
1762			}
1763			opj_free(cp->tcps);
1764		}
1765		if(cp->ppm_data_first != NULL) {
1766			opj_free(cp->ppm_data_first);
1767		}
1768		if(cp->tileno != NULL) {
1769			opj_free(cp->tileno);  
1770		}
1771		if(cp->comment != NULL) {
1772			opj_free(cp->comment);
1773		}
1774
1775		opj_free(cp);
1776	}
1777	opj_free(j2k);
1778}
1779
1780void j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters) {
1781	if(j2k && parameters) {
1782		/* create and initialize the coding parameters structure */
1783		opj_cp_t *cp = (opj_cp_t*) opj_calloc(1, sizeof(opj_cp_t));
1784		cp->reduce = parameters->cp_reduce;	
1785		cp->layer = parameters->cp_layer;
1786		cp->limit_decoding = parameters->cp_limit_decoding;
1787
1788#ifdef USE_JPWL
1789		cp->correct = parameters->jpwl_correct;
1790		cp->exp_comps = parameters->jpwl_exp_comps;
1791		cp->max_tiles = parameters->jpwl_max_tiles;
1792#endif /* USE_JPWL */
1793
1794
1795		/* keep a link to cp so that we can destroy it later in j2k_destroy_decompress */
1796		j2k->cp = cp;
1797	}
1798}
1799
1800opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *cstr_info) {
1801	opj_image_t *image = NULL;
1802
1803	opj_common_ptr cinfo = j2k->cinfo;	
1804
1805	j2k->cio = cio;
1806	j2k->cstr_info = cstr_info;
1807	if (cstr_info)
1808		memset(cstr_info, 0, sizeof(opj_codestream_info_t));
1809
1810	/* create an empty image */
1811	image = opj_image_create0();
1812	j2k->image = image;
1813
1814	j2k->state = J2K_STATE_MHSOC;
1815
1816	for (;;) {
1817		opj_dec_mstabent_t *e;
1818		int id = cio_read(cio, 2);
1819
1820#ifdef USE_JPWL
1821		/* we try to honor JPWL correction power */
1822		if (j2k->cp->correct) {
1823
1824			int orig_pos = cio_tell(cio);
1825			opj_bool status;
1826
1827			/* call the corrector */
1828			status = jpwl_correct(j2k);
1829
1830			/* go back to where you were */
1831			cio_seek(cio, orig_pos - 2);
1832
1833			/* re-read the marker */
1834			id = cio_read(cio, 2);
1835
1836			/* check whether it begins with ff */
1837			if (id >> 8 != 0xff) {
1838				opj_event_msg(cinfo, EVT_ERROR,
1839					"JPWL: possible bad marker %x at %d\n",
1840					id, cio_tell(cio) - 2);
1841				if (!JPWL_ASSUME) {
1842					opj_image_destroy(image);
1843					opj_event_msg(cinfo, EVT_ERROR, "JPWL: giving up\n");
1844					return 0;
1845				}
1846				/* we try to correct */
1847				id = id | 0xff00;
1848				cio_seek(cio, cio_tell(cio) - 2);
1849				cio_write(cio, id, 2);
1850				opj_event_msg(cinfo, EVT_WARNING, "- trying to adjust this\n"
1851					"- setting marker to %x\n",
1852					id);
1853			}
1854
1855		}
1856#endif /* USE_JPWL */
1857
1858		if (id >> 8 != 0xff) {
1859			opj_image_destroy(image);
1860			opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
1861			return 0;
1862		}
1863		e = j2k_dec_mstab_lookup(id);
1864		/* Check if the marker is known*/
1865		if (!(j2k->state & e->states)) {
1866			opj_image_destroy(image);
1867			opj_event_msg(cinfo, EVT_ERROR, "%.8x: unexpected marker %x\n", cio_tell(cio) - 2, id);
1868			return 0;
1869		}
1870		/* Check if the decoding is limited to the main header*/
1871		if (e->id == J2K_MS_SOT && j2k->cp->limit_decoding == LIMIT_TO_MAIN_HEADER) {
1872			opj_event_msg(cinfo, EVT_INFO, "Main Header decoded.\n");
1873			return image;
1874		}		
1875
1876		if (e->handler) {
1877			(*e->handler)(j2k);
1878		}
1879		if (j2k->state & J2K_STATE_ERR) 
1880			return NULL;	
1881
1882		if (j2k->state == J2K_STATE_MT) {
1883			break;
1884		}
1885		if (j2k->state == J2K_STATE_NEOC) {
1886			break;
1887		}
1888	}
1889	if (j2k->state == J2K_STATE_NEOC) {
1890		j2k_read_eoc(j2k);
1891	}
1892
1893	if (j2k->state != J2K_STATE_MT) {
1894		opj_event_msg(cinfo, EVT_WARNING, "Incomplete bitstream\n");
1895	}
1896	return image;
1897}
1898
1899/*
1900* Read a JPT-stream and decode file
1901*
1902*/
1903opj_image_t* j2k_decode_jpt_stream(opj_j2k_t *j2k, opj_cio_t *cio,  opj_codestream_info_t *cstr_info) {
1904	opj_image_t *image = NULL;
1905	opj_jpt_msg_header_t header;
1906	int position;
1907	opj_common_ptr cinfo = j2k->cinfo;
1908
1909	OPJ_ARG_NOT_USED(cstr_info);
1910
1911	j2k->cio = cio;
1912
1913	/* create an empty image */
1914	image = opj_image_create0();
1915	j2k->image = image;
1916
1917	j2k->state = J2K_STATE_MHSOC;
1918	
1919	/* Initialize the header */
1920	jpt_init_msg_header(&header);
1921	/* Read the first header of the message */
1922	jpt_read_msg_header(cinfo, cio, &header);
1923	
1924	position = cio_tell(cio);
1925	if (header.Class_Id != 6) {	/* 6 : Main header data-bin message */
1926		opj_image_destroy(image);
1927		opj_event_msg(cinfo, EVT_ERROR, "[JPT-stream] : Expecting Main header first [class_Id %d] !\n", header.Class_Id);
1928		return 0;
1929	}
1930	
1931	for (;;) {
1932		opj_dec_mstabent_t *e = NULL;
1933		int id;
1934		
1935		if (!cio_numbytesleft(cio)) {
1936			j2k_read_eoc(j2k);
1937			return image;
1938		}
1939		/* data-bin read -> need to read a new header */
1940		if ((unsigned int) (cio_tell(cio) - position) == header.Msg_length) {
1941			jpt_read_msg_header(cinfo, cio, &header);
1942			position = cio_tell(cio);
1943			if (header.Class_Id != 4) {	/* 4 : Tile data-bin message */
1944				opj_image_destroy(image);
1945				opj_event_msg(cinfo, EVT_ERROR, "[JPT-stream] : Expecting Tile info !\n");
1946				return 0;
1947			}
1948		}
1949		
1950		id = cio_read(cio, 2);
1951		if (id >> 8 != 0xff) {
1952			opj_image_destroy(image);
1953			opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
1954			return 0;
1955		}
1956		e = j2k_dec_mstab_lookup(id);
1957		if (!(j2k->state & e->states)) {
1958			opj_image_destroy(image);
1959			opj_event_msg(cinfo, EVT_ERROR, "%.8x: unexpected marker %x\n", cio_tell(cio) - 2, id);
1960			return 0;
1961		}
1962		if (e->handler) {
1963			(*e->handler)(j2k);
1964		}
1965		if (j2k->state == J2K_STATE_MT) {
1966			break;
1967		}
1968		if (j2k->state == J2K_STATE_NEOC) {
1969			break;
1970		}
1971	}
1972	if (j2k->state == J2K_STATE_NEOC) {
1973		j2k_read_eoc(j2k);
1974	}
1975	
1976	if (j2k->state != J2K_STATE_MT) {
1977		opj_event_msg(cinfo, EVT_WARNING, "Incomplete bitstream\n");
1978	}
1979
1980	return image;
1981}
1982
1983/* ----------------------------------------------------------------------- */
1984/* J2K encoder interface                                                       */
1985/* ----------------------------------------------------------------------- */
1986
1987opj_j2k_t* j2k_create_compress(opj_common_ptr cinfo) {
1988	opj_j2k_t *j2k = (opj_j2k_t*) opj_calloc(1, sizeof(opj_j2k_t));
1989	if(j2k) {
1990		j2k->cinfo = cinfo;
1991	}
1992	return j2k;
1993}
1994
1995void j2k_destroy_compress(opj_j2k_t *j2k) {
1996	int tileno;
1997
1998	if(!j2k) return;
1999	if(j2k->cp != NULL) {
2000		opj_cp_t *cp = j2k->cp;
2001
2002		if(cp->comment) {
2003			opj_free(cp->comment);
2004		}
2005		if(cp->matrice) {
2006			opj_free(cp->matrice);
2007		}
2008		for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
2009			opj_free(cp->tcps[tileno].tccps);
2010		}
2011		opj_free(cp->tcps);
2012		opj_free(cp);
2013	}
2014
2015	opj_free(j2k);
2016}
2017
2018void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_t *image) {
2019	int i, j, tileno, numpocs_tile;
2020	opj_cp_t *cp = NULL;
2021
2022	if(!j2k || !parameters || ! image) {
2023		return;
2024	}
2025
2026	/* create and initialize the coding parameters structure */
2027	cp = (opj_cp_t*) opj_calloc(1, sizeof(opj_cp_t));
2028
2029	/* keep a link to cp so that we can destroy it later in j2k_destroy_compress */
2030	j2k->cp = cp;
2031
2032	/* set default values for cp */
2033	cp->tw = 1;
2034	cp->th = 1;
2035
2036	/* 
2037	copy user encoding parameters 
2038	*/
2039	cp->cinema = parameters->cp_cinema;
2040	cp->max_comp_size =	parameters->max_comp_size;
2041	cp->rsiz   = parameters->cp_rsiz;
2042	cp->disto_alloc = parameters->cp_disto_alloc;
2043	cp->fixed_alloc = parameters->cp_fixed_alloc;
2044	cp->fixed_quality = parameters->cp_fixed_quality;
2045
2046	/* mod fixed_quality */
2047	if(parameters->cp_matrice) {
2048		size_t array_size = parameters->tcp_numlayers * parameters->numresolution * 3 * sizeof(int);
2049		cp->matrice = (int *) opj_malloc(array_size);
2050		memcpy(cp->matrice, parameters->cp_matrice, array_size);
2051	}
2052
2053	/* tiles */
2054	cp->tdx = parameters->cp_tdx;
2055	cp->tdy = parameters->cp_tdy;
2056
2057	/* tile offset */
2058	cp->tx0 = parameters->cp_tx0;
2059	cp->ty0 = parameters->cp_ty0;
2060
2061	/* comment string */
2062	if(parameters->cp_comment) {
2063		cp->comment = (char*)opj_malloc(strlen(parameters->cp_comment) + 1);
2064		if(cp->comment) {
2065			strcpy(cp->comment, parameters->cp_comment);
2066		}
2067	}
2068
2069	/*
2070	calculate other encoding parameters
2071	*/
2072
2073	if (parameters->tile_size_on) {
2074		cp->tw = int_ceildiv(image->x1 - cp->tx0, cp->tdx);
2075		cp->th = int_ceildiv(image->y1 - cp->ty0, cp->tdy);
2076	} else {
2077		cp->tdx = image->x1 - cp->tx0;
2078		cp->tdy = image->y1 - cp->ty0;
2079	}
2080
2081	if(parameters->tp_on){
2082		cp->tp_flag = parameters->tp_flag;
2083		cp->tp_on = 1;
2084	}
2085	
2086	cp->img_size = 0;
2087	for(i=0;i<image->numcomps ;i++){
2088	cp->img_size += (image->comps[i].w *image->comps[i].h * image->comps[i].prec);
2089	}
2090
2091
2092#ifdef USE_JPWL
2093	/*
2094	calculate JPWL encoding parameters
2095	*/
2096
2097	if (parameters->jpwl_epc_on) {
2098		int i;
2099
2100		/* set JPWL on */
2101		cp->epc_on = OPJ_TRUE;
2102		cp->info_on = OPJ_FALSE; /* no informative technique */
2103
2104		/* set EPB on */
2105		if ((parameters->jpwl_hprot_MH > 0) || (parameters->jpwl_hprot_TPH[0] > 0)) {
2106			cp->epb_on = OPJ_TRUE;
2107			
2108			cp->hprot_MH = parameters->jpwl_hprot_MH;
2109			for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) {
2110				cp->hprot_TPH_tileno[i] = parameters->jpwl_hprot_TPH_tileno[i];
2111				cp->hprot_TPH[i] = parameters->jpwl_hprot_TPH[i];
2112			}
2113			/* if tile specs are not specified, copy MH specs */
2114			if (cp->hprot_TPH[0] == -1) {
2115				cp->hprot_TPH_tileno[0] = 0;
2116				cp->hprot_TPH[0] = parameters->jpwl_hprot_MH;
2117			}
2118			for (i = 0; i < JPWL_MAX_NO_PACKSPECS; i++) {
2119				cp->pprot_tileno[i] = parameters->jpwl_pprot_tileno[i];
2120				cp->pprot_packno[i] = parameters->jpwl_pprot_packno[i];
2121				cp->pprot[i] = parameters->jpwl_pprot[i];
2122			}
2123		}
2124
2125		/* set ESD writing */
2126		if ((parameters->jpwl_sens_size == 1) || (parameters->jpwl_sens_size == 2)) {
2127			cp->esd_on = OPJ_TRUE;
2128
2129			cp->sens_size = parameters->jpwl_sens_size;
2130			cp->sens_addr = parameters->jpwl_sens_addr;
2131			cp->sens_range = parameters->jpwl_sens_range;
2132
2133			cp->sens_MH = parameters->jpwl_sens_MH;
2134			for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) {
2135				cp->sens_TPH_tileno[i] = parameters->jpwl_sens_TPH_tileno[i];
2136				cp->sens_TPH[i] = parameters->jpwl_sens_TPH[i];
2137			}
2138		}
2139
2140		/* always set RED writing to false: we are at the encoder */
2141		cp->red_on = OPJ_FALSE;
2142
2143	} else {
2144		cp->epc_on = OPJ_FALSE;
2145	}
2146#endif /* USE_JPWL */
2147
2148
2149	/* initialize the mutiple tiles */
2150	/* ---------------------------- */
2151	cp->tcps = (opj_tcp_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tcp_t));
2152
2153	for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
2154		opj_tcp_t *tcp = &cp->tcps[tileno];
2155		tcp->numlayers = parameters->tcp_numlayers;
2156		for (j = 0; j < tcp->numlayers; j++) {
2157			if(cp->cinema){
2158				if (cp->fixed_quality) {
2159					tcp->distoratio[j] = parameters->tcp_distoratio[j];
2160				}
2161				tcp->rates[j] = parameters->tcp_rates[j];
2162			}else{
2163				if (cp->fixed_quality) {	/* add fixed_quality */
2164					tcp->distoratio[j] = parameters->tcp_distoratio[j];
2165				} else {
2166					tcp->rates[j] = parameters->tcp_rates[j];
2167				}
2168			}
2169		}
2170		tcp->csty = parameters->csty;
2171		tcp->prg = parameters->prog_order;
2172		tcp->mct = parameters->tcp_mct; 
2173
2174		numpocs_tile = 0;
2175		tcp->POC = 0;
2176		if (parameters->numpocs) {
2177			/* initialisation of POC */
2178			tcp->POC = 1;
2179			for (i = 0; i < parameters->numpocs; i++) {
2180				if((tileno == parameters->POC[i].tile - 1) || (parameters->POC[i].tile == -1)) {
2181					opj_poc_t *tcp_poc = &tcp->pocs[numpocs_tile];
2182					tcp_poc->resno0		= parameters->POC[numpocs_tile].resno0;
2183					tcp_poc->compno0	= parameters->POC[numpocs_tile].compno0;
2184					tcp_poc->layno1		= parameters->POC[numpocs_tile].layno1;
2185					tcp_poc->resno1		= parameters->POC[numpocs_tile].resno1;
2186					tcp_poc->compno1	= parameters->POC[numpocs_tile].compno1;
2187					tcp_poc->prg1		= parameters->POC[numpocs_tile].prg1;
2188					tcp_poc->tile		= parameters->POC[numpocs_tile].tile;
2189					numpocs_tile++;
2190				}
2191			}
2192			tcp->numpocs = numpocs_tile -1 ;
2193		}else{ 
2194			tcp->numpocs = 0;
2195		}
2196
2197		tcp->tccps = (opj_tccp_t*) opj_calloc(image->numcomps, sizeof(opj_tccp_t));
2198
2199		for (i = 0; i < image->numcomps; i++) {
2200			opj_tccp_t *tccp = &tcp->tccps[i];
2201			tccp->csty = parameters->csty & 0x01;	/* 0 => one precinct || 1 => custom precinct  */
2202			tccp->numresolutions = parameters->numresolution;
2203			tccp->cblkw = int_floorlog2(parameters->cblockw_init);
2204			tccp->cblkh = int_floorlog2(parameters->cblockh_init);
2205			tccp->cblksty = parameters->mode;
2206			tccp->qmfbid = parameters->irreversible ? 0 : 1;
2207			tccp->qntsty = parameters->irreversible ? J2K_CCP_QNTSTY_SEQNT : J2K_CCP_QNTSTY_NOQNT;
2208			tccp->numgbits = 2;
2209			if (i == parameters->roi_compno) {
2210				tccp->roishift = parameters->roi_shift;
2211			} else {
2212				tccp->roishift = 0;
2213			}
2214
2215			if(parameters->cp_cinema)
2216			{
2217				/*Precinct size for lowest frequency subband=128*/
2218				tccp->prcw[0] = 7;
2219				tccp->prch[0] = 7;
2220				/*Precinct size at all other resolutions = 256*/
2221				for (j = 1; j < tccp->numresolutions; j++) {
2222					tccp->prcw[j] = 8;
2223					tccp->prch[j] = 8;
2224				}
2225			}else{
2226				if (parameters->csty & J2K_CCP_CSTY_PRT) {
2227					int p = 0;
2228					for (j = tccp->numresolutions - 1; j >= 0; j--) {
2229						if (p < parameters->res_spec) {
2230							
2231							if (parameters->prcw_init[p] < 1) {
2232								tccp->prcw[j] = 1;
2233							} else {
2234								tccp->prcw[j] = int_floorlog2(parameters->prcw_init[p]);
2235							}
2236							
2237							if (parameters->prch_init[p] < 1) {
2238								tccp->prch[j] = 1;
2239							}else {
2240								tccp->prch[j] = int_floorlog2(parameters->prch_init[p]);
2241							}
2242
2243						} else {
2244							int res_spec = parameters->res_spec;
2245							int size_prcw = parameters->prcw_init[res_spec - 1] >> (p - (res_spec - 1));
2246							int size_prch = parameters->prch_init[res_spec - 1] >> (p - (res_spec - 1));
2247							
2248							if (size_prcw < 1) {
2249								tccp->prcw[j] = 1;
2250							} else {
2251								tccp->prcw[j] = int_floorlog2(size_prcw);
2252							}
2253							
2254							if (size_prch < 1) {
2255								tccp->prch[j] = 1;
2256							} else {
2257								tccp->prch[j] = int_floorlog2(size_prch);
2258							}
2259						}
2260						p++;
2261						/*printf("\nsize precinct for level %d : %d,%d\n", j,tccp->prcw[j], tccp->prch[j]); */
2262					}	/*end for*/
2263				} else {
2264					for (j = 0; j < tccp->numresolutions; j++) {
2265						tccp->prcw[j] = 15;
2266						tccp->prch[j] = 15;
2267					}
2268				}
2269			}
2270
2271			dwt_calc_explicit_stepsizes(tccp, image->comps[i].prec);
2272		}
2273	}
2274}
2275
2276opj_bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) {
2277	int tileno, compno;
2278	opj_cp_t *cp = NULL;
2279
2280	opj_tcd_t *tcd = NULL;	/* TCD component */
2281
2282	j2k->cio = cio;	
2283	j2k->image = image;
2284
2285	cp = j2k->cp;
2286
2287	/* INDEX >> */
2288	j2k->cstr_info = cstr_info;
2289	if (cstr_info) {
2290		int compno;
2291		cstr_info->tile = (opj_tile_info_t *) opj_malloc(cp->tw * cp->th * sizeof(opj_tile_info_t));
2292		cstr_info->image_w = image->x1 - image->x0;
2293		cstr_info->image_h = image->y1 - image->y0;
2294		cstr_info->prog = (&cp->tcps[0])->prg;
2295		cstr_info->tw = cp->tw;
2296		cstr_info->th = cp->th;
2297		cstr_info->tile_x = cp->tdx;	/* new version parser */
2298		cstr_info->tile_y = cp->tdy;	/* new version parser */
2299		cstr_info->tile_Ox = cp->tx0;	/* new version parser */
2300		cstr_info->tile_Oy = cp->ty0;	/* new version parser */
2301		cstr_info->numcomps = image->numcomps;
2302		cstr_info->numlayers = (&cp->tcps[0])->numlayers;
2303		cstr_info->numdecompos = (int*) opj_malloc(image->numcomps * sizeof(int));
2304		for (compno=0; compno < image->numcomps; compno++) {
2305			cstr_info->numdecompos[compno] = (&cp->tcps[0])->tccps->numresolutions - 1;
2306		}
2307		cstr_info->D_max = 0.0;		/* ADD Marcela */
2308		cstr_info->main_head_start = cio_tell(cio); /* position of SOC */
2309		cstr_info->maxmarknum = 100;
2310		cstr_info->marker = (opj_marker_info_t *) opj_malloc(cstr_info->maxmarknum * sizeof(opj_marker_info_t));
2311		cstr_info->marknum = 0;
2312	}
2313	/* << INDEX */
2314
2315	j2k_write_soc(j2k);
2316	j2k_write_siz(j2k);
2317	j2k_write_cod(j2k);
2318	j2k_write_qcd(j2k);
2319
2320	if(cp->cinema){
2321		for (compno = 1; compno < image->numcomps; compno++) {
2322			j2k_write_coc(j2k, compno);
2323			j2k_write_qcc(j2k, compno);
2324		}
2325	}
2326
2327	for (compno = 0; compno < image->numcomps; compno++) {
2328		opj_tcp_t *tcp = &cp->tcps[0];
2329		if (tcp->tccps[compno].roishift)
2330			j2k_write_rgn(j2k, compno, 0);
2331	}
2332	if (cp->comment != NULL) {
2333		j2k_write_com(j2k);
2334	}
2335
2336	j2k->totnum_tp = j2k_calculate_tp(cp,image->numcomps,image,j2k);
2337	/* TLM Marker*/
2338	if(cp->cinema){
2339		j2k_write_tlm(j2k);
2340		if (cp->cinema == CINEMA4K_24) {
2341			j2k_write_poc(j2k);
2342		}
2343	}
2344
2345	/* uncomment only for testing JPSEC marker writing */
2346	/* j2k_write_sec(j2k); */
2347
2348	/* INDEX >> */
2349	if(cstr_info) {
2350		cstr_info->main_head_end = cio_tell(cio) - 1;
2351	}
2352	/* << INDEX */
2353	/**** Main Header ENDS here ***/
2354
2355	/* create the tile encoder */
2356	tcd = tcd_create(j2k->cinfo);
2357
2358	/* encode each tile */
2359	for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
2360		int pino;
2361		int tilepartno=0;
2362		/* UniPG>> */
2363		int acc_pack_num = 0;
2364		/* <<UniPG */
2365
2366
2367		opj_tcp_t *tcp = &cp->tcps[tileno];
2368		opj_event_msg(j2k->cinfo, EVT_INFO, "tile number %d / %d\n", tileno + 1, cp->tw * cp->th);
2369
2370		j2k->curtileno = tileno;
2371		j2k->cur_tp_num = 0;
2372		tcd->cur_totnum_tp = j2k->cur_totnum_tp[j2k->curtileno];
2373		/* initialisation before tile encoding  */
2374		if (tileno == 0) {
2375			tcd_malloc_encode(tcd, image, cp, j2k->curtileno);
2376		} else {
2377			tcd_init_encode(tcd, image, cp, j2k->curtileno);
2378		}
2379
2380		/* INDEX >> */
2381		if(cstr_info) {
2382			cstr_info->tile[j2k->curtileno].start_pos = cio_tell(cio) + j2k->pos_correction;
2383			cstr_info->tile[j2k->curtileno].maxmarknum = 10;
2384			cstr_info->tile[j2k->curtileno].marker = (opj_marker_info_t *) opj_malloc(cstr_info->tile[j2k->curtileno].maxmarknum * sizeof(opj_marker_info_t));
2385			cstr_info->tile[j2k->curtileno].marknum = 0;
2386		}
2387		/* << INDEX */
2388
2389		for(pino = 0; pino <= tcp->numpocs; pino++) {
2390			int tot_num_tp;
2391			tcd->cur_pino=pino;
2392
2393			/*Get number of tile parts*/
2394			tot_num_tp = j2k_get_num_tp(cp,pino,tileno);
2395			tcd->tp_pos = cp->tp_pos;
2396
2397			for(tilepartno = 0; tilepartno < tot_num_tp ; tilepartno++){
2398				j2k->tp_num = tilepartno;
2399				/* INDEX >> */
2400				if(cstr_info)
2401					cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_start_pos =
2402					cio_tell(cio) + j2k->pos_correction;
2403				/* << INDEX */
2404				j2k_write_sot(j2k);
2405
2406				if(j2k->cur_tp_num == 0 && cp->cinema == 0){
2407					for (compno = 1; compno < image->numcomps; compno++) {
2408						j2k_write_coc(j2k, compno);
2409						j2k_write_qcc(j2k, compno);
2410					}
2411					if (cp->tcps[tileno].numpocs) {
2412						j2k_write_poc(j2k);
2413					}
2414				}
2415
2416				/* INDEX >> */
2417				if(cstr_info)
2418					cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_end_header =
2419					cio_tell(cio) + j2k->pos_correction + 1;
2420				/* << INDEX */
2421
2422				j2k_write_sod(j2k, tcd);
2423
2424				/* INDEX >> */
2425				if(cstr_info) {
2426					cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_end_pos =
2427						cio_tell(cio) + j2k->pos_correction - 1;
2428					cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_start_pack =
2429						acc_pack_num;
2430					cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_numpacks =
2431						cstr_info->packno - acc_pack_num;
2432					acc_pack_num = cstr_info->packno;
2433				}
2434				/* << INDEX */
2435
2436				j2k->cur_tp_num++;
2437			}			
2438		}
2439		if(cstr_info) {
2440			cstr_info->tile[j2k->curtileno].end_pos = cio_tell(cio) + j2k->pos_correction - 1;
2441		}
2442
2443
2444		/*
2445		if (tile->PPT) { // BAD PPT !!! 
2446		FILE *PPT_file;
2447		int i;
2448		PPT_file=fopen("PPT","rb");
2449		fprintf(stderr,"%c%c%c%c",255,97,tile->len_ppt/256,tile->len_ppt%256);
2450		for (i=0;i<tile->len_ppt;i++) {
2451		unsigned char elmt;
2452		fread(&elmt, 1, 1, PPT_file);
2453		fwrite(&elmt,1,1,f);
2454		}
2455		fclose(PPT_file);
2456		unlink("PPT");
2457		}
2458		*/
2459
2460	}
2461
2462	/* destroy the tile encoder */
2463	tcd_free_encode(tcd);
2464	tcd_destroy(tcd);
2465
2466	opj_free(j2k->cur_totnum_tp);
2467
2468	j2k_write_eoc(j2k);
2469
2470	if(cstr_info) {
2471		cstr_info->codestream_size = cio_tell(cio) + j2k->pos_correction;
2472		/* UniPG>> */
2473		/* The following adjustment is done to adjust the codestream size */
2474		/* if SOD is not at 0 in the buffer. Useful in case of JP2, where */
2475		/* the first bunch of bytes is not in the codestream              */
2476		cstr_info->codestream_size -= cstr_info->main_head_start;
2477		/* <<UniPG */
2478	}
2479
2480#ifdef USE_JPWL
2481	/*
2482	preparation of JPWL marker segments
2483	*/
2484	if(cp->epc_on) {
2485
2486		/* encode according to JPWL */
2487		jpwl_encode(j2k, cio, image);
2488
2489	}
2490#endif /* USE_JPWL */
2491
2492	return OPJ_TRUE;
2493}
2494
2495static void j2k_add_mhmarker(opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len) {
2496
2497	if (!cstr_info)
2498		return;
2499
2500	/* expand the list? */
2501	if ((cstr_info->marknum + 1) > cstr_info->maxmarknum) {
2502		cstr_info->maxmarknum = 100 + (int) ((float) cstr_info->maxmarknum * 1.0F);
2503		cstr_info->marker = (opj_marker_info_t*)opj_realloc(cstr_info->marker, cstr_info->maxmarknum);
2504	}
2505
2506	/* add the marker */
2507	cstr_info->marker[cstr_info->marknum].type = type;
2508	cstr_info->marker[cstr_info->marknum].pos = pos;
2509	cstr_info->marker[cstr_info->marknum].len = len;
2510	cstr_info->marknum++;
2511
2512}
2513
2514static void j2k_add_tlmarker( int tileno, opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len) {
2515
2516  opj_marker_info_t *marker;
2517
2518	if (!cstr_info)
2519		return;
2520
2521	/* expand the list? */
2522	if ((cstr_info->tile[tileno].marknum + 1) > cstr_info->tile[tileno].maxmarknum) {
2523		cstr_info->tile[tileno].maxmarknum = 100 + (int) ((float) cstr_info->tile[tileno].maxmarknum * 1.0F);
2524		cstr_info->tile[tileno].marker = (opj_marker_info_t*)opj_realloc(cstr_info->tile[tileno].marker, cstr_info->maxmarknum);
2525	}
2526
2527	marker = &(cstr_info->tile[tileno].marker[cstr_info->tile[tileno].marknum]);
2528
2529	/* add the marker */
2530	marker->type = type;
2531	marker->pos = pos;
2532	marker->len = len;
2533	cstr_info->tile[tileno].marknum++;
2534}