fixed lt_version in configure.ac
[openjpeg.git] / libjp3dvm / 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, Herve 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 volume_info Structure to create an index file\r
56 @param tileno Number of the tile encoded\r
57 @param cp Coding parameters\r
58 @return Number of bytes encoded from the packet\r
59 */\r
60 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_volume_info_t *volume_info, int tileno, opj_cp_t *cp);\r
61 /**\r
62 Initialize the segment decoder\r
63 @param seg Segment instance\r
64 @param cblksty Codeblock style\r
65 @param first Is first segment\r
66 */\r
67 static void t2_init_seg(opj_tcd_seg_t *seg, int cblksty, int first);\r
68 /**\r
69 Decode a packet of a tile from a source buffer\r
70 @param t2 T2 handle\r
71 @param src Source buffer\r
72 @param len Length of the source buffer\r
73 @param tile Tile for which to write the packets\r
74 @param tcp Tile coding parameters\r
75 @param pi Packet identity\r
76 @return Number of bytes decoded from the packet\r
77 */\r
78 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
79 \r
80 /*@}*/\r
81 \r
82 /*@}*/\r
83 \r
84 /* ----------------------------------------------------------------------- */\r
85 \r
86 /* #define RESTART 0x04 */\r
87 static void t2_putcommacode(opj_bio_t *bio, int n) {\r
88         while (--n >= 0) {\r
89                 bio_write(bio, 1, 1);\r
90         }\r
91         bio_write(bio, 0, 1);\r
92 }\r
93 \r
94 static int t2_getcommacode(opj_bio_t *bio) {\r
95         int n;\r
96         for (n = 0; bio_read(bio, 1); n++) {\r
97                 ;\r
98         }\r
99         return n;\r
100 }\r
101 \r
102 static void t2_putnumpasses(opj_bio_t *bio, int n) {\r
103         if (n == 1) {\r
104                 bio_write(bio, 0, 1);\r
105         } else if (n == 2) {\r
106                 bio_write(bio, 2, 2);\r
107         } else if (n <= 5) {\r
108                 bio_write(bio, 0xc | (n - 3), 4);\r
109         } else if (n <= 36) {\r
110                 bio_write(bio, 0x1e0 | (n - 6), 9);\r
111         } else if (n <= 164) {\r
112                 bio_write(bio, 0xff80 | (n - 37), 16);\r
113         }\r
114 }\r
115 \r
116 static int t2_getnumpasses(opj_bio_t *bio) {\r
117         int n;\r
118         if (!bio_read(bio, 1))\r
119                 return 1;\r
120         if (!bio_read(bio, 1))\r
121                 return 2;\r
122         if ((n = bio_read(bio, 2)) != 3)\r
123                 return (3 + n);\r
124         if ((n = bio_read(bio, 5)) != 31)\r
125                 return (6 + n);\r
126         return (37 + bio_read(bio, 7));\r
127 }\r
128 \r
129 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_volume_info_t * volume_info, int tileno, opj_cp_t *cp) {\r
130         int bandno, cblkno;\r
131         unsigned char *sop = 0, *eph = 0;\r
132         unsigned char *c = dest;\r
133 \r
134         int compno = pi->compno;        /* component value */\r
135         int resno  = pi->resno;         /* resolution level value */\r
136         int precno = pi->precno;        /* precinct value */\r
137         int layno  = pi->layno;         /* quality layer value */\r
138 \r
139         opj_tcd_tilecomp_t *tilec = &tile->comps[compno];\r
140         opj_tcd_resolution_t *res = &tilec->resolutions[resno];\r
141         \r
142         opj_bio_t *bio = NULL;  /* BIO component */\r
143 \r
144         /* <SOP 0xff91> */\r
145         if ((tcp->csty & J3D_CP_CSTY_SOP)) {\r
146                 sop = (unsigned char *) opj_malloc(6 * sizeof(unsigned char));\r
147                 sop[0] = 255;\r
148                 sop[1] = 145;\r
149                 sop[2] = 0;\r
150                 sop[3] = 4;\r
151                 sop[4] = (volume_info) ? (volume_info->num % 65536) / 256 : (0 % 65536) / 256 ;\r
152                 sop[5] = (volume_info) ? (volume_info->num % 65536) % 256 : (0 % 65536) % 256 ;\r
153                 memcpy(c, sop, 6);\r
154                 opj_free(sop);\r
155                 c += 6;\r
156         } \r
157         /* </SOP> */\r
158         \r
159         if (!layno) {\r
160                 for (bandno = 0; bandno < res->numbands; bandno++) {\r
161                         opj_tcd_band_t *band = &res->bands[bandno];\r
162                         opj_tcd_precinct_t *prc = &band->precincts[precno];\r
163                         tgt_reset(prc->incltree);\r
164                         tgt_reset(prc->imsbtree);\r
165                         for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {\r
166                                 opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];\r
167                                 cblk->numpasses = 0;\r
168                 tgt_setvalue(prc->imsbtree, cblkno, band->numbps - cblk->numbps);\r
169                         }\r
170                 }\r
171         }\r
172                 \r
173         bio = bio_create();\r
174         bio_init_enc(bio, c, len);\r
175         bio_write(bio, 1, 1);           /* Empty header bit */\r
176         \r
177         /* Writing Packet header */\r
178         for (bandno = 0; bandno < res->numbands; bandno++) {\r
179                 opj_tcd_band_t *band = &res->bands[bandno];\r
180                 opj_tcd_precinct_t *prc = &band->precincts[precno];\r
181                 for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {\r
182                         opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];\r
183                         opj_tcd_layer_t *layer = &cblk->layers[layno];\r
184                         if (!cblk->numpasses && layer->numpasses) {\r
185                 tgt_setvalue(prc->incltree, cblkno, layno);\r
186                         }\r
187                 }\r
188 \r
189                 for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {\r
190                         opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];\r
191                         opj_tcd_layer_t *layer = &cblk->layers[layno];\r
192                         int increment = 0;\r
193                         int nump = 0;\r
194                         int len = 0, passno;\r
195                         /* cblk inclusion bits */\r
196                         if (!cblk->numpasses) {\r
197                                 tgt_encode(bio, prc->incltree, cblkno, layno + 1);\r
198                         } else {\r
199                                 bio_write(bio, layer->numpasses != 0, 1);\r
200                         }\r
201                         /* if cblk not included, go to the next cblk  */\r
202                         if (!layer->numpasses) {\r
203                                 continue;\r
204                         }\r
205                         /* if first instance of cblk --> zero bit-planes information */\r
206                         if (!cblk->numpasses) {\r
207                                 cblk->numlenbits = 3;\r
208                                 tgt_encode(bio, prc->imsbtree, cblkno, 999);\r
209                         }\r
210                         /* number of coding passes included */\r
211                         t2_putnumpasses(bio, layer->numpasses);\r
212                         \r
213                         /* computation of the increase of the length indicator and insertion in the header     */\r
214                         for (passno = cblk->numpasses; passno < cblk->numpasses + layer->numpasses; passno++) {\r
215                                 opj_tcd_pass_t *pass = &cblk->passes[passno];\r
216                                 nump++;\r
217                                 len += pass->len;\r
218                                 if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) {\r
219                                         increment = int_max(increment, int_floorlog2(len) + 1 - (cblk->numlenbits + int_floorlog2(nump)));\r
220                                         len = 0;\r
221                                         nump = 0;\r
222                                 }\r
223                         }\r
224                         t2_putcommacode(bio, increment);\r
225 \r
226                         /* computation of the new Length indicator */\r
227                         cblk->numlenbits += increment;\r
228 \r
229                         /* insertion of the codeword segment length */\r
230                         for (passno = cblk->numpasses; passno < cblk->numpasses + layer->numpasses; passno++) {\r
231                                 opj_tcd_pass_t *pass = &cblk->passes[passno];\r
232                                 nump++;\r
233                                 len += pass->len;\r
234                                 if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) {\r
235                                         bio_write(bio, len, cblk->numlenbits + int_floorlog2(nump));\r
236                                         len = 0;\r
237                                         nump = 0;\r
238                                 }\r
239                         }\r
240 \r
241                 }\r
242         }\r
243         \r
244         \r
245         if (bio_flush(bio)) {\r
246                 return -999;            /* modified to eliminate longjmp !! */\r
247         }\r
248         \r
249         c += bio_numbytes(bio);\r
250 \r
251         bio_destroy(bio);\r
252         \r
253         /* <EPH 0xff92> */\r
254         if (tcp->csty & J3D_CP_CSTY_EPH) {\r
255                 eph = (unsigned char *) opj_malloc(2 * sizeof(unsigned char));\r
256                 eph[0] = 255;\r
257                 eph[1] = 146;\r
258                 memcpy(c, eph, 2);\r
259                 opj_free(eph);\r
260                 c += 2;\r
261         }\r
262         /* </EPH> */\r
263         \r
264         /* Writing the packet body */\r
265         \r
266         for (bandno = 0; bandno < res->numbands; bandno++) {\r
267                 opj_tcd_band_t *band = &res->bands[bandno];\r
268                 opj_tcd_precinct_t *prc = &band->precincts[precno];\r
269                 for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {\r
270                         opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];\r
271                         opj_tcd_layer_t *layer = &cblk->layers[layno];\r
272                         if (!layer->numpasses) {\r
273                                 continue;\r
274                         }\r
275                         if (c + layer->len > dest + len) {\r
276                                 return -999;\r
277                         }\r
278                         \r
279                         memcpy(c, layer->data, layer->len);\r
280                         cblk->numpasses += layer->numpasses;\r
281                         c += layer->len;\r
282                         /* ADD for index Cfr. Marcela --> delta disto by packet */\r
283                         if(volume_info && volume_info->index_write && volume_info->index_on) {\r
284                                 opj_tile_info_t *info_TL = &volume_info->tile[tileno];\r
285                                 opj_packet_info_t *info_PK = &info_TL->packet[volume_info->num];\r
286                                 info_PK->disto += layer->disto;\r
287                                 if (volume_info->D_max < info_PK->disto) {\r
288                                         volume_info->D_max = info_PK->disto;\r
289                                 }\r
290                         }\r
291                         /* </ADD> */\r
292                 }\r
293         }\r
294         \r
295         return (c - dest);\r
296 }\r
297 \r
298 static void t2_init_seg(opj_tcd_seg_t * seg, int cblksty, int first) {\r
299         seg->numpasses = 0;\r
300         seg->len = 0;\r
301         if (cblksty & J3D_CCP_CBLKSTY_TERMALL) {\r
302                 seg->maxpasses = 1;\r
303         }\r
304         else if (cblksty & J3D_CCP_CBLKSTY_LAZY) {\r
305                 if (first) {\r
306                         seg->maxpasses = 10;\r
307                 } else {\r
308                         seg->maxpasses = (((seg - 1)->maxpasses == 1) || ((seg - 1)->maxpasses == 10)) ? 2 : 1;\r
309                 }\r
310         } else {\r
311                 seg->maxpasses = 109;\r
312         }\r
313 }\r
314 \r
315 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
316         int bandno, cblkno;\r
317         unsigned char *c = src;\r
318 \r
319         opj_cp_t *cp = t2->cp;\r
320 \r
321         int compno = pi->compno;        /* component value */\r
322         int resno  = pi->resno;         /* resolution level value */\r
323         int precno = pi->precno;        /* precinct value */\r
324         int layno  = pi->layno;         /* quality layer value */\r
325 \r
326         opj_tcd_tilecomp_t *tilec = &tile->comps[compno];\r
327         opj_tcd_resolution_t *res = &tilec->resolutions[resno];\r
328         \r
329         unsigned char *hd = NULL;\r
330         int present;\r
331         \r
332         opj_bio_t *bio = NULL;  /* BIO component */\r
333         \r
334         if (layno == 0) {\r
335                 for (bandno = 0; bandno < res->numbands; bandno++) {\r
336                         opj_tcd_band_t *band = &res->bands[bandno];\r
337                         opj_tcd_precinct_t *prc = &band->precincts[precno];\r
338                         \r
339                         if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)||(band->z1-band->z0 == 0)) continue;\r
340 \r
341                         tgt_reset(prc->incltree);\r
342                         tgt_reset(prc->imsbtree);\r
343                         for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {\r
344                                 opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];\r
345                                 cblk->numsegs = 0;\r
346                         }\r
347                 }\r
348         }\r
349         \r
350         /* SOP markers */\r
351         \r
352         if (tcp->csty & J3D_CP_CSTY_SOP) {\r
353                 if ((*c) != 0xff || (*(c + 1) != 0x91)) {\r
354                         opj_event_msg(t2->cinfo, EVT_WARNING, "Expected SOP marker\n");\r
355                 } else {\r
356                         c += 6;\r
357                 }\r
358                 \r
359                 /** TODO : check the Nsop value */\r
360         }\r
361         \r
362         /* \r
363         When the marker PPT/PPM is used the packet header are store in PPT/PPM marker\r
364         This part deal with this caracteristic\r
365         step 1: Read packet header in the saved structure\r
366         step 2: Return to codestream for decoding \r
367         */\r
368 \r
369         bio = bio_create();\r
370         \r
371         if (cp->ppm == 1) {             /* PPM */\r
372                 hd = cp->ppm_data;\r
373                 bio_init_dec(bio, hd, cp->ppm_len);\r
374         } else if (tcp->ppt == 1) {     /* PPT */\r
375                 hd = tcp->ppt_data;\r
376                 bio_init_dec(bio, hd, tcp->ppt_len);\r
377         } else {                        /* Normal Case */\r
378                 hd = c;\r
379                 bio_init_dec(bio, hd, src+len-hd);\r
380         }\r
381         \r
382         present = bio_read(bio, 1);\r
383         \r
384         if (!present) {\r
385                 bio_inalign(bio);\r
386                 hd += bio_numbytes(bio);\r
387                 bio_destroy(bio);\r
388                 \r
389                 /* EPH markers */\r
390                 \r
391                 if (tcp->csty & J3D_CP_CSTY_EPH) {\r
392                         if ((*hd) != 0xff || (*(hd + 1) != 0x92)) {\r
393                                 printf("Error : expected EPH marker\n");\r
394                         } else {\r
395                                 hd += 2;\r
396                         }\r
397                 }\r
398                 \r
399                 if (cp->ppm == 1) {             /* PPM case */\r
400                         cp->ppm_len += cp->ppm_data-hd;\r
401                         cp->ppm_data = hd;\r
402                         return (c - src);\r
403                 }\r
404                 if (tcp->ppt == 1) {    /* PPT case */\r
405                         tcp->ppt_len+=tcp->ppt_data-hd;\r
406                         tcp->ppt_data = hd;\r
407                         return (c - src);\r
408                 }\r
409                 \r
410                 return (hd - src);\r
411         }\r
412         \r
413         for (bandno = 0; bandno < res->numbands; bandno++) {\r
414                 opj_tcd_band_t *band = &res->bands[bandno];\r
415                 opj_tcd_precinct_t *prc = &band->precincts[precno];\r
416                 \r
417                 if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)||(band->z1-band->z0 == 0)) continue;\r
418                 \r
419                 for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {\r
420                         int included, increment, n;\r
421                         opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];\r
422                         opj_tcd_seg_t *seg = NULL;\r
423                         /* if cblk not yet included before --> inclusion tagtree */\r
424                         if (!cblk->numsegs) {\r
425                 included = tgt_decode(bio, prc->incltree, cblkno, layno + 1);\r
426                                 /* else one bit */\r
427                         } else {\r
428                                 included = bio_read(bio, 1);\r
429                         }\r
430                         /* if cblk not included */\r
431                         if (!included) {\r
432                                 cblk->numnewpasses = 0;\r
433                                 continue;\r
434                         }\r
435                         /* if cblk not yet included --> zero-bitplane tagtree */\r
436                         if (!cblk->numsegs) {\r
437                                 int i, numimsbs;\r
438                                 for (i = 0; !tgt_decode(bio, prc->imsbtree, cblkno, i); i++);\r
439                                 numimsbs = i - 1;\r
440                                 cblk->numbps = band->numbps - numimsbs;\r
441                                 cblk->numlenbits = 3;\r
442                         }\r
443                         /* number of coding passes */\r
444                         cblk->numnewpasses = t2_getnumpasses(bio);\r
445                         increment = t2_getcommacode(bio);\r
446                         /* length indicator increment */\r
447                         cblk->numlenbits += increment;\r
448                         if (!cblk->numsegs) {\r
449                                 seg = &cblk->segs[0];\r
450                                 t2_init_seg(seg, tcp->tccps[compno].cblksty, 1);\r
451                         } else {\r
452                                 seg = &cblk->segs[cblk->numsegs - 1];\r
453                                 if (seg->numpasses == seg->maxpasses) {\r
454                                         t2_init_seg(++seg, tcp->tccps[compno].cblksty, 0);\r
455                                 }\r
456                         }\r
457                         n = cblk->numnewpasses;\r
458                         \r
459                         do {\r
460                                 seg->numnewpasses = int_min(seg->maxpasses - seg->numpasses, n);\r
461                                 seg->newlen = bio_read(bio, cblk->numlenbits + int_floorlog2(seg->numnewpasses));\r
462                                 n -= seg->numnewpasses;\r
463                                 if (n > 0) {\r
464                                         t2_init_seg(++seg, tcp->tccps[compno].cblksty, 0);\r
465                                 }\r
466                         } while (n > 0);\r
467                 }\r
468         }\r
469         \r
470         if (bio_inalign(bio)) {\r
471                 bio_destroy(bio);\r
472                 return -999;\r
473         }\r
474         \r
475         hd += bio_numbytes(bio);\r
476         bio_destroy(bio);\r
477         \r
478         /* EPH markers */\r
479         if (tcp->csty & J3D_CP_CSTY_EPH) {\r
480                 if ((*hd) != 0xff || (*(hd + 1) != 0x92)) {\r
481                         opj_event_msg(t2->cinfo, EVT_ERROR, "Expected EPH marker\n");\r
482                 } else {\r
483                         hd += 2;\r
484                 }\r
485         }\r
486         \r
487         if (cp->ppm==1) {\r
488                 cp->ppm_len+=cp->ppm_data-hd;\r
489                 cp->ppm_data = hd;\r
490         } else if (tcp->ppt == 1) {\r
491                 tcp->ppt_len+=tcp->ppt_data-hd;\r
492                 tcp->ppt_data = hd;\r
493         } else {\r
494                 c=hd;\r
495         }\r
496         \r
497         for (bandno = 0; bandno < res->numbands; bandno++) {\r
498                 opj_tcd_band_t *band = &res->bands[bandno];\r
499                 opj_tcd_precinct_t *prc = &band->precincts[precno];\r
500                 \r
501                 if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)||(band->z1-band->z0 == 0)) continue;             \r
502 \r
503                 for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {\r
504                         opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];\r
505                         opj_tcd_seg_t *seg = NULL;\r
506                         if (!cblk->numnewpasses)\r
507                                 continue;\r
508                         if (!cblk->numsegs) {\r
509                                 seg = &cblk->segs[0];\r
510                                 cblk->numsegs++;\r
511                                 cblk->len = 0;\r
512                         } else {\r
513                                 seg = &cblk->segs[cblk->numsegs - 1];\r
514                                 if (seg->numpasses == seg->maxpasses) {\r
515                                         seg++;\r
516                                         cblk->numsegs++;\r
517                                 }\r
518                         }\r
519                         \r
520                         do {\r
521                                 if (c + seg->newlen > src + len) {\r
522                                         return -999;\r
523                                 }\r
524                                 \r
525                                 memcpy(cblk->data + cblk->len, c, seg->newlen);\r
526                                 if (seg->numpasses == 0) {\r
527                                         seg->data = cblk->data + cblk->len;\r
528                                 }\r
529                                 c += seg->newlen;\r
530                                 cblk->len += seg->newlen;\r
531                                 seg->len += seg->newlen;\r
532                                 seg->numpasses += seg->numnewpasses;\r
533                                 cblk->numnewpasses -= seg->numnewpasses;\r
534                                 if (cblk->numnewpasses > 0) {\r
535                                         seg++;\r
536                                         cblk->numsegs++;\r
537                                 }\r
538                         } while (cblk->numnewpasses > 0);\r
539                 }\r
540         }\r
541         \r
542         return (c - src);\r
543 }\r
544 \r
545 /* ----------------------------------------------------------------------- */\r
546 \r
547 int t2_encode_packets(opj_t2_t* t2, int tileno, opj_tcd_tile_t *tile, int maxlayers, unsigned char *dest, int len, opj_volume_info_t *volume_info) {\r
548         unsigned char *c = dest;\r
549         int e = 0;\r
550         opj_pi_iterator_t *pi = NULL;\r
551         int pino;\r
552 \r
553         opj_volume_t *volume = t2->volume;\r
554         opj_cp_t *cp = t2->cp;\r
555         \r
556         /* create a packet iterator */\r
557         pi = pi_create(volume, cp, tileno);\r
558         if(!pi) {\r
559                 fprintf(stdout,"[ERROR] Failed to create a pi structure\n");\r
560                 return -999;\r
561         }\r
562         \r
563         if(volume_info) {\r
564                 volume_info->num = 0;\r
565         }\r
566         \r
567         for (pino = 0; pino <= cp->tcps[tileno].numpocs; pino++) {\r
568                 while (pi_next(&pi[pino])) {\r
569                         if (pi[pino].layno < maxlayers) {\r
570                                 e = t2_encode_packet(tile, &cp->tcps[tileno], &pi[pino], c, dest + len - c, volume_info, tileno, cp);\r
571                                 //opj_event_msg(t2->cinfo, EVT_INFO, "  t2_encode_packet: %d bytes coded\n",e);\r
572                                 if (e == -999) {\r
573                                         break;\r
574                                 } else {\r
575                                         c += e;\r
576                                 }\r
577                                 \r
578                                 /* INDEX >> */\r
579                                 if(volume_info && volume_info->index_on) {\r
580                                         if(volume_info->index_write) {\r
581                                                 opj_tile_info_t *info_TL = &volume_info->tile[tileno];\r
582                                                 opj_packet_info_t *info_PK = &info_TL->packet[volume_info->num];\r
583                                                 if (!volume_info->num) {\r
584                                                         info_PK->start_pos = info_TL->end_header + 1;\r
585                                                 } else {\r
586                                                         info_PK->start_pos = info_TL->packet[volume_info->num - 1].end_pos + 1;\r
587                                                 }\r
588                                                 info_PK->end_pos = info_PK->start_pos + e - 1;\r
589                                         }\r
590 \r
591                                         volume_info->num++;\r
592                                 }\r
593                                 /* << INDEX */\r
594                         }\r
595                 }\r
596         }\r
597 \r
598         /* don't forget to release pi */\r
599         pi_destroy(pi, cp, tileno);\r
600         \r
601         if (e == -999) {\r
602                 return e;\r
603         }\r
604 \r
605     return (c - dest);\r
606 }\r
607 \r
608 int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj_tcd_tile_t *tile) {\r
609         unsigned char *c = src;\r
610         opj_pi_iterator_t *pi;\r
611         int pino, e = 0;\r
612         int n = 0,i;\r
613 \r
614         opj_volume_t *volume = t2->volume;\r
615         opj_cp_t *cp = t2->cp;\r
616         \r
617         /* create a packet iterator */\r
618         pi = pi_create(volume, cp, tileno);\r
619         if(!pi) {\r
620                 /* TODO: throw an error */\r
621                 return -999;\r
622         }\r
623         \r
624         for (pino = 0; pino <= cp->tcps[tileno].numpocs; pino++) {\r
625                 while (pi_next(&pi[pino])) {\r
626                         if ((cp->layer==0) || (cp->layer>=((pi[pino].layno)+1))) {\r
627                                 e = t2_decode_packet(t2, c, src + len - c, tile, &cp->tcps[tileno], &pi[pino]);\r
628                         } else {\r
629                                 e = 0;\r
630                         }\r
631                         \r
632                         /* progression in resolution */\r
633                         for (i = 0; i < 3; i++){\r
634                 volume->comps[pi[pino].compno].resno_decoded[i] = (e > 0) ? int_max(pi[pino].resno, volume->comps[pi[pino].compno].resno_decoded[i]) : volume->comps[pi[pino].compno].resno_decoded[i];\r
635                         }\r
636                         n++;\r
637                         \r
638                         if (e == -999) {                /* ADD */\r
639                                 break;\r
640                         } else {\r
641                                 opj_event_msg(t2->cinfo, EVT_INFO, "  t2_decode_packet: %d bytes decoded\n",e);\r
642                                 c += e;\r
643                         }\r
644                 }\r
645         }\r
646 \r
647         /* don't forget to release pi */\r
648         pi_destroy(pi, cp, tileno);\r
649         \r
650         if (e == -999) {\r
651                 return e;\r
652         }\r
653         \r
654     return (c - src);\r
655 }\r
656 \r
657 /* ----------------------------------------------------------------------- */\r
658 \r
659 opj_t2_t* t2_create(opj_common_ptr cinfo, opj_volume_t *volume, opj_cp_t *cp) {\r
660         /* create the tcd structure */\r
661         opj_t2_t *t2 = (opj_t2_t*)opj_malloc(sizeof(opj_t2_t));\r
662         if(!t2) return NULL;\r
663         t2->cinfo = cinfo;\r
664         t2->volume = volume;\r
665         t2->cp = cp;\r
666 \r
667         return t2;\r
668 }\r
669 \r
670 void t2_destroy(opj_t2_t *t2) {\r
671         if(t2) {\r
672                 opj_free(t2);\r
673         }\r
674 }\r
675 \r