[trunk] rename public symbols with OPJ_ prefix (enum part)
[openjpeg.git] / src / lib / openjp2 / 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 #define BOX_SIZE        1024
38
39 /** @name Local static functions */
40 /*@{*/
41
42 /*static void jp2_write_url(opj_cio_t *cio, char *Idx_file);*/
43
44 /**
45  * Reads a IHDR box - Image Header box
46  *
47  * @param       p_image_header_data                     pointer to actual data (already read from file)
48  * @param       jp2                                                     the jpeg2000 file codec.
49  * @param       p_image_header_size                     the size of the image header
50  * @param       p_manager                                       the user event manager.
51  *
52  * @return      true if the image header is valid, false else.
53  */
54 static opj_bool opj_jp2_read_ihdr(  opj_jp2_t *jp2,
55                                     OPJ_BYTE *p_image_header_data,
56                                     OPJ_UINT32 p_image_header_size,
57                                     opj_event_mgr_t * p_manager );
58
59 /**
60  * Writes the Image Header box - Image Header box.
61  *
62  * @param jp2                                   jpeg2000 file codec.
63  * @param p_nb_bytes_written    pointer to store the nb of bytes written by the function.
64  *
65  * @return      the data being copied.
66 */
67 static OPJ_BYTE * opj_jp2_write_ihdr(opj_jp2_t *jp2,
68                                      OPJ_UINT32 * p_nb_bytes_written );
69
70 /**
71  * Writes the Bit per Component box.
72  *
73  * @param       jp2                                             jpeg2000 file codec.
74  * @param       p_nb_bytes_written              pointer to store the nb of bytes written by the function.
75  *
76  * @return      the data being copied.
77 */
78 static OPJ_BYTE * opj_jp2_write_bpcc(   opj_jp2_t *jp2,
79                                                                         OPJ_UINT32 * p_nb_bytes_written );
80
81 /**
82  * Reads a Bit per Component box.
83  *
84  * @param       p_bpc_header_data                       pointer to actual data (already read from file)
85  * @param       jp2                                                     the jpeg2000 file codec.
86  * @param       p_bpc_header_size                       the size of the bpc header
87  * @param       p_manager                                       the user event manager.
88  *
89  * @return      true if the bpc header is valid, fale else.
90  */
91 static opj_bool opj_jp2_read_bpcc(  opj_jp2_t *jp2,
92                                     OPJ_BYTE * p_bpc_header_data,
93                                     OPJ_UINT32 p_bpc_header_size,
94                                     opj_event_mgr_t * p_manager );
95
96 static opj_bool opj_jp2_read_cdef(      opj_jp2_t * jp2,
97                                     OPJ_BYTE * p_cdef_header_data,
98                                                                         OPJ_UINT32 p_cdef_header_size,
99                                                                         opj_event_mgr_t * p_manager );
100
101 static void opj_jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color);
102
103 /**
104  * Writes the Colour Specification box.
105  *
106  * @param jp2                                   jpeg2000 file codec.
107  * @param p_nb_bytes_written    pointer to store the nb of bytes written by the function.
108  *
109  * @return      the data being copied.
110 */
111 static OPJ_BYTE * opj_jp2_write_colr(   opj_jp2_t *jp2,
112                                                                             OPJ_UINT32 * p_nb_bytes_written );
113
114 /**
115  * Writes a FTYP box - File type box
116  *
117  * @param       cio                     the stream to write data to.
118  * @param       jp2                     the jpeg2000 file codec.
119  * @param       p_manager       the user event manager.
120  *
121  * @return      true if writing was successful.
122  */
123 static opj_bool opj_jp2_write_ftyp(     opj_jp2_t *jp2,
124                                                                         opj_stream_private_t *cio,
125                                                                         opj_event_mgr_t * p_manager );
126
127 /**
128  * Reads a a FTYP box - File type box
129  *
130  * @param       p_header_data   the data contained in the FTYP box.
131  * @param       jp2                             the jpeg2000 file codec.
132  * @param       p_header_size   the size of the data contained in the FTYP box.
133  * @param       p_manager               the user event manager.
134  *
135  * @return true if the FTYP box is valid.
136  */
137 static opj_bool opj_jp2_read_ftyp(      opj_jp2_t *jp2,
138                                                                         OPJ_BYTE * p_header_data,
139                                                                         OPJ_UINT32 p_header_size,
140                                                                         opj_event_mgr_t * p_manager );
141
142 opj_bool opj_jp2_skip_jp2c(     opj_jp2_t *jp2,
143                                                     opj_stream_private_t *cio,
144                                                     opj_event_mgr_t * p_manager );
145
146 /**
147  * Reads the Jpeg2000 file Header box - JP2 Header box (warning, this is a super box).
148  *
149  * @param       p_header_data   the data contained in the file header box.
150  * @param       jp2                             the jpeg2000 file codec.
151  * @param       p_header_size   the size of the data contained in the file header box.
152  * @param       p_manager               the user event manager.
153  *
154  * @return true if the JP2 Header box was successfully reconized.
155 */
156 static opj_bool opj_jp2_read_jp2h(  opj_jp2_t *jp2,
157                                     OPJ_BYTE *p_header_data,
158                                     OPJ_UINT32 p_header_size,
159                                     opj_event_mgr_t * p_manager );
160
161 /**
162  * Writes the Jpeg2000 codestream Header box - JP2C Header box. This function must be called AFTER the coding has been done.
163  *
164  * @param       cio                     the stream to write data to.
165  * @param       jp2                     the jpeg2000 file codec.
166  * @param       p_manager       user event manager.
167  *
168  * @return true if writing was successful.
169 */
170 static opj_bool opj_jp2_write_jp2c(     opj_jp2_t *jp2,
171                                                                     opj_stream_private_t *cio,
172                                                                     opj_event_mgr_t * p_manager );
173
174 #ifdef USE_JPIP
175 /**
176  * Write index Finder box
177  * @param cio     the stream to write to.
178  * @param       jp2                     the jpeg2000 file codec.
179  * @param       p_manager       user event manager.
180 */
181 static opj_bool opj_jpip_write_iptr(    opj_jp2_t *jp2,
182                                                                     opj_stream_private_t *cio,
183                                                                     opj_event_mgr_t * p_manager );
184
185 /**
186  * Write index Finder box
187  * @param cio     the stream to write to.
188  * @param       jp2                     the jpeg2000 file codec.
189  * @param       p_manager       user event manager.
190  */
191 static opj_bool opj_jpip_write_cidx(opj_jp2_t *jp2,
192   opj_stream_private_t *cio,
193   opj_event_mgr_t * p_manager );
194
195 /**
196  * Write file Index (superbox)
197  * @param cio     the stream to write to.
198  * @param       jp2                     the jpeg2000 file codec.
199  * @param       p_manager       user event manager.
200  */
201 static opj_bool opj_jpip_write_fidx(opj_jp2_t *jp2,
202   opj_stream_private_t *cio,
203   opj_event_mgr_t * p_manager );
204 #endif /* USE_JPIP */
205
206 /**
207  * Reads a jpeg2000 file signature box.
208  *
209  * @param       p_header_data   the data contained in the signature box.
210  * @param       jp2                             the jpeg2000 file codec.
211  * @param       p_header_size   the size of the data contained in the signature box.
212  * @param       p_manager               the user event manager.
213  *
214  * @return true if the file signature box is valid.
215  */
216 static opj_bool opj_jp2_read_jp(opj_jp2_t *jp2,
217                                 OPJ_BYTE * p_header_data,
218                                 OPJ_UINT32 p_header_size,
219                                 opj_event_mgr_t * p_manager);
220
221 /**
222  * Writes a jpeg2000 file signature box.
223  *
224  * @param cio the stream to write data to.
225  * @param       jp2                     the jpeg2000 file codec.
226  * @param p_manager the user event manager.
227  *
228  * @return true if writing was successful.
229  */
230 static opj_bool opj_jp2_write_jp(       opj_jp2_t *jp2,
231                                                     opj_stream_private_t *cio,
232                                                         opj_event_mgr_t * p_manager );
233
234 /**
235 Apply collected palette data
236 @param color Collector for profile, cdef and pclr data
237 @param image
238 */
239 static void opj_jp2_apply_pclr(opj_image_t *image, opj_jp2_color_t *color);
240
241 static void opj_jp2_free_pclr(opj_jp2_color_t *color);
242
243 /**
244  * Collect palette data
245  *
246  * @param jp2 JP2 handle
247  * @param p_pclr_header_data    FIXME DOC
248  * @param p_pclr_header_size    FIXME DOC
249  * @param p_manager
250  *
251  * @return Returns true if successful, returns false otherwise
252 */
253 static opj_bool opj_jp2_read_pclr(      opj_jp2_t *jp2,
254                                     OPJ_BYTE * p_pclr_header_data,
255                                     OPJ_UINT32 p_pclr_header_size,
256                                     opj_event_mgr_t * p_manager );
257
258 /**
259  * Collect component mapping data
260  *
261  * @param jp2                 JP2 handle
262  * @param p_cmap_header_data  FIXME DOC
263  * @param p_cmap_header_size  FIXME DOC
264  * @param p_manager           FIXME DOC
265  *
266  * @return Returns true if successful, returns false otherwise
267 */
268
269 static opj_bool opj_jp2_read_cmap(      opj_jp2_t * jp2,
270                                     OPJ_BYTE * p_cmap_header_data,
271                                     OPJ_UINT32 p_cmap_header_size,
272                                     opj_event_mgr_t * p_manager );
273
274 /**
275  * Reads the Color Specification box.
276  *
277  * @param       p_colr_header_data                      pointer to actual data (already read from file)
278  * @param       jp2                                                     the jpeg2000 file codec.
279  * @param       p_colr_header_size                      the size of the color header
280  * @param       p_manager                                       the user event manager.
281  *
282  * @return      true if the bpc header is valid, fale else.
283 */
284 static opj_bool opj_jp2_read_colr(  opj_jp2_t *jp2,
285                                     OPJ_BYTE * p_colr_header_data,
286                                     OPJ_UINT32 p_colr_header_size,
287                                     opj_event_mgr_t * p_manager );
288
289 /*@}*/
290
291 /*@}*/
292
293 /**
294  * Sets up the procedures to do on writing header after the codestream.
295  * Developpers wanting to extend the library can add their own writing procedures.
296  */
297 static void opj_jp2_setup_end_header_writing (opj_jp2_t *jp2);
298
299 /**
300  * Sets up the procedures to do on reading header after the codestream.
301  * Developpers wanting to extend the library can add their own writing procedures.
302  */
303 static void opj_jp2_setup_end_header_reading (opj_jp2_t *jp2);
304
305 /**
306  * Reads a jpeg2000 file header structure.
307  *
308  * @param jp2 the jpeg2000 file header structure.
309  * @param stream the stream to read data from.
310  * @param p_manager the user event manager.
311  *
312  * @return true if the box is valid.
313  */
314 static opj_bool opj_jp2_read_header_procedure(  opj_jp2_t *jp2,
315                                                 opj_stream_private_t *stream,
316                                                 opj_event_mgr_t * p_manager );
317
318 /**
319  * Excutes the given procedures on the given codec.
320  *
321  * @param       p_procedure_list        the list of procedures to execute
322  * @param       jp2                                     the jpeg2000 file codec to execute the procedures on.
323  * @param       stream                                  the stream to execute the procedures on.
324  * @param       p_manager                       the user manager.
325  *
326  * @return      true                            if all the procedures were successfully executed.
327  */
328 static opj_bool opj_jp2_exec (  opj_jp2_t * jp2,
329                                 opj_procedure_list_t * p_procedure_list,
330                                 opj_stream_private_t *stream,
331                                 opj_event_mgr_t * p_manager );
332
333 /**
334  * Reads a box header. The box is the way data is packed inside a jpeg2000 file structure.
335  *
336  * @param       cio                                             the input stream to read data from.
337  * @param       box                                             the box structure to fill.
338  * @param       p_number_bytes_read             pointer to an int that will store the number of bytes read from the stream (shoul usually be 2).
339  * @param       p_manager                               user event manager.
340  *
341  * @return      true if the box is reconized, false otherwise
342 */
343 static opj_bool opj_jp2_read_boxhdr(opj_jp2_box_t *box,
344                                     OPJ_UINT32 * p_number_bytes_read,
345                                     opj_stream_private_t *cio,
346                                     opj_event_mgr_t * p_manager);
347
348 /**
349  * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
350  * are valid. Developpers wanting to extend the library can add their own validation procedures.
351  */
352 static void opj_jp2_setup_encoding_validation (opj_jp2_t *jp2);
353
354 /**
355  * Sets up the procedures to do on writing header. Developpers wanting to extend the library can add their own writing procedures.
356  */
357 static void opj_jp2_setup_header_writing (opj_jp2_t *jp2);
358
359 opj_bool opj_jp2_default_validation (   opj_jp2_t * jp2,
360                                         opj_stream_private_t *cio,
361                                         opj_event_mgr_t * p_manager );
362
363 /**
364  * Finds the image execution function related to the given box id.
365  *
366  * @param       p_id    the id of the handler to fetch.
367  *
368  * @return      the given handler or NULL if it could not be found.
369  */
370 static const opj_jp2_header_handler_t * opj_jp2_img_find_handler (OPJ_UINT32 p_id);
371
372 /**
373  * Finds the execution function related to the given box id.
374  *
375  * @param       p_id    the id of the handler to fetch.
376  *
377  * @return      the given handler or NULL if it could not be found.
378  */
379 static const opj_jp2_header_handler_t * opj_jp2_find_handler (OPJ_UINT32 p_id );
380
381 const opj_jp2_header_handler_t jp2_header [] =
382 {
383         {JP2_JP,opj_jp2_read_jp},
384         {JP2_FTYP,opj_jp2_read_ftyp},
385         {JP2_JP2H,opj_jp2_read_jp2h}
386 };
387
388 const opj_jp2_header_handler_t jp2_img_header [] =
389 {
390         {JP2_IHDR,opj_jp2_read_ihdr},
391         {JP2_COLR,opj_jp2_read_colr},
392         {JP2_BPCC,opj_jp2_read_bpcc},
393         {JP2_PCLR,opj_jp2_read_pclr},
394         {JP2_CMAP,opj_jp2_read_cmap},
395         {JP2_CDEF,opj_jp2_read_cdef}
396
397 };
398
399 /**
400  * Reads a box header. The box is the way data is packed inside a jpeg2000 file structure. Data is read from a character string
401  *
402  * @param       box                                             the box structure to fill.
403  * @param       p_data                                  the character string to read data from.
404  * @param       p_number_bytes_read             pointer to an int that will store the number of bytes read from the stream (shoul usually be 2).
405  * @param       p_box_max_size                  the maximum number of bytes in the box.
406  * @param       p_manager         FIXME DOC
407  *
408  * @return      true if the box is reconized, false otherwise
409 */
410 static opj_bool opj_jp2_read_boxhdr_char(   opj_jp2_box_t *box,
411                                             OPJ_BYTE * p_data,
412                                             OPJ_UINT32 * p_number_bytes_read,
413                                             OPJ_UINT32 p_box_max_size,
414                                             opj_event_mgr_t * p_manager );
415
416 /**
417  * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
418  * are valid. Developpers wanting to extend the library can add their own validation procedures.
419  */
420 static void opj_jp2_setup_decoding_validation (opj_jp2_t *jp2);
421
422 /**
423  * Sets up the procedures to do on reading header.
424  * Developpers wanting to extend the library can add their own writing procedures.
425  */
426 static void opj_jp2_setup_header_reading (opj_jp2_t *jp2);
427
428 /* ----------------------------------------------------------------------- */
429
430  opj_bool opj_jp2_read_boxhdr(opj_jp2_box_t *box,
431                                     OPJ_UINT32 * p_number_bytes_read,
432                                     opj_stream_private_t *cio,
433                                     opj_event_mgr_t * p_manager
434                                     )
435 {
436         /* read header from file */
437         OPJ_BYTE l_data_header [8];
438
439         /* preconditions */
440         assert(cio != 00);
441         assert(box != 00);
442         assert(p_number_bytes_read != 00);
443         assert(p_manager != 00);
444
445         *p_number_bytes_read = opj_stream_read_data(cio,l_data_header,8,p_manager);
446         if (*p_number_bytes_read != 8) {
447                 return OPJ_FALSE;
448         }
449
450         /* process read data */
451         opj_read_bytes(l_data_header,&(box->length), 4);
452         opj_read_bytes(l_data_header+4,&(box->type), 4);
453
454         /* do we have a "special very large box ?" */
455         /* read then the XLBox */
456         if (box->length == 1) {
457                 OPJ_UINT32 l_xl_part_size;
458
459                 OPJ_UINT32 l_nb_bytes_read = opj_stream_read_data(cio,l_data_header,8,p_manager);
460                 if (l_nb_bytes_read != 8) {
461                         if (l_nb_bytes_read > 0) {
462                                 *p_number_bytes_read += l_nb_bytes_read;
463                         }
464
465                         return OPJ_FALSE;
466                 }
467
468                 opj_read_bytes(l_data_header,&l_xl_part_size, 4);
469                 if (l_xl_part_size != 0) {
470                         opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box sizes higher than 2^32\n");
471                         return OPJ_FALSE;
472                 }
473                 opj_read_bytes(l_data_header,&(box->length), 4);
474         }
475         return OPJ_TRUE;
476 }
477
478 #if 0
479 static void jp2_write_url(opj_cio_t *cio, char *Idx_file) {
480         OPJ_UINT32 i;
481         opj_jp2_box_t box;
482
483         box.init_pos = cio_tell(cio);
484         cio_skip(cio, 4);
485         cio_write(cio, JP2_URL, 4);     /* DBTL */
486         cio_write(cio, 0, 1);           /* VERS */
487         cio_write(cio, 0, 3);           /* FLAG */
488
489         if(Idx_file) {
490                 for (i = 0; i < strlen(Idx_file); i++) {
491                         cio_write(cio, Idx_file[i], 1);
492                 }
493         }
494
495         box.length = cio_tell(cio) - box.init_pos;
496         cio_seek(cio, box.init_pos);
497         cio_write(cio, box.length, 4);  /* L */
498         cio_seek(cio, box.init_pos + box.length);
499 }
500 #endif
501
502 opj_bool opj_jp2_read_ihdr( opj_jp2_t *jp2,
503                             OPJ_BYTE *p_image_header_data,
504                             OPJ_UINT32 p_image_header_size,
505                             opj_event_mgr_t * p_manager )
506 {
507         /* preconditions */
508         assert(p_image_header_data != 00);
509         assert(jp2 != 00);
510         assert(p_manager != 00);
511
512         if (p_image_header_size != 14) {
513                 opj_event_msg(p_manager, EVT_ERROR, "Bad image header box (bad size)\n");
514                 return OPJ_FALSE;
515         }
516
517         opj_read_bytes(p_image_header_data,&(jp2->h),4);                        /* HEIGHT */
518         p_image_header_data += 4;
519         opj_read_bytes(p_image_header_data,&(jp2->w),4);                        /* WIDTH */
520         p_image_header_data += 4;
521         opj_read_bytes(p_image_header_data,&(jp2->numcomps),2);         /* NC */
522         p_image_header_data += 2;
523
524         /* allocate memory for components */
525         jp2->comps = (opj_jp2_comps_t*) opj_malloc(jp2->numcomps * sizeof(opj_jp2_comps_t));
526         if (jp2->comps == 0) {
527                 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle image header (ihdr)\n");
528                 return OPJ_FALSE;
529         }
530         memset(jp2->comps,0,jp2->numcomps * sizeof(opj_jp2_comps_t));
531
532         opj_read_bytes(p_image_header_data,&(jp2->bpc),1);                      /* BPC */
533         ++ p_image_header_data;
534
535         opj_read_bytes(p_image_header_data,&(jp2->C),1);                        /* C */
536         ++ p_image_header_data;
537
538         /* Should be equal to 7 cf. chapter about image header box of the norm */
539         if (jp2->C != 7){
540                 opj_event_msg(p_manager, EVT_INFO, "JP2 IHDR box: compression type indicate that the file is not a conforming JP2 file (%d) \n", jp2->C);
541         }
542
543         opj_read_bytes(p_image_header_data,&(jp2->UnkC),1);                     /* UnkC */
544         ++ p_image_header_data;
545         opj_read_bytes(p_image_header_data,&(jp2->IPR),1);                      /* IPR */
546         ++ p_image_header_data;
547
548         return OPJ_TRUE;
549 }
550
551 OPJ_BYTE * opj_jp2_write_ihdr(opj_jp2_t *jp2,
552                               OPJ_UINT32 * p_nb_bytes_written
553                               )
554 {
555         OPJ_BYTE * l_ihdr_data,* l_current_ihdr_ptr;
556         
557         /* preconditions */
558         assert(jp2 != 00);
559         assert(p_nb_bytes_written != 00);
560
561         /* default image header is 22 bytes wide */
562         l_ihdr_data = (OPJ_BYTE *) opj_malloc(22);
563         if (l_ihdr_data == 00) {
564                 return 00;
565         }
566         memset(l_ihdr_data,0,22);
567
568         l_current_ihdr_ptr = l_ihdr_data;
569         
570         opj_write_bytes(l_current_ihdr_ptr,22,4);                               /* write box size */
571         l_current_ihdr_ptr+=4;
572
573         opj_write_bytes(l_current_ihdr_ptr,JP2_IHDR, 4);                /* IHDR */
574         l_current_ihdr_ptr+=4;
575         
576         opj_write_bytes(l_current_ihdr_ptr,jp2->h, 4);          /* HEIGHT */
577         l_current_ihdr_ptr+=4;
578         
579         opj_write_bytes(l_current_ihdr_ptr, jp2->w, 4);         /* WIDTH */
580         l_current_ihdr_ptr+=4;
581         
582         opj_write_bytes(l_current_ihdr_ptr, jp2->numcomps, 2);          /* NC */
583         l_current_ihdr_ptr+=2;
584         
585         opj_write_bytes(l_current_ihdr_ptr, jp2->bpc, 1);               /* BPC */
586         ++l_current_ihdr_ptr;
587         
588         opj_write_bytes(l_current_ihdr_ptr, jp2->C, 1);         /* C : Always 7 */
589         ++l_current_ihdr_ptr;
590         
591         opj_write_bytes(l_current_ihdr_ptr, jp2->UnkC, 1);              /* UnkC, colorspace unknown */
592         ++l_current_ihdr_ptr;
593         
594         opj_write_bytes(l_current_ihdr_ptr, jp2->IPR, 1);               /* IPR, no intellectual property */
595         ++l_current_ihdr_ptr;
596         
597         *p_nb_bytes_written = 22;
598         
599         return l_ihdr_data;
600 }
601
602 OPJ_BYTE * opj_jp2_write_bpcc(  opj_jp2_t *jp2,
603                                                         OPJ_UINT32 * p_nb_bytes_written
604                                 )
605 {
606         OPJ_UINT32 i;
607         /* room for 8 bytes for box and 1 byte for each component */
608         OPJ_INT32 l_bpcc_size = 8 + jp2->numcomps;
609         OPJ_BYTE * l_bpcc_data,* l_current_bpcc_ptr;
610         
611         /* preconditions */
612         assert(jp2 != 00);
613         assert(p_nb_bytes_written != 00);
614
615         l_bpcc_data = (OPJ_BYTE *) opj_malloc(l_bpcc_size);
616         if (l_bpcc_data == 00) {
617                 return 00;
618         }
619         memset(l_bpcc_data,0,l_bpcc_size);
620
621         l_current_bpcc_ptr = l_bpcc_data;
622
623         opj_write_bytes(l_current_bpcc_ptr,l_bpcc_size,4);                              /* write box size */
624         l_current_bpcc_ptr += 4;
625         
626         opj_write_bytes(l_current_bpcc_ptr,JP2_BPCC,4);                                 /* BPCC */
627         l_current_bpcc_ptr += 4;
628
629         for (i = 0; i < jp2->numcomps; ++i)  {
630                 opj_write_bytes(l_current_bpcc_ptr, jp2->comps[i].bpcc, 1); /* write each component information */
631                 ++l_current_bpcc_ptr;
632         }
633
634         *p_nb_bytes_written = l_bpcc_size;
635         
636         return l_bpcc_data;
637 }
638
639 opj_bool opj_jp2_read_bpcc( opj_jp2_t *jp2,
640                             OPJ_BYTE * p_bpc_header_data,
641                             OPJ_UINT32 p_bpc_header_size,
642                             opj_event_mgr_t * p_manager
643                             )
644 {
645         OPJ_UINT32 i;
646
647         /* preconditions */
648         assert(p_bpc_header_data != 00);
649         assert(jp2 != 00);
650         assert(p_manager != 00);
651
652         
653         if (jp2->bpc != 255 ){
654                 opj_event_msg(p_manager, EVT_WARNING, "A BPCC header box is available although BPC given by the IHDR box (%d) indicate components bit depth is constant\n",jp2->bpc);
655         }
656
657         /* and length is relevant */
658         if (p_bpc_header_size != jp2->numcomps) {
659                 opj_event_msg(p_manager, EVT_ERROR, "Bad BPCC header box (bad size)\n");
660                 return OPJ_FALSE;
661         }
662
663         /* read info for each component */
664         for (i = 0; i < jp2->numcomps; ++i) {
665                 opj_read_bytes(p_bpc_header_data,&jp2->comps[i].bpcc ,1);       /* read each BPCC component */
666                 ++p_bpc_header_data;
667         }
668
669         return OPJ_TRUE;
670 }
671
672 OPJ_BYTE * opj_jp2_write_colr(  opj_jp2_t *jp2,
673                                                             OPJ_UINT32 * p_nb_bytes_written
674                                 )
675 {
676         /* room for 8 bytes for box 3 for common data and variable upon profile*/
677         OPJ_UINT32 l_colr_size = 11;
678         OPJ_BYTE * l_colr_data,* l_current_colr_ptr;
679         
680         /* preconditions */
681         assert(jp2 != 00);
682         assert(p_nb_bytes_written != 00);
683
684         switch (jp2->meth) {
685                 case 1 :
686                         l_colr_size += 4;
687                         break;
688                 case 2 :
689                         ++l_colr_size;
690                         break;
691                 default :
692                         return 00;
693         }
694
695         l_colr_data = (OPJ_BYTE *) opj_malloc(l_colr_size);
696         if (l_colr_data == 00) {
697                 return 00;
698         }
699         memset(l_colr_data,0,l_colr_size);
700         
701         l_current_colr_ptr = l_colr_data;
702
703         opj_write_bytes(l_current_colr_ptr,l_colr_size,4);                              /* write box size */
704         l_current_colr_ptr += 4;
705         
706         opj_write_bytes(l_current_colr_ptr,JP2_COLR,4);                                 /* BPCC */
707         l_current_colr_ptr += 4;
708         
709         opj_write_bytes(l_current_colr_ptr, jp2->meth,1);                               /* METH */
710         ++l_current_colr_ptr;
711         
712         opj_write_bytes(l_current_colr_ptr, jp2->precedence,1);                 /* PRECEDENCE */
713         ++l_current_colr_ptr;
714         
715         opj_write_bytes(l_current_colr_ptr, jp2->approx,1);                             /* APPROX */
716         ++l_current_colr_ptr;
717         
718         if (jp2->meth == 1) {
719                 opj_write_bytes(l_current_colr_ptr, jp2->enumcs,4);                     /* EnumCS */
720         }
721         else {
722                 opj_write_bytes(l_current_colr_ptr, 0, 1);                                      /* PROFILE (??) */
723         }
724
725         *p_nb_bytes_written = l_colr_size;
726         
727         return l_colr_data;
728 }
729
730 void opj_jp2_free_pclr(opj_jp2_color_t *color)
731 {
732     opj_free(color->jp2_pclr->channel_sign);
733     opj_free(color->jp2_pclr->channel_size);
734     opj_free(color->jp2_pclr->entries);
735
736         if(color->jp2_pclr->cmap) opj_free(color->jp2_pclr->cmap);
737
738     opj_free(color->jp2_pclr); color->jp2_pclr = NULL;
739 }
740
741 void opj_jp2_apply_pclr(opj_image_t *image, opj_jp2_color_t *color)
742 {
743         opj_image_comp_t *old_comps, *new_comps;
744         OPJ_BYTE *channel_size, *channel_sign;
745         OPJ_UINT32 *entries;
746         opj_jp2_cmap_comp_t *cmap;
747         OPJ_INT32 *src, *dst;
748         OPJ_UINT32 j, max;
749         OPJ_UINT16 i, nr_channels, cmp, pcol;
750         OPJ_INT32 k, top_k;
751
752         channel_size = color->jp2_pclr->channel_size;
753         channel_sign = color->jp2_pclr->channel_sign;
754         entries = color->jp2_pclr->entries;
755         cmap = color->jp2_pclr->cmap;
756         nr_channels = color->jp2_pclr->nr_channels;
757
758         old_comps = image->comps;
759         new_comps = (opj_image_comp_t*)
760                         opj_malloc(nr_channels * sizeof(opj_image_comp_t));
761
762         for(i = 0; i < nr_channels; ++i) {
763                 pcol = cmap[i].pcol; cmp = cmap[i].cmp;
764
765                 new_comps[pcol] = old_comps[cmp];
766
767                 /* Direct use */
768                 if(cmap[i].mtyp == 0){
769                         old_comps[cmp].data = NULL; continue;
770                 }
771
772                 /* Palette mapping: */
773                 new_comps[pcol].data = (OPJ_INT32*)
774                                 opj_malloc(old_comps[cmp].w * old_comps[cmp].h * sizeof(OPJ_INT32));
775                 new_comps[pcol].prec = channel_size[i];
776                 new_comps[pcol].sgnd = channel_sign[i];
777         }
778
779         top_k = color->jp2_pclr->nr_entries - 1;
780
781         for(i = 0; i < nr_channels; ++i) {
782                 /* Direct use: */
783                 if(cmap[i].mtyp == 0) continue;
784
785                 /* Palette mapping: */
786                 cmp = cmap[i].cmp; pcol = cmap[i].pcol;
787                 src = old_comps[cmp].data;
788                 dst = new_comps[pcol].data;
789                 max = new_comps[pcol].w * new_comps[pcol].h;
790
791                 for(j = 0; j < max; ++j)
792                 {
793                         /* The index */
794                         if((k = src[j]) < 0) k = 0; else if(k > top_k) k = top_k;
795
796                         /* The colour */
797                         dst[j] = entries[k * nr_channels + pcol];
798                 }
799         }
800
801         max = image->numcomps;
802         for(i = 0; i < max; ++i) {
803                 if(old_comps[i].data) opj_free(old_comps[i].data);
804         }
805
806         opj_free(old_comps);
807         image->comps = new_comps;
808         image->numcomps = nr_channels;
809
810         opj_jp2_free_pclr(color);
811
812 }/* apply_pclr() */
813
814 opj_bool opj_jp2_read_pclr(     opj_jp2_t *jp2,
815                             OPJ_BYTE * p_pclr_header_data,
816                             OPJ_UINT32 p_pclr_header_size,
817                             opj_event_mgr_t * p_manager
818                             )
819 {
820         opj_jp2_pclr_t *jp2_pclr;
821         OPJ_BYTE *channel_size, *channel_sign;
822         OPJ_UINT32 *entries;
823         OPJ_UINT16 nr_entries,nr_channels;
824         OPJ_UINT16 i, j;
825         OPJ_UINT32 l_value;
826
827         /* preconditions */
828         assert(p_pclr_header_data != 00);
829         assert(jp2 != 00);
830         assert(p_manager != 00);
831     (void)p_pclr_header_size;
832
833         if(jp2->color.jp2_pclr)
834                 return OPJ_FALSE;
835
836         opj_read_bytes(p_pclr_header_data, &l_value , 2);       /* NE */
837         p_pclr_header_data += 2;
838         nr_entries = (OPJ_UINT16) l_value;
839
840         opj_read_bytes(p_pclr_header_data, &l_value , 1);       /* NPC */
841         ++p_pclr_header_data;
842         nr_channels = (OPJ_UINT16) l_value;
843
844         entries = (OPJ_UINT32*) opj_malloc(nr_channels * nr_entries * sizeof(OPJ_UINT32));
845     if (!entries)
846         return OPJ_FALSE;
847         channel_size = (OPJ_BYTE*) opj_malloc(nr_channels);
848     if (!channel_size)
849     {
850         opj_free(entries);
851         return OPJ_FALSE;
852     }
853         channel_sign = (OPJ_BYTE*) opj_malloc(nr_channels);
854         if (!channel_sign)
855         {
856         opj_free(entries);
857         opj_free(channel_size);
858         return OPJ_FALSE;
859         }
860
861         jp2_pclr = (opj_jp2_pclr_t*)opj_malloc(sizeof(opj_jp2_pclr_t));
862     if (!jp2_pclr)
863     {
864         opj_free(entries);
865         opj_free(channel_size);
866         opj_free(channel_sign);
867         return OPJ_FALSE;
868     }
869
870         jp2_pclr->channel_sign = channel_sign;
871         jp2_pclr->channel_size = channel_size;
872         jp2_pclr->entries = entries;
873         jp2_pclr->nr_entries = nr_entries;
874         jp2_pclr->nr_channels = (OPJ_BYTE) l_value;
875         jp2_pclr->cmap = NULL;
876
877         jp2->color.jp2_pclr = jp2_pclr;
878
879         for(i = 0; i < nr_channels; ++i) {
880                 opj_read_bytes(p_pclr_header_data, &l_value , 1);       /* Bi */
881                 ++p_pclr_header_data;
882
883                 channel_size[i] = (l_value & 0x7f) + 1;
884                 channel_sign[i] = (l_value & 0x80)? 1 : 0;
885         }
886
887         for(j = 0; j < nr_entries; ++j) {
888                 for(i = 0; i < nr_channels; ++i) {
889                         OPJ_INT32 bytes_to_read = (channel_size[i]+7)>>3;
890
891                         opj_read_bytes(p_pclr_header_data, &l_value , bytes_to_read);   /* Cji */
892                         p_pclr_header_data += bytes_to_read;
893                         *entries = (OPJ_UINT32) l_value;
894                         entries++;
895                 }
896         }
897
898         return OPJ_TRUE;
899 }
900
901 opj_bool opj_jp2_read_cmap(     opj_jp2_t * jp2,
902                             OPJ_BYTE * p_cmap_header_data,
903                             OPJ_UINT32 p_cmap_header_size,
904                             opj_event_mgr_t * p_manager
905                             )
906 {
907         opj_jp2_cmap_comp_t *cmap;
908         OPJ_BYTE i, nr_channels;
909         OPJ_UINT32 l_value;
910
911         /* preconditions */
912         assert(jp2 != 00);
913         assert(p_cmap_header_data != 00);
914         assert(p_manager != 00);
915     (void)p_cmap_header_size;
916
917         /* Need nr_channels: */
918         if(jp2->color.jp2_pclr == NULL) {
919                 opj_event_msg(p_manager, EVT_ERROR, "Need to read a PCLR box before the CMAP box.\n");
920                 return OPJ_FALSE;
921         }
922
923         /* Part 1, I.5.3.5: 'There shall be at most one Component Mapping box
924          * inside a JP2 Header box' :
925         */
926         if(jp2->color.jp2_pclr->cmap) {
927                 opj_event_msg(p_manager, EVT_ERROR, "Only one CMAP box is allowed.\n");
928                 return OPJ_FALSE;
929         }
930
931         nr_channels = jp2->color.jp2_pclr->nr_channels;
932         cmap = (opj_jp2_cmap_comp_t*) opj_malloc(nr_channels * sizeof(opj_jp2_cmap_comp_t));
933     if (!cmap)
934         return OPJ_FALSE;
935
936
937         for(i = 0; i < nr_channels; ++i) {
938                 opj_read_bytes(p_cmap_header_data, &l_value, 2);                        /* CMP^i */
939                 p_cmap_header_data +=2;
940                 cmap[i].cmp = (OPJ_UINT16) l_value;
941
942                 opj_read_bytes(p_cmap_header_data, &l_value, 1);                        /* MTYP^i */
943                 ++p_cmap_header_data;
944                 cmap[i].mtyp = (OPJ_BYTE) l_value;
945
946                 opj_read_bytes(p_cmap_header_data, &l_value, 1);                        /* PCOL^i */
947                 ++p_cmap_header_data;
948                 cmap[i].pcol = (OPJ_BYTE) l_value;
949         }
950
951         jp2->color.jp2_pclr->cmap = cmap;
952
953         return OPJ_TRUE;
954 }
955
956 void opj_jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color)
957 {
958         opj_jp2_cdef_info_t *info;
959         OPJ_UINT16 i, n, cn, asoc, acn;
960
961         info = color->jp2_cdef->info;
962         n = color->jp2_cdef->n;
963
964         for(i = 0; i < n; ++i)
965         {
966                 /* WATCH: acn = asoc - 1 ! */
967                 if((asoc = info[i].asoc) == 0) continue;
968
969                 cn = info[i].cn; 
970         acn = asoc - 1;
971
972                 if(cn != acn)
973                 {
974                         opj_image_comp_t saved;
975
976                         memcpy(&saved, &image->comps[cn], sizeof(opj_image_comp_t));
977                         memcpy(&image->comps[cn], &image->comps[acn], sizeof(opj_image_comp_t));
978                         memcpy(&image->comps[acn], &saved, sizeof(opj_image_comp_t));
979
980                         info[i].asoc = cn + 1;
981                         info[acn].asoc = info[acn].cn + 1;
982                 }
983         }
984
985         if(color->jp2_cdef->info) opj_free(color->jp2_cdef->info);
986
987         opj_free(color->jp2_cdef); color->jp2_cdef = NULL;
988
989 }/* jp2_apply_cdef() */
990
991 opj_bool opj_jp2_read_cdef(     opj_jp2_t * jp2,
992                             OPJ_BYTE * p_cdef_header_data,
993                                                         OPJ_UINT32 p_cdef_header_size,
994                                                         opj_event_mgr_t * p_manager
995                             )
996 {
997         opj_jp2_cdef_info_t *cdef_info;
998         OPJ_UINT16 i;
999         OPJ_UINT32 l_value;
1000
1001         /* preconditions */
1002         assert(jp2 != 00);
1003         assert(p_cdef_header_data != 00);
1004         assert(p_manager != 00);
1005     (void)p_cdef_header_size;
1006
1007         /* Part 1, I.5.3.6: 'The shall be at most one Channel Definition box
1008          * inside a JP2 Header box.'*/
1009         if(jp2->color.jp2_cdef) return OPJ_FALSE;
1010
1011         opj_read_bytes(p_cdef_header_data,&l_value ,2);                 /* N */
1012         p_cdef_header_data+= 2;
1013
1014         if ( (OPJ_UINT16)l_value == 0){ /* szukw000: FIXME */
1015                 opj_event_msg(p_manager, EVT_ERROR, "Number of channel description is equal to zero in CDEF box.\n");
1016                 return OPJ_FALSE;
1017         }
1018
1019         cdef_info = (opj_jp2_cdef_info_t*) opj_malloc(l_value * sizeof(opj_jp2_cdef_info_t));
1020     if (!cdef_info)
1021         return OPJ_FALSE;
1022
1023         jp2->color.jp2_cdef = (opj_jp2_cdef_t*)opj_malloc(sizeof(opj_jp2_cdef_t));
1024     if(!jp2->color.jp2_cdef)
1025     {
1026         opj_free(cdef_info);
1027         return OPJ_FALSE;
1028     }
1029         jp2->color.jp2_cdef->info = cdef_info;
1030         jp2->color.jp2_cdef->n = (OPJ_UINT16) l_value;
1031
1032         for(i = 0; i < jp2->color.jp2_cdef->n; ++i) {
1033                 opj_read_bytes(p_cdef_header_data, &l_value, 2);                        /* Cn^i */
1034                 p_cdef_header_data +=2;
1035                 cdef_info[i].cn = (OPJ_UINT16) l_value;
1036
1037                 opj_read_bytes(p_cdef_header_data, &l_value, 2);                        /* Typ^i */
1038                 p_cdef_header_data +=2;
1039                 cdef_info[i].typ = (OPJ_UINT16) l_value;
1040
1041                 opj_read_bytes(p_cdef_header_data, &l_value, 2);                        /* Asoc^i */
1042                 p_cdef_header_data +=2;
1043                 cdef_info[i].asoc = (OPJ_UINT16) l_value;
1044    }
1045
1046         return OPJ_TRUE;
1047 }
1048
1049 opj_bool opj_jp2_read_colr( opj_jp2_t *jp2,
1050                             OPJ_BYTE * p_colr_header_data,
1051                             OPJ_UINT32 p_colr_header_size,
1052                             opj_event_mgr_t * p_manager
1053                             )
1054 {
1055         OPJ_UINT32 l_value;
1056
1057         /* preconditions */
1058         assert(jp2 != 00);
1059         assert(p_colr_header_data != 00);
1060         assert(p_manager != 00);
1061
1062         if (p_colr_header_size < 3) {
1063                 opj_event_msg(p_manager, EVT_ERROR, "Bad COLR header box (bad size)\n");
1064                 return OPJ_FALSE;
1065         }
1066
1067         /* Part 1, I.5.3.3 : 'A conforming JP2 reader shall ignore all Colour
1068          * Specification boxes after the first.'
1069         */
1070         if(jp2->color.jp2_has_colr) {
1071                 opj_event_msg(p_manager, EVT_INFO, "A conforming JP2 reader shall ignore all Colour Specification boxes after the first, so we ignore this one.\n");
1072                 p_colr_header_data += p_colr_header_size;
1073                 return OPJ_TRUE;
1074         }
1075
1076         opj_read_bytes(p_colr_header_data,&jp2->meth ,1);                       /* METH */
1077         ++p_colr_header_data;
1078
1079         opj_read_bytes(p_colr_header_data,&jp2->precedence ,1);         /* PRECEDENCE */
1080         ++p_colr_header_data;
1081
1082         opj_read_bytes(p_colr_header_data,&jp2->approx ,1);                     /* APPROX */
1083         ++p_colr_header_data;
1084
1085         if (jp2->meth == 1) {
1086                 if (p_colr_header_size != 7) {
1087                         opj_event_msg(p_manager, EVT_ERROR, "Bad BPCC header box (bad size)\n");
1088                         return OPJ_FALSE;
1089                 }
1090
1091                 opj_read_bytes(p_colr_header_data,&jp2->enumcs ,4);                     /* EnumCS */
1092         }
1093         else if (jp2->meth == 2) {
1094                 /* ICC profile */
1095                 OPJ_INT32 it_icc_value = 0;
1096                 OPJ_INT32 icc_len = p_colr_header_size - 3;
1097
1098                 jp2->color.icc_profile_len = icc_len;
1099                 jp2->color.icc_profile_buf = (OPJ_BYTE*) opj_malloc(icc_len);
1100         if (!jp2->color.icc_profile_buf)
1101         {
1102             jp2->color.icc_profile_len = 0;
1103             return OPJ_FALSE;
1104         }
1105                 memset(jp2->color.icc_profile_buf, 0, icc_len * sizeof(OPJ_BYTE));
1106
1107                 for (it_icc_value = 0; it_icc_value < icc_len; ++it_icc_value)
1108                 {
1109                         opj_read_bytes(p_colr_header_data,&l_value,1);          /* icc values */
1110                         ++p_colr_header_data;
1111                         jp2->color.icc_profile_buf[it_icc_value] = (OPJ_BYTE) l_value;
1112                 }
1113
1114         }
1115         else 
1116                 opj_event_msg(p_manager, EVT_INFO, "COLR BOX meth value is not a regular value (%d), so we will skip the fields following the approx field.\n", jp2->meth);
1117
1118         jp2->color.jp2_has_colr = 1;
1119
1120         return OPJ_TRUE;
1121 }
1122
1123 opj_bool opj_jp2_decode(opj_jp2_t *jp2,
1124                         opj_stream_private_t *p_stream,
1125                         opj_image_t* p_image,
1126                         opj_event_mgr_t * p_manager)
1127 {
1128         if (!p_image)
1129                 return OPJ_FALSE;
1130
1131         /* J2K decoding */
1132         if( ! opj_j2k_decode(jp2->j2k, p_stream, p_image, p_manager) ) {
1133                 opj_event_msg(p_manager, EVT_ERROR, "Failed to decode the codestream in the JP2 file\n");
1134                 return OPJ_FALSE;
1135         }
1136
1137     if (!jp2->ignore_pclr_cmap_cdef){
1138
1139             /* Set Image Color Space */
1140             if (jp2->enumcs == 16)
1141                     p_image->color_space = OPJ_CLRSPC_SRGB;
1142             else if (jp2->enumcs == 17)
1143                     p_image->color_space = OPJ_CLRSPC_GRAY;
1144             else if (jp2->enumcs == 18)
1145                     p_image->color_space = OPJ_CLRSPC_SYCC;
1146             else
1147                     p_image->color_space = OPJ_CLRSPC_UNKNOWN;
1148
1149             /* Apply the color space if needed */
1150             if(jp2->color.jp2_cdef) {
1151                     opj_jp2_apply_cdef(p_image, &(jp2->color));
1152             }
1153
1154             if(jp2->color.jp2_pclr) {
1155                     /* Part 1, I.5.3.4: Either both or none : */
1156                     if( !jp2->color.jp2_pclr->cmap)
1157                             opj_jp2_free_pclr(&(jp2->color));
1158                     else
1159                             opj_jp2_apply_pclr(p_image, &(jp2->color));
1160             }
1161
1162             if(jp2->color.icc_profile_buf) {
1163                     p_image->icc_profile_buf = jp2->color.icc_profile_buf;
1164                     p_image->icc_profile_len = jp2->color.icc_profile_len;
1165                     jp2->color.icc_profile_buf = NULL;
1166             }
1167     }
1168
1169         return OPJ_TRUE;
1170 }
1171
1172 opj_bool opj_jp2_write_jp2h(opj_jp2_t *jp2,
1173                             opj_stream_private_t *stream,
1174                             opj_event_mgr_t * p_manager
1175                             )
1176 {
1177         opj_jp2_img_header_writer_handler_t l_writers [3];
1178         opj_jp2_img_header_writer_handler_t * l_current_writer;
1179
1180         OPJ_INT32 i, l_nb_pass;
1181         /* size of data for super box*/
1182         OPJ_INT32 l_jp2h_size = 8;
1183         opj_bool l_result = OPJ_TRUE;
1184
1185         /* to store the data of the super box */
1186         OPJ_BYTE l_jp2h_data [8];
1187         
1188         /* preconditions */
1189         assert(stream != 00);
1190         assert(jp2 != 00);
1191         assert(p_manager != 00);
1192
1193         memset(l_writers,0,sizeof(l_writers));
1194
1195         if (jp2->bpc == 255) {
1196                 l_nb_pass = 3;
1197                 l_writers[0].handler = opj_jp2_write_ihdr;
1198                 l_writers[1].handler = opj_jp2_write_bpcc;
1199                 l_writers[2].handler = opj_jp2_write_colr;
1200         }
1201         else {
1202                 l_nb_pass = 2;
1203                 l_writers[0].handler = opj_jp2_write_ihdr;
1204                 l_writers[1].handler = opj_jp2_write_colr;
1205         }
1206         
1207         /* write box header */
1208         /* write JP2H type */
1209         opj_write_bytes(l_jp2h_data+4,JP2_JP2H,4);
1210
1211         l_current_writer = l_writers;
1212         for (i=0;i<l_nb_pass;++i) {
1213                 l_current_writer->m_data = l_current_writer->handler(jp2,&(l_current_writer->m_size));
1214                 if (l_current_writer->m_data == 00) {
1215                         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to hold JP2 Header data\n");
1216                         l_result = OPJ_FALSE;
1217                         break;
1218                 }
1219
1220                 l_jp2h_size += l_current_writer->m_size;
1221                 ++l_current_writer;
1222         }
1223
1224         if (! l_result) {
1225                 l_current_writer = l_writers;
1226                 for (i=0;i<l_nb_pass;++i) {
1227                         if (l_current_writer->m_data != 00) {
1228                                 opj_free(l_current_writer->m_data );
1229                         }
1230                         ++l_current_writer;
1231                 }
1232
1233                 return OPJ_FALSE;
1234         }
1235
1236         /* write super box size */
1237         opj_write_bytes(l_jp2h_data,l_jp2h_size,4);
1238         
1239         /* write super box data on stream */
1240         if (opj_stream_write_data(stream,l_jp2h_data,8,p_manager) != 8) {
1241                 opj_event_msg(p_manager, EVT_ERROR, "Stream error while writing JP2 Header box\n");
1242                 l_result = OPJ_FALSE;
1243         }
1244         
1245         if (l_result) {
1246                 l_current_writer = l_writers;
1247                 for (i=0;i<l_nb_pass;++i) {
1248                         if (opj_stream_write_data(stream,l_current_writer->m_data,l_current_writer->m_size,p_manager) != l_current_writer->m_size) {
1249                                 opj_event_msg(p_manager, EVT_ERROR, "Stream error while writing JP2 Header box\n");
1250                                 l_result = OPJ_FALSE;
1251                                 break;
1252                         }
1253                         ++l_current_writer;
1254                 }
1255         }
1256
1257         l_current_writer = l_writers;
1258         
1259         /* cleanup */
1260         for (i=0;i<l_nb_pass;++i) {
1261                 if (l_current_writer->m_data != 00) {
1262                         opj_free(l_current_writer->m_data );
1263                 }
1264                 ++l_current_writer;
1265         }
1266
1267         return l_result;
1268 }
1269
1270 opj_bool opj_jp2_write_ftyp(opj_jp2_t *jp2,
1271                                                         opj_stream_private_t *cio,
1272                                                         opj_event_mgr_t * p_manager )
1273 {
1274         OPJ_UINT32 i;
1275         OPJ_UINT32 l_ftyp_size = 16 + 4 * jp2->numcl;
1276         OPJ_BYTE * l_ftyp_data, * l_current_data_ptr;
1277         opj_bool l_result;
1278
1279         /* preconditions */
1280         assert(cio != 00);
1281         assert(jp2 != 00);
1282         assert(p_manager != 00);
1283
1284         l_ftyp_data = (OPJ_BYTE *) opj_malloc(l_ftyp_size);
1285         
1286         if (l_ftyp_data == 00) {
1287                 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle ftyp data\n");
1288                 return OPJ_FALSE;
1289         }
1290
1291         memset(l_ftyp_data,0,l_ftyp_size);
1292
1293         l_current_data_ptr = l_ftyp_data;
1294
1295         opj_write_bytes(l_current_data_ptr, l_ftyp_size,4); /* box size */
1296         l_current_data_ptr += 4;
1297
1298         opj_write_bytes(l_current_data_ptr, JP2_FTYP,4); /* FTYP */
1299         l_current_data_ptr += 4;
1300
1301         opj_write_bytes(l_current_data_ptr, jp2->brand,4); /* BR */
1302         l_current_data_ptr += 4;
1303
1304         opj_write_bytes(l_current_data_ptr, jp2->minversion,4); /* MinV */
1305         l_current_data_ptr += 4;
1306
1307         for (i = 0; i < jp2->numcl; i++)  {
1308                 opj_write_bytes(l_current_data_ptr, jp2->cl[i],4);      /* CL */
1309         }
1310         
1311         l_result = (opj_stream_write_data(cio,l_ftyp_data,l_ftyp_size,p_manager) == l_ftyp_size);
1312         if (! l_result)
1313         {
1314                 opj_event_msg(p_manager, EVT_ERROR, "Error while writing ftyp data to stream\n");
1315         }
1316
1317         opj_free(l_ftyp_data);
1318         
1319         return l_result;
1320 }
1321
1322 opj_bool opj_jp2_write_jp2c(opj_jp2_t *jp2,
1323                                                         opj_stream_private_t *cio,
1324                                                         opj_event_mgr_t * p_manager )
1325 {
1326         OPJ_OFF_T j2k_codestream_exit;
1327         OPJ_BYTE l_data_header [8];
1328         
1329         /* preconditions */
1330         assert(jp2 != 00);
1331         assert(cio != 00);
1332         assert(p_manager != 00);
1333         assert(opj_stream_has_seek(cio));
1334         
1335         j2k_codestream_exit = opj_stream_tell(cio);
1336         opj_write_bytes(l_data_header,
1337                     (OPJ_UINT32) (j2k_codestream_exit - jp2->j2k_codestream_offset),
1338                     4); /* size of codestream */
1339         opj_write_bytes(l_data_header + 4,JP2_JP2C,4);                                                                     /* JP2C */
1340
1341         if (! opj_stream_seek(cio,jp2->j2k_codestream_offset,p_manager)) {
1342                 opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
1343                 return OPJ_FALSE;
1344         }
1345         
1346         if (opj_stream_write_data(cio,l_data_header,8,p_manager) != 8) {
1347                 opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
1348                 return OPJ_FALSE;
1349         }
1350
1351         if (! opj_stream_seek(cio,j2k_codestream_exit,p_manager)) {
1352                 opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
1353                 return OPJ_FALSE;
1354         }
1355
1356         return OPJ_TRUE;
1357 }
1358
1359 opj_bool opj_jp2_write_jp(      opj_jp2_t *jp2,
1360                                             opj_stream_private_t *cio,
1361                                                 opj_event_mgr_t * p_manager )
1362 {
1363         /* 12 bytes will be read */
1364         OPJ_BYTE l_signature_data [12];
1365
1366         /* preconditions */
1367         assert(cio != 00);
1368         assert(jp2 != 00);
1369         assert(p_manager != 00);
1370
1371         /* write box length */
1372         opj_write_bytes(l_signature_data,12,4);
1373         /* writes box type */
1374         opj_write_bytes(l_signature_data+4,JP2_JP,4);
1375         /* writes magic number*/
1376         opj_write_bytes(l_signature_data+8,0x0d0a870a,4);
1377         
1378         if (opj_stream_write_data(cio,l_signature_data,12,p_manager) != 12) {
1379                 return OPJ_FALSE;
1380         }
1381
1382         return OPJ_TRUE;
1383 }
1384
1385 /* ----------------------------------------------------------------------- */
1386 /* JP2 decoder interface                                             */
1387 /* ----------------------------------------------------------------------- */
1388
1389 void opj_jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters)
1390 {
1391         /* setup the J2K codec */
1392         opj_j2k_setup_decoder(jp2->j2k, parameters);
1393
1394         /* further JP2 initializations go here */
1395         jp2->color.jp2_has_colr = 0;
1396     jp2->ignore_pclr_cmap_cdef = parameters->flags & OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG;
1397 }
1398
1399 /* ----------------------------------------------------------------------- */
1400 /* JP2 encoder interface                                             */
1401 /* ----------------------------------------------------------------------- */
1402
1403 void opj_jp2_setup_encoder(     opj_jp2_t *jp2,
1404                             opj_cparameters_t *parameters,
1405                             opj_image_t *image,
1406                             opj_event_mgr_t * p_manager)
1407 {
1408     OPJ_UINT32 i;
1409         OPJ_INT32 depth_0, sign;
1410
1411         if(!jp2 || !parameters || !image)
1412                 return;
1413
1414         /* setup the J2K codec */
1415         /* ------------------- */
1416
1417         /* Check if number of components respects standard */
1418         if (image->numcomps < 1 || image->numcomps > 16384) {
1419                 opj_event_msg(p_manager, EVT_ERROR, "Invalid number of components specified while setting up JP2 encoder\n");
1420                 return;
1421         }
1422
1423         opj_j2k_setup_encoder(jp2->j2k, parameters, image, p_manager );
1424
1425         /* setup the JP2 codec */
1426         /* ------------------- */
1427         
1428         /* Profile box */
1429
1430         jp2->brand = JP2_JP2;   /* BR */
1431         jp2->minversion = 0;    /* MinV */
1432         jp2->numcl = 1;
1433         jp2->cl = (OPJ_UINT32*) opj_malloc(jp2->numcl * sizeof(OPJ_UINT32));
1434     if (!jp2->cl){
1435         jp2->cl = NULL;
1436         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory when setup the JP2 encoder\n");
1437         return;
1438     }
1439         jp2->cl[0] = JP2_JP2;   /* CL0 : JP2 */
1440
1441         /* Image Header box */
1442
1443         jp2->numcomps = image->numcomps;        /* NC */
1444         jp2->comps = (opj_jp2_comps_t*) opj_malloc(jp2->numcomps * sizeof(opj_jp2_comps_t));
1445     if (!jp2->comps) {
1446         jp2->comps = NULL;
1447         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory when setup the JP2 encoder\n");
1448         return;
1449     }
1450
1451         jp2->h = image->y1 - image->y0;         /* HEIGHT */
1452         jp2->w = image->x1 - image->x0;         /* WIDTH */
1453         /* BPC */
1454         depth_0 = image->comps[0].prec - 1;
1455         sign = image->comps[0].sgnd;
1456         jp2->bpc = depth_0 + (sign << 7);
1457         for (i = 1; i < image->numcomps; i++) {
1458                 OPJ_INT32 depth = image->comps[i].prec - 1;
1459                 sign = image->comps[i].sgnd;
1460                 if (depth_0 != depth)
1461                         jp2->bpc = 255;
1462         }
1463         jp2->C = 7;                     /* C : Always 7 */
1464         jp2->UnkC = 0;          /* UnkC, colorspace specified in colr box */
1465         jp2->IPR = 0;           /* IPR, no intellectual property */
1466         
1467         /* BitsPerComponent box */
1468         for (i = 0; i < image->numcomps; i++) {
1469                 jp2->comps[i].bpcc = image->comps[i].prec - 1 + (image->comps[i].sgnd << 7);
1470         }
1471
1472         /* Colour Specification box */
1473         if ((image->numcomps == 1 || image->numcomps == 3) && (jp2->bpc != 255)) {
1474                 jp2->meth = 1;  /* METH: Enumerated colourspace */
1475         } else {
1476                 jp2->meth = 2;  /* METH: Restricted ICC profile */
1477         }
1478         if (jp2->meth == 1) {
1479                 if (image->color_space == 1)
1480                         jp2->enumcs = 16;       /* sRGB as defined by IEC 61966-2-1 */
1481                 else if (image->color_space == 2)
1482                         jp2->enumcs = 17;       /* greyscale */
1483                 else if (image->color_space == 3)
1484                         jp2->enumcs = 18;       /* YUV */
1485         } else {
1486                 jp2->enumcs = 0;                /* PROFILE (??) */
1487         }
1488         jp2->precedence = 0;    /* PRECEDENCE */
1489         jp2->approx = 0;                /* APPROX */
1490
1491         jp2->jpip_on = parameters->jpip_on;
1492 }
1493
1494 opj_bool opj_jp2_encode(opj_jp2_t *jp2,
1495                                                 opj_stream_private_t *stream,
1496                                                 opj_event_mgr_t * p_manager)
1497 {
1498         return opj_j2k_encode_v2(jp2->j2k, stream, p_manager);
1499 }
1500
1501 opj_bool opj_jp2_end_decompress(opj_jp2_t *jp2,
1502                                 opj_stream_private_t *cio,
1503                                 opj_event_mgr_t * p_manager
1504                                 )
1505 {
1506         /* preconditions */
1507         assert(jp2 != 00);
1508         assert(cio != 00);
1509         assert(p_manager != 00);
1510
1511         /* customization of the end encoding */
1512         opj_jp2_setup_end_header_reading(jp2);
1513
1514         /* write header */
1515         if (! opj_jp2_exec (jp2,jp2->m_procedure_list,cio,p_manager)) {
1516                 return OPJ_FALSE;
1517         }
1518
1519         return opj_j2k_end_decompress(jp2->j2k, cio, p_manager);
1520 }
1521
1522 opj_bool opj_jp2_end_compress(  opj_jp2_t *jp2,
1523                                                             opj_stream_private_t *cio,
1524                                                             opj_event_mgr_t * p_manager
1525                                 )
1526 {
1527         /* preconditions */
1528         assert(jp2 != 00);
1529         assert(cio != 00);
1530         assert(p_manager != 00);
1531
1532         /* customization of the end encoding */
1533         opj_jp2_setup_end_header_writing(jp2);
1534
1535         if (! opj_j2k_end_compress(jp2->j2k,cio,p_manager)) {
1536                 return OPJ_FALSE;
1537         }
1538
1539         /* write header */
1540         return opj_jp2_exec(jp2,jp2->m_procedure_list,cio,p_manager);
1541 }
1542
1543 void opj_jp2_setup_end_header_writing (opj_jp2_t *jp2)
1544 {
1545         /* preconditions */
1546         assert(jp2 != 00);
1547
1548 #ifdef USE_JPIP
1549   if( jp2->jpip_on )
1550     opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jpip_write_iptr );
1551 #endif
1552         opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_write_jp2c );
1553         /* DEVELOPER CORNER, add your custom procedures */
1554 #ifdef USE_JPIP
1555   if( jp2->jpip_on )
1556     {
1557     opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jpip_write_cidx );
1558     opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jpip_write_fidx );
1559     }
1560 #endif
1561 }
1562
1563 void opj_jp2_setup_end_header_reading (opj_jp2_t *jp2)
1564 {
1565         /* preconditions */
1566         assert(jp2 != 00);
1567         opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_read_header_procedure );
1568         /* DEVELOPER CORNER, add your custom procedures */
1569 }
1570
1571 opj_bool opj_jp2_default_validation (   opj_jp2_t * jp2,
1572                                         opj_stream_private_t *cio,
1573                                         opj_event_mgr_t * p_manager
1574                                         )
1575 {
1576         opj_bool l_is_valid = OPJ_TRUE;
1577         OPJ_UINT32 i;
1578
1579         /* preconditions */
1580         assert(jp2 != 00);
1581         assert(cio != 00);
1582         assert(p_manager != 00);
1583
1584         /* JPEG2000 codec validation */
1585
1586         /* STATE checking */
1587         /* make sure the state is at 0 */
1588         l_is_valid &= (jp2->jp2_state == JP2_STATE_NONE);
1589
1590         /* make sure not reading a jp2h ???? WEIRD */
1591         l_is_valid &= (jp2->jp2_img_state == JP2_IMG_STATE_NONE);
1592
1593         /* POINTER validation */
1594         /* make sure a j2k codec is present */
1595         l_is_valid &= (jp2->j2k != 00);
1596
1597         /* make sure a procedure list is present */
1598         l_is_valid &= (jp2->m_procedure_list != 00);
1599
1600         /* make sure a validation list is present */
1601         l_is_valid &= (jp2->m_validation_list != 00);
1602
1603         /* PARAMETER VALIDATION */
1604         /* number of components */
1605         l_is_valid &= (jp2->numcl > 0);
1606         /* width */
1607         l_is_valid &= (jp2->h > 0);
1608         /* height */
1609         l_is_valid &= (jp2->w > 0);
1610         /* precision */
1611         for (i = 0; i < jp2->numcomps; ++i)     {
1612                 l_is_valid &= (jp2->comps[i].bpcc > 0);
1613         }
1614
1615         /* METH */
1616         l_is_valid &= ((jp2->meth > 0) && (jp2->meth < 3));
1617
1618         /* stream validation */
1619         /* back and forth is needed */
1620         l_is_valid &= opj_stream_has_seek(cio);
1621
1622         return l_is_valid;
1623 }
1624
1625 opj_bool opj_jp2_read_header_procedure(  opj_jp2_t *jp2,
1626                                                 opj_stream_private_t *stream,
1627                                                 opj_event_mgr_t * p_manager
1628                                                 )
1629 {
1630         opj_jp2_box_t box;
1631         OPJ_UINT32 l_nb_bytes_read;
1632         const opj_jp2_header_handler_t * l_current_handler;
1633         OPJ_UINT32 l_last_data_size = BOX_SIZE;
1634         OPJ_UINT32 l_current_data_size;
1635         OPJ_BYTE * l_current_data = 00;
1636
1637         /* preconditions */
1638         assert(stream != 00);
1639         assert(jp2 != 00);
1640         assert(p_manager != 00);
1641
1642         l_current_data = (OPJ_BYTE*)opj_malloc(l_last_data_size);
1643
1644         if (l_current_data == 00) {
1645                 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle jpeg2000 file header\n");
1646                 return OPJ_FALSE;
1647         }
1648         memset(l_current_data, 0 , l_last_data_size);
1649
1650         while (opj_jp2_read_boxhdr(&box,&l_nb_bytes_read,stream,p_manager)) {
1651                 /* is it the codestream box ? */
1652                 if (box.type == JP2_JP2C) {
1653                         if (jp2->jp2_state & JP2_STATE_HEADER) {
1654                                 jp2->jp2_state |= JP2_STATE_CODESTREAM;
1655                                 opj_free(l_current_data);
1656                                 return OPJ_TRUE;
1657                         }
1658                         else {
1659                                 opj_event_msg(p_manager, EVT_ERROR, "bad placed jpeg codestream\n");
1660                                 opj_free(l_current_data);
1661                                 return OPJ_FALSE;
1662                         }
1663                 }
1664                 else if (box.length == 0) {
1665                         opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box of undefined sizes\n");
1666                         opj_free(l_current_data);
1667                         return OPJ_FALSE;
1668                 }
1669
1670                 l_current_handler = opj_jp2_find_handler(box.type);
1671                 l_current_data_size = box.length - l_nb_bytes_read;
1672
1673                 if (l_current_handler != 00) {
1674                         if (l_current_data_size > l_last_data_size) {
1675                                 OPJ_BYTE* new_current_data = (OPJ_BYTE*)opj_realloc(l_current_data,l_current_data_size);
1676                                 if (!l_current_data){
1677                                         opj_free(l_current_data);
1678                     opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle jpeg2000 box\n");
1679                                         return OPJ_FALSE;
1680                                 }
1681                 l_current_data = new_current_data;
1682                                 l_last_data_size = l_current_data_size;
1683                         }
1684
1685                         l_nb_bytes_read = opj_stream_read_data(stream,l_current_data,l_current_data_size,p_manager);
1686                         if (l_nb_bytes_read != l_current_data_size) {
1687                                 opj_event_msg(p_manager, EVT_ERROR, "Problem with reading JPEG2000 box, stream error\n");
1688                 opj_free(l_current_data);                
1689                                 return OPJ_FALSE;
1690                         }
1691
1692                         if (! l_current_handler->handler(jp2,l_current_data,l_current_data_size,p_manager)) {
1693                                 opj_free(l_current_data);
1694                                 return OPJ_FALSE;
1695                         }
1696                 }
1697                 else {
1698                         jp2->jp2_state |= JP2_STATE_UNKNOWN;
1699                         if (opj_stream_skip(stream,l_current_data_size,p_manager) != l_current_data_size) {
1700                                 opj_event_msg(p_manager, EVT_ERROR, "Problem with skipping JPEG2000 box, stream error\n");
1701                                 opj_free(l_current_data);
1702                                 return OPJ_FALSE;
1703                         }
1704                 }
1705         }
1706
1707         opj_free(l_current_data);
1708
1709         return OPJ_TRUE;
1710 }
1711
1712 /**
1713  * Excutes the given procedures on the given codec.
1714  *
1715  * @param       p_procedure_list        the list of procedures to execute
1716  * @param       jp2                                     the jpeg2000 file codec to execute the procedures on.
1717  * @param       stream                                  the stream to execute the procedures on.
1718  * @param       p_manager                       the user manager.
1719  *
1720  * @return      true                            if all the procedures were successfully executed.
1721  */
1722 static opj_bool opj_jp2_exec (  opj_jp2_t * jp2,
1723                                 opj_procedure_list_t * p_procedure_list,
1724                                 opj_stream_private_t *stream,
1725                                 opj_event_mgr_t * p_manager
1726                                 )
1727
1728 {
1729         opj_bool (** l_procedure) (opj_jp2_t * jp2, opj_stream_private_t *, opj_event_mgr_t *) = 00;
1730         opj_bool l_result = OPJ_TRUE;
1731         OPJ_UINT32 l_nb_proc, i;
1732
1733         /* preconditions */
1734         assert(p_procedure_list != 00);
1735         assert(jp2 != 00);
1736         assert(stream != 00);
1737         assert(p_manager != 00);
1738
1739         l_nb_proc = opj_procedure_list_get_nb_procedures(p_procedure_list);
1740         l_procedure = (opj_bool (**) (opj_jp2_t * jp2, opj_stream_private_t *, opj_event_mgr_t *)) opj_procedure_list_get_first_procedure(p_procedure_list);
1741
1742         for     (i=0;i<l_nb_proc;++i) {
1743                 l_result = l_result && (*l_procedure) (jp2,stream,p_manager);
1744                 ++l_procedure;
1745         }
1746
1747         /* and clear the procedure list at the end. */
1748         opj_procedure_list_clear(p_procedure_list);
1749         return l_result;
1750 }
1751
1752 opj_bool opj_jp2_start_compress(opj_jp2_t *jp2,
1753                                 opj_stream_private_t *stream,
1754                                 opj_image_t * p_image,
1755                                 opj_event_mgr_t * p_manager
1756                                 )
1757 {
1758         /* preconditions */
1759         assert(jp2 != 00);
1760         assert(stream != 00);
1761         assert(p_manager != 00);
1762
1763         /* customization of the validation */
1764         opj_jp2_setup_encoding_validation (jp2);
1765
1766         /* validation of the parameters codec */
1767         if (! opj_jp2_exec(jp2,jp2->m_validation_list,stream,p_manager)) {
1768                 return OPJ_FALSE;
1769         }
1770
1771         /* customization of the encoding */
1772         opj_jp2_setup_header_writing(jp2);
1773
1774         /* write header */
1775         if (! opj_jp2_exec (jp2,jp2->m_procedure_list,stream,p_manager)) {
1776                 return OPJ_FALSE;
1777         }
1778
1779         return opj_j2k_start_compress(jp2->j2k,stream,p_image,p_manager);
1780 }
1781
1782 const opj_jp2_header_handler_t * opj_jp2_find_handler (OPJ_UINT32 p_id)
1783 {
1784         OPJ_UINT32 i, l_handler_size = sizeof(jp2_header) / sizeof(opj_jp2_header_handler_t);
1785
1786         for (i=0;i<l_handler_size;++i) {
1787                 if (jp2_header[i].id == p_id) {
1788                         return &jp2_header[i];
1789                 }
1790         }
1791         return NULL;
1792 }
1793
1794 /**
1795  * Finds the image execution function related to the given box id.
1796  *
1797  * @param       p_id    the id of the handler to fetch.
1798  *
1799  * @return      the given handler or 00 if it could not be found.
1800  */
1801 static const opj_jp2_header_handler_t * opj_jp2_img_find_handler (OPJ_UINT32 p_id)
1802 {
1803         OPJ_UINT32 i, l_handler_size = sizeof(jp2_img_header) / sizeof(opj_jp2_header_handler_t);
1804         for (i=0;i<l_handler_size;++i)
1805         {
1806                 if (jp2_img_header[i].id == p_id) {
1807                         return &jp2_img_header[i];
1808                 }
1809         }
1810
1811         return NULL;
1812 }
1813
1814 /**
1815  * Reads a jpeg2000 file signature box.
1816  *
1817  * @param       p_header_data   the data contained in the signature box.
1818  * @param       jp2                             the jpeg2000 file codec.
1819  * @param       p_header_size   the size of the data contained in the signature box.
1820  * @param       p_manager               the user event manager.
1821  *
1822  * @return true if the file signature box is valid.
1823  */
1824 static opj_bool opj_jp2_read_jp(opj_jp2_t *jp2,
1825                                 OPJ_BYTE * p_header_data,
1826                                 OPJ_UINT32 p_header_size,
1827                                 opj_event_mgr_t * p_manager
1828                                 )
1829
1830 {
1831         OPJ_UINT32 l_magic_number;
1832
1833         /* preconditions */
1834         assert(p_header_data != 00);
1835         assert(jp2 != 00);
1836         assert(p_manager != 00);
1837
1838         if (jp2->jp2_state != JP2_STATE_NONE) {
1839                 opj_event_msg(p_manager, EVT_ERROR, "The signature box must be the first box in the file.\n");
1840                 return OPJ_FALSE;
1841         }
1842
1843         /* assure length of data is correct (4 -> magic number) */
1844         if (p_header_size != 4) {
1845                 opj_event_msg(p_manager, EVT_ERROR, "Error with JP signature Box size\n");
1846                 return OPJ_FALSE;
1847         }
1848
1849         /* rearrange data */
1850         opj_read_bytes(p_header_data,&l_magic_number,4);
1851         if (l_magic_number != 0x0d0a870a ) {
1852                 opj_event_msg(p_manager, EVT_ERROR, "Error with JP Signature : bad magic number\n");
1853                 return OPJ_FALSE;
1854         }
1855
1856         jp2->jp2_state |= JP2_STATE_SIGNATURE;
1857
1858         return OPJ_TRUE;
1859 }
1860
1861 /**
1862  * Reads a a FTYP box - File type box
1863  *
1864  * @param       p_header_data   the data contained in the FTYP box.
1865  * @param       jp2                             the jpeg2000 file codec.
1866  * @param       p_header_size   the size of the data contained in the FTYP box.
1867  * @param       p_manager               the user event manager.
1868  *
1869  * @return true if the FTYP box is valid.
1870  */
1871 static opj_bool opj_jp2_read_ftyp(      opj_jp2_t *jp2,
1872                                                                         OPJ_BYTE * p_header_data,
1873                                                                         OPJ_UINT32 p_header_size,
1874                                                                         opj_event_mgr_t * p_manager
1875                                     )
1876 {
1877         OPJ_UINT32 i, l_remaining_bytes;
1878
1879         /* preconditions */
1880         assert(p_header_data != 00);
1881         assert(jp2 != 00);
1882         assert(p_manager != 00);
1883
1884         if (jp2->jp2_state != JP2_STATE_SIGNATURE) {
1885                 opj_event_msg(p_manager, EVT_ERROR, "The ftyp box must be the second box in the file.\n");
1886                 return OPJ_FALSE;
1887         }
1888
1889         /* assure length of data is correct */
1890         if (p_header_size < 8) {
1891                 opj_event_msg(p_manager, EVT_ERROR, "Error with FTYP signature Box size\n");
1892                 return OPJ_FALSE;
1893         }
1894
1895         opj_read_bytes(p_header_data,&jp2->brand,4);            /* BR */
1896         p_header_data += 4;
1897
1898         opj_read_bytes(p_header_data,&jp2->minversion,4);               /* MinV */
1899         p_header_data += 4;
1900
1901         l_remaining_bytes = p_header_size - 8;
1902
1903         /* the number of remaining bytes should be a multiple of 4 */
1904         if ((l_remaining_bytes & 0x3) != 0) {
1905                 opj_event_msg(p_manager, EVT_ERROR, "Error with FTYP signature Box size\n");
1906                 return OPJ_FALSE;
1907         }
1908
1909         /* div by 4 */
1910         jp2->numcl = l_remaining_bytes >> 2;
1911         if (jp2->numcl) {
1912                 jp2->cl = (OPJ_UINT32 *) opj_malloc(jp2->numcl * sizeof(OPJ_UINT32));
1913                 if (jp2->cl == 00) {
1914                         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory with FTYP Box\n");
1915                         return OPJ_FALSE;
1916                 }
1917                 memset(jp2->cl,0,jp2->numcl * sizeof(OPJ_UINT32));
1918         }
1919
1920         for (i = 0; i < jp2->numcl; ++i)
1921         {
1922                 opj_read_bytes(p_header_data,&jp2->cl[i],4);            /* CLi */
1923                 p_header_data += 4;
1924         }
1925
1926         jp2->jp2_state |= JP2_STATE_FILE_TYPE;
1927
1928         return OPJ_TRUE;
1929 }
1930
1931 opj_bool opj_jp2_skip_jp2c(     opj_jp2_t *jp2,
1932                                                 opj_stream_private_t *stream,
1933                                                 opj_event_mgr_t * p_manager )
1934 {
1935         /* preconditions */
1936         assert(jp2 != 00);
1937         assert(stream != 00);
1938         assert(p_manager != 00);
1939
1940         jp2->j2k_codestream_offset = opj_stream_tell(stream);
1941
1942         if (opj_stream_skip(stream,8,p_manager) != 8) {
1943                 return OPJ_FALSE;
1944         }
1945
1946         return OPJ_TRUE;
1947 }
1948
1949 static opj_bool opj_jpip_skip_iptr(     opj_jp2_t *jp2,
1950   opj_stream_private_t *stream,
1951   opj_event_mgr_t * p_manager )
1952 {
1953   /* preconditions */
1954   assert(jp2 != 00);
1955   assert(stream != 00);
1956   assert(p_manager != 00);
1957
1958   jp2->jpip_iptr_offset = opj_stream_tell(stream);
1959
1960   if (opj_stream_skip(stream,24,p_manager) != 24) {
1961     return OPJ_FALSE;
1962   }
1963
1964   return OPJ_TRUE;
1965 }
1966
1967 /**
1968  * Reads the Jpeg2000 file Header box - JP2 Header box (warning, this is a super box).
1969  *
1970  * @param       p_header_data   the data contained in the file header box.
1971  * @param       jp2                             the jpeg2000 file codec.
1972  * @param       p_header_size   the size of the data contained in the file header box.
1973  * @param       p_manager               the user event manager.
1974  *
1975  * @return true if the JP2 Header box was successfully reconized.
1976 */
1977 static opj_bool opj_jp2_read_jp2h(  opj_jp2_t *jp2,
1978                                     OPJ_BYTE *p_header_data,
1979                                     OPJ_UINT32 p_header_size,
1980                                     opj_event_mgr_t * p_manager
1981                                     )
1982 {
1983         OPJ_UINT32 l_box_size=0, l_current_data_size = 0;
1984         opj_jp2_box_t box;
1985         const opj_jp2_header_handler_t * l_current_handler;
1986
1987         /* preconditions */
1988         assert(p_header_data != 00);
1989         assert(jp2 != 00);
1990         assert(p_manager != 00);
1991
1992         /* make sure the box is well placed */
1993         if ((jp2->jp2_state & JP2_STATE_FILE_TYPE) != JP2_STATE_FILE_TYPE ) {
1994                 opj_event_msg(p_manager, EVT_ERROR, "The  box must be the first box in the file.\n");
1995                 return OPJ_FALSE;
1996         }
1997
1998         jp2->jp2_img_state = JP2_IMG_STATE_NONE;
1999
2000         /* iterate while remaining data */
2001         while (p_header_size > 0) {
2002
2003                 if (! opj_jp2_read_boxhdr_char(&box,p_header_data,&l_box_size,p_header_size, p_manager)) {
2004                         opj_event_msg(p_manager, EVT_ERROR, "Stream error while reading JP2 Header box\n");
2005                         return OPJ_FALSE;
2006                 }
2007
2008                 if (box.length > p_header_size) {
2009                         opj_event_msg(p_manager, EVT_ERROR, "Stream error while reading JP2 Header box: box length is inconsistent.\n");
2010                         return OPJ_FALSE;
2011                 }
2012
2013                 l_current_handler = opj_jp2_img_find_handler(box.type);
2014                 l_current_data_size = box.length - l_box_size;
2015                 p_header_data += l_box_size;
2016
2017                 if (l_current_handler != 00) {
2018                         if (! l_current_handler->handler(jp2,p_header_data,l_current_data_size,p_manager)) {
2019                                 return OPJ_FALSE;
2020                         }
2021                 }
2022                 else {
2023                         jp2->jp2_img_state |= JP2_IMG_STATE_UNKNOWN;
2024                 }
2025
2026                 p_header_data += l_current_data_size;
2027                 p_header_size -= box.length;
2028         }
2029
2030         jp2->jp2_state |= JP2_STATE_HEADER;
2031
2032         return OPJ_TRUE;
2033 }
2034
2035 opj_bool opj_jp2_read_boxhdr_char(   opj_jp2_box_t *box,
2036                                      OPJ_BYTE * p_data,
2037                                      OPJ_UINT32 * p_number_bytes_read,
2038                                      OPJ_UINT32 p_box_max_size,
2039                                      opj_event_mgr_t * p_manager
2040                                      )
2041 {
2042         OPJ_UINT32 l_value;
2043
2044         /* preconditions */
2045         assert(p_data != 00);
2046         assert(box != 00);
2047         assert(p_number_bytes_read != 00);
2048         assert(p_manager != 00);
2049
2050         if (p_box_max_size < 8) {
2051                 opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box of less than 8 bytes\n");
2052                 return OPJ_FALSE;
2053         }
2054
2055         /* process read data */
2056         opj_read_bytes(p_data, &l_value, 4);
2057         p_data += 4;
2058         box->length = (OPJ_INT32)(l_value);
2059
2060         opj_read_bytes(p_data, &l_value, 4);
2061         p_data += 4;
2062         box->type = (OPJ_INT32)(l_value);
2063
2064         *p_number_bytes_read = 8;
2065
2066         /* do we have a "special very large box ?" */
2067         /* read then the XLBox */
2068         if (box->length == 1) {
2069                 OPJ_UINT32 l_xl_part_size;
2070
2071                 if (p_box_max_size < 16) {
2072                         opj_event_msg(p_manager, EVT_ERROR, "Cannot handle XL box of less than 16 bytes\n");
2073                         return OPJ_FALSE;
2074                 }
2075
2076                 opj_read_bytes(p_data,&l_xl_part_size, 4);
2077                 p_data += 4;
2078                 *p_number_bytes_read += 4;
2079
2080                 if (l_xl_part_size != 0) {
2081                         opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box sizes higher than 2^32\n");
2082                         return OPJ_FALSE;
2083                 }
2084
2085                 opj_read_bytes(p_data, &l_value, 4);
2086                 *p_number_bytes_read += 4;
2087                 box->length = (OPJ_INT32)(l_value);
2088
2089                 if (box->length == 0) {
2090                         opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box of undefined sizes\n");
2091                         return OPJ_FALSE;
2092                 }
2093         }
2094         else if (box->length == 0) {
2095                 opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box of undefined sizes\n");
2096                 return OPJ_FALSE;
2097         }
2098
2099         return OPJ_TRUE;
2100 }
2101
2102 opj_bool opj_jp2_read_header(   opj_stream_private_t *p_stream,
2103                                 opj_jp2_t *jp2,
2104                                 opj_image_t ** p_image,
2105                                 opj_event_mgr_t * p_manager
2106                                 )
2107 {
2108         /* preconditions */
2109         assert(jp2 != 00);
2110         assert(p_stream != 00);
2111         assert(p_manager != 00);
2112
2113         /* customization of the validation */
2114         opj_jp2_setup_decoding_validation (jp2);
2115
2116         /* customization of the encoding */
2117         opj_jp2_setup_header_reading(jp2);
2118
2119         /* validation of the parameters codec */
2120         if (! opj_jp2_exec(jp2,jp2->m_validation_list,p_stream,p_manager)) {
2121                 return OPJ_FALSE;
2122         }
2123
2124         /* read header */
2125         if (! opj_jp2_exec (jp2,jp2->m_procedure_list,p_stream,p_manager)) {
2126                 return OPJ_FALSE;
2127         }
2128
2129         return opj_j2k_read_header(     p_stream,
2130                                                         jp2->j2k,
2131                                                         p_image,
2132                                                         p_manager);
2133 }
2134
2135 void opj_jp2_setup_encoding_validation (opj_jp2_t *jp2)
2136 {
2137         /* preconditions */
2138         assert(jp2 != 00);
2139
2140         opj_procedure_list_add_procedure(jp2->m_validation_list, (opj_procedure)opj_jp2_default_validation);
2141         /* DEVELOPER CORNER, add your custom validation procedure */
2142 }
2143
2144 void opj_jp2_setup_decoding_validation (opj_jp2_t *jp2)
2145 {
2146         /* preconditions */
2147         assert(jp2 != 00);
2148         /* DEVELOPER CORNER, add your custom validation procedure */
2149 }
2150
2151 void opj_jp2_setup_header_writing (opj_jp2_t *jp2)
2152 {
2153         /* preconditions */
2154         assert(jp2 != 00);
2155
2156         opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_write_jp );
2157         opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_write_ftyp );
2158         opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_write_jp2h );
2159   if( jp2->jpip_on )
2160     opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jpip_skip_iptr );
2161         opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_skip_jp2c );
2162
2163         /* DEVELOPER CORNER, insert your custom procedures */
2164
2165 }
2166
2167 void opj_jp2_setup_header_reading (opj_jp2_t *jp2)
2168 {
2169         /* preconditions */
2170         assert(jp2 != 00);
2171
2172         opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_read_header_procedure );
2173         /* DEVELOPER CORNER, add your custom procedures */
2174 }
2175
2176 opj_bool opj_jp2_read_tile_header ( opj_jp2_t * p_jp2,
2177                                     OPJ_UINT32 * p_tile_index,
2178                                     OPJ_UINT32 * p_data_size,
2179                                     OPJ_INT32 * p_tile_x0,
2180                                     OPJ_INT32 * p_tile_y0,
2181                                     OPJ_INT32 * p_tile_x1,
2182                                     OPJ_INT32 * p_tile_y1,
2183                                     OPJ_UINT32 * p_nb_comps,
2184                                     opj_bool * p_go_on,
2185                                     opj_stream_private_t *p_stream,
2186                                     opj_event_mgr_t * p_manager
2187                                     )
2188 {
2189         return opj_j2k_read_tile_header(p_jp2->j2k,
2190                                                                 p_tile_index,
2191                                                                 p_data_size,
2192                                                                 p_tile_x0, p_tile_y0,
2193                                                                 p_tile_x1, p_tile_y1,
2194                                                                 p_nb_comps,
2195                                                                 p_go_on,
2196                                                                 p_stream,
2197                                                                 p_manager);
2198 }
2199
2200 opj_bool opj_jp2_write_tile (   opj_jp2_t *p_jp2,
2201                                                             OPJ_UINT32 p_tile_index,
2202                                                             OPJ_BYTE * p_data,
2203                                                             OPJ_UINT32 p_data_size,
2204                                                             opj_stream_private_t *p_stream,
2205                                                             opj_event_mgr_t * p_manager
2206                                 )
2207
2208 {
2209         return opj_j2k_write_tile (p_jp2->j2k,p_tile_index,p_data,p_data_size,p_stream,p_manager);
2210 }
2211
2212 opj_bool opj_jp2_decode_tile (  opj_jp2_t * p_jp2,
2213                                 OPJ_UINT32 p_tile_index,
2214                                 OPJ_BYTE * p_data,
2215                                 OPJ_UINT32 p_data_size,
2216                                 opj_stream_private_t *p_stream,
2217                                 opj_event_mgr_t * p_manager
2218                                 )
2219 {
2220         return opj_j2k_decode_tile (p_jp2->j2k,p_tile_index,p_data,p_data_size,p_stream,p_manager);
2221 }
2222
2223 void opj_jp2_destroy(opj_jp2_t *jp2)
2224 {
2225         if (jp2) {
2226                 /* destroy the J2K codec */
2227                 opj_j2k_destroy(jp2->j2k);
2228                 jp2->j2k = 00;
2229
2230                 if (jp2->comps) {
2231                         opj_free(jp2->comps);
2232                         jp2->comps = 00;
2233                 }
2234
2235                 if (jp2->cl) {
2236                         opj_free(jp2->cl);
2237                         jp2->cl = 00;
2238                 }
2239
2240                 if (jp2->color.icc_profile_buf) {
2241                         opj_free(jp2->color.icc_profile_buf);
2242                         jp2->color.icc_profile_buf = 00;
2243                 }
2244
2245                 if (jp2->color.jp2_cdef) {
2246                         if (jp2->color.jp2_cdef->info) {
2247                                 opj_free(jp2->color.jp2_cdef->info);
2248                                 jp2->color.jp2_cdef->info = NULL;
2249                         }
2250
2251                         opj_free(jp2->color.jp2_cdef);
2252                         jp2->color.jp2_cdef = 00;
2253                 }
2254
2255                 if (jp2->color.jp2_pclr) {
2256                         if (jp2->color.jp2_pclr->cmap) {
2257                                 opj_free(jp2->color.jp2_pclr->cmap);
2258                                 jp2->color.jp2_pclr->cmap = NULL;
2259                         }
2260                         if (jp2->color.jp2_pclr->channel_sign) {
2261                                 opj_free(jp2->color.jp2_pclr->channel_sign);
2262                                 jp2->color.jp2_pclr->channel_sign = NULL;
2263                         }
2264                         if (jp2->color.jp2_pclr->channel_size) {
2265                                 opj_free(jp2->color.jp2_pclr->channel_size);
2266                                 jp2->color.jp2_pclr->channel_size = NULL;
2267                         }
2268                         if (jp2->color.jp2_pclr->entries) {
2269                                 opj_free(jp2->color.jp2_pclr->entries);
2270                                 jp2->color.jp2_pclr->entries = NULL;
2271                         }
2272
2273                         opj_free(jp2->color.jp2_pclr);
2274                         jp2->color.jp2_pclr = 00;
2275                 }
2276
2277                 if (jp2->m_validation_list) {
2278                         opj_procedure_list_destroy(jp2->m_validation_list);
2279                         jp2->m_validation_list = 00;
2280                 }
2281
2282                 if (jp2->m_procedure_list) {
2283                         opj_procedure_list_destroy(jp2->m_procedure_list);
2284                         jp2->m_procedure_list = 00;
2285                 }
2286
2287                 opj_free(jp2);
2288         }
2289 }
2290
2291 opj_bool opj_jp2_set_decode_area(       opj_jp2_t *p_jp2,
2292                                                                     opj_image_t* p_image,
2293                                                                     OPJ_INT32 p_start_x, OPJ_INT32 p_start_y,
2294                                                                     OPJ_INT32 p_end_x, OPJ_INT32 p_end_y,
2295                                                                     opj_event_mgr_t * p_manager
2296                                     )
2297 {
2298         return opj_j2k_set_decode_area(p_jp2->j2k, p_image, p_start_x, p_start_y, p_end_x, p_end_y, p_manager);
2299 }
2300
2301 opj_bool opj_jp2_get_tile(      opj_jp2_t *p_jp2,
2302                             opj_stream_private_t *p_stream,
2303                             opj_image_t* p_image,
2304                             opj_event_mgr_t * p_manager,
2305                             OPJ_UINT32 tile_index
2306                             )
2307 {
2308         if (!p_image)
2309                 return OPJ_FALSE;
2310
2311         opj_event_msg(p_manager, EVT_WARNING, "JP2 box which are after the codestream will not be read by this function.\n");
2312
2313         if (! opj_j2k_get_tile(p_jp2->j2k, p_stream, p_image, p_manager, tile_index) ){
2314                 opj_event_msg(p_manager, EVT_ERROR, "Failed to decode the codestream in the JP2 file\n");
2315                 return OPJ_FALSE;
2316         }
2317
2318         /* Set Image Color Space */
2319         if (p_jp2->enumcs == 16)
2320                 p_image->color_space = OPJ_CLRSPC_SRGB;
2321         else if (p_jp2->enumcs == 17)
2322                 p_image->color_space = OPJ_CLRSPC_GRAY;
2323         else if (p_jp2->enumcs == 18)
2324                 p_image->color_space = OPJ_CLRSPC_SYCC;
2325         else
2326                 p_image->color_space = OPJ_CLRSPC_UNKNOWN;
2327
2328         /* Apply the color space if needed */
2329         if(p_jp2->color.jp2_cdef) {
2330                 opj_jp2_apply_cdef(p_image, &(p_jp2->color));
2331         }
2332
2333         if(p_jp2->color.jp2_pclr) {
2334                 /* Part 1, I.5.3.4: Either both or none : */
2335                 if( !p_jp2->color.jp2_pclr->cmap)
2336                         opj_jp2_free_pclr(&(p_jp2->color));
2337                 else
2338                         opj_jp2_apply_pclr(p_image, &(p_jp2->color));
2339         }
2340
2341         if(p_jp2->color.icc_profile_buf) {
2342                 p_image->icc_profile_buf = p_jp2->color.icc_profile_buf;
2343                 p_image->icc_profile_len = p_jp2->color.icc_profile_len;
2344                 p_jp2->color.icc_profile_buf = NULL;
2345         }
2346
2347         return OPJ_TRUE;
2348 }
2349
2350 /* ----------------------------------------------------------------------- */
2351 /* JP2 encoder interface                                             */
2352 /* ----------------------------------------------------------------------- */
2353
2354 opj_jp2_t* opj_jp2_create(opj_bool p_is_decoder)
2355 {
2356         opj_jp2_t *jp2 = (opj_jp2_t*)opj_malloc(sizeof(opj_jp2_t));
2357         if (jp2) {
2358                 memset(jp2,0,sizeof(opj_jp2_t));
2359
2360                 /* create the J2K codec */
2361                 if (! p_is_decoder) {
2362                         jp2->j2k = opj_j2k_create_compress();
2363                 }
2364                 else {
2365                         jp2->j2k = opj_j2k_create_decompress();
2366                 }
2367
2368                 if (jp2->j2k == 00) {
2369                         opj_jp2_destroy(jp2);
2370                         return 00;
2371                 }
2372
2373                 /* Color structure */
2374                 jp2->color.icc_profile_buf = NULL;
2375                 jp2->color.icc_profile_len = 0;
2376                 jp2->color.jp2_cdef = NULL;
2377                 jp2->color.jp2_pclr = NULL;
2378                 jp2->color.jp2_has_colr = 0;
2379
2380                 /* validation list creation */
2381                 jp2->m_validation_list = opj_procedure_list_create();
2382                 if (! jp2->m_validation_list) {
2383                         opj_jp2_destroy(jp2);
2384                         return 00;
2385                 }
2386
2387                 /* execution list creation */
2388                 jp2->m_procedure_list = opj_procedure_list_create();
2389                 if (! jp2->m_procedure_list) {
2390                         opj_jp2_destroy(jp2);
2391                         return 00;
2392                 }
2393         }
2394
2395         return jp2;
2396 }
2397
2398 void jp2_dump(opj_jp2_t* p_jp2, OPJ_INT32 flag, FILE* out_stream)
2399 {
2400         /* preconditions */
2401         assert(p_jp2 != 00);
2402
2403         j2k_dump(p_jp2->j2k,
2404                                         flag,
2405                                         out_stream);
2406 }
2407
2408 opj_codestream_index_t* jp2_get_cstr_index(opj_jp2_t* p_jp2)
2409 {
2410         return j2k_get_cstr_index(p_jp2->j2k);
2411 }
2412
2413 opj_codestream_info_v2_t* jp2_get_cstr_info(opj_jp2_t* p_jp2)
2414 {
2415         return j2k_get_cstr_info(p_jp2->j2k);
2416 }
2417
2418 opj_bool opj_jp2_set_decoded_resolution_factor(opj_jp2_t *p_jp2,
2419                                                OPJ_UINT32 res_factor,
2420                                                opj_event_mgr_t * p_manager)
2421 {
2422         return opj_j2k_set_decoded_resolution_factor(p_jp2->j2k, res_factor, p_manager);
2423 }
2424
2425 /* JPIP specific */
2426
2427 #ifdef USE_JPIP
2428 static opj_bool opj_jpip_write_iptr(opj_jp2_t *jp2,
2429   opj_stream_private_t *cio,
2430   opj_event_mgr_t * p_manager )
2431 {
2432   OPJ_OFF_T j2k_codestream_exit;
2433   OPJ_BYTE l_data_header [24];
2434
2435   /* preconditions */
2436   assert(jp2 != 00);
2437   assert(cio != 00);
2438   assert(p_manager != 00);
2439   assert(opj_stream_has_seek(cio));
2440
2441   j2k_codestream_exit = opj_stream_tell(cio);
2442   opj_write_bytes(l_data_header, 24, 4); /* size of iptr */
2443   opj_write_bytes(l_data_header + 4,JPIP_IPTR,4);                                                                          /* IPTR */
2444 #if 0
2445   opj_write_bytes(l_data_header + 4 + 4, 0, 8); /* offset */
2446   opj_write_bytes(l_data_header + 8 + 8, 0, 8); /* length */
2447 #else
2448   opj_write_double(l_data_header + 4 + 4, 0); /* offset */
2449   opj_write_double(l_data_header + 8 + 8, 0); /* length */
2450 #endif
2451
2452   if (! opj_stream_seek(cio,jp2->jpip_iptr_offset,p_manager)) {
2453     opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
2454     return OPJ_FALSE;
2455   }
2456
2457   if (opj_stream_write_data(cio,l_data_header,24,p_manager) != 24) {
2458     opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
2459     return OPJ_FALSE;
2460   }
2461
2462   if (! opj_stream_seek(cio,j2k_codestream_exit,p_manager)) {
2463     opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
2464     return OPJ_FALSE;
2465   }
2466
2467   return OPJ_TRUE;
2468 }
2469
2470 static opj_bool opj_jpip_write_fidx(opj_jp2_t *jp2,
2471   opj_stream_private_t *cio,
2472   opj_event_mgr_t * p_manager )
2473 {
2474   OPJ_OFF_T j2k_codestream_exit;
2475   OPJ_BYTE l_data_header [24];
2476
2477   /* preconditions */
2478   assert(jp2 != 00);
2479   assert(cio != 00);
2480   assert(p_manager != 00);
2481   assert(opj_stream_has_seek(cio));
2482
2483   opj_write_bytes(l_data_header, 24, 4); /* size of iptr */
2484   opj_write_bytes(l_data_header + 4,JPIP_FIDX,4);                                                                          /* IPTR */
2485   opj_write_double(l_data_header + 4 + 4, 0); /* offset */
2486   opj_write_double(l_data_header + 8 + 8, 0); /* length */
2487
2488   if (opj_stream_write_data(cio,l_data_header,24,p_manager) != 24) {
2489     opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
2490     return OPJ_FALSE;
2491   }
2492
2493   j2k_codestream_exit = opj_stream_tell(cio);
2494   if (! opj_stream_seek(cio,j2k_codestream_exit,p_manager)) {
2495     opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
2496     return OPJ_FALSE;
2497   }
2498
2499   return OPJ_TRUE;
2500 }
2501
2502 static opj_bool opj_jpip_write_cidx(opj_jp2_t *jp2,
2503   opj_stream_private_t *cio,
2504   opj_event_mgr_t * p_manager )
2505 {
2506   OPJ_OFF_T j2k_codestream_exit;
2507   OPJ_BYTE l_data_header [24];
2508
2509   /* preconditions */
2510   assert(jp2 != 00);
2511   assert(cio != 00);
2512   assert(p_manager != 00);
2513   assert(opj_stream_has_seek(cio));
2514
2515   j2k_codestream_exit = opj_stream_tell(cio);
2516   opj_write_bytes(l_data_header, 24, 4); /* size of iptr */
2517   opj_write_bytes(l_data_header + 4,JPIP_CIDX,4);                                                                          /* IPTR */
2518 #if 0
2519   opj_write_bytes(l_data_header + 4 + 4, 0, 8); /* offset */
2520   opj_write_bytes(l_data_header + 8 + 8, 0, 8); /* length */
2521 #else
2522   opj_write_double(l_data_header + 4 + 4, 0); /* offset */
2523   opj_write_double(l_data_header + 8 + 8, 0); /* length */
2524 #endif
2525
2526   if (! opj_stream_seek(cio,j2k_codestream_exit,p_manager)) {
2527     opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
2528     return OPJ_FALSE;
2529   }
2530
2531   if (opj_stream_write_data(cio,l_data_header,24,p_manager) != 24) {
2532     opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
2533     return OPJ_FALSE;
2534   }
2535
2536   j2k_codestream_exit = opj_stream_tell(cio);
2537   if (! opj_stream_seek(cio,j2k_codestream_exit,p_manager)) {
2538     opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
2539     return OPJ_FALSE;
2540   }
2541
2542   return OPJ_TRUE;
2543 }
2544
2545 static void write_prxy( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_stream_private_t *cio,
2546   opj_event_mgr_t * p_manager )
2547 {
2548   OPJ_BYTE l_data_header [8];
2549   OPJ_OFF_T len, lenp;
2550
2551   lenp = opj_stream_tell(cio);
2552   opj_stream_skip(cio, 4, p_manager);         /* L [at the end] */
2553   opj_write_bytes(l_data_header,JPIP_PRXY,4); /* IPTR           */
2554   opj_stream_write_data(cio,l_data_header,4,p_manager);
2555
2556   opj_write_bytes( l_data_header, offset_jp2c, 8); /* OOFF           */
2557   opj_stream_write_data(cio,l_data_header,8,p_manager);
2558   opj_write_bytes( l_data_header, length_jp2c, 4); /* OBH part 1     */
2559   opj_write_bytes( l_data_header+4, JP2_JP2C, 4);  /* OBH part 2     */
2560   opj_stream_write_data(cio,l_data_header,8,p_manager);
2561
2562   opj_write_bytes( l_data_header, 1, 1);/* NI             */
2563   opj_stream_write_data(cio,l_data_header,1,p_manager);
2564
2565   opj_write_bytes( l_data_header, offset_idx, 8);  /* IOFF           */
2566   opj_stream_write_data(cio,l_data_header,8,p_manager);
2567   opj_write_bytes( l_data_header, length_idx, 4);  /* IBH part 1     */
2568   opj_write_bytes( l_data_header+4, JPIP_CIDX, 4);   /* IBH part 2     */
2569   opj_stream_write_data(cio,l_data_header,8,p_manager);
2570
2571   len = opj_stream_tell(cio)-lenp;
2572   opj_stream_skip(cio, lenp, p_manager);
2573   opj_write_bytes(l_data_header,len,4);/* L              */
2574   opj_stream_write_data(cio,l_data_header,4,p_manager);
2575   opj_stream_seek(cio, lenp+len,p_manager);
2576 }
2577
2578
2579 static int write_fidx( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_stream_private_t *cio,
2580   opj_event_mgr_t * p_manager )
2581 {
2582   OPJ_BYTE l_data_header [4];
2583   OPJ_OFF_T len, lenp;
2584
2585   lenp = opj_stream_tell(cio);
2586   opj_stream_skip(cio, 4, p_manager);
2587   opj_write_bytes(l_data_header,JPIP_FIDX,4); /* FIDX */
2588   opj_stream_write_data(cio,l_data_header,4,p_manager);
2589
2590   write_prxy( offset_jp2c, length_jp2c, offset_idx, length_idx, cio,p_manager);
2591
2592   len = opj_stream_tell(cio)-lenp;
2593   opj_stream_skip(cio, lenp, p_manager);
2594   opj_write_bytes(l_data_header,len,4);/* L              */
2595   opj_stream_write_data(cio,l_data_header,4,p_manager);
2596   opj_stream_seek(cio, lenp+len,p_manager);
2597
2598   return len;
2599 }
2600 #endif /* USE_JPIP */