]> Creatis software - gdcm.git/blob - src/gdcmopenjpeg/libopenjpeg/t2.c
368acda2e603297ee534103eb5c4685eb583147e
[gdcm.git] / src / gdcmopenjpeg / libopenjpeg / t2.c
1 /*\r
2  * Copyright (c) 2001-2003, David Janssens\r
3  * Copyright (c) 2002-2003, Yannick Verschueren\r
4  * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe\r
5  * Copyright (c) 2005, HervĂ© Drolon, FreeImage Team\r
6  * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium\r
7  * All rights reserved.\r
8  *\r
9  * Redistribution and use in source and binary forms, with or without\r
10  * modification, are permitted provided that the following conditions\r
11  * are met:\r
12  * 1. Redistributions of source code must retain the above copyright\r
13  *    notice, this list of conditions and the following disclaimer.\r
14  * 2. Redistributions in binary form must reproduce the above copyright\r
15  *    notice, this list of conditions and the following disclaimer in the\r
16  *    documentation and/or other materials provided with the distribution.\r
17  *\r
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'\r
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
28  * POSSIBILITY OF SUCH DAMAGE.\r
29  */\r
30 \r
31 #include "opj_includes.h"\r
32 \r
33 /** @defgroup T2 T2 - Implementation of a tier-2 coding */\r
34 /*@{*/\r
35 \r
36 /** @name Local static functions */\r
37 /*@{*/\r
38 \r
39 static void t2_putcommacode(opj_bio_t *bio, int n);\r
40 static int t2_getcommacode(opj_bio_t *bio);\r
41 /**\r
42 Variable length code for signalling delta Zil (truncation point)\r
43 @param bio Bit Input/Output component\r
44 @param n delta Zil\r
45 */\r
46 static void t2_putnumpasses(opj_bio_t *bio, int n);\r
47 static int t2_getnumpasses(opj_bio_t *bio);\r
48 /**\r
49 Encode a packet of a tile to a destination buffer\r
50 @param tile Tile for which to write the packets\r
51 @param tcp Tile coding parameters\r
52 @param pi Packet identity\r
53 @param dest Destination buffer\r
54 @param len Length of the destination buffer\r
55 @param image_info Structure to create an index file\r
56 @param tileno Number of the tile encoded\r
57 @return \r
58 */\r
59 static int t2_encode_packet(opj_tcd_tile_t *tile, opj_tcp_t *tcp, opj_pi_iterator_t *pi, unsigned char *dest, int len, opj_image_info_t *image_info, int tileno);\r
60 /**\r
61 @param seg\r
62 @param cblksty\r
63 @param first\r
64 */\r
65 static void t2_init_seg(opj_tcd_seg_t *seg, int cblksty, int first);\r
66 /**\r
67 Decode a packet of a tile from a source buffer\r
68 @param t2 T2 handle\r
69 @param src Source buffer\r
70 @param len Length of the source buffer\r
71 @param tile Tile for which to write the packets\r
72 @param tcp Tile coding parameters\r
73 @param pi Packet identity\r
74 @return \r
75 */\r
76 int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile, opj_tcp_t *tcp, opj_pi_iterator_t *pi);\r
77 \r
78 /*@}*/\r
79 \r
80 /*@}*/\r
81 \r
82 /* ----------------------------------------------------------------------- */\r
83 \r
84 /* #define RESTART 0x04 */\r
85 \r
86 static void t2_putcommacode(opj_bio_t *bio, int n) {\r
87   while (--n >= 0) {\r
88     bio_write(bio, 1, 1);\r
89   }\r
90   bio_write(bio, 0, 1);\r
91 }\r
92 \r
93 static int t2_getcommacode(opj_bio_t *bio) {\r
94   int n;\r
95   for (n = 0; bio_read(bio, 1); n++) {\r
96     ;\r
97   }\r
98   return n;\r
99 }\r
100 \r
101 static void t2_putnumpasses(opj_bio_t *bio, int n) {\r
102   if (n == 1) {\r
103     bio_write(bio, 0, 1);\r
104   } else if (n == 2) {\r
105     bio_write(bio, 2, 2);\r
106   } else if (n <= 5) {\r
107     bio_write(bio, 0xc | (n - 3), 4);\r
108   } else if (n <= 36) {\r
109     bio_write(bio, 0x1e0 | (n - 6), 9);\r
110   } else if (n <= 164) {\r
111     bio_write(bio, 0xff80 | (n - 37), 16);\r
112   }\r
113 }\r
114 \r
115 static int t2_getnumpasses(opj_bio_t *bio) {\r
116   int n;\r
117   if (!bio_read(bio, 1))\r
118     return 1;\r
119   if (!bio_read(bio, 1))\r
120     return 2;\r
121   if ((n = bio_read(bio, 2)) != 3)\r
122     return (3 + n);\r
123   if ((n = bio_read(bio, 5)) != 31)\r
124     return (6 + n);\r
125   return (37 + bio_read(bio, 7));\r
126 }\r
127 \r
128 static int t2_encode_packet(opj_tcd_tile_t * tile, opj_tcp_t * tcp, opj_pi_iterator_t *pi, unsigned char *dest, int len, opj_image_info_t * image_info, int tileno) {\r
129   int bandno, cblkno;\r
130   unsigned char *sop = 0, *eph = 0;\r
131   unsigned char *c = dest;\r
132 \r
133   int compno = pi->compno;  /* component value */\r
134   int resno  = pi->resno;    /* resolution level value */\r
135   int precno = pi->precno;  /* precinct value */\r
136   int layno  = pi->layno;    /* quality layer value */\r
137 \r
138   opj_tcd_tilecomp_t *tilec = &tile->comps[compno];\r
139   opj_tcd_resolution_t *res = &tilec->resolutions[resno];\r
140   \r
141   opj_bio_t *bio = NULL;  /* BIO component */\r
142   \r
143   /* <SOP 0xff91> */\r
144   if (tcp->csty & J2K_CP_CSTY_SOP) {\r
145     sop = (unsigned char *) opj_malloc(6 * sizeof(unsigned char));\r
146     sop[0] = 255;\r
147     sop[1] = 145;\r
148     sop[2] = 0;\r
149     sop[3] = 4;\r
150     sop[4] = (image_info->num % 65536) / 256;\r
151     sop[5] = (image_info->num % 65536) % 256;\r
152     memcpy(c, sop, 6);\r
153     opj_free(sop);\r
154     c += 6;\r
155   }\r
156   /* </SOP> */\r
157   \r
158   if (!layno) {\r
159     for (bandno = 0; bandno < res->numbands; bandno++) {\r
160       opj_tcd_band_t *band = &res->bands[bandno];\r
161       opj_tcd_precinct_t *prc = &band->precincts[precno];\r
162       tgt_reset(prc->incltree);\r
163       tgt_reset(prc->imsbtree);\r
164       for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {\r
165         opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];\r
166         cblk->numpasses = 0;\r
167         tgt_setvalue(prc->imsbtree, cblkno, band->numbps - cblk->numbps);\r
168       }\r
169     }\r
170   }\r
171   \r
172   bio = bio_create();\r
173   bio_init_enc(bio, c, len);\r
174   bio_write(bio, 1, 1);    /* Empty header bit */\r
175   \r
176   /* Writing Packet header */\r
177   for (bandno = 0; bandno < res->numbands; bandno++) {\r
178     opj_tcd_band_t *band = &res->bands[bandno];\r
179     opj_tcd_precinct_t *prc = &band->precincts[precno];\r
180     for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {\r
181       opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];\r
182       opj_tcd_layer_t *layer = &cblk->layers[layno];\r
183       if (!cblk->numpasses && layer->numpasses) {\r
184         tgt_setvalue(prc->incltree, cblkno, layno);\r
185       }\r
186     }\r
187     for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {\r
188       opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];\r
189       opj_tcd_layer_t *layer = &cblk->layers[layno];\r
190       int increment = 0;\r
191       int nump = 0;\r
192       int len = 0, passno;\r
193       /* cblk inclusion bits */\r
194       if (!cblk->numpasses) {\r
195         tgt_encode(bio, prc->incltree, cblkno, layno + 1);\r
196       } else {\r
197         bio_write(bio, layer->numpasses != 0, 1);\r
198       }\r
199       /* if cblk not included, go to the next cblk  */\r
200       if (!layer->numpasses) {\r
201         continue;\r
202       }\r
203       /* if first instance of cblk --> zero bit-planes information */\r
204       if (!cblk->numpasses) {\r
205         cblk->numlenbits = 3;\r
206         tgt_encode(bio, prc->imsbtree, cblkno, 999);\r
207       }\r
208       /* number of coding passes included */\r
209       t2_putnumpasses(bio, layer->numpasses);\r
210       \r
211       /* computation of the increase of the length indicator and insertion in the header     */\r
212       for (passno = cblk->numpasses; passno < cblk->numpasses + layer->numpasses; passno++) {\r
213         opj_tcd_pass_t *pass = &cblk->passes[passno];\r
214         nump++;\r
215         len += pass->len;\r
216         if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) {\r
217           increment = int_max(increment, int_floorlog2(len) + 1 - (cblk->numlenbits + int_floorlog2(nump)));\r
218           len = 0;\r
219           nump = 0;\r
220         }\r
221       }\r
222       t2_putcommacode(bio, increment);\r
223 \r
224       /* computation of the new Length indicator */\r
225       cblk->numlenbits += increment;\r
226 \r
227       /* insertion of the codeword segment length */\r
228       for (passno = cblk->numpasses; passno < cblk->numpasses + layer->numpasses; passno++) {\r
229         opj_tcd_pass_t *pass = &cblk->passes[passno];\r
230         nump++;\r
231         len += pass->len;\r
232         if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) {\r
233           bio_write(bio, len, cblk->numlenbits + int_floorlog2(nump));\r
234           len = 0;\r
235           nump = 0;\r
236         }\r
237       }\r
238     }\r
239   }\r
240   \r
241   if (bio_flush(bio)) {\r
242     return -999;    /* modified to eliminate longjmp !! */\r
243   }\r
244   \r
245   c += bio_numbytes(bio);\r
246 \r
247   bio_destroy(bio);\r
248   \r
249   /* <EPH 0xff92> */\r
250   if (tcp->csty & J2K_CP_CSTY_EPH) {\r
251     eph = (unsigned char *) opj_malloc(2 * sizeof(unsigned char));\r
252     eph[0] = 255;\r
253     eph[1] = 146;\r
254     memcpy(c, eph, 2);\r
255     opj_free(eph);\r
256     c += 2;\r
257   }\r
258   /* </EPH> */\r
259   \r
260   /* Writing the packet body */\r
261   \r
262   for (bandno = 0; bandno < res->numbands; bandno++) {\r
263     opj_tcd_band_t *band = &res->bands[bandno];\r
264     opj_tcd_precinct_t *prc = &band->precincts[precno];\r
265     for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {\r
266       opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];\r
267       opj_tcd_layer_t *layer = &cblk->layers[layno];\r
268       if (!layer->numpasses) {\r
269         continue;\r
270       }\r
271       if (c + layer->len > dest + len) {\r
272         return -999;\r
273       }\r
274       \r
275       memcpy(c, layer->data, layer->len);\r
276       cblk->numpasses += layer->numpasses;\r
277       c += layer->len;\r
278       /* ADD for index Cfr. Marcela --> delta disto by packet */\r
279       if(image_info && image_info->index_write && image_info->index_on) {\r
280         opj_tile_info_t *info_TL = &image_info->tile[tileno];\r
281         opj_packet_info_t *info_PK = &info_TL->packet[image_info->num];\r
282         info_PK->disto += layer->disto;\r
283         if (image_info->D_max < info_PK->disto) {\r
284           image_info->D_max = info_PK->disto;\r
285         }\r
286       }\r
287       /* </ADD> */\r
288     }\r
289   }\r
290   \r
291   return (c - dest);\r
292 }\r
293 \r
294 static void t2_init_seg(opj_tcd_seg_t * seg, int cblksty, int first) {\r
295   seg->numpasses = 0;\r
296   seg->len = 0;\r
297   if (cblksty & J2K_CCP_CBLKSTY_TERMALL) {\r
298     seg->maxpasses = 1;\r
299   }\r
300   else if (cblksty & J2K_CCP_CBLKSTY_LAZY) {\r
301     if (first) {\r
302       seg->maxpasses = 10;\r
303     } else {\r
304       seg->maxpasses = (((seg - 1)->maxpasses == 1) || ((seg - 1)->maxpasses == 10)) ? 2 : 1;\r
305     }\r
306   } else {\r
307     seg->maxpasses = 109;\r
308   }\r
309 }\r
310 \r
311 int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile, opj_tcp_t *tcp, opj_pi_iterator_t *pi) {\r
312   int bandno, cblkno;\r
313   unsigned char *c = src;\r
314 \r
315   opj_cp_t *cp = t2->cp;\r
316 \r
317   int compno = pi->compno;  /* component value */\r
318   int resno  = pi->resno;    /* resolution level value */\r
319   int precno = pi->precno;  /* precinct value */\r
320   int layno  = pi->layno;    /* quality layer value */\r
321 \r
322   opj_tcd_tilecomp_t *tilec = &tile->comps[compno];\r
323   opj_tcd_resolution_t *res = &tilec->resolutions[resno];\r
324   \r
325   unsigned char *hd = NULL;\r
326   int present;\r
327   \r
328   opj_bio_t *bio = NULL;  /* BIO component */\r
329   \r
330   if (layno == 0) {\r
331     for (bandno = 0; bandno < res->numbands; bandno++) {\r
332       opj_tcd_band_t *band = &res->bands[bandno];\r
333       opj_tcd_precinct_t *prc = &band->precincts[precno];\r
334       \r
335       if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)) continue;\r
336       \r
337       tgt_reset(prc->incltree);\r
338       tgt_reset(prc->imsbtree);\r
339       for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {\r
340         opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];\r
341         cblk->numsegs = 0;\r
342       }\r
343     }\r
344   }\r
345   \r
346   /* SOP markers */\r
347   \r
348   if (tcp->csty & J2K_CP_CSTY_SOP) {\r
349     if ((*c) != 0xff || (*(c + 1) != 0x91)) {\r
350       opj_event_msg(t2->cinfo, EVT_WARNING, "Expected SOP marker\n");\r
351     } else {\r
352       c += 6;\r
353     }\r
354     \r
355     /** TODO : check the Nsop value */\r
356   }\r
357   \r
358   /* \r
359   When the marker PPT/PPM is used the packet header are store in PPT/PPM marker\r
360   This part deal with this caracteristic\r
361   step 1: Read packet header in the saved structure\r
362   step 2: Return to codestream for decoding \r
363   */\r
364 \r
365   bio = bio_create();\r
366   \r
367   if (cp->ppm == 1) {    /* PPM */\r
368     hd = cp->ppm_data;\r
369     bio_init_dec(bio, hd, cp->ppm_len);\r
370   } else if (tcp->ppt == 1) {  /* PPT */\r
371     hd = tcp->ppt_data;\r
372     bio_init_dec(bio, hd, tcp->ppt_len);\r
373   } else {      /* Normal Case */\r
374     hd = c;\r
375     bio_init_dec(bio, hd, src+len-hd);\r
376   }\r
377   \r
378   present = bio_read(bio, 1);\r
379   \r
380   if (!present) {\r
381     bio_inalign(bio);\r
382     hd += bio_numbytes(bio);\r
383     bio_destroy(bio);\r
384     \r
385     /* EPH markers */\r
386     \r
387     if (tcp->csty & J2K_CP_CSTY_EPH) {\r
388       if ((*hd) != 0xff || (*(hd + 1) != 0x92)) {\r
389         printf("Error : expected EPH marker\n");\r
390       } else {\r
391         hd += 2;\r
392       }\r
393     }\r
394     \r
395     if (cp->ppm == 1) {    /* PPM case */\r
396       cp->ppm_len += cp->ppm_data-hd;\r
397       cp->ppm_data = hd;\r
398       return (c - src);\r
399     }\r
400     if (tcp->ppt == 1) {  /* PPT case */\r
401       tcp->ppt_len+=tcp->ppt_data-hd;\r
402       tcp->ppt_data = hd;\r
403       return (c - src);\r
404     }\r
405     \r
406     return (hd - src);\r
407   }\r
408   \r
409   for (bandno = 0; bandno < res->numbands; bandno++) {\r
410     opj_tcd_band_t *band = &res->bands[bandno];\r
411     opj_tcd_precinct_t *prc = &band->precincts[precno];\r
412     \r
413     if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)) continue;\r
414     \r
415     for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {\r
416       int included, increment, n;\r
417       opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];\r
418       opj_tcd_seg_t *seg = NULL;\r
419       /* if cblk not yet included before --> inclusion tagtree */\r
420       if (!cblk->numsegs) {\r
421         included = tgt_decode(bio, prc->incltree, cblkno, layno + 1);\r
422         /* else one bit */\r
423       } else {\r
424         included = bio_read(bio, 1);\r
425       }\r
426       /* if cblk not included */\r
427       if (!included) {\r
428         cblk->numnewpasses = 0;\r
429         continue;\r
430       }\r
431       /* if cblk not yet included --> zero-bitplane tagtree */\r
432       if (!cblk->numsegs) {\r
433         int i, numimsbs;\r
434         for (i = 0; !tgt_decode(bio, prc->imsbtree, cblkno, i); i++) {\r
435           ;\r
436         }\r
437         numimsbs = i - 1;\r
438         cblk->numbps = band->numbps - numimsbs;\r
439         cblk->numlenbits = 3;\r
440       }\r
441       /* number of coding passes */\r
442       cblk->numnewpasses = t2_getnumpasses(bio);\r
443       increment = t2_getcommacode(bio);\r
444       /* length indicator increment */\r
445       cblk->numlenbits += increment;\r
446       if (!cblk->numsegs) {\r
447         seg = &cblk->segs[0];\r
448         t2_init_seg(seg, tcp->tccps[compno].cblksty, 1);\r
449       } else {\r
450         seg = &cblk->segs[cblk->numsegs - 1];\r
451         if (seg->numpasses == seg->maxpasses) {\r
452           t2_init_seg(++seg, tcp->tccps[compno].cblksty, 0);\r
453         }\r
454       }\r
455       n = cblk->numnewpasses;\r
456       \r
457       do {\r
458         seg->numnewpasses = int_min(seg->maxpasses - seg->numpasses, n);\r
459         seg->newlen = bio_read(bio, cblk->numlenbits + int_floorlog2(seg->numnewpasses));\r
460         n -= seg->numnewpasses;\r
461         if (n > 0) {\r
462           t2_init_seg(++seg, tcp->tccps[compno].cblksty, 0);\r
463         }\r
464       } while (n > 0);\r
465     }\r
466   }\r
467   \r
468   if (bio_inalign(bio)) {\r
469     bio_destroy(bio);\r
470     return -999;\r
471   }\r
472   \r
473   hd += bio_numbytes(bio);\r
474   bio_destroy(bio);\r
475   \r
476   /* EPH markers */\r
477   if (tcp->csty & J2K_CP_CSTY_EPH) {\r
478     if ((*hd) != 0xff || (*(hd + 1) != 0x92)) {\r
479       opj_event_msg(t2->cinfo, EVT_ERROR, "Expected EPH marker\n");\r
480     } else {\r
481       hd += 2;\r
482     }\r
483   }\r
484   \r
485   if (cp->ppm==1) {\r
486     cp->ppm_len+=cp->ppm_data-hd;\r
487     cp->ppm_data = hd;\r
488   } else if (tcp->ppt == 1) {\r
489     tcp->ppt_len+=tcp->ppt_data-hd;\r
490     tcp->ppt_data = hd;\r
491   } else {\r
492     c=hd;\r
493   }\r
494   \r
495   for (bandno = 0; bandno < res->numbands; bandno++) {\r
496     opj_tcd_band_t *band = &res->bands[bandno];\r
497     opj_tcd_precinct_t *prc = &band->precincts[precno];\r
498     \r
499     if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)) continue;\r
500     \r
501     for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {\r
502       opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];\r
503       opj_tcd_seg_t *seg = NULL;\r
504       if (!cblk->numnewpasses)\r
505         continue;\r
506       if (!cblk->numsegs) {\r
507         seg = &cblk->segs[0];\r
508         cblk->numsegs++;\r
509         cblk->len = 0;\r
510       } else {\r
511         seg = &cblk->segs[cblk->numsegs - 1];\r
512         if (seg->numpasses == seg->maxpasses) {\r
513           seg++;\r
514           cblk->numsegs++;\r
515         }\r
516       }\r
517       \r
518       do {\r
519         if (c + seg->newlen > src + len) {\r
520           return -999;\r
521         }\r
522         \r
523         memcpy(cblk->data + cblk->len, c, seg->newlen);\r
524         if (seg->numpasses == 0) {\r
525           seg->data = cblk->data + cblk->len;\r
526         }\r
527         c += seg->newlen;\r
528         cblk->len += seg->newlen;\r
529         seg->len += seg->newlen;\r
530         seg->numpasses += seg->numnewpasses;\r
531         cblk->numnewpasses -= seg->numnewpasses;\r
532         if (cblk->numnewpasses > 0) {\r
533           seg++;\r
534           cblk->numsegs++;\r
535         }\r
536       } while (cblk->numnewpasses > 0);\r
537     }\r
538   }\r
539   \r
540   return (c - src);\r
541 }\r
542 \r
543 /* ----------------------------------------------------------------------- */\r
544 \r
545 int t2_encode_packets(opj_t2_t* t2, int tileno, opj_tcd_tile_t *tile, int maxlayers, unsigned char *dest, int len, opj_image_info_t *image_info) {\r
546   unsigned char *c = dest;\r
547   int e = 0;\r
548   opj_pi_iterator_t *pi = NULL;\r
549   int pino;\r
550 \r
551   opj_image_t *image = t2->image;\r
552   opj_cp_t *cp = t2->cp;\r
553   \r
554   /* create a packet iterator */\r
555   pi = pi_create(image, cp, tileno);\r
556   if(!pi) {\r
557     /* TODO: throw an error */\r
558     return -999;\r
559   }\r
560   \r
561   if(image_info) {\r
562     image_info->num = 0;\r
563   }\r
564   \r
565   for (pino = 0; pino <= cp->tcps[tileno].numpocs; pino++) {\r
566     while (pi_next(&pi[pino])) {\r
567       if (pi[pino].layno < maxlayers) {\r
568         e = t2_encode_packet(tile, &cp->tcps[tileno], &pi[pino], c, dest + len - c, image_info, tileno);\r
569         if (e == -999) {\r
570           break;\r
571         } else {\r
572           c += e;\r
573         }\r
574         \r
575         /* INDEX >> */\r
576         if(image_info && image_info->index_on) {\r
577           if(image_info->index_write) {\r
578             opj_tile_info_t *info_TL = &image_info->tile[tileno];\r
579             opj_packet_info_t *info_PK = &info_TL->packet[image_info->num];\r
580             if (!image_info->num) {\r
581               info_PK->start_pos = info_TL->end_header + 1;\r
582             } else {\r
583               info_PK->start_pos = info_TL->packet[image_info->num - 1].end_pos + 1;\r
584             }\r
585             info_PK->end_pos = info_PK->start_pos + e - 1;\r
586           }\r
587 \r
588           image_info->num++;\r
589         }\r
590         /* << INDEX */\r
591       }\r
592     }\r
593   }\r
594 \r
595   /* don't forget to release pi */\r
596   pi_destroy(pi, cp, tileno);\r
597   \r
598   if (e == -999) {\r
599     return e;\r
600   }\r
601 \r
602     return (c - dest);\r
603 }\r
604 \r
605 int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj_tcd_tile_t *tile) {\r
606   unsigned char *c = src;\r
607   opj_pi_iterator_t *pi;\r
608   int pino, e = 0;\r
609   int n = 0;\r
610 \r
611   opj_image_t *image = t2->image;\r
612   opj_cp_t *cp = t2->cp;\r
613   \r
614   /* create a packet iterator */\r
615   pi = pi_create(image, cp, tileno);\r
616   if(!pi) {\r
617     /* TODO: throw an error */\r
618     return -999;\r
619   }\r
620   \r
621   for (pino = 0; pino <= cp->tcps[tileno].numpocs; pino++) {\r
622     while (pi_next(&pi[pino])) {\r
623       if ((cp->layer==0) || (cp->layer>=((pi[pino].layno)+1))) {\r
624         e = t2_decode_packet(t2, c, src + len - c, tile, &cp->tcps[tileno], &pi[pino]);\r
625       } else {\r
626         e = 0;\r
627       }\r
628       \r
629       /* progression in resolution */\r
630       image->comps[pi[pino].compno].resno_decoded =  \r
631         (e > 0) ? \r
632         int_max(pi[pino].resno, image->comps[pi[pino].compno].resno_decoded) \r
633         : image->comps[pi[pino].compno].resno_decoded;\r
634       n++;\r
635       \r
636       if (e == -999) {    /* ADD */\r
637         break;\r
638       } else {\r
639         c += e;\r
640       }\r
641     }\r
642   }\r
643 \r
644   /* don't forget to release pi */\r
645   pi_destroy(pi, cp, tileno);\r
646   \r
647   if (e == -999) {\r
648     return e;\r
649   }\r
650   \r
651     return (c - src);\r
652 }\r
653 \r
654 /* ----------------------------------------------------------------------- */\r
655 \r
656 opj_t2_t* t2_create(opj_common_ptr cinfo, opj_image_t *image, opj_cp_t *cp) {\r
657   /* create the tcd structure */\r
658   opj_t2_t *t2 = (opj_t2_t*)opj_malloc(sizeof(opj_t2_t));\r
659   if(!t2) return NULL;\r
660   t2->cinfo = cinfo;\r
661   t2->image = image;\r
662   t2->cp = cp;\r
663 \r
664   return t2;\r
665 }\r
666 \r
667 void t2_destroy(opj_t2_t *t2) {\r
668   if(t2) {\r
669     opj_free(t2);\r
670   }\r
671 }\r
672 \r