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