[1.5] Import first patch (fixes.patch) from issue 249 to fix leaks on error condition.
[openjpeg.git] / libopenjpeg / jp2.c
1 /*
2  * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
3  * Copyright (c) 2002-2007, Professor Benoit Macq
4  * Copyright (c) 2001-2003, David Janssens
5  * Copyright (c) 2002-2003, Yannick Verschueren
6  * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
7  * Copyright (c) 2005, Herve Drolon, FreeImage Team
8  * Copyright (c) 2010-2011, Kaori Hagihara
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 #include "opj_includes.h"
33
34 /** @defgroup JP2 JP2 - JPEG-2000 file format reader/writer */
35 /*@{*/
36
37 /** @name Local static functions */
38 /*@{*/
39
40 /**
41 Read box headers
42 @param cinfo Codec context info
43 @param cio Input stream
44 @param box
45 @return Returns true if successful, returns false otherwise
46 */
47 static opj_bool jp2_read_boxhdr(opj_common_ptr cinfo, opj_cio_t *cio, opj_jp2_box_t *box);
48 /*static void jp2_write_url(opj_cio_t *cio, char *Idx_file);*/
49 /**
50 Read the IHDR box - Image Header box
51 @param jp2 JP2 handle
52 @param cio Input buffer stream
53 @return Returns true if successful, returns false otherwise
54 */
55 static opj_bool jp2_read_ihdr(opj_jp2_t *jp2, opj_cio_t *cio);
56 static void jp2_write_ihdr(opj_jp2_t *jp2, opj_cio_t *cio);
57 static void jp2_write_bpcc(opj_jp2_t *jp2, opj_cio_t *cio);
58 static opj_bool jp2_read_bpcc(opj_jp2_t *jp2, opj_cio_t *cio);
59 static void jp2_write_colr(opj_jp2_t *jp2, opj_cio_t *cio);
60 /**
61 Write the FTYP box - File type box
62 @param jp2 JP2 handle
63 @param cio Output buffer stream
64 */
65 static void jp2_write_ftyp(opj_jp2_t *jp2, opj_cio_t *cio);
66 /**
67 Read the FTYP box - File type box
68 @param jp2 JP2 handle
69 @param cio Input buffer stream
70 @return Returns true if successful, returns false otherwise
71 */
72 static opj_bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio);
73 static int jp2_write_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info);
74 static opj_bool jp2_read_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, unsigned int *j2k_codestream_length, unsigned int *j2k_codestream_offset);
75 static void jp2_write_jp(opj_cio_t *cio);
76 /**
77 Read the JP box - JPEG 2000 signature
78 @param jp2 JP2 handle
79 @param cio Input buffer stream
80 @return Returns true if successful, returns false otherwise
81 */
82 static opj_bool jp2_read_jp(opj_jp2_t *jp2, opj_cio_t *cio);
83 /**
84 Decode the structure of a JP2 file
85 @param jp2 JP2 handle
86 @param cio Input buffer stream
87 @param color Collector for profile, cdef and pclr data
88 @return Returns true if successful, returns false otherwise
89 */
90 static opj_bool jp2_read_struct(opj_jp2_t *jp2, opj_cio_t *cio,
91         opj_jp2_color_t *color);
92 /**
93 Apply collected palette data
94 @param color Collector for profile, cdef and pclr data
95 @param image 
96 */
97 static void jp2_apply_pclr(opj_jp2_color_t *color, opj_image_t *image, opj_common_ptr cinfo);
98 /**
99 Collect palette data
100 @param jp2 JP2 handle
101 @param cio Input buffer stream
102 @param box
103 @param color Collector for profile, cdef and pclr data
104 @return Returns true if successful, returns false otherwise
105 */
106 static opj_bool jp2_read_pclr(opj_jp2_t *jp2, opj_cio_t *cio,
107     opj_jp2_box_t *box, opj_jp2_color_t *color);
108 /**
109 Collect component mapping data
110 @param jp2 JP2 handle
111 @param cio Input buffer stream
112 @param box
113 @param color Collector for profile, cdef and pclr data
114 @return Returns true if successful, returns false otherwise
115 */
116 static opj_bool jp2_read_cmap(opj_jp2_t *jp2, opj_cio_t *cio,
117     opj_jp2_box_t *box, opj_jp2_color_t *color);
118 /**
119 Collect colour specification data
120 @param jp2 JP2 handle
121 @param cio Input buffer stream
122 @param box
123 @param color Collector for profile, cdef and pclr data
124 @return Returns true if successful, returns false otherwise
125 */
126 static opj_bool jp2_read_colr(opj_jp2_t *jp2, opj_cio_t *cio,
127     opj_jp2_box_t *box, opj_jp2_color_t *color);
128 /**
129 Write file Index (superbox)
130 @param[in] offset_jp2c offset of jp2c box
131 @param[in] length_jp2c length of jp2c box
132 @param[in] offset_idx  offset of cidx box
133 @param[in] length_idx  length of cidx box
134 @param[in] cio         file output handle
135 @return                length of fidx box
136 */
137 static int write_fidx( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_cio_t *cio);
138 /**
139 Write index Finder box
140 @param[in] offset offset of fidx box
141 @param[in] length length of fidx box
142 @param[in] cio         file output handle
143 */
144 static void write_iptr( int offset, int length, opj_cio_t *cio);
145 /**
146 Write proxy box
147 @param[in] offset_jp2c offset of jp2c box
148 @param[in] length_jp2c length of jp2c box
149 @param[in] offset_idx  offset of cidx box
150 @param[in] length_idx  length of cidx box
151 @param[in] cio         file output handle
152 */
153 static void write_prxy( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_cio_t *cio);
154 /*@}*/
155
156 /*@}*/
157
158 /* ----------------------------------------------------------------------- */
159
160 static opj_bool jp2_read_boxhdr(opj_common_ptr cinfo, opj_cio_t *cio, opj_jp2_box_t *box) {
161         box->init_pos = cio_tell(cio);
162         box->length = cio_read(cio, 4);
163         box->type = cio_read(cio, 4);
164         if (box->length == 1) {
165                 if (cio_read(cio, 4) != 0) {
166                         opj_event_msg(cinfo, EVT_ERROR, "Cannot handle box sizes higher than 2^32\n");
167                         return OPJ_FALSE;
168                 }
169                 box->length = cio_read(cio, 4);
170                 if (box->length == 0) 
171                         box->length = cio_numbytesleft(cio) + 12;
172         }
173         else if (box->length == 0) {
174                 box->length = cio_numbytesleft(cio) + 8;
175         }
176         if (box->length < 0) {
177                 opj_event_msg(cinfo, EVT_ERROR, "Integer overflow in box->length\n");
178                 return OPJ_FALSE; // TODO: actually check jp2_read_boxhdr's return value
179         }
180         
181         return OPJ_TRUE;
182 }
183
184 #if 0
185 static void jp2_write_url(opj_cio_t *cio, char *Idx_file) {
186         unsigned int i;
187         opj_jp2_box_t box;
188
189         box.init_pos = cio_tell(cio);
190         cio_skip(cio, 4);
191         cio_write(cio, JP2_URL, 4);     /* DBTL */
192         cio_write(cio, 0, 1);           /* VERS */
193         cio_write(cio, 0, 3);           /* FLAG */
194
195         if(Idx_file) {
196                 for (i = 0; i < strlen(Idx_file); i++) {
197                         cio_write(cio, Idx_file[i], 1);
198                 }
199         }
200
201         box.length = cio_tell(cio) - box.init_pos;
202         cio_seek(cio, box.init_pos);
203         cio_write(cio, box.length, 4);  /* L */
204         cio_seek(cio, box.init_pos + box.length);
205 }
206 #endif
207
208 static opj_bool jp2_read_ihdr(opj_jp2_t *jp2, opj_cio_t *cio) {
209         opj_jp2_box_t box;
210
211         opj_common_ptr cinfo = jp2->cinfo;
212
213   if(jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) {
214     opj_event_msg(cinfo, EVT_ERROR, "Failed to read boxhdr\n");
215     return OPJ_FALSE;
216   }
217         if (JP2_IHDR != box.type) {
218                 opj_event_msg(cinfo, EVT_ERROR, "Expected IHDR Marker\n");
219                 return OPJ_FALSE;
220         }
221
222         jp2->h = cio_read(cio, 4);                      /* HEIGHT */
223         jp2->w = cio_read(cio, 4);                      /* WIDTH */
224         jp2->numcomps = cio_read(cio, 2);       /* NC */
225         jp2->comps = (opj_jp2_comps_t*) opj_malloc(jp2->numcomps * sizeof(opj_jp2_comps_t));
226
227         jp2->bpc = cio_read(cio, 1);            /* BPC */
228
229         jp2->C = cio_read(cio, 1);                      /* C */
230         jp2->UnkC = cio_read(cio, 1);           /* UnkC */
231         jp2->IPR = cio_read(cio, 1);            /* IPR */
232
233         if (cio_tell(cio) - box.init_pos != box.length) {
234                 opj_event_msg(cinfo, EVT_ERROR, "Error with IHDR Box\n");
235                 return OPJ_FALSE;
236         }
237
238         return OPJ_TRUE;
239 }
240
241 static void jp2_write_ihdr(opj_jp2_t *jp2, opj_cio_t *cio) {
242         opj_jp2_box_t box;
243
244         box.init_pos = cio_tell(cio);
245         cio_skip(cio, 4);
246         cio_write(cio, JP2_IHDR, 4);            /* IHDR */
247
248         cio_write(cio, jp2->h, 4);                      /* HEIGHT */
249         cio_write(cio, jp2->w, 4);                      /* WIDTH */
250         cio_write(cio, jp2->numcomps, 2);       /* NC */
251
252         cio_write(cio, jp2->bpc, 1);            /* BPC */
253
254         cio_write(cio, jp2->C, 1);                      /* C : Always 7 */
255         cio_write(cio, jp2->UnkC, 1);           /* UnkC, colorspace unknown */
256         cio_write(cio, jp2->IPR, 1);            /* IPR, no intellectual property */
257
258         box.length = cio_tell(cio) - box.init_pos;
259         cio_seek(cio, box.init_pos);
260         cio_write(cio, box.length, 4);  /* L */
261         cio_seek(cio, box.init_pos + box.length);
262 }
263
264 static void jp2_write_bpcc(opj_jp2_t *jp2, opj_cio_t *cio) {
265         unsigned int i;
266         opj_jp2_box_t box;
267
268         box.init_pos = cio_tell(cio);
269         cio_skip(cio, 4);
270         cio_write(cio, JP2_BPCC, 4);    /* BPCC */
271
272         for (i = 0; i < jp2->numcomps; i++) {
273                 cio_write(cio, jp2->comps[i].bpcc, 1);
274         }
275
276         box.length = cio_tell(cio) - box.init_pos;
277         cio_seek(cio, box.init_pos);
278         cio_write(cio, box.length, 4);  /* L */
279         cio_seek(cio, box.init_pos + box.length);
280 }
281
282
283 static opj_bool jp2_read_bpcc(opj_jp2_t *jp2, opj_cio_t *cio) {
284         unsigned int i;
285         opj_jp2_box_t box;
286
287         opj_common_ptr cinfo = jp2->cinfo;
288
289   if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) {
290     opj_event_msg(cinfo, EVT_ERROR, "Failed to read boxhdr\n");
291     return OPJ_FALSE;
292   }
293         if (JP2_BPCC != box.type) {
294                 opj_event_msg(cinfo, EVT_ERROR, "Expected BPCC Marker\n");
295                 return OPJ_FALSE;
296         }
297
298         for (i = 0; i < jp2->numcomps; i++) {
299                 jp2->comps[i].bpcc = cio_read(cio, 1);
300         }
301
302         if (cio_tell(cio) - box.init_pos != box.length) {
303                 opj_event_msg(cinfo, EVT_ERROR, "Error with BPCC Box\n");
304                 return OPJ_FALSE;
305         }
306
307         return OPJ_TRUE;
308 }
309
310 static void jp2_write_colr(opj_jp2_t *jp2, opj_cio_t *cio) {
311         opj_jp2_box_t box;
312
313         box.init_pos = cio_tell(cio);
314         cio_skip(cio, 4);
315         cio_write(cio, JP2_COLR, 4);            /* COLR */
316
317         cio_write(cio, jp2->meth, 1);           /* METH */
318         cio_write(cio, jp2->precedence, 1);     /* PRECEDENCE */
319         cio_write(cio, jp2->approx, 1);         /* APPROX */
320
321         if(jp2->meth == 2)
322          jp2->enumcs = 0;
323
324         cio_write(cio, jp2->enumcs, 4); /* EnumCS */
325
326         box.length = cio_tell(cio) - box.init_pos;
327         cio_seek(cio, box.init_pos);
328         cio_write(cio, box.length, 4);  /* L */
329         cio_seek(cio, box.init_pos + box.length);
330 }
331
332 static void jp2_free_pclr(opj_jp2_color_t *color)
333 {
334     opj_free(color->jp2_pclr->channel_sign);
335     opj_free(color->jp2_pclr->channel_size);
336     opj_free(color->jp2_pclr->entries);
337
338         if(color->jp2_pclr->cmap) opj_free(color->jp2_pclr->cmap);
339
340     opj_free(color->jp2_pclr); color->jp2_pclr = NULL;
341 }
342
343 static void free_color_data(opj_jp2_color_t *color)
344 {
345         if(color->jp2_pclr)
346    {
347         jp2_free_pclr(color);
348    }
349         if(color->jp2_cdef) 
350    {
351         if(color->jp2_cdef->info) opj_free(color->jp2_cdef->info);
352         opj_free(color->jp2_cdef);
353    }
354         if(color->icc_profile_buf) opj_free(color->icc_profile_buf);
355 }
356
357 static void jp2_apply_pclr(opj_jp2_color_t *color, opj_image_t *image, opj_common_ptr cinfo)
358 {
359         opj_image_comp_t *old_comps, *new_comps;
360         unsigned char *channel_size, *channel_sign;
361         unsigned int *entries;
362         opj_jp2_cmap_comp_t *cmap;
363         int *src, *dst;
364         unsigned int j, max;
365         unsigned short i, nr_channels, cmp, pcol;
366         int k, top_k;
367
368         channel_size = color->jp2_pclr->channel_size;
369         channel_sign = color->jp2_pclr->channel_sign;
370         entries = color->jp2_pclr->entries;
371         cmap = color->jp2_pclr->cmap;
372         nr_channels = color->jp2_pclr->nr_channels;
373
374         old_comps = image->comps;
375         new_comps = (opj_image_comp_t*)
376          opj_malloc(nr_channels * sizeof(opj_image_comp_t));
377
378         for(i = 0; i < nr_channels; ++i)
379    {
380         pcol = cmap[i].pcol; cmp = cmap[i].cmp;
381
382   if( pcol < nr_channels )
383     new_comps[pcol] = old_comps[cmp];
384   else
385     {
386     opj_event_msg(cinfo, EVT_ERROR, "Error with pcol value %d (max: %d). skipping\n", pcol, nr_channels);
387     continue;
388     }
389
390         if(cmap[i].mtyp == 0) /* Direct use */
391   {
392         old_comps[cmp].data = NULL; continue;
393   }
394 /* Palette mapping: */
395         new_comps[pcol].data = (int*)
396          opj_malloc(old_comps[cmp].w * old_comps[cmp].h * sizeof(int));
397         new_comps[pcol].prec = channel_size[i];
398         new_comps[pcol].sgnd = channel_sign[i];
399    }
400         top_k = color->jp2_pclr->nr_entries - 1;
401
402         for(i = 0; i < nr_channels; ++i)
403    {
404 /* Direct use: */
405         if(cmap[i].mtyp == 0) continue;
406
407 /* Palette mapping: */
408         cmp = cmap[i].cmp; pcol = cmap[i].pcol;
409         src = old_comps[cmp].data; 
410         dst = new_comps[pcol].data;
411         max = new_comps[pcol].w * new_comps[pcol].h;
412
413         for(j = 0; j < max; ++j)
414   {
415 /* The index */
416         if((k = src[j]) < 0) k = 0; else if(k > top_k) k = top_k;
417 /* The colour */
418         dst[j] = entries[k * nr_channels + pcol];
419   }
420    }
421         max = image->numcomps;
422         for(i = 0; i < max; ++i)
423    {
424         if(old_comps[i].data) opj_free(old_comps[i].data);
425    }
426         opj_free(old_comps);
427         image->comps = new_comps;
428         image->numcomps = nr_channels;
429
430         jp2_free_pclr(color);
431
432 }/* apply_pclr() */
433
434 static opj_bool jp2_read_pclr(opj_jp2_t *jp2, opj_cio_t *cio,
435         opj_jp2_box_t *box, opj_jp2_color_t *color)
436 {
437         opj_jp2_pclr_t *jp2_pclr;
438         unsigned char *channel_size, *channel_sign;
439         unsigned int *entries;
440         unsigned short nr_entries, nr_channels;
441         unsigned short i, j;
442         unsigned char uc;
443
444         OPJ_ARG_NOT_USED(box);
445         OPJ_ARG_NOT_USED(jp2);
446
447 /* Part 1, I.5.3.4: 'There shall be at most one Palette box inside
448  * a JP2 Header box' :
449 */
450         if(color->jp2_pclr) return OPJ_FALSE;
451
452         nr_entries = (unsigned short)cio_read(cio, 2); /* NE */
453         nr_channels = (unsigned short)cio_read(cio, 1);/* NPC */
454
455         entries = (unsigned int*)
456          opj_malloc(nr_channels * nr_entries * sizeof(unsigned int));
457         channel_size = (unsigned char*)opj_malloc(nr_channels);
458         channel_sign = (unsigned char*)opj_malloc(nr_channels);
459
460         jp2_pclr = (opj_jp2_pclr_t*)opj_malloc(sizeof(opj_jp2_pclr_t));
461         jp2_pclr->channel_sign = channel_sign;
462         jp2_pclr->channel_size = channel_size;
463         jp2_pclr->entries = entries;
464         jp2_pclr->nr_entries = nr_entries;
465         jp2_pclr->nr_channels = nr_channels;
466         jp2_pclr->cmap = NULL;
467
468         color->jp2_pclr = jp2_pclr;
469
470         for(i = 0; i < nr_channels; ++i)
471    {
472         uc = cio_read(cio, 1); /* Bi */
473         channel_size[i] = (uc & 0x7f) + 1;
474         channel_sign[i] = (uc & 0x80)?1:0;
475    }
476
477         for(j = 0; j < nr_entries; ++j)
478    {
479         for(i = 0; i < nr_channels; ++i)
480   {
481 /* Cji */
482         *entries++ = cio_read(cio, (channel_size[i]+7)>>3);
483   }
484    }
485
486         return OPJ_TRUE;
487 }/* jp2_read_pclr() */
488
489 static opj_bool jp2_read_cmap(opj_jp2_t *jp2, opj_cio_t *cio,
490         opj_jp2_box_t *box, opj_jp2_color_t *color)
491 {
492         opj_jp2_cmap_comp_t *cmap;
493         unsigned short i, nr_channels;
494
495         OPJ_ARG_NOT_USED(box);
496         OPJ_ARG_NOT_USED(jp2);
497
498 /* Need nr_channels: */
499         if(color->jp2_pclr == NULL) return OPJ_FALSE;
500
501 /* Part 1, I.5.3.5: 'There shall be at most one Component Mapping box
502  * inside a JP2 Header box' :
503 */
504         if(color->jp2_pclr->cmap) return OPJ_FALSE;
505
506         nr_channels = color->jp2_pclr->nr_channels;
507         cmap = (opj_jp2_cmap_comp_t*)
508          opj_malloc(nr_channels * sizeof(opj_jp2_cmap_comp_t));
509
510         for(i = 0; i < nr_channels; ++i)
511    {
512         cmap[i].cmp = (unsigned short)cio_read(cio, 2);
513         cmap[i].mtyp = cio_read(cio, 1);
514         cmap[i].pcol = cio_read(cio, 1);
515
516    }
517         color->jp2_pclr->cmap = cmap;
518
519         return OPJ_TRUE;
520 }/* jp2_read_cmap() */
521
522 static void jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color)
523 {
524         opj_jp2_cdef_info_t *info;
525         int color_space;
526         unsigned short i, n, cn, typ, asoc, acn;
527
528         color_space = image->color_space;
529         info = color->jp2_cdef->info;
530         n = color->jp2_cdef->n;
531
532         for(i = 0; i < n; ++i)
533    {
534 /* WATCH: acn = asoc - 1 ! */
535         if((asoc = info[i].asoc) == 0) continue;
536
537         cn = info[i].cn; typ = info[i].typ; acn = asoc - 1;
538
539         if(cn != acn)
540   {
541         opj_image_comp_t saved;
542
543         memcpy(&saved, &image->comps[cn], sizeof(opj_image_comp_t));
544         memcpy(&image->comps[cn], &image->comps[acn], sizeof(opj_image_comp_t));
545         memcpy(&image->comps[acn], &saved, sizeof(opj_image_comp_t));
546
547         info[i].asoc = cn + 1;
548         info[acn].asoc = info[acn].cn + 1;
549   }
550    }
551         if(color->jp2_cdef->info) opj_free(color->jp2_cdef->info);
552
553         opj_free(color->jp2_cdef); color->jp2_cdef = NULL;
554
555 }/* jp2_apply_cdef() */
556
557 static opj_bool jp2_read_cdef(opj_jp2_t *jp2, opj_cio_t *cio,
558         opj_jp2_box_t *box, opj_jp2_color_t *color)
559 {
560         opj_jp2_cdef_info_t *info;
561         unsigned short i, n;
562
563         OPJ_ARG_NOT_USED(box);
564         OPJ_ARG_NOT_USED(jp2);
565
566 /* Part 1, I.5.3.6: 'The shall be at most one Channel Definition box
567  * inside a JP2 Header box.' 
568 */
569         if(color->jp2_cdef) return OPJ_FALSE;
570
571         if((n = (unsigned short)cio_read(cio, 2)) == 0) return OPJ_FALSE; /* szukw000: FIXME */
572
573         info = (opj_jp2_cdef_info_t*)
574          opj_malloc(n * sizeof(opj_jp2_cdef_info_t));
575
576         color->jp2_cdef = (opj_jp2_cdef_t*)opj_malloc(sizeof(opj_jp2_cdef_t));
577         color->jp2_cdef->info = info;
578         color->jp2_cdef->n = n;
579
580         for(i = 0; i < n; ++i)
581    {
582         info[i].cn = (unsigned short)cio_read(cio, 2);
583         info[i].typ = (unsigned short)cio_read(cio, 2);
584         info[i].asoc = (unsigned short)cio_read(cio, 2);
585
586    }
587         return OPJ_TRUE;
588 }/* jp2_read_cdef() */
589
590 static opj_bool jp2_read_colr(opj_jp2_t *jp2, opj_cio_t *cio,
591         opj_jp2_box_t *box, opj_jp2_color_t *color) 
592 {
593         int skip_len;
594     opj_common_ptr cinfo;
595
596 /* Part 1, I.5.3.3 : 'A conforming JP2 reader shall ignore all Colour
597  * Specification boxes after the first.' 
598 */
599         if(color->jp2_has_colr) return OPJ_FALSE;
600
601         cinfo = jp2->cinfo;
602
603         jp2->meth = cio_read(cio, 1);           /* METH */
604         jp2->precedence = cio_read(cio, 1);     /* PRECEDENCE */
605         jp2->approx = cio_read(cio, 1);         /* APPROX */
606
607         if (jp2->meth == 1) 
608    {
609         jp2->enumcs = cio_read(cio, 4); /* EnumCS */
610    } 
611         else
612         if (jp2->meth == 2) 
613    {
614 /* skip PROFILE */
615         skip_len = box->init_pos + box->length - cio_tell(cio);
616         if (skip_len < 0) 
617   {
618         opj_event_msg(cinfo, EVT_ERROR, "Error with COLR box size\n");
619         return OPJ_FALSE;
620   }
621         if(skip_len > 0)
622   {
623         unsigned char *start;
624
625         start = cio_getbp(cio);
626         color->icc_profile_buf = (unsigned char*)opj_malloc(skip_len);
627         color->icc_profile_len = skip_len;
628
629         cio_skip(cio, box->init_pos + box->length - cio_tell(cio));
630
631         memcpy(color->icc_profile_buf, start, skip_len);
632   }
633    }
634
635         if (cio_tell(cio) - box->init_pos != box->length) 
636    {
637         opj_event_msg(cinfo, EVT_ERROR, "Error with COLR Box\n");
638         return OPJ_FALSE;
639    }
640         color->jp2_has_colr = 1;
641
642         return OPJ_TRUE;
643 }/* jp2_read_colr() */
644
645 opj_bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio, opj_jp2_color_t *color) 
646 {
647         opj_jp2_box_t box;
648         int jp2h_end;
649
650         opj_common_ptr cinfo = jp2->cinfo;
651
652   if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE;
653   do {
654     if (JP2_JP2H != box.type) 
655       {
656       if (box.type == JP2_JP2C) 
657         {
658         opj_event_msg(cinfo, EVT_ERROR, "Expected JP2H Marker\n");
659         return OPJ_FALSE;
660         }
661           if (box.length <= 8) return OPJ_FALSE;
662       cio_skip(cio, box.length - 8);
663
664       if(cio->bp >= cio->end) return OPJ_FALSE;
665
666       if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE;
667       }
668   } while(JP2_JP2H != box.type);
669
670         if (!jp2_read_ihdr(jp2, cio))
671                 return OPJ_FALSE;
672         jp2h_end = box.init_pos + box.length;
673
674   if (jp2->bpc == 255) 
675     {
676     if (!jp2_read_bpcc(jp2, cio))
677       return OPJ_FALSE;
678     }
679   if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE;
680
681   while(cio_tell(cio) < jp2h_end)
682     {
683     if(box.type == JP2_COLR)
684       {
685       if( !jp2_read_colr(jp2, cio, &box, color))
686         {
687         if (box.length <= 8) return OPJ_FALSE;
688         cio_seek(cio, box.init_pos + 8);
689         cio_skip(cio, box.length - 8);
690         }
691       if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE;
692       continue;
693       }
694     if(box.type == JP2_CDEF && !jp2->ignore_pclr_cmap_cdef)
695       {
696       if( !jp2_read_cdef(jp2, cio, &box, color))
697         {
698         if (box.length <= 8) return OPJ_FALSE;
699         cio_seek(cio, box.init_pos + 8);
700         cio_skip(cio, box.length - 8);
701         }
702       if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE;
703       continue;
704       }
705     if(box.type == JP2_PCLR && !jp2->ignore_pclr_cmap_cdef)
706       {
707       if( !jp2_read_pclr(jp2, cio, &box, color))
708         {
709         if (box.length <= 8) return OPJ_FALSE;
710         cio_seek(cio, box.init_pos + 8);
711         cio_skip(cio, box.length - 8);
712         }
713       if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE;
714       continue;
715       }
716     if(box.type == JP2_CMAP && !jp2->ignore_pclr_cmap_cdef)
717       {
718       if( !jp2_read_cmap(jp2, cio, &box, color))
719         {
720         if (box.length <= 8) return OPJ_FALSE;
721         cio_seek(cio, box.init_pos + 8);
722         cio_skip(cio, box.length - 8);
723         }
724       if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE;
725       continue;
726       }
727     if (box.length <= 8) return OPJ_FALSE;
728     cio_seek(cio, box.init_pos + 8);
729     cio_skip(cio, box.length - 8);
730     if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE;
731
732     }/* while(cio_tell(cio) < box_end) */
733
734   cio_seek(cio, jp2h_end);
735
736   /* Part 1, I.5.3.3 : 'must contain at least one' */
737   return (color->jp2_has_colr == 1);
738
739 }/* jp2_read_jp2h() */
740
741 opj_image_t* opj_jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio, 
742         opj_codestream_info_t *cstr_info) 
743 {
744         opj_common_ptr cinfo;
745         opj_image_t *image = NULL;
746         opj_jp2_color_t color;
747
748         if(!jp2 || !cio) 
749    {
750         return NULL;
751    }
752         memset(&color, 0, sizeof(opj_jp2_color_t));
753         cinfo = jp2->cinfo;
754
755 /* JP2 decoding */
756         if(!jp2_read_struct(jp2, cio, &color)) 
757    {
758         free_color_data(&color);
759         opj_event_msg(cinfo, EVT_ERROR, "Failed to decode jp2 structure\n");
760         return NULL;
761    }
762
763 /* J2K decoding */
764         image = j2k_decode(jp2->j2k, cio, cstr_info);
765
766         if(!image) 
767    {
768         free_color_data(&color);
769         opj_event_msg(cinfo, EVT_ERROR, "Failed to decode J2K image\n");
770         return NULL;
771    }
772    
773     if (!jp2->ignore_pclr_cmap_cdef){
774
775     /* Set Image Color Space */
776         if (jp2->enumcs == 16)
777                 image->color_space = CLRSPC_SRGB;
778         else if (jp2->enumcs == 17)
779                 image->color_space = CLRSPC_GRAY;
780         else if (jp2->enumcs == 18)
781                 image->color_space = CLRSPC_SYCC;
782         else
783                 image->color_space = CLRSPC_UNKNOWN;
784
785         if(color.jp2_cdef)
786    {
787         jp2_apply_cdef(image, &color);
788    }
789         if(color.jp2_pclr)
790    {
791 /* Part 1, I.5.3.4: Either both or none : */
792         if( !color.jp2_pclr->cmap) 
793          jp2_free_pclr(&color);
794         else
795          jp2_apply_pclr(&color, image, cinfo);
796    }
797         if(color.icc_profile_buf)
798    {
799         image->icc_profile_buf = color.icc_profile_buf;
800         color.icc_profile_buf = NULL;
801         image->icc_profile_len = color.icc_profile_len;
802    }
803    }
804    
805         return image;
806
807 }/* opj_jp2_decode() */
808
809
810 void jp2_write_jp2h(opj_jp2_t *jp2, opj_cio_t *cio) {
811         opj_jp2_box_t box;
812
813         box.init_pos = cio_tell(cio);
814         cio_skip(cio, 4);
815         cio_write(cio, JP2_JP2H, 4);    /* JP2H */
816
817         jp2_write_ihdr(jp2, cio);
818
819         if (jp2->bpc == 255) {
820                 jp2_write_bpcc(jp2, cio);
821         }
822         jp2_write_colr(jp2, cio);
823
824         box.length = cio_tell(cio) - box.init_pos;
825         cio_seek(cio, box.init_pos);
826         cio_write(cio, box.length, 4);  /* L */
827         cio_seek(cio, box.init_pos + box.length);
828 }
829
830 static void jp2_write_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) {
831         unsigned int i;
832         opj_jp2_box_t box;
833
834         box.init_pos = cio_tell(cio);
835         cio_skip(cio, 4);
836         cio_write(cio, JP2_FTYP, 4);            /* FTYP */
837
838         cio_write(cio, jp2->brand, 4);          /* BR */
839         cio_write(cio, jp2->minversion, 4);     /* MinV */
840
841         for (i = 0; i < jp2->numcl; i++) {
842                 cio_write(cio, jp2->cl[i], 4);  /* CL */
843         }
844
845         box.length = cio_tell(cio) - box.init_pos;
846         cio_seek(cio, box.init_pos);
847         cio_write(cio, box.length, 4);  /* L */
848         cio_seek(cio, box.init_pos + box.length);
849 }
850
851 static opj_bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) {
852         int i;
853         opj_jp2_box_t box;
854
855         opj_common_ptr cinfo = jp2->cinfo;
856
857   if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) {
858     opj_event_msg(cinfo, EVT_ERROR, "Failed to read boxhdr\n");
859     return OPJ_FALSE;
860   }
861         if (JP2_FTYP != box.type) {
862                 opj_event_msg(cinfo, EVT_ERROR, "Expected FTYP Marker\n");
863                 return OPJ_FALSE;
864         }
865
866         jp2->brand = cio_read(cio, 4);          /* BR */
867         jp2->minversion = cio_read(cio, 4);     /* MinV */
868         jp2->numcl = (box.length - 16) / 4;
869         jp2->cl = (unsigned int *) opj_malloc(jp2->numcl * sizeof(unsigned int));
870
871         for (i = 0; i < (int)jp2->numcl; i++) {
872                 jp2->cl[i] = cio_read(cio, 4);  /* CLi */
873         }
874
875         if (cio_tell(cio) - box.init_pos != box.length) {
876                 opj_event_msg(cinfo, EVT_ERROR, "Error with FTYP Box\n");
877                 return OPJ_FALSE;
878         }
879
880         return OPJ_TRUE;
881 }
882
883 static int jp2_write_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) {
884         unsigned int j2k_codestream_offset, j2k_codestream_length;
885         opj_jp2_box_t box;
886
887         opj_j2k_t *j2k = jp2->j2k;
888
889         box.init_pos = cio_tell(cio);
890         cio_skip(cio, 4);
891         cio_write(cio, JP2_JP2C, 4);    /* JP2C */
892
893         /* J2K encoding */
894         j2k_codestream_offset = cio_tell(cio);
895         if(!j2k_encode(j2k, cio, image, cstr_info)) {
896                 opj_event_msg(j2k->cinfo, EVT_ERROR, "Failed to encode image\n");
897                 return 0;
898         }
899         j2k_codestream_length = cio_tell(cio) - j2k_codestream_offset;
900
901         jp2->j2k_codestream_offset = j2k_codestream_offset;
902         jp2->j2k_codestream_length = j2k_codestream_length;
903
904         box.length = 8 + jp2->j2k_codestream_length;
905         cio_seek(cio, box.init_pos);
906         cio_write(cio, box.length, 4);  /* L */
907         cio_seek(cio, box.init_pos + box.length);
908
909         return box.length;
910 }
911
912 static opj_bool jp2_read_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, unsigned int *j2k_codestream_length, unsigned int *j2k_codestream_offset) {
913         opj_jp2_box_t box;
914
915         opj_common_ptr cinfo = jp2->cinfo;
916
917   if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) {
918     opj_event_msg(cinfo, EVT_ERROR, "Failed to read boxhdr\n");
919     return OPJ_FALSE;
920   }
921         do {
922                 if(JP2_JP2C != box.type) {
923                         if (box.length <= 8) return OPJ_FALSE;
924                         cio_skip(cio, box.length - 8);
925                         if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) return OPJ_FALSE;
926                 }
927         } while(JP2_JP2C != box.type);
928
929         *j2k_codestream_offset = cio_tell(cio);
930         if (box.length <= 8) return OPJ_FALSE;
931         *j2k_codestream_length = box.length - 8;
932
933         return OPJ_TRUE;
934 }
935
936 static void jp2_write_jp(opj_cio_t *cio) {
937         opj_jp2_box_t box;
938
939         box.init_pos = cio_tell(cio);
940         cio_skip(cio, 4);
941         cio_write(cio, JP2_JP, 4);              /* JP2 signature */
942         cio_write(cio, 0x0d0a870a, 4);
943
944         box.length = cio_tell(cio) - box.init_pos;
945         cio_seek(cio, box.init_pos);
946         cio_write(cio, box.length, 4);  /* L */
947         cio_seek(cio, box.init_pos + box.length);
948 }
949
950 static opj_bool jp2_read_jp(opj_jp2_t *jp2, opj_cio_t *cio) {
951         opj_jp2_box_t box;
952
953         opj_common_ptr cinfo = jp2->cinfo;
954
955   if( jp2_read_boxhdr(cinfo, cio, &box) == OPJ_FALSE ) {
956     opj_event_msg(cinfo, EVT_ERROR, "Failed to read boxhdr\n");
957     return OPJ_FALSE;
958   }
959         if (JP2_JP != box.type) {
960                 opj_event_msg(cinfo, EVT_ERROR, "Expected JP Marker\n");
961                 return OPJ_FALSE;
962         }
963         if (0x0d0a870a != cio_read(cio, 4)) {
964                 opj_event_msg(cinfo, EVT_ERROR, "Error with JP Marker\n");
965                 return OPJ_FALSE;
966         }
967         if (cio_tell(cio) - box.init_pos != box.length) {
968                 opj_event_msg(cinfo, EVT_ERROR, "Error with JP Box size\n");
969                 return OPJ_FALSE;
970         }
971
972         return OPJ_TRUE;
973 }
974
975
976 static opj_bool jp2_read_struct(opj_jp2_t *jp2, opj_cio_t *cio,
977         opj_jp2_color_t *color) {
978         if (!jp2_read_jp(jp2, cio))
979                 return OPJ_FALSE;
980         if (!jp2_read_ftyp(jp2, cio))
981                 return OPJ_FALSE;
982         if (!jp2_read_jp2h(jp2, cio, color))
983                 return OPJ_FALSE;
984         if (!jp2_read_jp2c(jp2, cio, &jp2->j2k_codestream_length, &jp2->j2k_codestream_offset))
985                 return OPJ_FALSE;
986         
987         return OPJ_TRUE;
988 }
989
990
991 static int write_fidx( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_cio_t *cio)
992 {  
993   int len, lenp;
994   
995   lenp = cio_tell( cio);
996   cio_skip( cio, 4);              /* L [at the end] */
997   cio_write( cio, JPIP_FIDX, 4);  /* IPTR           */
998   
999   write_prxy( offset_jp2c, length_jp2c, offset_idx, length_idx, cio);
1000
1001   len = cio_tell( cio)-lenp;
1002   cio_seek( cio, lenp);
1003   cio_write( cio, len, 4);        /* L              */
1004   cio_seek( cio, lenp+len);  
1005
1006   return len;
1007 }
1008
1009 static void write_prxy( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_cio_t *cio)
1010 {
1011   int len, lenp;
1012
1013   lenp = cio_tell( cio);
1014   cio_skip( cio, 4);              /* L [at the end] */
1015   cio_write( cio, JPIP_PRXY, 4);  /* IPTR           */
1016   
1017   cio_write( cio, offset_jp2c, 8); /* OOFF           */
1018   cio_write( cio, length_jp2c, 4); /* OBH part 1     */
1019   cio_write( cio, JP2_JP2C, 4);        /* OBH part 2     */
1020   
1021   cio_write( cio, 1,1);           /* NI             */
1022
1023   cio_write( cio, offset_idx, 8);  /* IOFF           */
1024   cio_write( cio, length_idx, 4);  /* IBH part 1     */
1025   cio_write( cio, JPIP_CIDX, 4);   /* IBH part 2     */
1026
1027   len = cio_tell( cio)-lenp;
1028   cio_seek( cio, lenp);
1029   cio_write( cio, len, 4);        /* L              */
1030   cio_seek( cio, lenp+len);
1031 }
1032
1033 static void write_iptr( int offset, int length, opj_cio_t *cio)
1034 {
1035   int len, lenp;
1036   
1037   lenp = cio_tell( cio);
1038   cio_skip( cio, 4);              /* L [at the end] */
1039   cio_write( cio, JPIP_IPTR, 4);  /* IPTR           */
1040   
1041   cio_write( cio, offset, 8);
1042   cio_write( cio, length, 8);
1043
1044   len = cio_tell( cio)-lenp;
1045   cio_seek( cio, lenp);
1046   cio_write( cio, len, 4);        /* L             */
1047   cio_seek( cio, lenp+len);
1048 }
1049
1050
1051 /* ----------------------------------------------------------------------- */
1052 /* JP2 decoder interface                                             */
1053 /* ----------------------------------------------------------------------- */
1054
1055 opj_jp2_t* jp2_create_decompress(opj_common_ptr cinfo) {
1056         opj_jp2_t *jp2 = (opj_jp2_t*) opj_calloc(1, sizeof(opj_jp2_t));
1057         if(jp2) {
1058                 jp2->cinfo = cinfo;
1059                 /* create the J2K codec */
1060                 jp2->j2k = j2k_create_decompress(cinfo);
1061                 if(jp2->j2k == NULL) {
1062                         jp2_destroy_decompress(jp2);
1063                         return NULL;
1064                 }
1065         }
1066         return jp2;
1067 }
1068
1069 void jp2_destroy_decompress(opj_jp2_t *jp2) {
1070         if(jp2) {
1071                 /* destroy the J2K codec */
1072                 j2k_destroy_decompress(jp2->j2k);
1073
1074                 if(jp2->comps) {
1075                         opj_free(jp2->comps);
1076                 }
1077                 if(jp2->cl) {
1078                         opj_free(jp2->cl);
1079                 }
1080                 opj_free(jp2);
1081         }
1082 }
1083
1084 void jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters) {
1085         /* setup the J2K codec */
1086         j2k_setup_decoder(jp2->j2k, parameters);
1087         /* further JP2 initializations go here */
1088         jp2->ignore_pclr_cmap_cdef = parameters->flags & OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG;
1089 }
1090
1091 /* ----------------------------------------------------------------------- */
1092 /* JP2 encoder interface                                             */
1093 /* ----------------------------------------------------------------------- */
1094
1095 opj_jp2_t* jp2_create_compress(opj_common_ptr cinfo) {
1096         opj_jp2_t *jp2 = (opj_jp2_t*)opj_malloc(sizeof(opj_jp2_t));
1097         if(jp2) {
1098                 memset(jp2, 0, sizeof(opj_jp2_t));
1099                 jp2->cinfo = cinfo;
1100                 /* create the J2K codec */
1101                 jp2->j2k = j2k_create_compress(cinfo);
1102                 if(jp2->j2k == NULL) {
1103                         jp2_destroy_compress(jp2);
1104                         return NULL;
1105                 }
1106         }
1107         return jp2;
1108 }
1109
1110 void jp2_destroy_compress(opj_jp2_t *jp2) {
1111         if(jp2) {
1112                 /* destroy the J2K codec */
1113                 j2k_destroy_compress(jp2->j2k);
1114
1115                 if(jp2->comps) {
1116                         opj_free(jp2->comps);
1117                 }
1118                 if(jp2->cl) {
1119                         opj_free(jp2->cl);
1120                 }
1121                 opj_free(jp2);
1122         }
1123 }
1124
1125 void jp2_setup_encoder(opj_jp2_t *jp2, opj_cparameters_t *parameters, opj_image_t *image) {
1126         int i;
1127         int depth_0, sign;
1128
1129         if(!jp2 || !parameters || !image)
1130                 return;
1131
1132         /* setup the J2K codec */
1133         /* ------------------- */
1134
1135         /* Check if number of components respects standard */
1136         if (image->numcomps < 1 || image->numcomps > 16384) {
1137                 opj_event_msg(jp2->cinfo, EVT_ERROR, "Invalid number of components specified while setting up JP2 encoder\n");
1138                 return;
1139         }
1140
1141         j2k_setup_encoder(jp2->j2k, parameters, image);
1142
1143         /* setup the JP2 codec */
1144         /* ------------------- */
1145         
1146         /* Profile box */
1147
1148         jp2->brand = JP2_JP2;   /* BR */
1149         jp2->minversion = 0;    /* MinV */
1150         jp2->numcl = 1;
1151         jp2->cl = (unsigned int*) opj_malloc(jp2->numcl * sizeof(unsigned int));
1152         jp2->cl[0] = JP2_JP2;   /* CL0 : JP2 */
1153
1154         /* Image Header box */
1155
1156         jp2->numcomps = image->numcomps;        /* NC */
1157         jp2->comps = (opj_jp2_comps_t*) opj_malloc(jp2->numcomps * sizeof(opj_jp2_comps_t));
1158         jp2->h = image->y1 - image->y0;         /* HEIGHT */
1159         jp2->w = image->x1 - image->x0;         /* WIDTH */
1160         /* BPC */
1161         depth_0 = image->comps[0].prec - 1;
1162         sign = image->comps[0].sgnd;
1163         jp2->bpc = depth_0 + (sign << 7);
1164         for (i = 1; i < image->numcomps; i++) {
1165                 int depth = image->comps[i].prec - 1;
1166                 sign = image->comps[i].sgnd;
1167                 if (depth_0 != depth)
1168                         jp2->bpc = 255;
1169         }
1170         jp2->C = 7;                     /* C : Always 7 */
1171         jp2->UnkC = 0;          /* UnkC, colorspace specified in colr box */
1172         jp2->IPR = 0;           /* IPR, no intellectual property */
1173         
1174         /* BitsPerComponent box */
1175
1176         for (i = 0; i < image->numcomps; i++) {
1177                 jp2->comps[i].bpcc = image->comps[i].prec - 1 + (image->comps[i].sgnd << 7);
1178         }
1179         jp2->meth = 1;
1180         if (image->color_space == 1)
1181                 jp2->enumcs = 16;       /* sRGB as defined by IEC 61966-2.1 */
1182         else if (image->color_space == 2)
1183                 jp2->enumcs = 17;       /* greyscale */
1184         else if (image->color_space == 3)
1185                 jp2->enumcs = 18;       /* YUV */
1186         jp2->precedence = 0;    /* PRECEDENCE */
1187         jp2->approx = 0;                /* APPROX */
1188         
1189         jp2->jpip_on = parameters->jpip_on;
1190 }
1191
1192 opj_bool opj_jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) {
1193
1194         int pos_iptr, pos_cidx, pos_jp2c, len_jp2c, len_cidx, end_pos, pos_fidx, len_fidx;
1195         pos_jp2c = pos_iptr = -1; /* remove a warning */
1196
1197         /* JP2 encoding */
1198
1199         /* JPEG 2000 Signature box */
1200         jp2_write_jp(cio);
1201         /* File Type box */
1202         jp2_write_ftyp(jp2, cio);
1203         /* JP2 Header box */
1204         jp2_write_jp2h(jp2, cio);
1205
1206         if( jp2->jpip_on){
1207           pos_iptr = cio_tell( cio);
1208           cio_skip( cio, 24); /* IPTR further ! */
1209           
1210           pos_jp2c = cio_tell( cio);
1211         }
1212
1213         /* J2K encoding */
1214         if(!(len_jp2c = jp2_write_jp2c( jp2, cio, image, cstr_info))){
1215             opj_event_msg(jp2->cinfo, EVT_ERROR, "Failed to encode image\n");
1216             return OPJ_FALSE;
1217         }
1218
1219         if( jp2->jpip_on){
1220           pos_cidx = cio_tell( cio);
1221           
1222           len_cidx = write_cidx( pos_jp2c+8, cio, image, *cstr_info, len_jp2c-8);
1223           
1224           pos_fidx = cio_tell( cio);
1225           len_fidx = write_fidx( pos_jp2c, len_jp2c, pos_cidx, len_cidx, cio);
1226           
1227           end_pos = cio_tell( cio);
1228           
1229           cio_seek( cio, pos_iptr);
1230           write_iptr( pos_fidx, len_fidx, cio);
1231           
1232           cio_seek( cio, end_pos);
1233         }
1234
1235         return OPJ_TRUE;
1236 }