Initial revision
[openjpeg.git] / libopenjpeg / j2k.c
1 /*
2  * Copyright (c) 2001-2002, David Janssens
3  * Copyright (c) 2002-2004, Yannick Verschueren
4  * Copyright (c) 2002-2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <setjmp.h>
33 #include <math.h>
34
35 #include "j2k.h"
36 #include "cio.h"
37 #include "tcd.h"
38 #include "dwt.h"
39 #include "int.h"
40 #include "jpt.h"
41
42 #define J2K_MS_SOC 0xff4f
43 #define J2K_MS_SOT 0xff90
44 #define J2K_MS_SOD 0xff93
45 #define J2K_MS_EOC 0xffd9
46 #define J2K_MS_SIZ 0xff51
47 #define J2K_MS_COD 0xff52
48 #define J2K_MS_COC 0xff53
49 #define J2K_MS_RGN 0xff5e
50 #define J2K_MS_QCD 0xff5c
51 #define J2K_MS_QCC 0xff5d
52 #define J2K_MS_POC 0xff5f
53 #define J2K_MS_TLM 0xff55
54 #define J2K_MS_PLM 0xff57
55 #define J2K_MS_PLT 0xff58
56 #define J2K_MS_PPM 0xff60
57 #define J2K_MS_PPT 0xff61
58 #define J2K_MS_SOP 0xff91
59 #define J2K_MS_EPH 0xff92
60 #define J2K_MS_CRG 0xff63
61 #define J2K_MS_COM 0xff64
62
63 #define J2K_STATE_MHSOC 0x0001
64 #define J2K_STATE_MHSIZ 0x0002
65 #define J2K_STATE_MH 0x0004
66 #define J2K_STATE_TPHSOT 0x0008
67 #define J2K_STATE_TPH 0x0010
68 #define J2K_STATE_MT 0x0020
69 #define J2K_STATE_NEOC 0x0040
70
71
72 jmp_buf j2k_error;
73
74 static int j2k_state;
75 static int j2k_curtileno;
76 static j2k_tcp_t j2k_default_tcp;
77 static unsigned char *j2k_eot;
78 static int j2k_sot_start;
79 static int pos_correction;
80
81 static j2k_image_t *j2k_img;
82 static j2k_cp_t *j2k_cp;
83
84 static unsigned char **j2k_tile_data;
85 static int *j2k_tile_len;
86
87 static info_image info_IM;
88
89 /* Add Patrick */
90 void j2k_clean()
91 {
92         int tileno = 0;
93         tcd_free_encode(j2k_img, j2k_cp, j2k_curtileno);
94
95         if (info_IM.index_on) {
96                 for (tileno = 0; tileno < j2k_cp->tw * j2k_cp->th; tileno++) {
97                         free(info_IM.tile[tileno].packet);
98                 }
99                 free(info_IM.tile);
100         }
101 }
102
103 /* \Add Patrick */
104
105 void j2k_dump_image(j2k_image_t * img)
106 {
107         int compno;
108         fprintf(stderr, "image {\n");
109         fprintf(stderr, "  x0=%d, y0=%d, x1=%d, y1=%d\n", img->x0, img->y0,
110                                         img->x1, img->y1);
111         fprintf(stderr, "  numcomps=%d\n", img->numcomps);
112         for (compno = 0; compno < img->numcomps; compno++) {
113                 j2k_comp_t *comp = &img->comps[compno];
114                 fprintf(stderr, "  comp %d {\n", compno);
115                 fprintf(stderr, "    dx=%d, dy=%d\n", comp->dx, comp->dy);
116                 fprintf(stderr, "    prec=%d\n", comp->prec);
117                 fprintf(stderr, "    sgnd=%d\n", comp->sgnd);
118                 fprintf(stderr, "  }\n");
119         }
120         fprintf(stderr, "}\n");
121 }
122
123 void j2k_dump_cp(j2k_image_t * img, j2k_cp_t * cp)
124 {
125         int tileno, compno, layno, bandno, resno, numbands;
126         fprintf(stderr, "coding parameters {\n");
127         fprintf(stderr, "  tx0=%d, ty0=%d\n", cp->tx0, cp->ty0);
128         fprintf(stderr, "  tdx=%d, tdy=%d\n", cp->tdx, cp->tdy);
129         fprintf(stderr, "  tw=%d, th=%d\n", cp->tw, cp->th);
130         for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
131                 j2k_tcp_t *tcp = &cp->tcps[tileno];
132                 fprintf(stderr, "  tile %d {\n", tileno);
133                 fprintf(stderr, "    csty=%x\n", tcp->csty);
134                 fprintf(stderr, "    prg=%d\n", tcp->prg);
135                 fprintf(stderr, "    numlayers=%d\n", tcp->numlayers);
136                 fprintf(stderr, "    mct=%d\n", tcp->mct);
137                 fprintf(stderr, "    rates=");
138                 for (layno = 0; layno < tcp->numlayers; layno++) {
139                         fprintf(stderr, "%d ", tcp->rates[layno]);
140                 }
141                 fprintf(stderr, "\n");
142                 for (compno = 0; compno < img->numcomps; compno++) {
143                         j2k_tccp_t *tccp = &tcp->tccps[compno];
144                         fprintf(stderr, "    comp %d {\n", compno);
145                         fprintf(stderr, "      csty=%x\n", tccp->csty);
146                         fprintf(stderr, "      numresolutions=%d\n", tccp->numresolutions);
147                         fprintf(stderr, "      cblkw=%d\n", tccp->cblkw);
148                         fprintf(stderr, "      cblkh=%d\n", tccp->cblkh);
149                         fprintf(stderr, "      cblksty=%x\n", tccp->cblksty);
150                         fprintf(stderr, "      qmfbid=%d\n", tccp->qmfbid);
151                         fprintf(stderr, "      qntsty=%d\n", tccp->qntsty);
152                         fprintf(stderr, "      numgbits=%d\n", tccp->numgbits);
153                         fprintf(stderr, "      roishift=%d\n", tccp->roishift);
154                         fprintf(stderr, "      stepsizes=");
155                         numbands =
156                                 tccp->qntsty ==
157                                 J2K_CCP_QNTSTY_SIQNT ? 1 : tccp->numresolutions * 3 - 2;
158                         for (bandno = 0; bandno < numbands; bandno++) {
159                                 fprintf(stderr, "(%d,%d) ", tccp->stepsizes[bandno].mant,
160                                                                 tccp->stepsizes[bandno].expn);
161                         }
162                         fprintf(stderr, "\n");
163
164                         if (tccp->csty & J2K_CCP_CSTY_PRT) {
165                                 fprintf(stderr, "      prcw=");
166                                 for (resno = 0; resno < tccp->numresolutions; resno++) {
167                                         fprintf(stderr, "%d ", tccp->prcw[resno]);
168                                 }
169                                 fprintf(stderr, "\n");
170                                 fprintf(stderr, "      prch=");
171                                 for (resno = 0; resno < tccp->numresolutions; resno++) {
172                                         fprintf(stderr, "%d ", tccp->prch[resno]);
173                                 }
174                                 fprintf(stderr, "\n");
175                         }
176                         fprintf(stderr, "    }\n");
177                 }
178                 fprintf(stderr, "  }\n");
179         }
180         fprintf(stderr, "}\n");
181 }
182
183 void j2k_write_soc()
184 {
185   /* fprintf(stderr, "%.8x: SOC\n", cio_tell()); */
186   cio_write(J2K_MS_SOC, 2);
187 }
188
189 void j2k_read_soc()
190 {
191   fprintf(stderr, "%.8x: SOC\n", cio_tell()-2);
192         j2k_state = J2K_STATE_MHSIZ;
193 }
194
195 void j2k_write_siz()
196 {
197         int i;
198         int lenp, len;
199         /* fprintf(stderr, "%.8x: SIZ\n", cio_tell()); */
200         cio_write(J2K_MS_SIZ, 2);                    /* SIZ                 */
201         lenp = cio_tell();
202         cio_skip(2);
203         cio_write(0, 2);                             /* Rsiz (capabilities) */
204         cio_write(j2k_img->x1, 4);                   /* Xsiz                */
205         cio_write(j2k_img->y1, 4);                   /* Ysiz                */
206         cio_write(j2k_img->x0, 4);                   /* X0siz               */
207         cio_write(j2k_img->y0, 4);                   /* Y0siz               */
208         cio_write(j2k_cp->tdx, 4);                   /* XTsiz               */
209         cio_write(j2k_cp->tdy, 4);                   /* YTsiz               */
210         cio_write(j2k_cp->tx0, 4);                   /* XT0siz              */
211         cio_write(j2k_cp->ty0, 4);                   /* YT0siz              */
212         cio_write(j2k_img->numcomps, 2);             /* Csiz                */
213         for (i = 0; i < j2k_img->numcomps; i++) {
214                 cio_write(j2k_img->comps[i].prec - 1 + (j2k_img->comps[i].sgnd << 7), 1);       /* Ssiz_i */
215                 cio_write(j2k_img->comps[i].dx, 1);  /* XRsiz_i             */
216                 cio_write(j2k_img->comps[i].dy, 1);  /* YRsiz_i             */
217         }
218         len = cio_tell() - lenp;
219         cio_seek(lenp);
220         cio_write(len, 2);                           /* Lsiz                */
221         cio_seek(lenp + len);
222
223 }
224
225 void j2k_read_siz()
226 {
227         int len, i;
228         fprintf(stderr, "%.8x: SIZ\n", cio_tell());
229         len = cio_read(2);                       /* Lsiz                */
230         cio_read(2);                             /* Rsiz (capabilities) */
231         j2k_img->x1 = cio_read(4);               /* Xsiz                */
232         j2k_img->y1 = cio_read(4);               /* Ysiz                */ 
233         j2k_img->x0 = cio_read(4);               /* X0siz               */
234         j2k_img->y0 = cio_read(4);               /* Y0siz               */
235         j2k_cp->tdx = cio_read(4);               /* XTsiz               */
236         j2k_cp->tdy = cio_read(4);               /* YTsiz               */
237         j2k_cp->tx0 = cio_read(4);               /* XT0siz              */
238         j2k_cp->ty0 = cio_read(4);               /* YT0siz              */
239
240         j2k_img->numcomps = cio_read(2);         /* Csiz                */
241         j2k_img->comps = (j2k_comp_t *) malloc(j2k_img->numcomps * sizeof(j2k_comp_t));
242         for (i = 0; i < j2k_img->numcomps; i++) {
243                 int tmp, w, h;
244                 tmp = cio_read(1);                   /* Ssiz_i          */
245                 j2k_img->comps[i].prec = (tmp & 0x7f) + 1;
246                 j2k_img->comps[i].sgnd = tmp >> 7;
247                 j2k_img->comps[i].dx = cio_read(1);  /* XRsiz_i         */
248                 j2k_img->comps[i].dy = cio_read(1);  /* YRsiz_i         */
249                 w = int_ceildiv(j2k_img->x1 - j2k_img->x0, j2k_img->comps[i].dx);
250                 h = int_ceildiv(j2k_img->y1 - j2k_img->y0, j2k_img->comps[i].dy);
251                 j2k_img->comps[i].data = (int *) malloc(sizeof(int) * w * h);
252         }
253
254         j2k_cp->tw = int_ceildiv(j2k_img->x1 - j2k_cp->tx0, j2k_cp->tdx);
255         j2k_cp->th = int_ceildiv(j2k_img->y1 - j2k_cp->ty0, j2k_cp->tdy);
256         j2k_cp->tcps =  (j2k_tcp_t *) calloc(j2k_cp->tw * j2k_cp->th, sizeof(j2k_tcp_t));
257         for (i=0; i<j2k_cp->tw * j2k_cp->th; i++)
258           {
259             j2k_cp->tcps[i].POC=0;
260             j2k_cp->tcps[i].numpocs=0;
261             j2k_cp->tcps[i].first=1;
262           }
263
264         /* Initialization for PPM marker */
265         j2k_cp->ppm = 0;
266         j2k_cp->ppm_data = NULL;
267         j2k_cp->ppm_previous = 0;
268         j2k_cp->ppm_store = 0;
269
270         j2k_default_tcp.tccps = (j2k_tccp_t *) calloc(sizeof(j2k_tccp_t), j2k_img->numcomps);
271         for (i = 0; i < j2k_cp->tw * j2k_cp->th; i++) {
272                 j2k_cp->tcps[i].tccps = (j2k_tccp_t *) calloc(sizeof(j2k_tccp_t), j2k_img->numcomps);
273         }
274         j2k_tile_data = (unsigned char **) calloc(j2k_cp->tw * j2k_cp->th, sizeof(char *));
275         j2k_tile_len = (int *) calloc(j2k_cp->tw * j2k_cp->th, sizeof(int));
276         j2k_state = J2K_STATE_MH;
277
278         
279 }
280
281 void j2k_write_com()
282 {
283         unsigned int i;
284         int lenp, len;
285         char str[256];
286         sprintf(str, "%s", j2k_cp->comment);
287         /* fprintf(stderr, "%.8x: COM\n", cio_tell()); */
288         cio_write(J2K_MS_COM, 2);
289         lenp = cio_tell();
290         cio_skip(2);
291         cio_write(0, 2);
292         for (i = 0; i < strlen(str); i++) {
293                 cio_write(str[i], 1);
294         }
295         len = cio_tell() - lenp;
296         cio_seek(lenp);
297         cio_write(len, 2);
298         cio_seek(lenp + len);
299
300 }
301
302 void j2k_read_com()
303 {
304         int len;
305         fprintf(stderr, "%.8x: COM\n", cio_tell()-2);
306         len = cio_read(2);
307         cio_skip(len - 2);
308         
309 }
310
311 void j2k_write_cox(int compno)
312 {
313         int i;
314         j2k_tcp_t *tcp;
315         j2k_tccp_t *tccp;
316         tcp = &j2k_cp->tcps[j2k_curtileno];
317         tccp = &tcp->tccps[compno];
318
319         cio_write(tccp->numresolutions - 1, 1); /* SPcox (D) */
320         cio_write(tccp->cblkw - 2, 1);          /* SPcox (E) */
321         cio_write(tccp->cblkh - 2, 1);          /* SPcox (F) */
322         cio_write(tccp->cblksty, 1);            /* SPcox (G) */
323         cio_write(tccp->qmfbid, 1);             /* SPcox (H) */
324
325         if (tccp->csty & J2K_CCP_CSTY_PRT) {
326                 for (i = 0; i < tccp->numresolutions; i++) {
327                         cio_write(tccp->prcw[i] + (tccp->prch[i] << 4), 1);     /* SPcox (I_i) */
328                 }
329         }
330 }
331
332 void j2k_read_cox(int compno)
333 {
334         int i;
335         j2k_tcp_t *tcp;
336         j2k_tccp_t *tccp;
337         tcp = j2k_state == J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp;
338         tccp = &tcp->tccps[compno];
339         tccp->numresolutions = cio_read(1) + 1;  /* SPcox (D) */
340         tccp->cblkw = cio_read(1) + 2;           /* SPcox (E) */
341         tccp->cblkh = cio_read(1) + 2;           /* SPcox (F) */
342         tccp->cblksty = cio_read(1);             /* SPcox (G) */
343         tccp->qmfbid = cio_read(1);              /* SPcox (H) */
344         if (tccp->csty & J2K_CP_CSTY_PRT) {
345                 for (i = 0; i < tccp->numresolutions; i++) {
346                         int tmp = cio_read(1);   /* SPcox (I_i) */
347                         tccp->prcw[i] = tmp & 0xf;
348                         tccp->prch[i] = tmp >> 4;
349                 }
350         }
351 }
352
353 void j2k_write_cod()
354 {
355         j2k_tcp_t *tcp;
356         int lenp, len;
357         /* fprintf(stderr, "%.8x: COD\n", cio_tell()+pos_correction); */
358         cio_write(J2K_MS_COD, 2);       /* COD */
359
360         lenp = cio_tell();
361         cio_skip(2);
362
363         tcp = &j2k_cp->tcps[j2k_curtileno];
364         cio_write(tcp->csty, 1);        /* Scod */
365         cio_write(tcp->prg, 1);         /* SGcod (A) */
366         cio_write(tcp->numlayers, 2);   /* SGcod (B) */
367         cio_write(tcp->mct, 1);         /* SGcod (C) */
368
369         j2k_write_cox(0);
370         len = cio_tell() - lenp;
371         cio_seek(lenp);
372         cio_write(len, 2);              /* Lcod */
373         cio_seek(lenp + len);
374 }
375
376 void j2k_read_cod()
377 {
378         int len, i, pos;
379         j2k_tcp_t *tcp;
380         fprintf(stderr, "%.8x: COD\n", cio_tell()-2);
381         tcp = j2k_state == J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp;
382         len = cio_read(2);              /* Lcod */
383         tcp->csty = cio_read(1);        /* Scod */
384         tcp->prg = cio_read(1);         /* SGcod (A) */
385         tcp->numlayers = cio_read(2);   /* SGcod (B) */
386         tcp->mct = cio_read(1);         /* SGcod (C) */
387         /*tcp->numpocs=0;
388           tcp->POC=0;*/
389         pos = cio_tell();
390         for (i = 0; i < j2k_img->numcomps; i++) {
391                 tcp->tccps[i].csty = tcp->csty & J2K_CP_CSTY_PRT;
392                 cio_seek(pos);
393                 j2k_read_cox(i);
394         }
395 }
396
397 void j2k_write_coc(int compno)
398 {
399         j2k_tcp_t *tcp;
400         int lenp, len;
401         /* fprintf(stderr, "%.8x: COC\n", cio_tell()+pos_correction); */
402         cio_write(J2K_MS_COC, 2);                               /* COC */
403         lenp = cio_tell();
404         cio_skip(2);
405         tcp = &j2k_cp->tcps[j2k_curtileno];
406         cio_write(compno, j2k_img->numcomps <= 256 ? 1 : 2);    /* Ccoc */
407         cio_write(tcp->tccps[compno].csty, 1);                  /* Scoc */
408         j2k_write_cox(compno);
409         len = cio_tell() - lenp;
410         cio_seek(lenp);
411         cio_write(len, 2);                                      /* Lcoc */
412         cio_seek(lenp + len);
413 }
414
415 void j2k_read_coc()
416 {
417         int len, compno;
418         j2k_tcp_t *tcp;
419         fprintf(stderr, "%.8x: COC\n", cio_tell());
420         tcp = j2k_state == J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp;
421         len = cio_read(2);                                      /* Lcoc */
422         compno = cio_read(j2k_img->numcomps <= 256 ? 1 : 2);    /* Ccoc */
423         tcp->tccps[compno].csty = cio_read(1);                  /* Scoc */
424         j2k_read_cox(compno);
425 }
426
427 void j2k_write_qcx(int compno)
428 {
429         j2k_tcp_t *tcp;
430         j2k_tccp_t *tccp;
431         int bandno, numbands;
432         int expn, mant;
433         tcp = &j2k_cp->tcps[j2k_curtileno];
434         tccp = &tcp->tccps[compno];
435
436         cio_write(tccp->qntsty + (tccp->numgbits << 5), 1);     /* Sqcx */
437         numbands = tccp->qntsty == J2K_CCP_QNTSTY_SIQNT ? 1 : tccp->numresolutions * 3 - 2;
438
439         for (bandno = 0; bandno < numbands; bandno++) {
440                 expn = tccp->stepsizes[bandno].expn;
441                 mant = tccp->stepsizes[bandno].mant;
442
443                 if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) {
444                         cio_write(expn << 3, 1);                /* SPqcx_i */
445                 } else {
446                         cio_write((expn << 11) + mant, 2);      /* SPqcx_i */
447                 }
448         }
449
450 }
451
452 void j2k_read_qcx(int compno, int len)
453 {
454         int tmp;
455         j2k_tcp_t *tcp;
456         j2k_tccp_t *tccp;
457         int bandno, numbands;
458         tcp = j2k_state == J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp;
459         tccp = &tcp->tccps[compno];
460         tmp = cio_read(1);                                      /* Sqcx */
461         tccp->qntsty = tmp & 0x1f;
462         tccp->numgbits = tmp >> 5;
463         numbands = tccp->qntsty == J2K_CCP_QNTSTY_SIQNT ? 1 : (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT ? len - 1 : (len - 1) / 2);
464         for (bandno = 0; bandno < numbands; bandno++) {
465                 int expn, mant;
466                 if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) {     /* WHY STEPSIZES WHEN NOQNT ? */
467                         expn = cio_read(1) >> 3;                /* SPqcx_i */
468                         mant = 0;
469                 } else {
470                         tmp = cio_read(2);                      /* SPqcx_i */
471                         expn = tmp >> 11;
472                         mant = tmp & 0x7ff;
473                 }
474                 tccp->stepsizes[bandno].expn = expn;
475                 tccp->stepsizes[bandno].mant = mant;
476         }
477 }
478
479 void j2k_write_qcd()
480 {
481         int lenp, len;
482         /* fprintf(stderr, "%.8x: QCD\n", cio_tell()+pos_correction); */
483         cio_write(J2K_MS_QCD, 2);               /* QCD */
484         lenp = cio_tell();
485         cio_skip(2);
486         j2k_write_qcx(0);
487         len = cio_tell() - lenp;
488         cio_seek(lenp);
489         cio_write(len, 2);                      /* Lqcd */
490         cio_seek(lenp + len);
491 }
492
493 void j2k_read_qcd()
494 {
495         int len, i, pos;
496         fprintf(stderr, "%.8x: QCD\n", cio_tell()-2);
497         len = cio_read(2);                      /* Lqcd */
498         pos = cio_tell();
499         for (i = 0; i < j2k_img->numcomps; i++) {
500                 cio_seek(pos);
501                 j2k_read_qcx(i, len - 2);
502         }
503 }
504
505 void j2k_write_qcc(int compno)
506 {
507         int lenp, len;
508         /* fprintf(stderr, "%.8x: QCC\n", cio_tell()+pos_correction); */
509         cio_write(J2K_MS_QCC, 2);                             /* QCC */
510         lenp = cio_tell();
511         cio_skip(2);
512         cio_write(compno, j2k_img->numcomps <= 256 ? 1 : 2);  /* Cqcc */
513         j2k_write_qcx(compno);
514         len = cio_tell() - lenp;
515         cio_seek(lenp);
516         cio_write(len, 2);                                    /* Lqcc */
517         cio_seek(lenp + len);
518 }
519
520 void j2k_read_qcc()
521 {
522         int len, compno;
523         fprintf(stderr, "%.8x: QCC\n", cio_tell()-2);
524         len = cio_read(2);                                    /* Lqcc */
525         compno = cio_read(j2k_img->numcomps <= 256 ? 1 : 2);  /* Cqcc */
526         j2k_read_qcx(compno, len - 2 - (j2k_img->numcomps <= 256 ? 1 : 2));
527 }
528
529 void j2k_write_poc() {
530   int len,  numpchgs, i;
531   j2k_tcp_t *tcp;
532   j2k_tccp_t *tccp;
533   fprintf(stderr, "%.8x: POC\n", cio_tell() + pos_correction);
534   tcp = &j2k_cp->tcps[j2k_curtileno];
535   tccp = &tcp->tccps[0];
536   numpchgs = tcp->numpocs;
537   cio_write(J2K_MS_POC, 2);                                         /* POC  */
538   len = 2 + (5 + 2*(j2k_img->numcomps <= 256 ? 1 : 2))*numpchgs;         
539   cio_write(len, 2);                                                /* Lpoc */
540   for (i = 0; i < numpchgs; i++)
541     {
542       // MODIF
543       j2k_poc_t *poc;
544       poc = &tcp->pocs[i];
545       cio_write(poc->resno0, 1);                                    /* RSpoc_i */
546       cio_write(poc->compno0, (j2k_img->numcomps <= 256 ? 1 : 2));  /* CSpoc_i */
547       cio_write(poc->layno1, 2);                                    /* LYEpoc_i */
548       poc->layno1 = int_min(poc->layno1, tcp->numlayers);
549       cio_write(poc->resno1, 1);                                    /* REpoc_i */
550       poc->resno1 = int_min(poc->resno1, tccp->numresolutions);
551       cio_write(poc->compno1, (j2k_img->numcomps <= 256 ? 1 : 2));  /* CEpoc_i */
552       poc->compno1 = int_min(poc->compno1, j2k_img->numcomps);
553       cio_write(poc->prg, 1);                                       /* Ppoc_i */
554     }
555 }
556
557 void j2k_read_poc() {
558     int len, numpchgs, i, old_poc;
559     j2k_tcp_t *tcp;
560     j2k_tccp_t *tccp;
561     fprintf(stderr, "%.8x: POC\n", cio_tell()-2);
562     tcp = j2k_state==J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp;
563
564     old_poc = tcp->POC ? tcp->numpocs+1 : 0;
565     printf("old_poc %d\n",old_poc);
566     tcp->POC = 1;
567     tccp = &tcp->tccps[0];
568     len = cio_read(2);                                              /* Lpoc */
569     numpchgs = (len-2)/(5+2*(j2k_img->numcomps <= 256 ? 1 : 2));
570
571     for (i = old_poc; i < numpchgs+old_poc; i++) 
572       {
573         j2k_poc_t *poc;
574         poc = &tcp->pocs[i];
575         poc->resno0 = cio_read(1);                                  /* RSpoc_i */
576         poc->compno0 = cio_read(j2k_img->numcomps <= 256 ? 1 : 2);  /* CSpoc_i */
577         poc->layno1 = int_min(cio_read(2), tcp->numlayers);         /* LYEpoc_i */
578         poc->resno1 = int_min(cio_read(1), tccp->numresolutions);   /* REpoc_i */
579         poc->compno1 = int_min(cio_read(j2k_img->numcomps <= 256 ? 1 : 2), j2k_img->numcomps);  /* CEpoc_i */
580         poc->prg = cio_read(1);                                     /* Ppoc_i */
581         printf("res0 %d comp0 %d lay1 %d res1 %d comp1 %d prg %d\n",poc->resno0,poc->compno0,poc->layno1,poc->resno1,poc->compno1,poc->prg);
582       }
583
584     tcp->numpocs = numpchgs+old_poc-1;
585 }
586
587 void j2k_read_crg()
588 {
589         int len, i, Xcrg_i, Ycrg_i;
590         fprintf(stderr, "%.8x: CRG\n", cio_tell() - 2);
591         len = cio_read(2);                                          /* Lcrg */
592         for (i=0;i<j2k_img->numcomps;i++)
593           {  
594             Xcrg_i = cio_read(2);                                   /* Xcrg_i */
595             Ycrg_i = cio_read(2);                                   /* Ycrg_i */
596           }
597 }
598
599 void j2k_read_tlm()
600 {
601         int len, Ztlm, Stlm, ST, SP, tile_tlm, i;
602         long int Ttlm_i, Ptlm_i;
603         fprintf(stderr, "%.8x: TLM\n", cio_tell() - 2);
604         len = cio_read(2);                                       /* Ltlm */
605         Ztlm = cio_read(1);                                      /* Ztlm */
606         Stlm = cio_read(1);                                      /* Stlm */
607         ST = ((Stlm >> 4) & 0x01) + ((Stlm >> 4) & 0x02);        
608         SP = (Stlm >> 6) & 0x01;
609         tile_tlm = (len-4)/((SP+1)*2+ST);
610         for (i=0;i<tile_tlm;i++)
611           {
612             Ttlm_i = cio_read(ST);                               /* Ttlm_i */
613             Ptlm_i = cio_read(SP?4:2);                           /* Ptlm_i */
614           }
615 }
616
617 void j2k_read_plm()
618 {
619         int len, i, Zplm, Nplm, add, packet_len=0;
620         fprintf(stderr, "%.8x: PLM\n", cio_tell() - 2);
621         len = cio_read(2);                                       /* Lplm */
622         Zplm = cio_read(1);                                      /* Zplm */
623         len-=3;
624         while (len>0)
625           {
626             Nplm = cio_read(4);                                  /* Nplm */
627             len-=4;
628             for (i=Nplm ; i>0 ; i--)
629               {
630                 add=cio_read(1);
631                 len--;
632                 packet_len=(packet_len<<7) + add;                /* Iplm_ij */
633                 if ((add & 0x80)==0)
634                   {
635                     /* New packet */
636                     packet_len=0;
637                   }
638                 if (len<=0) break;
639               } 
640           }
641 }
642
643 void j2k_read_plt()
644 {
645         int len, i, Zplt, packet_len=0, add;
646         fprintf(stderr, "%.8x: PLT\n", cio_tell() - 2);
647         len = cio_read(2);                                      /* Lplt */
648         Zplt=cio_read(1);                                       /* Zplt */
649         for (i=len-3;i>0;i--)
650           {
651             add=cio_read(1);
652             packet_len=(packet_len<<7) + add;                   /* Iplt_i */
653             if ((add & 0x80)==0)
654               {
655                 /* New packet */
656                 packet_len=0;
657               }
658           }
659 }
660
661 void j2k_read_ppm()
662 {
663   int len, Z_ppm, i, j;
664   int N_ppm;
665   fprintf(stderr, "%.8x: PPM\n", cio_tell() - 2);
666   len = cio_read(2);
667   j2k_cp->ppm=1;
668   
669   Z_ppm = cio_read(1);                   /* Z_ppm */
670   len-=3;
671   while (len > 0)
672     {
673       if (j2k_cp->ppm_previous==0)
674         {
675           N_ppm = cio_read(4);           /* N_ppm */
676           len-=4;
677         } else
678           {
679             N_ppm = j2k_cp->ppm_previous;
680           }
681       
682       j=j2k_cp->ppm_store;
683       if (Z_ppm==0) /* First PPM marker */
684         j2k_cp->ppm_data=(unsigned char*)calloc(N_ppm,sizeof(unsigned char));
685       else      /* NON-first PPM marker */
686         j2k_cp->ppm_data=(unsigned char*)realloc(j2k_cp->ppm_data, (N_ppm+j2k_cp->ppm_store)*sizeof(unsigned char));
687
688       for (i=N_ppm ; i>0 ; i--) /* Read packet header */
689         {
690           j2k_cp->ppm_data[j]=cio_read(1);
691           j++;
692           len--;
693           if (len==0) break; /* Case of non-finished packet header in present marker but finished in next one */
694         }
695       
696       j2k_cp->ppm_previous=i-1;
697       j2k_cp->ppm_store=j;
698     }
699 }
700
701 void j2k_read_ppt()
702 {
703         int len, Z_ppt, i, j=0;
704         j2k_tcp_t *tcp;
705         fprintf(stderr, "%.8x: PPT\n", cio_tell() - 2);
706         len = cio_read(2);      
707         Z_ppt = cio_read(1);
708         tcp=&j2k_cp->tcps[j2k_curtileno];
709         tcp->ppt=1;
710         if (Z_ppt==0) /* First PPT marker */
711           {
712             tcp->ppt_data=(unsigned char*)calloc(len-3,sizeof(unsigned char));
713             tcp->ppt_store=0;
714           }
715         else      /* NON-first PPT marker */
716           tcp->ppt_data=(unsigned char*)realloc(tcp->ppt_data, (len-3+tcp->ppt_store)*sizeof(unsigned char));
717         
718         j=tcp->ppt_store;
719         for (i=len-3 ; i>0 ; i--)
720           {
721             tcp->ppt_data[j]=cio_read(1);
722             j++;
723           }
724         tcp->ppt_store=j;
725 }
726
727 void j2k_write_sot()
728 {
729         int lenp, len;
730         /* fprintf(stderr, "%.8x: SOT\n", cio_tell()+pos_correction); */
731         j2k_sot_start = cio_tell();
732         cio_write(J2K_MS_SOT, 2);       /* SOT */
733         lenp = cio_tell();      
734         cio_skip(2);                    /* Lsot (further) */
735         cio_write(j2k_curtileno, 2);    /* Isot */
736         cio_skip(4);                    /* Psot (further in j2k_write_sod) */
737         cio_write(0, 1);                /* TPsot */
738         cio_write(1, 1);                /* TNsot */
739         len = cio_tell() - lenp;
740         cio_seek(lenp);
741         cio_write(len, 2);              /* Lsot */
742         cio_seek(lenp + len);
743 }
744
745 void j2k_read_sot()
746 {
747         int len, tileno, totlen, partno, numparts, i;
748         j2k_tcp_t *tcp;
749         j2k_tccp_t *tmp;
750
751         fprintf(stderr, "%.8x: SOT\n", cio_tell()-2);
752         len = cio_read(2);
753         tileno = cio_read(2);
754         totlen = cio_read(4);
755         if (!totlen) 
756           totlen = cio_numbytesleft() + 8;
757
758         partno = cio_read(1);
759         numparts = cio_read(1);
760
761         j2k_curtileno = tileno;
762         j2k_eot = cio_getbp() - 12 + totlen;
763         j2k_state = J2K_STATE_TPH;
764         tcp = &j2k_cp->tcps[j2k_curtileno];
765
766         if (tcp->first == 1)
767           {
768             tmp = tcp->tccps;
769             *tcp = j2k_default_tcp;
770             
771             /* Initialization PPT */
772             tcp->ppt=0; 
773             tcp->ppt_data=NULL;
774             
775             tcp->tccps = tmp;
776             for (i = 0; i < j2k_img->numcomps; i++) {
777               tcp->tccps[i] = j2k_default_tcp.tccps[i];
778             }
779             j2k_cp->tcps[j2k_curtileno].first=0; 
780           }
781 }
782
783 void j2k_write_sod()
784 {
785         int l, layno;
786         int totlen;
787         j2k_tcp_t *tcp;
788         static int j2k_sod_start;
789
790         /* fprintf(stderr, "%.8x: SOD\n", cio_tell()+pos_correction); */
791         cio_write(J2K_MS_SOD, 2);
792         if (j2k_curtileno == 0) {
793                 j2k_sod_start = cio_tell() + pos_correction;
794         }
795
796         /* INDEX >> */
797         if (info_IM.index_on) {
798                 info_IM.tile[j2k_curtileno].end_header = cio_tell() + pos_correction - 1;
799                 info_IM.tile[j2k_curtileno].packet = (info_packet *) calloc(info_IM.Comp * info_IM.Layer * (info_IM.Decomposition + 1) * 
800                                                                             10,sizeof(info_packet));
801         }
802         /* << INDEX */
803
804         tcp = &j2k_cp->tcps[j2k_curtileno];
805         for (layno = 0; layno < tcp->numlayers; layno++) {
806                 tcp->rates[layno] -= (j2k_sod_start / (j2k_cp->th * j2k_cp->tw));
807                 /* fprintf(stderr, "tcp->rates[%d]=%d\n", layno, tcp->rates[layno]); */
808         }
809
810         info_IM.num = 0;
811         if (j2k_cp->image_type)
812                 l = tcd_encode_tile_pxm(j2k_curtileno, cio_getbp(), cio_numbytesleft() - 2, &info_IM);
813         else
814                 l = tcd_encode_tile_pgx(j2k_curtileno, cio_getbp(), cio_numbytesleft() - 2, &info_IM);
815
816         /* Writing Psot in SOT marker */
817         totlen = cio_tell() + l - j2k_sot_start;
818         cio_seek(j2k_sot_start + 6);
819         cio_write(totlen, 4);
820         cio_seek(j2k_sot_start + totlen);
821 }
822
823 void j2k_read_sod()
824 {
825         int len, truncate = 0;
826         unsigned char *data;
827
828         fprintf(stderr, "%.8x: SOD\n", cio_tell()-2);
829         len = int_min(j2k_eot - cio_getbp(), cio_numbytesleft() + 1);
830         if (len == cio_numbytesleft() + 1)
831                 truncate = 1;           /* Case of a truncate codestream */
832
833         j2k_tile_len[j2k_curtileno] += len;
834         data =  (unsigned char *) realloc(j2k_tile_data[j2k_curtileno], j2k_tile_len[j2k_curtileno]);
835         memcpy(data, cio_getbp(), len);
836         j2k_tile_data[j2k_curtileno] = data;
837
838         cio_skip(len);
839
840         if (!truncate)
841                 j2k_state = J2K_STATE_TPHSOT;
842         else
843                 j2k_state = J2K_STATE_NEOC;     /* RAJOUTE !! */
844 }
845
846 void j2k_write_rgn(int compno, int tileno)
847 {
848         j2k_tcp_t *tcp = &j2k_cp->tcps[tileno];
849         /* fprintf(stderr, "%.8x: RGN\n",cio_tell()+pos_correction); */
850         cio_write(J2K_MS_RGN, 2);                               /* RGN  */
851         cio_write(j2k_img->numcomps <= 256 ? 5 : 6, 2);         /* Lrgn */
852         cio_write(compno, j2k_img->numcomps <= 256 ? 1 : 2);    /* Crgn */
853         cio_write(0, 1);                                        /* Srgn */
854         cio_write(tcp->tccps[compno].roishift, 1);              /* SPrgn */
855 }
856
857 void j2k_read_rgn()
858 {
859         int len, compno, roisty;
860         j2k_tcp_t *tcp;
861         fprintf(stderr, "%.8x: RGN\n", cio_tell() - 2);
862         tcp = j2k_state == J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp;
863         len = cio_read(2);                                      /* Lrgn */
864         compno = cio_read(j2k_img->numcomps <= 256 ? 1 : 2);    /* Crgn */
865         roisty = cio_read(1);                                   /* Srgn */
866         tcp->tccps[compno].roishift = cio_read(1);              /* SPrgn */
867 }
868
869 void j2k_write_eoc()
870 {
871   /* fprintf(stderr, "%.8x: EOC\n", cio_tell() + pos_correction); */
872         cio_write(J2K_MS_EOC, 2);
873 }
874
875 void j2k_read_eoc()
876 {
877         int tileno;
878         fprintf(stderr, "%.8x: EOC\n", cio_tell()-2);
879         /* j2k_dump_image(j2k_img); */
880         /* j2k_dump_cp(j2k_img, j2k_cp); */
881
882         tcd_init(j2k_img, j2k_cp);
883         for (tileno = 0; tileno < j2k_cp->tw * j2k_cp->th; tileno++) {
884                 tcd_decode_tile(j2k_tile_data[tileno], j2k_tile_len[tileno], tileno);
885         }
886         
887         j2k_state = J2K_STATE_MT;
888         longjmp(j2k_error, 1);
889 }
890
891 void j2k_read_unk()
892 {
893         fprintf(stderr, "warning: unknown marker\n");
894 }
895
896 LIBJ2K_API int j2k_encode(j2k_image_t * img, j2k_cp_t * cp, char *outfile, int len, char *index)
897 {
898         int tileno, compno, layno, resno, precno, pack_nb;
899         char *dest;
900         FILE *INDEX;
901         FILE *f;
902
903         if (setjmp(j2k_error)) {
904                 return 0;
905         }
906
907         f = fopen(outfile, "wb");
908
909         if (!f) {
910                 fprintf(stderr, "failed to open %s for writing\n", outfile);
911                 return 1;
912         }
913
914         dest = (char *) malloc(len);
915         cio_init(dest, len);
916
917         j2k_img = img;
918         j2k_cp = cp;
919         /* j2k_dump_cp(j2k_img, j2k_cp); */
920
921         /* INDEX >> */
922         info_IM.index_on = j2k_img->index_on;
923         if (info_IM.index_on) {
924                 info_IM.tile = (info_tile *) malloc(j2k_cp->tw * j2k_cp->th * sizeof(info_tile));
925                 info_IM.Im_w = j2k_img->x1 - j2k_img->x0;
926                 info_IM.Im_h = j2k_img->y1 - j2k_img->y0;
927                 info_IM.Prog = (&j2k_cp->tcps[0])->prg;
928                 /* info_IM.Tile_x=j2k_cp->tw; old version parser */
929                 /* info_IM.Tile_y=j2k_cp->th; old version parser */
930                 info_IM.Tile_x = j2k_cp->tdx;   /* new version parser */
931                 info_IM.Tile_y = j2k_cp->tdy;   /* new version parser */
932                 info_IM.Comp = j2k_img->numcomps;
933                 info_IM.Layer = (&j2k_cp->tcps[0])->numlayers;
934                 info_IM.Decomposition = (&j2k_cp->tcps[0])->tccps->numresolutions - 1;
935                 info_IM.D_max = 0;                                      /* ADD Marcela */
936         }
937         /* << INDEX */
938
939         j2k_write_soc();
940         j2k_write_siz();
941         j2k_write_cod();
942         j2k_write_qcd();
943         for (compno = 0; compno < j2k_img->numcomps; compno++) {
944                 j2k_tcp_t *tcp = &j2k_cp->tcps[0];
945                 if (tcp->tccps[compno].roishift)
946                         j2k_write_rgn(compno, 0);
947         }
948         if (j2k_cp->comment != NULL)
949                 j2k_write_com();
950
951         /* Writing the main header */
952         pos_correction = cio_tell();
953         fwrite(dest, 1, cio_tell(), f);
954
955         /* INDEX >> */
956         if (info_IM.index_on) {
957                 info_IM.Main_head_end = cio_tell() - 1;
958         }
959         /* << INDEX */
960
961         
962         for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
963                 fprintf(stderr, "\nTile number %d / %d \n", tileno + 1,
964                                                 cp->tw * cp->th);
965
966                 /* new dest for each tile  */
967                 free(dest);
968                 dest = (char *) malloc(len);
969                 cio_init(dest, len);
970                 j2k_curtileno = tileno;
971                 /* initialisation before tile encoding  */
972
973                 if (tileno == 0) {
974                         tcd_malloc_encode(j2k_img, j2k_cp, j2k_curtileno);
975                 } else {
976                         tcd_init_encode(j2k_img, j2k_cp, j2k_curtileno);
977                 }
978
979                 /* INDEX >> */
980                 if (info_IM.index_on) {
981                         info_IM.tile[j2k_curtileno].num_tile = j2k_curtileno;
982                         info_IM.tile[j2k_curtileno].start_pos = cio_tell() + pos_correction;
983                 }
984                 /* << INDEX */
985                 j2k_write_sot();
986
987                 for (compno = 1; compno < img->numcomps; compno++) {
988                         j2k_write_coc(compno);
989                         j2k_write_qcc(compno);
990                 }
991
992                 if (cp->tcps[tileno].numpocs)
993                         j2k_write_poc();
994                 j2k_write_sod();
995
996                 /* INDEX >> */
997                 if (info_IM.index_on) {
998                         info_IM.tile[j2k_curtileno].end_pos =
999                                 cio_tell() + pos_correction - 1;
1000                 }
1001                 /* << INDEX */
1002
1003                 /*
1004                    if (tile->PPT)  BAD PPT !!!
1005                    {
1006                    FILE *PPT_file;
1007
1008                    int i;
1009                    PPT_file=fopen("PPT","rb");
1010                    fprintf(stderr,"%c%c%c%c",255,97,tile->len_ppt/256,tile->len_ppt%256);
1011                    for (i=0;i<tile->len_ppt;i++)
1012                    {
1013                    unsigned char elmt;
1014                    fread(&elmt, 1, 1, PPT_file);
1015                    fwrite(&elmt,1,1,f);
1016                    }
1017                    fclose(PPT_file);
1018                    unlink("PPT");
1019                    }
1020                  */
1021
1022                 fwrite(dest, 1, cio_tell(), f);
1023                 pos_correction = cio_tell() + pos_correction;
1024         }
1025
1026         free(dest);
1027         dest = (char *) malloc(len);
1028         cio_init(dest, len);
1029
1030         j2k_write_eoc();
1031
1032         fwrite(dest, 1, 2, f);
1033         free(dest);
1034         /* closing file *.j2k */
1035         fclose(f);
1036
1037         /* Creation of the index file     */
1038         if (info_IM.index_on) {
1039                 info_IM.codestream_size = cio_tell() + pos_correction;  /* Correction 14/4/03 suite rmq de Patrick */
1040                 INDEX = fopen(index, "w");
1041
1042                 if (!INDEX) {
1043                         fprintf(stderr, "failed to open %s for writing\n", index);
1044                         return 1;
1045                 }
1046
1047                 fprintf(INDEX, "%d %d\n", info_IM.Im_w, info_IM.Im_h);
1048                 fprintf(INDEX, "%d\n", info_IM.Prog);
1049                 fprintf(INDEX, "%d %d\n", info_IM.Tile_x, info_IM.Tile_y);
1050                 fprintf(INDEX, "%d\n", info_IM.Comp);
1051                 fprintf(INDEX, "%d\n", info_IM.Layer);
1052                 fprintf(INDEX, "%d\n", info_IM.Decomposition);
1053                 fprintf(INDEX, "%d %d\n", info_IM.pdx, info_IM.pdy);
1054                 fprintf(INDEX, "%d\n", info_IM.Main_head_end);
1055                 fprintf(INDEX, "%d\n", info_IM.codestream_size);
1056
1057                 for (tileno = 0; tileno < j2k_cp->tw * j2k_cp->th; tileno++) {
1058                         fprintf(INDEX, "%d %d %d %d", info_IM.tile[tileno].num_tile,
1059                                                         info_IM.tile[tileno].start_pos,
1060                                                         info_IM.tile[tileno].end_header,
1061                                                         info_IM.tile[tileno].end_pos);
1062                         /*for (layno=0;layno<info_IM.Layer;layno++)
1063                           fprintf(INDEX, " %f",info_IM.tile[tileno].thresh[layno]);
1064                         */      fprintf(INDEX,"\n");
1065                         }
1066                 for (tileno = 0; tileno < j2k_cp->tw * j2k_cp->th; tileno++) {
1067                         pack_nb = 0;
1068                         if (info_IM.Prog == 0) {        /* LRCP */
1069                                 for (layno = 0; layno < info_IM.Layer; layno++) {
1070                                         for (resno = 0; resno < info_IM.Decomposition + 1; resno++) {
1071                                                 for (compno = 0; compno < info_IM.Comp; compno++) {
1072                                                         for (precno = 0;
1073                                                                          precno <
1074                                                                          info_IM.tile[tileno].pw * info_IM.tile[tileno].ph;
1075                                                                          precno++) {
1076                                                                  fprintf(INDEX,"%d %d %d %d %d %d %d %d %.04f\n",pack_nb,tileno,layno,resno,compno,precno,info_IM.tile[tileno].packet[pack_nb].start_pos,info_IM.tile[tileno].packet[pack_nb].end_pos,info_IM.tile[tileno].packet[pack_nb].disto); 
1077                                                                  /*fprintf(INDEX, "%d %d %d %d %d %d %d %d\n", pack_nb, tileno, layno, resno, compno, precno, info_IM.tile[tileno].packet[pack_nb].start_pos, info_IM.tile[tileno].packet[pack_nb].end_pos);*/
1078                                                                 pack_nb++;
1079                                                         }
1080                                                 }
1081                                         }
1082                                 }
1083                         } else if (info_IM.Prog == 1) { /* RLCP */
1084                                 for (resno = 0; resno < info_IM.Decomposition + 1; resno++) {
1085                                         for (layno = 0; layno < info_IM.Layer; layno++) {
1086                                                 for (compno = 0; compno < info_IM.Comp; compno++) {
1087                                                         for (precno = 0; precno < info_IM.pw * info_IM.ph; precno++) {
1088                                                                 /* fprintf(INDEX,"%d %d %d %d %d %d %d %d %.04f\n",pack_nb,tileno,layno,resno,compno,precno,info_IM.tile[tileno].packet[pack_nb].start_pos,info_IM.tile[tileno].packet[pack_nb].end_pos,info_IM.tile[tileno].packet[pack_nb].disto/info_IM.D_max); */
1089                                                                 fprintf(INDEX, "%d %d %d %d %d %d %d %d\n", pack_nb,
1090                                                                                                 tileno, layno, resno, compno, precno,
1091                                                                                                 info_IM.tile[tileno].packet[pack_nb].start_pos,
1092                                                                                                 info_IM.tile[tileno].packet[pack_nb].end_pos);
1093                                                                 pack_nb++;
1094                                                         }
1095                                                 }
1096                                         }
1097                                 }
1098                         } else if (info_IM.Prog == 2) { /* RPCL */
1099                                 for (resno = 0; resno < info_IM.Decomposition + 1; resno++) {
1100                                         for (precno = 0; precno < info_IM.pw * info_IM.ph; precno++) {
1101                                                 for (compno = 0; compno < info_IM.Comp; compno++) {
1102                                                         for (layno = 0; layno < info_IM.Layer; layno++) {
1103                                                                 /* fprintf(INDEX,"%d %d %d %d %d %d %d %d %.04f\n",pack_nb,tileno,layno,resno,compno,precno,info_IM.tile[tileno].packet[pack_nb].start_pos,info_IM.tile[tileno].packet[pack_nb].end_pos,info_IM.tile[tileno].packet[pack_nb].disto/info_IM.D_max); */
1104                                                                 fprintf(INDEX, "%d %d %d %d %d %d %d %d\n", pack_nb,
1105                                                                                                 tileno, layno, resno, compno, precno,
1106                                                                                                 info_IM.tile[tileno].packet[pack_nb].start_pos,
1107                                                                                                 info_IM.tile[tileno].packet[pack_nb].end_pos);
1108                                                                 pack_nb++;
1109                                                         }
1110                                                 }
1111                                         }
1112                                 }
1113                         } else if (info_IM.Prog == 3) { /* PCRL */
1114                                 for (precno = 0; precno < info_IM.pw * info_IM.ph; precno++) {
1115                                         for (compno = 0; compno < info_IM.Comp; compno++) {
1116                                                 for (resno = 0; resno < info_IM.Decomposition + 1; resno++) {
1117                                                         for (layno = 0; layno < info_IM.Layer; layno++) {
1118                                                                 /* fprintf(INDEX,"%d %d %d %d %d %d %d %d %.04f\n",pack_nb,tileno,layno,resno,compno,precno,info_IM.tile[tileno].packet[pack_nb].start_pos,info_IM.tile[tileno].packet[pack_nb].end_pos,info_IM.tile[tileno].packet[pack_nb].disto/info_IM.D_max); */
1119                                                                 fprintf(INDEX, "%d %d %d %d %d %d %d %d\n", pack_nb,
1120                                                                                                 tileno, layno, resno, compno, precno,
1121                                                                                                 info_IM.tile[tileno].packet[pack_nb].start_pos,
1122                                                                                                 info_IM.tile[tileno].packet[pack_nb].end_pos);
1123                                                                 pack_nb++;
1124                                                         }
1125                                                 }
1126                                         }
1127                                 }
1128                         } else {                                                                        /* CPRL */
1129
1130                                 for (compno = 0; compno < info_IM.Comp; compno++) {
1131                                         for (precno = 0; precno < info_IM.pw * info_IM.ph; precno++) {
1132                                                 for (resno = 0; resno < info_IM.Decomposition + 1; resno++) {
1133                                                         for (layno = 0; layno < info_IM.Layer; layno++) {
1134                                                           /*fprintf(INDEX,"%d %d %d %d %d %d %d %d %.04f\n",pack_nb,tileno,layno,resno,compno,precno,info_IM.tile[tileno].packet[pack_nb].start_pos,info_IM.tile[tileno].packet[pack_nb].end_pos,info_IM.tile[tileno].packet[pack_nb].disto/info_IM.D_max);*/
1135                                                           fprintf(INDEX, "%d %d %d %d %d %d %d %d\n", pack_nb, tileno, layno, resno, compno, precno, info_IM.tile[tileno].packet[pack_nb].start_pos, info_IM.tile[tileno].packet[pack_nb].end_pos);
1136                                                                 pack_nb++;
1137                                                         }
1138                                                 }
1139                                         }
1140                                 }
1141                         }
1142                 }
1143                 fclose(INDEX);
1144         }
1145
1146         j2k_clean();
1147
1148         return cio_tell();
1149 }
1150
1151 typedef struct {
1152         int id;
1153         int states;
1154         void (*handler) ();
1155 } j2k_dec_mstabent_t;
1156
1157 j2k_dec_mstabent_t j2k_dec_mstab[] = {
1158         {J2K_MS_SOC, J2K_STATE_MHSOC, j2k_read_soc},
1159         {J2K_MS_SOT, J2K_STATE_MH | J2K_STATE_TPHSOT, j2k_read_sot},
1160         {J2K_MS_SOD, J2K_STATE_TPH, j2k_read_sod},
1161         {J2K_MS_EOC, J2K_STATE_TPHSOT, j2k_read_eoc},
1162         {J2K_MS_SIZ, J2K_STATE_MHSIZ, j2k_read_siz},
1163         {J2K_MS_COD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_cod},
1164         {J2K_MS_COC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_coc},
1165         {J2K_MS_RGN, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_rgn},
1166         {J2K_MS_QCD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_qcd},
1167         {J2K_MS_QCC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_qcc},
1168         {J2K_MS_POC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_poc},
1169         {J2K_MS_TLM, J2K_STATE_MH, j2k_read_tlm},
1170         {J2K_MS_PLM, J2K_STATE_MH, j2k_read_plm},
1171         {J2K_MS_PLT, J2K_STATE_TPH, j2k_read_plt},
1172         {J2K_MS_PPM, J2K_STATE_MH, j2k_read_ppm},
1173         {J2K_MS_PPT, J2K_STATE_TPH, j2k_read_ppt},
1174         {J2K_MS_SOP, 0, 0},
1175         {J2K_MS_CRG, J2K_STATE_MH, j2k_read_crg},
1176         {J2K_MS_COM, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_com},
1177         {0, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_unk}
1178 };
1179
1180 j2k_dec_mstabent_t *j2k_dec_mstab_lookup(int id)
1181 {
1182         j2k_dec_mstabent_t *e;
1183         for (e = j2k_dec_mstab; e->id != 0; e++) {
1184                 if (e->id == id) {
1185                         break;
1186                 }
1187         }
1188         return e;
1189 }
1190
1191 LIBJ2K_API int j2k_decode(unsigned char *src, int len, j2k_image_t ** img, j2k_cp_t ** cp)
1192 {
1193
1194         if (setjmp(j2k_error)) {
1195                 if (j2k_state != J2K_STATE_MT) {
1196                         fprintf(stderr, "WARNING: incomplete bitstream\n");
1197                         return 0;
1198                 }
1199                 return cio_numbytes();
1200         }
1201
1202         j2k_img = (j2k_image_t *) malloc(sizeof(j2k_image_t));
1203         j2k_cp = (j2k_cp_t *) malloc(sizeof(j2k_cp_t));
1204         *img = j2k_img;
1205         *cp = j2k_cp;
1206         j2k_state = J2K_STATE_MHSOC;
1207         cio_init(src, len);
1208
1209         for (;;) {
1210                 j2k_dec_mstabent_t *e;
1211                 int id = cio_read(2);
1212                 if (id >> 8 != 0xff) {
1213                         fprintf(stderr, "%.8x: expected a marker instead of %x\n", cio_tell() - 2, id);
1214                         return 0;
1215                 }
1216                 e = j2k_dec_mstab_lookup(id);
1217                 if (!(j2k_state & e->states)) {
1218                         fprintf(stderr, "%.8x: unexpected marker %x\n", cio_tell() - 2, id);
1219                         return 0;
1220                 }
1221                 if (e->handler) {
1222                   (*e->handler) ();
1223                 }
1224                 if (j2k_state == J2K_STATE_NEOC)
1225                   break;                                        /* RAJOUTE */
1226         }
1227         if (j2k_state == J2K_STATE_NEOC)
1228           j2k_read_eoc();                                       /* RAJOUTE */
1229         
1230         return 0;
1231 }
1232
1233 /*
1234  * Read a JPT-stream and decode file
1235  *
1236  */
1237 int j2k_decode_jpt_stream(unsigned char *src, int len, j2k_image_t ** img, j2k_cp_t ** cp)
1238
1239   jpt_msg_header_struct_t header;
1240   int position;
1241
1242   if (setjmp(j2k_error)) {
1243     if (j2k_state != J2K_STATE_MT) {
1244       fprintf(stderr, "WARNING: incomplete bitstream\n");
1245       return 0;
1246     }
1247     return cio_numbytes();
1248   }
1249   
1250   j2k_img = (j2k_image_t *) malloc(sizeof(j2k_image_t));
1251   j2k_cp = (j2k_cp_t *) malloc(sizeof(j2k_cp_t));
1252   *img = j2k_img;
1253   *cp = j2k_cp; 
1254   j2k_state = J2K_STATE_MHSOC;
1255   cio_init(src, len);
1256
1257   /* Initialize the header */
1258   jpt_init_Msg_Header(&header);
1259   /* Read the first header of the message */
1260   jpt_read_Msg_Header(&header);
1261   
1262   position = cio_tell();
1263   if (header.Class_Id != 6) /* 6 : Main header data-bin message */
1264     {
1265       fprintf(stderr,"[JPT-stream] : Expecting Main header first [class_Id %d] !\n",header.Class_Id);
1266       return 0;
1267     }
1268
1269   for (;;) {
1270     j2k_dec_mstabent_t *e;
1271     int id;
1272
1273     if(!cio_numbytesleft())
1274       {
1275         j2k_read_eoc();
1276         return 0;
1277       }
1278     /* data-bin read -> need to read a new header */
1279     if ((cio_tell() - position) == header.Msg_length)
1280       {
1281         jpt_read_Msg_Header(&header);
1282         position = cio_tell();
1283         if (header.Class_Id != 4) /* 4 : Tile data-bin message */
1284           {
1285             fprintf(stderr,"[JPT-stream] : Expecting Tile info !\n");
1286             return 0;
1287           }
1288       }
1289
1290     id = cio_read(2);
1291     if (id >> 8 != 0xff) {
1292       fprintf(stderr, "%.8x: expected a marker instead of %x\n", cio_tell() - 2, id);
1293       return 0;
1294     }
1295     e = j2k_dec_mstab_lookup(id);
1296     if (!(j2k_state & e->states)) {
1297       fprintf(stderr, "%.8x: unexpected marker %x\n", cio_tell() - 2, id);
1298       return 0;
1299     }
1300     if (e->handler) {
1301       (*e->handler) ();
1302     }
1303     if (j2k_state == J2K_STATE_NEOC)
1304       break;                                            /* RAJOUTE */
1305   }
1306   if (j2k_state == J2K_STATE_NEOC)
1307     j2k_read_eoc();                                     /* RAJOUTE */
1308   
1309   return 0;
1310 }
1311
1312 #ifdef WIN32
1313 #include <windows.h>
1314
1315 BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
1316 {
1317         switch (ul_reason_for_call) {
1318         case DLL_PROCESS_ATTACH:
1319         case DLL_THREAD_ATTACH:
1320         case DLL_THREAD_DETACH:
1321         case DLL_PROCESS_DETACH:
1322                 break;
1323         }
1324         return TRUE;
1325 }
1326 #endif