[trunk] Remove deprecated functions (not called anywhere in the code base).
[openjpeg.git] / src / lib / openjp2 / j2k.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) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes@c-s.fr>
9  * Copyright (c) 2006-2007, Parvatha Elangovan
10  * Copyright (c) 2010-2011, Kaori Hagihara
11  * Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France 
12  * Copyright (c) 2012, CS Systemes d'Information, France
13  * All rights reserved.
14  *
15  * Redistribution and use in source and binary forms, with or without
16  * modification, are permitted provided that the following conditions
17  * are met:
18  * 1. Redistributions of source code must retain the above copyright
19  *    notice, this list of conditions and the following disclaimer.
20  * 2. Redistributions in binary form must reproduce the above copyright
21  *    notice, this list of conditions and the following disclaimer in the
22  *    documentation and/or other materials provided with the distribution.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
25  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  */
36
37 #include "opj_includes.h"
38
39 #define CINEMA_24_CS 1302083    /*Codestream length for 24fps*/
40 #define CINEMA_48_CS 651041             /*Codestream length for 48fps*/
41 #define COMP_24_CS 1041666              /*Maximum size per color component for 2K & 4K @ 24fps*/
42 #define COMP_48_CS 520833               /*Maximum size per color component for 2K @ 48fps*/
43
44 /** @defgroup J2K J2K - JPEG-2000 codestream reader/writer */
45 /*@{*/
46
47 /** @name Local static functions */
48 /*@{*/
49
50 /**
51  * Sets up the procedures to do on reading header. Developpers wanting to extend the library can add their own reading procedures.
52  */
53 static void opj_j2k_setup_header_reading (opj_j2k_t *p_j2k);
54
55 /**
56  * The read header procedure.
57  */
58 static OPJ_BOOL opj_j2k_read_header_procedure(  opj_j2k_t *p_j2k,
59                                                 opj_stream_private_t *p_stream,
60                                                 opj_event_mgr_t * p_manager);
61
62 /**
63  * The default encoding validation procedure without any extension.
64  *
65  * @param       p_j2k                   the jpeg2000 codec to validate.
66  * @param       p_stream                the input stream to validate.
67  * @param       p_manager               the user event manager.
68  *
69  * @return true if the parameters are correct.
70  */
71 static OPJ_BOOL opj_j2k_encoding_validation (   opj_j2k_t * p_j2k,
72                                                 opj_stream_private_t *p_stream,
73                                                 opj_event_mgr_t * p_manager );
74
75 /**
76  * The default decoding validation procedure without any extension.
77  *
78  * @param       p_j2k                   the jpeg2000 codec to validate.
79  * @param       p_stream                                the input stream to validate.
80  * @param       p_manager               the user event manager.
81  *
82  * @return true if the parameters are correct.
83  */
84 static OPJ_BOOL opj_j2k_decoding_validation (   opj_j2k_t * p_j2k,
85                                                 opj_stream_private_t *p_stream,
86                                                 opj_event_mgr_t * p_manager );
87
88 /**
89  * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
90  * are valid. Developpers wanting to extend the library can add their own validation procedures.
91  */
92 static void opj_j2k_setup_encoding_validation (opj_j2k_t *p_j2k);
93
94 /**
95  * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
96  * are valid. Developpers wanting to extend the library can add their own validation procedures.
97  */
98 static void opj_j2k_setup_decoding_validation (opj_j2k_t *p_j2k);
99
100 /**
101  * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
102  * are valid. Developpers wanting to extend the library can add their own validation procedures.
103  */
104 static void opj_j2k_setup_end_compress (opj_j2k_t *p_j2k);
105
106 /**
107  * The mct encoding validation procedure.
108  *
109  * @param       p_j2k                   the jpeg2000 codec to validate.
110  * @param       p_stream                                the input stream to validate.
111  * @param       p_manager               the user event manager.
112  *
113  * @return true if the parameters are correct.
114  */
115 static OPJ_BOOL opj_j2k_mct_validation (opj_j2k_t * p_j2k,
116                                         opj_stream_private_t *p_stream,
117                                         opj_event_mgr_t * p_manager );
118
119 /**
120  * Builds the tcd decoder to use to decode tile.
121  */
122 static OPJ_BOOL opj_j2k_build_decoder ( opj_j2k_t * p_j2k,
123                                         opj_stream_private_t *p_stream,
124                                         opj_event_mgr_t * p_manager );
125 /**
126  * Builds the tcd encoder to use to encode tile.
127  */
128 static OPJ_BOOL opj_j2k_build_encoder ( opj_j2k_t * p_j2k,
129                                         opj_stream_private_t *p_stream,
130                                         opj_event_mgr_t * p_manager );
131
132 /**
133  * Creates a tile-coder decoder.
134  *
135  * @param       p_stream                        the stream to write data to.
136  * @param       p_j2k                           J2K codec.
137  * @param       p_manager                   the user event manager.
138 */
139 static OPJ_BOOL opj_j2k_create_tcd(     opj_j2k_t *p_j2k,
140                                                                     opj_stream_private_t *p_stream,
141                                                                     opj_event_mgr_t * p_manager );
142
143 /**
144  * Excutes the given procedures on the given codec.
145  *
146  * @param       p_procedure_list        the list of procedures to execute
147  * @param       p_j2k                           the jpeg2000 codec to execute the procedures on.
148  * @param       p_stream                        the stream to execute the procedures on.
149  * @param       p_manager                       the user manager.
150  *
151  * @return      true                            if all the procedures were successfully executed.
152  */
153 static OPJ_BOOL opj_j2k_exec (  opj_j2k_t * p_j2k,
154                             opj_procedure_list_t * p_procedure_list,
155                             opj_stream_private_t *p_stream,
156                             opj_event_mgr_t * p_manager);
157
158 /**
159  * Updates the rates of the tcp.
160  *
161  * @param       p_stream                                the stream to write data to.
162  * @param       p_j2k                           J2K codec.
163  * @param       p_manager               the user event manager.
164 */
165 static OPJ_BOOL opj_j2k_update_rates(   opj_j2k_t *p_j2k,
166                                                                             opj_stream_private_t *p_stream,
167                                                                             opj_event_mgr_t * p_manager );
168
169 /**
170  * Copies the decoding tile parameters onto all the tile parameters.
171  * Creates also the tile decoder.
172  */
173 static OPJ_BOOL opj_j2k_copy_default_tcp_and_create_tcd (       opj_j2k_t * p_j2k,
174                                                             opj_stream_private_t *p_stream,
175                                                             opj_event_mgr_t * p_manager );
176
177 /**
178  * Destroys the memory associated with the decoding of headers.
179  */
180 static OPJ_BOOL opj_j2k_destroy_header_memory ( opj_j2k_t * p_j2k,
181                                                 opj_stream_private_t *p_stream,
182                                                 opj_event_mgr_t * p_manager );
183
184 /**
185  * Reads the lookup table containing all the marker, status and action, and returns the handler associated
186  * with the marker value.
187  * @param       p_id            Marker value to look up
188  *
189  * @return      the handler associated with the id.
190 */
191 static const struct opj_dec_memory_marker_handler * opj_j2k_get_marker_handler (OPJ_UINT32 p_id);
192
193 /**
194  * Destroys a tile coding parameter structure.
195  *
196  * @param       p_tcp           the tile coding parameter to destroy.
197  */
198 static void opj_j2k_tcp_destroy (opj_tcp_t *p_tcp);
199
200 /**
201  * Destroys the data inside a tile coding parameter structure.
202  *
203  * @param       p_tcp           the tile coding parameter which contain data to destroy.
204  */
205 static void opj_j2k_tcp_data_destroy (opj_tcp_t *p_tcp);
206
207 /**
208  * Destroys a coding parameter structure.
209  *
210  * @param       p_cp            the coding parameter to destroy.
211  */
212 static void opj_j2k_cp_destroy (opj_cp_t *p_cp);
213
214 /**
215  * Writes a SPCod or SPCoc element, i.e. the coding style of a given component of a tile.
216  *
217  * @param       p_j2k           J2K codec.
218  * @param       p_tile_no       FIXME DOC
219  * @param       p_comp_no       the component number to output.
220  * @param       p_data          FIXME DOC
221  * @param       p_header_size   FIXME DOC
222  * @param       p_manager       the user event manager.
223  *
224  * @return FIXME DOC
225 */
226 static OPJ_BOOL opj_j2k_write_SPCod_SPCoc(      opj_j2k_t *p_j2k,
227                                                                                     OPJ_UINT32 p_tile_no,
228                                                                                     OPJ_UINT32 p_comp_no,
229                                                                                     OPJ_BYTE * p_data,
230                                                                                     OPJ_UINT32 * p_header_size,
231                                                                                     opj_event_mgr_t * p_manager );
232
233 /**
234  * Gets the size taken by writing a SPCod or SPCoc for the given tile and component.
235  *
236  * @param       p_j2k                   the J2K codec.
237  * @param       p_tile_no               the tile index.
238  * @param       p_comp_no               the component being outputted.
239  *
240  * @return      the number of bytes taken by the SPCod element.
241  */
242 static OPJ_UINT32 opj_j2k_get_SPCod_SPCoc_size (opj_j2k_t *p_j2k,
243                                                                                             OPJ_UINT32 p_tile_no,
244                                                                                             OPJ_UINT32 p_comp_no );
245
246 /**
247  * Reads a SPCod or SPCoc element, i.e. the coding style of a given component of a tile.
248  * @param       p_j2k           the jpeg2000 codec.
249  * @param       compno          FIXME DOC
250  * @param       p_header_data   the data contained in the COM box.
251  * @param       p_header_size   the size of the data contained in the COM marker.
252  * @param       p_manager       the user event manager.
253 */
254 static OPJ_BOOL opj_j2k_read_SPCod_SPCoc(   opj_j2k_t *p_j2k,
255                                             OPJ_UINT32 compno,
256                                             OPJ_BYTE * p_header_data,
257                                             OPJ_UINT32 * p_header_size,
258                                             opj_event_mgr_t * p_manager );
259
260 /**
261  * Gets the size taken by writing SQcd or SQcc element, i.e. the quantization values of a band in the QCD or QCC.
262  *
263  * @param       p_tile_no               the tile index.
264  * @param       p_comp_no               the component being outputted.
265  * @param       p_j2k                   the J2K codec.
266  *
267  * @return      the number of bytes taken by the SPCod element.
268  */
269 static OPJ_UINT32 opj_j2k_get_SQcd_SQcc_size (  opj_j2k_t *p_j2k,
270                                                                                     OPJ_UINT32 p_tile_no,
271                                                                                     OPJ_UINT32 p_comp_no );
272
273 /**
274  * Writes a SQcd or SQcc element, i.e. the quantization values of a band in the QCD or QCC.
275  *
276  * @param       p_tile_no               the tile to output.
277  * @param       p_comp_no               the component number to output.
278  * @param       p_data                  the data buffer.
279  * @param       p_header_size   pointer to the size of the data buffer, it is changed by the function.
280  * @param       p_j2k                   J2K codec.
281  * @param       p_manager               the user event manager.
282  *
283 */
284 static OPJ_BOOL opj_j2k_write_SQcd_SQcc(opj_j2k_t *p_j2k,
285                                                                             OPJ_UINT32 p_tile_no,
286                                                                             OPJ_UINT32 p_comp_no,
287                                                                             OPJ_BYTE * p_data,
288                                                                             OPJ_UINT32 * p_header_size,
289                                                                             opj_event_mgr_t * p_manager);
290
291 /**
292  * Updates the Tile Length Marker.
293  */
294 static void opj_j2k_update_tlm ( opj_j2k_t * p_j2k, OPJ_UINT32 p_tile_part_size);
295
296 /**
297  * Reads a SQcd or SQcc element, i.e. the quantization values of a band in the QCD or QCC.
298  *
299  * @param       p_j2k           J2K codec.
300  * @param       compno          the component number to output.
301  * @param       p_header_data   the data buffer.
302  * @param       p_header_size   pointer to the size of the data buffer, it is changed by the function.
303  * @param       p_manager       the user event manager.
304  *
305 */
306 static OPJ_BOOL opj_j2k_read_SQcd_SQcc( opj_j2k_t *p_j2k,
307                                         OPJ_UINT32 compno,
308                                         OPJ_BYTE * p_header_data,
309                                         OPJ_UINT32 * p_header_size,
310                                         opj_event_mgr_t * p_manager );
311
312 /**
313  * Copies the tile component parameters of all the component from the first tile component.
314  *
315  * @param               p_j2k           the J2k codec.
316  */
317 static void opj_j2k_copy_tile_component_parameters( opj_j2k_t *p_j2k );
318
319 /**
320  * Copies the tile quantization parameters of all the component from the first tile component.
321  *
322  * @param               p_j2k           the J2k codec.
323  */
324 static void opj_j2k_copy_tile_quantization_parameters( opj_j2k_t *p_j2k );
325
326 /**
327  * Reads the tiles.
328  */
329 static OPJ_BOOL opj_j2k_decode_tiles (  opj_j2k_t *p_j2k,
330                                         opj_stream_private_t *p_stream,
331                                         opj_event_mgr_t * p_manager);
332
333 static OPJ_BOOL opj_j2k_pre_write_tile ( opj_j2k_t * p_j2k,
334                                                                              OPJ_UINT32 p_tile_index,
335                                                                              opj_stream_private_t *p_stream,
336                                                                              opj_event_mgr_t * p_manager );
337
338 static OPJ_BOOL opj_j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data, opj_image_t* p_output_image);
339
340 static void opj_j2k_get_tile_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data);
341
342 static OPJ_BOOL opj_j2k_post_write_tile (opj_j2k_t * p_j2k,
343                                                                              OPJ_BYTE * p_data,
344                                                                              OPJ_UINT32 p_data_size,
345                                                                              opj_stream_private_t *p_stream,
346                                                                              opj_event_mgr_t * p_manager );
347
348 /**
349  * Sets up the procedures to do on writing header.
350  * Developers wanting to extend the library can add their own writing procedures.
351  */
352 static void opj_j2k_setup_header_writing (opj_j2k_t *p_j2k);
353
354 static OPJ_BOOL opj_j2k_write_first_tile_part(  opj_j2k_t *p_j2k,
355                                                                                             OPJ_BYTE * p_data,
356                                                                                             OPJ_UINT32 * p_data_written,
357                                                                                             OPJ_UINT32 p_total_data_size,
358                                                                                             opj_stream_private_t *p_stream,
359                                                                                             struct opj_event_mgr * p_manager );
360
361 static OPJ_BOOL opj_j2k_write_all_tile_parts(   opj_j2k_t *p_j2k,
362                                                                                             OPJ_BYTE * p_data,
363                                                                                             OPJ_UINT32 * p_data_written,
364                                                                                             OPJ_UINT32 p_total_data_size,
365                                                                                             opj_stream_private_t *p_stream,
366                                                                                             struct opj_event_mgr * p_manager );
367
368 /**
369  * Gets the offset of the header.
370  *
371  * @param       p_stream                the stream to write data to.
372  * @param       p_j2k                   J2K codec.
373  * @param       p_manager               the user event manager.
374 */
375 static OPJ_BOOL opj_j2k_get_end_header( opj_j2k_t *p_j2k,
376                                         opj_stream_private_t *p_stream,
377                                         opj_event_mgr_t * p_manager );
378
379 static OPJ_BOOL opj_j2k_allocate_tile_element_cstr_index(opj_j2k_t *p_j2k);
380
381 /*
382  * -----------------------------------------------------------------------
383  * -----------------------------------------------------------------------
384  * -----------------------------------------------------------------------
385  */
386
387 /**
388  * Writes the SOC marker (Start Of Codestream)
389  *
390  * @param       p_stream                        the stream to write data to.
391  * @param       p_j2k                   J2K codec.
392  * @param       p_manager       the user event manager.
393 */
394 static OPJ_BOOL opj_j2k_write_soc(      opj_j2k_t *p_j2k,
395                                                         opj_stream_private_t *p_stream,
396                                                             opj_event_mgr_t * p_manager );
397
398 /**
399  * Reads a SOC marker (Start of Codestream)
400  * @param       p_j2k           the jpeg2000 file codec.
401  * @param       p_stream        XXX needs data
402  * @param       p_manager       the user event manager.
403 */
404 static OPJ_BOOL opj_j2k_read_soc(   opj_j2k_t *p_j2k,
405                                     opj_stream_private_t *p_stream,
406                                     opj_event_mgr_t * p_manager );
407
408 /**
409  * Writes the SIZ marker (image and tile size)
410  *
411  * @param       p_j2k           J2K codec.
412  * @param       p_stream        the stream to write data to.
413  * @param       p_manager       the user event manager.
414 */
415 static OPJ_BOOL opj_j2k_write_siz(      opj_j2k_t *p_j2k,
416                                                                 opj_stream_private_t *p_stream,
417                                                                 opj_event_mgr_t * p_manager );
418
419 /**
420  * Reads a SIZ marker (image and tile size)
421  * @param       p_j2k           the jpeg2000 file codec.
422  * @param       p_header_data   the data contained in the SIZ box.
423  * @param       p_header_size   the size of the data contained in the SIZ marker.
424  * @param       p_manager       the user event manager.
425 */
426 static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k,
427                                  OPJ_BYTE * p_header_data,
428                                  OPJ_UINT32 p_header_size,
429                                  opj_event_mgr_t * p_manager);
430
431 /**
432  * Writes the COM marker (comment)
433  *
434  * @param       p_stream                        the stream to write data to.
435  * @param       p_j2k                   J2K codec.
436  * @param       p_manager       the user event manager.
437 */
438 static OPJ_BOOL opj_j2k_write_com(      opj_j2k_t *p_j2k,
439                                                                         opj_stream_private_t *p_stream,
440                                                                         opj_event_mgr_t * p_manager );
441
442 /**
443  * Reads a COM marker (comments)
444  * @param       p_j2k           the jpeg2000 file codec.
445  * @param       p_header_data   the data contained in the COM box.
446  * @param       p_header_size   the size of the data contained in the COM marker.
447  * @param       p_manager       the user event manager.
448 */
449 static OPJ_BOOL opj_j2k_read_com (  opj_j2k_t *p_j2k,
450                                     OPJ_BYTE * p_header_data,
451                                     OPJ_UINT32 p_header_size,
452                                     opj_event_mgr_t * p_manager );
453 /**
454  * Writes the COD marker (Coding style default)
455  *
456  * @param       p_stream                        the stream to write data to.
457  * @param       p_j2k                   J2K codec.
458  * @param       p_manager       the user event manager.
459 */
460 static OPJ_BOOL opj_j2k_write_cod(      opj_j2k_t *p_j2k,
461                                                                         opj_stream_private_t *p_stream,
462                                                                         opj_event_mgr_t * p_manager );
463
464 /**
465  * Reads a COD marker (Coding Styke defaults)
466  * @param       p_header_data   the data contained in the COD box.
467  * @param       p_j2k                   the jpeg2000 codec.
468  * @param       p_header_size   the size of the data contained in the COD marker.
469  * @param       p_manager               the user event manager.
470 */
471 static OPJ_BOOL opj_j2k_read_cod (  opj_j2k_t *p_j2k,
472                                     OPJ_BYTE * p_header_data,
473                                     OPJ_UINT32 p_header_size,
474                                     opj_event_mgr_t * p_manager);
475
476 #if 0
477 /**
478  * Writes the COC marker (Coding style component)
479  *
480  * @param       p_j2k       J2K codec.
481  * @param       p_comp_no   the index of the component to output.
482  * @param       p_stream    the stream to write data to.
483  * @param       p_manager   the user event manager.
484 */
485 static OPJ_BOOL opj_j2k_write_coc(  opj_j2k_t *p_j2k,
486                                                                 OPJ_UINT32 p_comp_no,
487                                                                 opj_stream_private_t *p_stream,
488                                                                 opj_event_mgr_t * p_manager );
489 #endif
490
491 #if 0
492 /**
493  * Writes the COC marker (Coding style component)
494  *
495  * @param       p_j2k                   J2K codec.
496  * @param       p_comp_no               the index of the component to output.
497  * @param       p_data          FIXME DOC
498  * @param       p_data_written  FIXME DOC
499  * @param       p_manager               the user event manager.
500 */
501 static void opj_j2k_write_coc_in_memory(opj_j2k_t *p_j2k,
502                                                                             OPJ_UINT32 p_comp_no,
503                                                                             OPJ_BYTE * p_data,
504                                                                             OPJ_UINT32 * p_data_written,
505                                                                             opj_event_mgr_t * p_manager );
506 #endif
507
508 /**
509  * Gets the maximum size taken by a coc.
510  *
511  * @param       p_j2k   the jpeg2000 codec to use.
512  */
513 static OPJ_UINT32 opj_j2k_get_max_coc_size(opj_j2k_t *p_j2k);
514
515 /**
516  * Reads a COC marker (Coding Style Component)
517  * @param       p_header_data   the data contained in the COC box.
518  * @param       p_j2k                   the jpeg2000 codec.
519  * @param       p_header_size   the size of the data contained in the COC marker.
520  * @param       p_manager               the user event manager.
521 */
522 static OPJ_BOOL opj_j2k_read_coc (  opj_j2k_t *p_j2k,
523                                     OPJ_BYTE * p_header_data,
524                                     OPJ_UINT32 p_header_size,
525                                     opj_event_mgr_t * p_manager );
526
527 /**
528  * Writes the QCD marker (quantization default)
529  *
530  * @param       p_j2k                   J2K codec.
531  * @param       p_stream                the stream to write data to.
532  * @param       p_manager               the user event manager.
533 */
534 static OPJ_BOOL opj_j2k_write_qcd(      opj_j2k_t *p_j2k,
535                                                                         opj_stream_private_t *p_stream,
536                                                                         opj_event_mgr_t * p_manager );
537
538 /**
539  * Reads a QCD marker (Quantization defaults)
540  * @param       p_header_data   the data contained in the QCD box.
541  * @param       p_j2k                   the jpeg2000 codec.
542  * @param       p_header_size   the size of the data contained in the QCD marker.
543  * @param       p_manager               the user event manager.
544 */
545 static OPJ_BOOL opj_j2k_read_qcd (  opj_j2k_t *p_j2k,
546                                     OPJ_BYTE * p_header_data,
547                                     OPJ_UINT32 p_header_size,
548                                     opj_event_mgr_t * p_manager );
549 #if 0
550 /**
551  * Writes the QCC marker (quantization component)
552  *
553  * @param       p_comp_no       the index of the component to output.
554  * @param       p_stream                the stream to write data to.
555  * @param       p_j2k                   J2K codec.
556  * @param       p_manager               the user event manager.
557 */
558 static OPJ_BOOL opj_j2k_write_qcc(      opj_j2k_t *p_j2k,
559                                                                         OPJ_UINT32 p_comp_no,
560                                                                         opj_stream_private_t *p_stream,
561                                                                         opj_event_mgr_t * p_manager );
562 #endif
563
564 #if 0
565 /**
566  * Writes the QCC marker (quantization component)
567  *
568  * @param       p_j2k           J2K codec.
569  * @param       p_comp_no       the index of the component to output.
570  * @param       p_data          FIXME DOC
571  * @param       p_data_written  the stream to write data to.
572  * @param       p_manager       the user event manager.
573 */
574 static void opj_j2k_write_qcc_in_memory(opj_j2k_t *p_j2k,
575                                                                             OPJ_UINT32 p_comp_no,
576                                                                             OPJ_BYTE * p_data,
577                                                                             OPJ_UINT32 * p_data_written,
578                                                                             opj_event_mgr_t * p_manager );
579 #endif
580
581 /**
582  * Gets the maximum size taken by a qcc.
583  */
584 static OPJ_UINT32 opj_j2k_get_max_qcc_size (opj_j2k_t *p_j2k);
585
586 /**
587  * Reads a QCC marker (Quantization component)
588  * @param       p_header_data   the data contained in the QCC box.
589  * @param       p_j2k                   the jpeg2000 codec.
590  * @param       p_header_size   the size of the data contained in the QCC marker.
591  * @param       p_manager               the user event manager.
592 */
593 static OPJ_BOOL opj_j2k_read_qcc(   opj_j2k_t *p_j2k,
594                                     OPJ_BYTE * p_header_data,
595                                     OPJ_UINT32 p_header_size,
596                                     opj_event_mgr_t * p_manager);
597 /**
598  * Writes the POC marker (Progression Order Change)
599  *
600  * @param       p_stream                                the stream to write data to.
601  * @param       p_j2k                           J2K codec.
602  * @param       p_manager               the user event manager.
603 */
604 static OPJ_BOOL opj_j2k_write_poc(      opj_j2k_t *p_j2k,
605                                                                         opj_stream_private_t *p_stream,
606                                                                         opj_event_mgr_t * p_manager );
607 /**
608  * Writes the POC marker (Progression Order Change)
609  *
610  * @param       p_j2k          J2K codec.
611  * @param       p_data         FIXME DOC
612  * @param       p_data_written the stream to write data to.
613  * @param       p_manager      the user event manager.
614  */
615 static void opj_j2k_write_poc_in_memory(opj_j2k_t *p_j2k,
616                                                                             OPJ_BYTE * p_data,
617                                                                             OPJ_UINT32 * p_data_written,
618                                                                             opj_event_mgr_t * p_manager );
619 /**
620  * Gets the maximum size taken by the writing of a POC.
621  */
622 static OPJ_UINT32 opj_j2k_get_max_poc_size(opj_j2k_t *p_j2k);
623
624 /**
625  * Reads a POC marker (Progression Order Change)
626  *
627  * @param       p_header_data   the data contained in the POC box.
628  * @param       p_j2k                   the jpeg2000 codec.
629  * @param       p_header_size   the size of the data contained in the POC marker.
630  * @param       p_manager               the user event manager.
631 */
632 static OPJ_BOOL opj_j2k_read_poc (  opj_j2k_t *p_j2k,
633                                     OPJ_BYTE * p_header_data,
634                                     OPJ_UINT32 p_header_size,
635                                     opj_event_mgr_t * p_manager );
636
637 /**
638  * Gets the maximum size taken by the toc headers of all the tile parts of any given tile.
639  */
640 static OPJ_UINT32 opj_j2k_get_max_toc_size (opj_j2k_t *p_j2k);
641
642 /**
643  * Gets the maximum size taken by the headers of the SOT.
644  *
645  * @param       p_j2k   the jpeg2000 codec to use.
646  */
647 static OPJ_UINT32 opj_j2k_get_specific_header_sizes(opj_j2k_t *p_j2k);
648
649 /**
650  * Reads a CRG marker (Component registration)
651  *
652  * @param       p_header_data   the data contained in the TLM box.
653  * @param       p_j2k                   the jpeg2000 codec.
654  * @param       p_header_size   the size of the data contained in the TLM marker.
655  * @param       p_manager               the user event manager.
656 */
657 static OPJ_BOOL opj_j2k_read_crg (  opj_j2k_t *p_j2k,
658                                     OPJ_BYTE * p_header_data,
659                                     OPJ_UINT32 p_header_size,
660                                     opj_event_mgr_t * p_manager );
661 /**
662  * Reads a TLM marker (Tile Length Marker)
663  *
664  * @param       p_header_data   the data contained in the TLM box.
665  * @param       p_j2k                   the jpeg2000 codec.
666  * @param       p_header_size   the size of the data contained in the TLM marker.
667  * @param       p_manager               the user event manager.
668 */
669 static OPJ_BOOL opj_j2k_read_tlm (  opj_j2k_t *p_j2k,
670                                     OPJ_BYTE * p_header_data,
671                                     OPJ_UINT32 p_header_size,
672                                     opj_event_mgr_t * p_manager);
673
674 /**
675  * Writes the updated tlm.
676  *
677  * @param       p_stream                the stream to write data to.
678  * @param       p_j2k                   J2K codec.
679  * @param       p_manager               the user event manager.
680 */
681 static OPJ_BOOL opj_j2k_write_updated_tlm(      opj_j2k_t *p_j2k,
682                                             opj_stream_private_t *p_stream,
683                                             opj_event_mgr_t * p_manager );
684
685 /**
686  * Reads a PLM marker (Packet length, main header marker)
687  *
688  * @param       p_header_data   the data contained in the TLM box.
689  * @param       p_j2k                   the jpeg2000 codec.
690  * @param       p_header_size   the size of the data contained in the TLM marker.
691  * @param       p_manager               the user event manager.
692 */
693 static OPJ_BOOL opj_j2k_read_plm (  opj_j2k_t *p_j2k,
694                                     OPJ_BYTE * p_header_data,
695                                     OPJ_UINT32 p_header_size,
696                                     opj_event_mgr_t * p_manager);
697 /**
698  * Reads a PLT marker (Packet length, tile-part header)
699  *
700  * @param       p_header_data   the data contained in the PLT box.
701  * @param       p_j2k                   the jpeg2000 codec.
702  * @param       p_header_size   the size of the data contained in the PLT marker.
703  * @param       p_manager               the user event manager.
704 */
705 static OPJ_BOOL opj_j2k_read_plt (  opj_j2k_t *p_j2k,
706                                     OPJ_BYTE * p_header_data,
707                                     OPJ_UINT32 p_header_size,
708                                     opj_event_mgr_t * p_manager );
709
710 #if 0
711 /**
712  * Reads a PPM marker (Packed packet headers, main header)
713  *
714  * @param       p_header_data   the data contained in the POC box.
715  * @param       p_j2k                   the jpeg2000 codec.
716  * @param       p_header_size   the size of the data contained in the POC marker.
717  * @param       p_manager               the user event manager.
718 */
719 static OPJ_BOOL j2k_read_ppm_v2 (
720                                                 opj_j2k_t *p_j2k,
721                                                 OPJ_BYTE * p_header_data,
722                                                 OPJ_UINT32 p_header_size,
723                                                 struct opj_event_mgr * p_manager
724                                         );
725 #endif
726
727 static OPJ_BOOL j2k_read_ppm_v3 (
728                                                 opj_j2k_t *p_j2k,
729                                                 OPJ_BYTE * p_header_data,
730                                                 OPJ_UINT32 p_header_size,
731                                                 opj_event_mgr_t * p_manager );
732
733 /**
734  * Reads a PPT marker (Packed packet headers, tile-part header)
735  *
736  * @param       p_header_data   the data contained in the PPT box.
737  * @param       p_j2k                   the jpeg2000 codec.
738  * @param       p_header_size   the size of the data contained in the PPT marker.
739  * @param       p_manager               the user event manager.
740 */
741 static OPJ_BOOL opj_j2k_read_ppt (  opj_j2k_t *p_j2k,
742                                     OPJ_BYTE * p_header_data,
743                                     OPJ_UINT32 p_header_size,
744                                     opj_event_mgr_t * p_manager );
745 /**
746  * Writes the TLM marker (Tile Length Marker)
747  *
748  * @param       p_stream                                the stream to write data to.
749  * @param       p_j2k                           J2K codec.
750  * @param       p_manager               the user event manager.
751 */
752 static OPJ_BOOL opj_j2k_write_tlm(      opj_j2k_t *p_j2k,
753                                                                         opj_stream_private_t *p_stream,
754                                                                         opj_event_mgr_t * p_manager );
755
756 /**
757  * Writes the SOT marker (Start of tile-part)
758  *
759  * @param       p_j2k            J2K codec.
760  * @param       p_data           FIXME DOC
761  * @param       p_data_written   FIXME DOC
762  * @param       p_stream         the stream to write data to.
763  * @param       p_manager        the user event manager.
764 */
765 static OPJ_BOOL opj_j2k_write_sot(      opj_j2k_t *p_j2k,
766                                                                         OPJ_BYTE * p_data,
767                                                                         OPJ_UINT32 * p_data_written,
768                                                                         const opj_stream_private_t *p_stream,
769                                                                         opj_event_mgr_t * p_manager );
770
771 /**
772  * Reads a PPT marker (Packed packet headers, tile-part header)
773  *
774  * @param       p_header_data   the data contained in the PPT box.
775  * @param       p_j2k                   the jpeg2000 codec.
776  * @param       p_header_size   the size of the data contained in the PPT marker.
777  * @param       p_manager               the user event manager.
778 */
779 static OPJ_BOOL opj_j2k_read_sot (  opj_j2k_t *p_j2k,
780                                     OPJ_BYTE * p_header_data,
781                                     OPJ_UINT32 p_header_size,
782                                     opj_event_mgr_t * p_manager );
783 /**
784  * Writes the SOD marker (Start of data)
785  *
786  * @param       p_j2k               J2K codec.
787  * @param       p_tile_coder        FIXME DOC
788  * @param       p_data              FIXME DOC
789  * @param       p_data_written      FIXME DOC
790  * @param       p_total_data_size   FIXME DOC
791  * @param       p_stream            the stream to write data to.
792  * @param       p_manager           the user event manager.
793 */
794 static OPJ_BOOL opj_j2k_write_sod(      opj_j2k_t *p_j2k,
795                                                                         opj_tcd_t * p_tile_coder,
796                                                                         OPJ_BYTE * p_data,
797                                                                         OPJ_UINT32 * p_data_written,
798                                                                         OPJ_UINT32 p_total_data_size,
799                                                                         const opj_stream_private_t *p_stream,
800                                                                         opj_event_mgr_t * p_manager );
801
802 /**
803  * Reads a SOD marker (Start Of Data)
804  *
805  * @param       p_j2k                   the jpeg2000 codec.
806  * @param       p_stream                FIXME DOC
807  * @param       p_manager               the user event manager.
808 */
809 static OPJ_BOOL opj_j2k_read_sod(   opj_j2k_t *p_j2k,
810                                     opj_stream_private_t *p_stream,
811                                     opj_event_mgr_t * p_manager );
812
813 void opj_j2k_update_tlm (opj_j2k_t * p_j2k, OPJ_UINT32 p_tile_part_size )
814 {
815         opj_write_bytes(p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current,p_j2k->m_current_tile_number,1);            /* PSOT */
816         ++p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current;
817
818         opj_write_bytes(p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current,p_tile_part_size,4);                                        /* PSOT */
819         p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current += 4;
820 }
821
822 /**
823  * Writes the RGN marker (Region Of Interest)
824  *
825  * @param       p_tile_no               the tile to output
826  * @param       p_comp_no               the component to output
827  * @param       nb_comps                the number of components
828  * @param       p_stream                the stream to write data to.
829  * @param       p_j2k                   J2K codec.
830  * @param       p_manager               the user event manager.
831 */
832 static OPJ_BOOL opj_j2k_write_rgn(  opj_j2k_t *p_j2k,
833                                     OPJ_UINT32 p_tile_no,
834                                     OPJ_UINT32 p_comp_no,
835                                     OPJ_UINT32 nb_comps,
836                                     opj_stream_private_t *p_stream,
837                                     opj_event_mgr_t * p_manager );
838
839 /**
840  * Reads a RGN marker (Region Of Interest)
841  *
842  * @param       p_header_data   the data contained in the POC box.
843  * @param       p_j2k                   the jpeg2000 codec.
844  * @param       p_header_size   the size of the data contained in the POC marker.
845  * @param       p_manager               the user event manager.
846 */
847 static OPJ_BOOL opj_j2k_read_rgn (opj_j2k_t *p_j2k,
848                                   OPJ_BYTE * p_header_data,
849                                   OPJ_UINT32 p_header_size,
850                                   opj_event_mgr_t * p_manager );
851
852 /**
853  * Writes the EOC marker (End of Codestream)
854  *
855  * @param       p_stream                the stream to write data to.
856  * @param       p_j2k                   J2K codec.
857  * @param       p_manager               the user event manager.
858 */
859 static OPJ_BOOL opj_j2k_write_eoc(      opj_j2k_t *p_j2k,
860                                     opj_stream_private_t *p_stream,
861                                     opj_event_mgr_t * p_manager );
862
863 #if 0
864 /**
865  * Reads a EOC marker (End Of Codestream)
866  *
867  * @param       p_j2k                   the jpeg2000 codec.
868  * @param       p_stream                FIXME DOC
869  * @param       p_manager               the user event manager.
870 */
871 static OPJ_BOOL opj_j2k_read_eoc (      opj_j2k_t *p_j2k,
872                                                                 opj_stream_private_t *p_stream,
873                                                                 opj_event_mgr_t * p_manager );
874 #endif
875
876 /**
877  * Writes the CBD-MCT-MCC-MCO markers (Multi components transform)
878  *
879  * @param       p_stream                        the stream to write data to.
880  * @param       p_j2k                   J2K codec.
881  * @param       p_manager       the user event manager.
882 */
883 static OPJ_BOOL opj_j2k_write_mct_data_group(   opj_j2k_t *p_j2k,
884                                                 opj_stream_private_t *p_stream,
885                                                 opj_event_mgr_t * p_manager );
886
887 /**
888  * Inits the Info
889  *
890  * @param       p_stream                the stream to write data to.
891  * @param       p_j2k                   J2K codec.
892  * @param       p_manager               the user event manager.
893 */
894 static OPJ_BOOL opj_j2k_init_info(      opj_j2k_t *p_j2k,
895                                     opj_stream_private_t *p_stream,
896                                     opj_event_mgr_t * p_manager );
897
898 /**
899 Add main header marker information
900 @param cstr_index    Codestream information structure
901 @param type         marker type
902 @param pos          byte offset of marker segment
903 @param len          length of marker segment
904  */
905 static OPJ_BOOL opj_j2k_add_mhmarker(opj_codestream_index_t *cstr_index, OPJ_UINT32 type, OPJ_OFF_T pos, OPJ_UINT32 len) ;
906 /**
907 Add tile header marker information
908 @param tileno       tile index number
909 @param cstr_index   Codestream information structure
910 @param type         marker type
911 @param pos          byte offset of marker segment
912 @param len          length of marker segment
913  */
914 static OPJ_BOOL opj_j2k_add_tlmarker(OPJ_UINT32 tileno, opj_codestream_index_t *cstr_index, OPJ_UINT32 type, OPJ_OFF_T pos, OPJ_UINT32 len);
915
916 /**
917  * Reads an unknown marker
918  *
919  * @param       p_j2k                   the jpeg2000 codec.
920  * @param       p_stream                the stream object to read from.
921  * @param       output_marker           FIXME DOC
922  * @param       p_manager               the user event manager.
923  *
924  * @return      true                    if the marker could be deduced.
925 */
926 static OPJ_BOOL opj_j2k_read_unk( opj_j2k_t *p_j2k,
927                                   opj_stream_private_t *p_stream,
928                                   OPJ_UINT32 *output_marker,
929                                   opj_event_mgr_t * p_manager );
930
931 /**
932  * Writes the MCT marker (Multiple Component Transform)
933  *
934  * @param       p_j2k           J2K codec.
935  * @param       p_mct_record    FIXME DOC
936  * @param       p_stream        the stream to write data to.
937  * @param       p_manager       the user event manager.
938 */
939 static OPJ_BOOL opj_j2k_write_mct_record(       opj_j2k_t *p_j2k,
940                                                                                     opj_mct_data_t * p_mct_record,
941                                             opj_stream_private_t *p_stream,
942                                             opj_event_mgr_t * p_manager );
943
944 /**
945  * Reads a MCT marker (Multiple Component Transform)
946  *
947  * @param       p_header_data   the data contained in the MCT box.
948  * @param       p_j2k                   the jpeg2000 codec.
949  * @param       p_header_size   the size of the data contained in the MCT marker.
950  * @param       p_manager               the user event manager.
951 */
952 static OPJ_BOOL opj_j2k_read_mct (      opj_j2k_t *p_j2k,
953                                                                     OPJ_BYTE * p_header_data,
954                                                                     OPJ_UINT32 p_header_size,
955                                                                     opj_event_mgr_t * p_manager );
956
957 /**
958  * Writes the MCC marker (Multiple Component Collection)
959  *
960  * @param       p_j2k                   J2K codec.
961  * @param       p_mcc_record            FIXME DOC
962  * @param       p_stream                the stream to write data to.
963  * @param       p_manager               the user event manager.
964 */
965 static OPJ_BOOL opj_j2k_write_mcc_record(   opj_j2k_t *p_j2k,
966                                             opj_simple_mcc_decorrelation_data_t * p_mcc_record,
967                                             opj_stream_private_t *p_stream,
968                                             opj_event_mgr_t * p_manager );
969
970 /**
971  * Reads a MCC marker (Multiple Component Collection)
972  *
973  * @param       p_header_data   the data contained in the MCC box.
974  * @param       p_j2k                   the jpeg2000 codec.
975  * @param       p_header_size   the size of the data contained in the MCC marker.
976  * @param       p_manager               the user event manager.
977 */
978 static OPJ_BOOL opj_j2k_read_mcc (      opj_j2k_t *p_j2k,
979                                                                     OPJ_BYTE * p_header_data,
980                                                                     OPJ_UINT32 p_header_size,
981                                                                     opj_event_mgr_t * p_manager );
982
983 /**
984  * Writes the MCO marker (Multiple component transformation ordering)
985  *
986  * @param       p_stream                                the stream to write data to.
987  * @param       p_j2k                           J2K codec.
988  * @param       p_manager               the user event manager.
989 */
990 static OPJ_BOOL opj_j2k_write_mco(      opj_j2k_t *p_j2k,
991                                     opj_stream_private_t *p_stream,
992                                     opj_event_mgr_t * p_manager );
993
994 /**
995  * Reads a MCO marker (Multiple Component Transform Ordering)
996  *
997  * @param       p_header_data   the data contained in the MCO box.
998  * @param       p_j2k                   the jpeg2000 codec.
999  * @param       p_header_size   the size of the data contained in the MCO marker.
1000  * @param       p_manager               the user event manager.
1001 */
1002 static OPJ_BOOL opj_j2k_read_mco (      opj_j2k_t *p_j2k,
1003                                                                     OPJ_BYTE * p_header_data,
1004                                                                     OPJ_UINT32 p_header_size,
1005                                                                     opj_event_mgr_t * p_manager );
1006
1007 static OPJ_BOOL opj_j2k_add_mct(opj_tcp_t * p_tcp, opj_image_t * p_image, OPJ_UINT32 p_index);
1008
1009 static void  opj_j2k_read_int16_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
1010 static void  opj_j2k_read_int32_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
1011 static void  opj_j2k_read_float32_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
1012 static void  opj_j2k_read_float64_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
1013
1014 static void  opj_j2k_read_int16_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
1015 static void  opj_j2k_read_int32_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
1016 static void  opj_j2k_read_float32_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
1017 static void  opj_j2k_read_float64_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
1018
1019 static void  opj_j2k_write_float_to_int16 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
1020 static void  opj_j2k_write_float_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
1021 static void  opj_j2k_write_float_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
1022 static void  opj_j2k_write_float_to_float64 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
1023
1024 /**
1025  * Ends the encoding, i.e. frees memory.
1026  *
1027  * @param       p_stream                the stream to write data to.
1028  * @param       p_j2k                   J2K codec.
1029  * @param       p_manager               the user event manager.
1030 */
1031 static OPJ_BOOL opj_j2k_end_encoding(   opj_j2k_t *p_j2k,
1032                                                                             opj_stream_private_t *p_stream,
1033                                                                             opj_event_mgr_t * p_manager );
1034
1035 /**
1036  * Writes the CBD marker (Component bit depth definition)
1037  *
1038  * @param       p_stream                                the stream to write data to.
1039  * @param       p_j2k                           J2K codec.
1040  * @param       p_manager               the user event manager.
1041 */
1042 static OPJ_BOOL opj_j2k_write_cbd(      opj_j2k_t *p_j2k,
1043                                                                     opj_stream_private_t *p_stream,
1044                                                                         opj_event_mgr_t * p_manager );
1045
1046 /**
1047  * Reads a CBD marker (Component bit depth definition)
1048  * @param       p_header_data   the data contained in the CBD box.
1049  * @param       p_j2k                   the jpeg2000 codec.
1050  * @param       p_header_size   the size of the data contained in the CBD marker.
1051  * @param       p_manager               the user event manager.
1052 */
1053 static OPJ_BOOL opj_j2k_read_cbd (      opj_j2k_t *p_j2k,
1054                                                                 OPJ_BYTE * p_header_data,
1055                                                                 OPJ_UINT32 p_header_size,
1056                                                                 opj_event_mgr_t * p_manager);
1057
1058 #if 0
1059 /**
1060  * Writes COC marker for each component.
1061  *
1062  * @param       p_stream                the stream to write data to.
1063  * @param       p_j2k                   J2K codec.
1064  * @param       p_manager               the user event manager.
1065 */
1066 static OPJ_BOOL opj_j2k_write_all_coc( opj_j2k_t *p_j2k,
1067                                                                         opj_stream_private_t *p_stream,
1068                                                                         opj_event_mgr_t * p_manager );
1069 #endif
1070
1071 #if 0
1072 /**
1073  * Writes QCC marker for each component.
1074  *
1075  * @param       p_stream                the stream to write data to.
1076  * @param       p_j2k                   J2K codec.
1077  * @param       p_manager               the user event manager.
1078 */
1079 static OPJ_BOOL opj_j2k_write_all_qcc( opj_j2k_t *p_j2k,
1080                                                                         opj_stream_private_t *p_stream,
1081                                                                         opj_event_mgr_t * p_manager );
1082 #endif
1083
1084 /**
1085  * Writes regions of interests.
1086  *
1087  * @param       p_stream                the stream to write data to.
1088  * @param       p_j2k                   J2K codec.
1089  * @param       p_manager               the user event manager.
1090 */
1091 static OPJ_BOOL opj_j2k_write_regions(  opj_j2k_t *p_j2k,
1092                                                                         opj_stream_private_t *p_stream,
1093                                                                         opj_event_mgr_t * p_manager );
1094
1095 /**
1096  * Writes EPC ????
1097  *
1098  * @param       p_stream                the stream to write data to.
1099  * @param       p_j2k                   J2K codec.
1100  * @param       p_manager               the user event manager.
1101 */
1102 static OPJ_BOOL opj_j2k_write_epc(      opj_j2k_t *p_j2k,
1103                                                                     opj_stream_private_t *p_stream,
1104                                                                     opj_event_mgr_t * p_manager );
1105
1106 /**
1107  * Checks the progression order changes values. Tells of the poc given as input are valid.
1108  * A nice message is outputted at errors.
1109  *
1110  * @param       p_pocs                  the progression order changes.
1111  * @param       p_nb_pocs               the number of progression order changes.
1112  * @param       p_nb_resolutions        the number of resolutions.
1113  * @param       numcomps                the number of components
1114  * @param       numlayers               the number of layers.
1115  * @param       p_manager               the user event manager.
1116  *
1117  * @return      true if the pocs are valid.
1118  */
1119 static OPJ_BOOL opj_j2k_check_poc_val(  const opj_poc_t *p_pocs,
1120                                                                             OPJ_UINT32 p_nb_pocs,
1121                                                                             OPJ_UINT32 p_nb_resolutions,
1122                                                                             OPJ_UINT32 numcomps,
1123                                                                             OPJ_UINT32 numlayers,
1124                                                                             opj_event_mgr_t * p_manager);
1125
1126 /**
1127  * Gets the number of tile parts used for the given change of progression (if any) and the given tile.
1128  *
1129  * @param               cp                      the coding parameters.
1130  * @param               pino            the offset of the given poc (i.e. its position in the coding parameter).
1131  * @param               tileno          the given tile.
1132  *
1133  * @return              the number of tile parts.
1134  */
1135 static OPJ_UINT32 opj_j2k_get_num_tp( opj_cp_t *cp, OPJ_UINT32 pino, OPJ_UINT32 tileno);
1136
1137 /**
1138  * Calculates the total number of tile parts needed by the encoder to
1139  * encode such an image. If not enough memory is available, then the function return false.
1140  *
1141  * @param       p_nb_tiles      pointer that will hold the number of tile parts.
1142  * @param       cp                      the coding parameters for the image.
1143  * @param       image           the image to encode.
1144  * @param       p_j2k                   the p_j2k encoder.
1145  * @param       p_manager       the user event manager.
1146  *
1147  * @return true if the function was successful, false else.
1148  */
1149 static OPJ_BOOL opj_j2k_calculate_tp(   opj_j2k_t *p_j2k,
1150                                                                             opj_cp_t *cp,
1151                                                                             OPJ_UINT32 * p_nb_tiles,
1152                                                                             opj_image_t *image,
1153                                                                             opj_event_mgr_t * p_manager);
1154
1155 static void opj_j2k_dump_MH_info(opj_j2k_t* p_j2k, FILE* out_stream);
1156
1157 static void opj_j2k_dump_MH_index(opj_j2k_t* p_j2k, FILE* out_stream);
1158
1159 static opj_codestream_index_t* opj_j2k_create_cstr_index(void);
1160
1161 static OPJ_FLOAT32 opj_j2k_get_tp_stride (opj_tcp_t * p_tcp);
1162
1163 static OPJ_FLOAT32 opj_j2k_get_default_stride (opj_tcp_t * p_tcp);
1164
1165 static int opj_j2k_initialise_4K_poc(opj_poc_t *POC, int numres);
1166
1167 static void opj_j2k_set_cinema_parameters(opj_cparameters_t *parameters, opj_image_t *image, opj_event_mgr_t *p_manager);
1168
1169 static OPJ_BOOL opj_j2k_is_cinema_compliant(opj_image_t *image, OPJ_CINEMA_MODE cinema_mode, opj_event_mgr_t *p_manager);
1170
1171 /*@}*/
1172
1173 /*@}*/
1174
1175 /* ----------------------------------------------------------------------- */
1176 typedef struct j2k_prog_order{
1177         OPJ_PROG_ORDER enum_prog;
1178         char str_prog[5];
1179 }j2k_prog_order_t;
1180
1181 j2k_prog_order_t j2k_prog_order_list[] = {
1182         {OPJ_CPRL, "CPRL"},
1183         {OPJ_LRCP, "LRCP"},
1184         {OPJ_PCRL, "PCRL"},
1185         {OPJ_RLCP, "RLCP"},
1186         {OPJ_RPCL, "RPCL"},
1187         {(OPJ_PROG_ORDER)-1, ""}
1188 };
1189
1190 /**
1191  * FIXME DOC
1192  */
1193 static const OPJ_UINT32 MCT_ELEMENT_SIZE [] =
1194 {
1195         2,
1196         4,
1197         4,
1198         8
1199 };
1200
1201 typedef void (* opj_j2k_mct_function) (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
1202
1203 const opj_j2k_mct_function j2k_mct_read_functions_to_float [] =
1204 {
1205         opj_j2k_read_int16_to_float,
1206         opj_j2k_read_int32_to_float,
1207         opj_j2k_read_float32_to_float,
1208         opj_j2k_read_float64_to_float
1209 };
1210
1211 const opj_j2k_mct_function j2k_mct_read_functions_to_int32 [] =
1212 {
1213         opj_j2k_read_int16_to_int32,
1214         opj_j2k_read_int32_to_int32,
1215         opj_j2k_read_float32_to_int32,
1216         opj_j2k_read_float64_to_int32
1217 };
1218
1219 const opj_j2k_mct_function j2k_mct_write_functions_from_float [] =
1220 {
1221         opj_j2k_write_float_to_int16,
1222         opj_j2k_write_float_to_int32,
1223         opj_j2k_write_float_to_float,
1224         opj_j2k_write_float_to_float64
1225 };
1226
1227 typedef struct opj_dec_memory_marker_handler
1228 {
1229         /** marker value */
1230         OPJ_UINT32 id;
1231         /** value of the state when the marker can appear */
1232         OPJ_UINT32 states;
1233         /** action linked to the marker */
1234         OPJ_BOOL (*handler) (   opj_j2k_t *p_j2k,
1235                             OPJ_BYTE * p_header_data,
1236                             OPJ_UINT32 p_header_size,
1237                             opj_event_mgr_t * p_manager );
1238 }
1239 opj_dec_memory_marker_handler_t;
1240
1241 const opj_dec_memory_marker_handler_t j2k_memory_marker_handler_tab [] =
1242 {
1243   {J2K_MS_SOT, J2K_STATE_MH | J2K_STATE_TPHSOT, opj_j2k_read_sot},
1244   {J2K_MS_COD, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_cod},
1245   {J2K_MS_COC, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_coc},
1246   {J2K_MS_RGN, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_rgn},
1247   {J2K_MS_QCD, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_qcd},
1248   {J2K_MS_QCC, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_qcc},
1249   {J2K_MS_POC, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_poc},
1250   {J2K_MS_SIZ, J2K_STATE_MHSIZ, opj_j2k_read_siz},
1251   {J2K_MS_TLM, J2K_STATE_MH, opj_j2k_read_tlm},
1252   {J2K_MS_PLM, J2K_STATE_MH, opj_j2k_read_plm},
1253   {J2K_MS_PLT, J2K_STATE_TPH, opj_j2k_read_plt},
1254   {J2K_MS_PPM, J2K_STATE_MH, j2k_read_ppm_v3},
1255   {J2K_MS_PPT, J2K_STATE_TPH, opj_j2k_read_ppt},
1256   {J2K_MS_SOP, 0, 0},
1257   {J2K_MS_CRG, J2K_STATE_MH, opj_j2k_read_crg},
1258   {J2K_MS_COM, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_com},
1259   {J2K_MS_MCT, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_mct},
1260   {J2K_MS_CBD, J2K_STATE_MH , opj_j2k_read_cbd},
1261   {J2K_MS_MCC, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_mcc},
1262   {J2K_MS_MCO, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_mco},
1263 #ifdef USE_JPWL
1264 #ifdef TODO_MS /* remove these functions which are not commpatible with the v2 API */
1265   {J2K_MS_EPC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_epc},
1266   {J2K_MS_EPB, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_epb},
1267   {J2K_MS_ESD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_esd},
1268   {J2K_MS_RED, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_red},
1269 #endif
1270 #endif /* USE_JPWL */
1271 #ifdef USE_JPSEC
1272   {J2K_MS_SEC, J2K_DEC_STATE_MH, j2k_read_sec},
1273   {J2K_MS_INSEC, 0, j2k_read_insec}
1274 #endif /* USE_JPSEC */
1275   {J2K_MS_UNK, J2K_STATE_MH | J2K_STATE_TPH, 0}/*opj_j2k_read_unk is directly used*/
1276 };
1277
1278 void  opj_j2k_read_int16_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
1279 {
1280         OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
1281         OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data;
1282         OPJ_UINT32 i;
1283         OPJ_UINT32 l_temp;
1284
1285         for (i=0;i<p_nb_elem;++i) {
1286                 opj_read_bytes(l_src_data,&l_temp,2);
1287
1288                 l_src_data+=sizeof(OPJ_INT16);
1289
1290                 *(l_dest_data++) = (OPJ_FLOAT32) l_temp;
1291         }
1292 }
1293
1294 void  opj_j2k_read_int32_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
1295 {
1296         OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
1297         OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data;
1298         OPJ_UINT32 i;
1299         OPJ_UINT32 l_temp;
1300
1301         for (i=0;i<p_nb_elem;++i) {
1302                 opj_read_bytes(l_src_data,&l_temp,4);
1303
1304                 l_src_data+=sizeof(OPJ_INT32);
1305
1306                 *(l_dest_data++) = (OPJ_FLOAT32) l_temp;
1307         }
1308 }
1309
1310 void  opj_j2k_read_float32_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
1311 {
1312         OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
1313         OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data;
1314         OPJ_UINT32 i;
1315         OPJ_FLOAT32 l_temp;
1316
1317         for (i=0;i<p_nb_elem;++i) {
1318                 opj_read_float(l_src_data,&l_temp);
1319
1320                 l_src_data+=sizeof(OPJ_FLOAT32);
1321
1322                 *(l_dest_data++) = l_temp;
1323         }
1324 }
1325
1326 void  opj_j2k_read_float64_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
1327 {
1328         OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
1329         OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data;
1330         OPJ_UINT32 i;
1331         OPJ_FLOAT64 l_temp;
1332
1333         for (i=0;i<p_nb_elem;++i) {
1334                 opj_read_double(l_src_data,&l_temp);
1335
1336                 l_src_data+=sizeof(OPJ_FLOAT64);
1337
1338                 *(l_dest_data++) = (OPJ_FLOAT32) l_temp;
1339         }
1340 }
1341
1342 void  opj_j2k_read_int16_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
1343 {
1344         OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
1345         OPJ_INT32 * l_dest_data = (OPJ_INT32 *) p_dest_data;
1346         OPJ_UINT32 i;
1347         OPJ_UINT32 l_temp;
1348
1349         for (i=0;i<p_nb_elem;++i) {
1350                 opj_read_bytes(l_src_data,&l_temp,2);
1351
1352                 l_src_data+=sizeof(OPJ_INT16);
1353
1354                 *(l_dest_data++) = (OPJ_INT32) l_temp;
1355         }
1356 }
1357
1358 void  opj_j2k_read_int32_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
1359 {
1360         OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
1361         OPJ_INT32 * l_dest_data = (OPJ_INT32 *) p_dest_data;
1362         OPJ_UINT32 i;
1363         OPJ_UINT32 l_temp;
1364
1365         for (i=0;i<p_nb_elem;++i) {
1366                 opj_read_bytes(l_src_data,&l_temp,4);
1367
1368                 l_src_data+=sizeof(OPJ_INT32);
1369
1370                 *(l_dest_data++) = (OPJ_INT32) l_temp;
1371         }
1372 }
1373
1374 void  opj_j2k_read_float32_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
1375 {
1376         OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
1377         OPJ_INT32 * l_dest_data = (OPJ_INT32 *) p_dest_data;
1378         OPJ_UINT32 i;
1379         OPJ_FLOAT32 l_temp;
1380
1381         for (i=0;i<p_nb_elem;++i) {
1382                 opj_read_float(l_src_data,&l_temp);
1383
1384                 l_src_data+=sizeof(OPJ_FLOAT32);
1385
1386                 *(l_dest_data++) = (OPJ_INT32) l_temp;
1387         }
1388 }
1389
1390 void  opj_j2k_read_float64_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
1391 {
1392         OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
1393         OPJ_INT32 * l_dest_data = (OPJ_INT32 *) p_dest_data;
1394         OPJ_UINT32 i;
1395         OPJ_FLOAT64 l_temp;
1396
1397         for (i=0;i<p_nb_elem;++i) {
1398                 opj_read_double(l_src_data,&l_temp);
1399
1400                 l_src_data+=sizeof(OPJ_FLOAT64);
1401
1402                 *(l_dest_data++) = (OPJ_INT32) l_temp;
1403         }
1404 }
1405
1406 void  opj_j2k_write_float_to_int16 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
1407 {
1408         OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data;
1409         OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data;
1410         OPJ_UINT32 i;
1411         OPJ_UINT32 l_temp;
1412
1413         for (i=0;i<p_nb_elem;++i) {
1414                 l_temp = (OPJ_UINT32) *(l_src_data++);
1415
1416                 opj_write_bytes(l_dest_data,l_temp,sizeof(OPJ_INT16));
1417
1418                 l_dest_data+=sizeof(OPJ_INT16);
1419         }
1420 }
1421
1422 void opj_j2k_write_float_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
1423 {
1424         OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data;
1425         OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data;
1426         OPJ_UINT32 i;
1427         OPJ_UINT32 l_temp;
1428
1429         for (i=0;i<p_nb_elem;++i) {
1430                 l_temp = (OPJ_UINT32) *(l_src_data++);
1431
1432                 opj_write_bytes(l_dest_data,l_temp,sizeof(OPJ_INT32));
1433
1434                 l_dest_data+=sizeof(OPJ_INT32);
1435         }
1436 }
1437
1438 void  opj_j2k_write_float_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
1439 {
1440         OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data;
1441         OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data;
1442         OPJ_UINT32 i;
1443         OPJ_FLOAT32 l_temp;
1444
1445         for (i=0;i<p_nb_elem;++i) {
1446                 l_temp = (OPJ_FLOAT32) *(l_src_data++);
1447
1448                 opj_write_float(l_dest_data,l_temp);
1449
1450                 l_dest_data+=sizeof(OPJ_FLOAT32);
1451         }
1452 }
1453
1454 void  opj_j2k_write_float_to_float64 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
1455 {
1456         OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data;
1457         OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data;
1458         OPJ_UINT32 i;
1459         OPJ_FLOAT64 l_temp;
1460
1461         for (i=0;i<p_nb_elem;++i) {
1462                 l_temp = (OPJ_FLOAT64) *(l_src_data++);
1463
1464                 opj_write_double(l_dest_data,l_temp);
1465
1466                 l_dest_data+=sizeof(OPJ_FLOAT64);
1467         }
1468 }
1469
1470 char *opj_j2k_convert_progression_order(OPJ_PROG_ORDER prg_order){
1471         j2k_prog_order_t *po;
1472         for(po = j2k_prog_order_list; po->enum_prog != -1; po++ ){
1473                 if(po->enum_prog == prg_order){
1474                         return po->str_prog;
1475                 }
1476         }
1477         return po->str_prog;
1478 }
1479
1480 OPJ_BOOL opj_j2k_check_poc_val( const opj_poc_t *p_pocs,
1481                                                         OPJ_UINT32 p_nb_pocs,
1482                                                         OPJ_UINT32 p_nb_resolutions,
1483                                                         OPJ_UINT32 p_num_comps,
1484                                                         OPJ_UINT32 p_num_layers,
1485                                                         opj_event_mgr_t * p_manager)
1486 {
1487         OPJ_UINT32* packet_array;
1488         OPJ_UINT32 index , resno, compno, layno;
1489         OPJ_UINT32 i;
1490         OPJ_UINT32 step_c = 1;
1491         OPJ_UINT32 step_r = p_num_comps * step_c;
1492         OPJ_UINT32 step_l = p_nb_resolutions * step_r;
1493         OPJ_BOOL loss = OPJ_FALSE;
1494         OPJ_UINT32 layno0 = 0;
1495
1496         packet_array = (OPJ_UINT32*) opj_calloc(step_l * p_num_layers, sizeof(OPJ_UINT32));
1497         if (packet_array == 00) {
1498                 opj_event_msg(p_manager , EVT_ERROR, "Not enough memory for checking the poc values.\n");
1499                 return OPJ_FALSE;
1500         }
1501         memset(packet_array,0,step_l * p_num_layers* sizeof(OPJ_UINT32));
1502
1503         if (p_nb_pocs == 0) {
1504                 return OPJ_TRUE;
1505         }
1506
1507         index = step_r * p_pocs->resno0;
1508         /* take each resolution for each poc */
1509         for (resno = p_pocs->resno0 ; resno < p_pocs->resno1 ; ++resno)
1510         {
1511                 OPJ_UINT32 res_index = index + p_pocs->compno0 * step_c;
1512
1513                 /* take each comp of each resolution for each poc */
1514                 for (compno = p_pocs->compno0 ; compno < p_pocs->compno1 ; ++compno) {
1515                         OPJ_UINT32 comp_index = res_index + layno0 * step_l;
1516
1517                         /* and finally take each layer of each res of ... */
1518                         for (layno = layno0; layno < p_pocs->layno1 ; ++layno) {
1519                                 /*index = step_r * resno + step_c * compno + step_l * layno;*/
1520                                 packet_array[comp_index] = 1;
1521                                 comp_index += step_l;
1522                         }
1523
1524                         res_index += step_c;
1525                 }
1526
1527                 index += step_r;
1528         }
1529         ++p_pocs;
1530
1531         /* iterate through all the pocs */
1532         for (i = 1; i < p_nb_pocs ; ++i) {
1533                 OPJ_UINT32 l_last_layno1 = (p_pocs-1)->layno1 ;
1534
1535                 layno0 = (p_pocs->layno1 > l_last_layno1)? l_last_layno1 : 0;
1536                 index = step_r * p_pocs->resno0;
1537
1538                 /* take each resolution for each poc */
1539                 for (resno = p_pocs->resno0 ; resno < p_pocs->resno1 ; ++resno) {
1540                         OPJ_UINT32 res_index = index + p_pocs->compno0 * step_c;
1541
1542                         /* take each comp of each resolution for each poc */
1543                         for (compno = p_pocs->compno0 ; compno < p_pocs->compno1 ; ++compno) {
1544                                 OPJ_UINT32 comp_index = res_index + layno0 * step_l;
1545
1546                                 /* and finally take each layer of each res of ... */
1547                                 for (layno = layno0; layno < p_pocs->layno1 ; ++layno) {
1548                                         /*index = step_r * resno + step_c * compno + step_l * layno;*/
1549                                         packet_array[comp_index] = 1;
1550                                         comp_index += step_l;
1551                                 }
1552
1553                                 res_index += step_c;
1554                         }
1555
1556                         index += step_r;
1557                 }
1558
1559                 ++p_pocs;
1560         }
1561
1562         index = 0;
1563         for (layno = 0; layno < p_num_layers ; ++layno) {
1564                 for (resno = 0; resno < p_nb_resolutions; ++resno) {
1565                         for (compno = 0; compno < p_num_comps; ++compno) {
1566                                 loss |= (packet_array[index]!=1);
1567                                 /*index = step_r * resno + step_c * compno + step_l * layno;*/
1568                                 index += step_c;
1569                         }
1570                 }
1571         }
1572
1573         if (loss) {
1574                 opj_event_msg(p_manager , EVT_ERROR, "Missing packets possible loss of data\n");
1575         }
1576
1577         opj_free(packet_array);
1578
1579         return !loss;
1580 }
1581
1582 /* ----------------------------------------------------------------------- */
1583
1584 OPJ_UINT32 opj_j2k_get_num_tp(opj_cp_t *cp, OPJ_UINT32 pino, OPJ_UINT32 tileno)
1585 {
1586         const OPJ_CHAR *prog = 00;
1587         OPJ_INT32 i;
1588         OPJ_UINT32 tpnum = 1;
1589         opj_tcp_t *tcp = 00;
1590         opj_poc_t * l_current_poc = 00;
1591
1592         /*  preconditions */
1593         assert(tileno < (cp->tw * cp->th));
1594         assert(pino < (cp->tcps[tileno].numpocs + 1));
1595
1596         /* get the given tile coding parameter */
1597         tcp = &cp->tcps[tileno];
1598         assert(tcp != 00);
1599
1600         l_current_poc = &(tcp->pocs[pino]);
1601         assert(l_current_poc != 0);
1602
1603         /* get the progression order as a character string */
1604         prog = opj_j2k_convert_progression_order(tcp->prg);
1605         assert(strlen(prog) > 0);
1606
1607         if (cp->m_specific_param.m_enc.m_tp_on == 1) {
1608                 for (i=0;i<4;++i) {
1609                         switch (prog[i])
1610                         {
1611                                 /* component wise */
1612                                 case 'C':
1613                                         tpnum *= l_current_poc->compE;
1614                                         break;
1615                                 /* resolution wise */
1616                                 case 'R':
1617                                         tpnum *= l_current_poc->resE;
1618                                         break;
1619                                 /* precinct wise */
1620                                 case 'P':
1621                                         tpnum *= l_current_poc->prcE;
1622                                         break;
1623                                 /* layer wise */
1624                                 case 'L':
1625                                         tpnum *= l_current_poc->layE;
1626                                         break;
1627                         }
1628                         /* whould we split here ? */
1629                         if ( cp->m_specific_param.m_enc.m_tp_flag == prog[i] ) {
1630                                 cp->m_specific_param.m_enc.m_tp_pos=i;
1631                                 break;
1632                         }
1633                 }
1634         }
1635         else {
1636                 tpnum=1;
1637         }
1638
1639         return tpnum;
1640 }
1641
1642 OPJ_BOOL opj_j2k_calculate_tp(  opj_j2k_t *p_j2k,
1643                                                         opj_cp_t *cp,
1644                                                         OPJ_UINT32 * p_nb_tiles,
1645                                                         opj_image_t *image,
1646                                                         opj_event_mgr_t * p_manager
1647                                 )
1648 {
1649         OPJ_UINT32 pino,tileno;
1650         OPJ_UINT32 l_nb_tiles;
1651         opj_tcp_t *tcp;
1652
1653         /* preconditions */
1654         assert(p_nb_tiles != 00);
1655         assert(cp != 00);
1656         assert(image != 00);
1657         assert(p_j2k != 00);
1658         assert(p_manager != 00);
1659
1660         l_nb_tiles = cp->tw * cp->th;
1661         * p_nb_tiles = 0;
1662         tcp = cp->tcps;
1663
1664         /* INDEX >> */
1665         /* TODO mergeV2: check this part which use cstr_info */
1666         /*if (p_j2k->cstr_info) {
1667                 opj_tile_info_t * l_info_tile_ptr = p_j2k->cstr_info->tile;
1668
1669                 for (tileno = 0; tileno < l_nb_tiles; ++tileno) {
1670                         OPJ_UINT32 cur_totnum_tp = 0;
1671
1672                         opj_pi_update_encoding_parameters(image,cp,tileno);
1673
1674                         for (pino = 0; pino <= tcp->numpocs; ++pino)
1675                         {
1676                                 OPJ_UINT32 tp_num = opj_j2k_get_num_tp(cp,pino,tileno);
1677
1678                                 *p_nb_tiles = *p_nb_tiles + tp_num;
1679
1680                                 cur_totnum_tp += tp_num;
1681                         }
1682
1683                         tcp->m_nb_tile_parts = cur_totnum_tp;
1684
1685                         l_info_tile_ptr->tp = (opj_tp_info_t *) opj_malloc(cur_totnum_tp * sizeof(opj_tp_info_t));
1686                         if (l_info_tile_ptr->tp == 00) {
1687                                 return OPJ_FALSE;
1688                         }
1689
1690                         memset(l_info_tile_ptr->tp,0,cur_totnum_tp * sizeof(opj_tp_info_t));
1691
1692                         l_info_tile_ptr->num_tps = cur_totnum_tp;
1693
1694                         ++l_info_tile_ptr;
1695                         ++tcp;
1696                 }
1697         }
1698         else */{
1699                 for (tileno = 0; tileno < l_nb_tiles; ++tileno) {
1700                         OPJ_UINT32 cur_totnum_tp = 0;
1701
1702                         opj_pi_update_encoding_parameters(image,cp,tileno);
1703
1704                         for (pino = 0; pino <= tcp->numpocs; ++pino) {
1705                                 OPJ_UINT32 tp_num = opj_j2k_get_num_tp(cp,pino,tileno);
1706
1707                                 *p_nb_tiles = *p_nb_tiles + tp_num;
1708
1709                                 cur_totnum_tp += tp_num;
1710                         }
1711                         tcp->m_nb_tile_parts = cur_totnum_tp;
1712
1713                         ++tcp;
1714                 }
1715         }
1716
1717         return OPJ_TRUE;
1718 }
1719
1720 OPJ_BOOL opj_j2k_write_soc(     opj_j2k_t *p_j2k,
1721                                                 opj_stream_private_t *p_stream,
1722                                                     opj_event_mgr_t * p_manager )
1723 {
1724         /* 2 bytes will be written */
1725         OPJ_BYTE * l_start_stream = 00;
1726
1727         /* preconditions */
1728         assert(p_stream != 00);
1729         assert(p_j2k != 00);
1730         assert(p_manager != 00);
1731
1732         l_start_stream = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
1733
1734         /* write SOC identifier */
1735         opj_write_bytes(l_start_stream,J2K_MS_SOC,2);
1736
1737         if (opj_stream_write_data(p_stream,l_start_stream,2,p_manager) != 2) {
1738                 return OPJ_FALSE;
1739         }
1740
1741 /* UniPG>> */
1742 #ifdef USE_JPWL
1743         /* update markers struct */
1744 /*
1745         OPJ_BOOL res = j2k_add_marker(p_j2k->cstr_info, J2K_MS_SOC, p_stream_tell(p_stream) - 2, 2);
1746 */
1747   assert( 0 && "TODO" );
1748 #endif /* USE_JPWL */
1749 /* <<UniPG */
1750
1751         return OPJ_TRUE;
1752 }
1753
1754 /**
1755  * Reads a SOC marker (Start of Codestream)
1756  * @param       p_j2k           the jpeg2000 file codec.
1757  * @param       p_stream        FIXME DOC
1758  * @param       p_manager       the user event manager.
1759 */
1760 static OPJ_BOOL opj_j2k_read_soc(   opj_j2k_t *p_j2k,
1761                                     opj_stream_private_t *p_stream,
1762                                     opj_event_mgr_t * p_manager
1763                                     )
1764 {
1765         OPJ_BYTE l_data [2];
1766         OPJ_UINT32 l_marker;
1767
1768         /* preconditions */
1769         assert(p_j2k != 00);
1770         assert(p_manager != 00);
1771         assert(p_stream != 00);
1772
1773         if (opj_stream_read_data(p_stream,l_data,2,p_manager) != 2) {
1774                 return OPJ_FALSE;
1775         }
1776
1777         opj_read_bytes(l_data,&l_marker,2);
1778         if (l_marker != J2K_MS_SOC) {
1779                 return OPJ_FALSE;
1780         }
1781
1782         /* Next marker should be a SIZ marker in the main header */
1783         p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_MHSIZ;
1784
1785         /* FIXME move it in a index structure included in p_j2k*/
1786         p_j2k->cstr_index->main_head_start = opj_stream_tell(p_stream) - 2;
1787
1788         opj_event_msg(p_manager, EVT_INFO, "Start to read j2k main header (%d).\n", p_j2k->cstr_index->main_head_start);
1789
1790         /* Add the marker to the codestream index*/
1791         if (OPJ_FALSE == opj_j2k_add_mhmarker(p_j2k->cstr_index, J2K_MS_SOC, p_j2k->cstr_index->main_head_start, 2)) {
1792                 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to add mh marker\n");
1793                 return OPJ_FALSE;
1794         }
1795         return OPJ_TRUE;
1796 }
1797
1798 OPJ_BOOL opj_j2k_write_siz(     opj_j2k_t *p_j2k,
1799                                                         opj_stream_private_t *p_stream,
1800                                                         opj_event_mgr_t * p_manager )
1801 {
1802         OPJ_UINT32 i;
1803         OPJ_UINT32 l_size_len;
1804         OPJ_BYTE * l_current_ptr;
1805         opj_image_t * l_image = 00;
1806         opj_cp_t *cp = 00;
1807         opj_image_comp_t * l_img_comp = 00;
1808
1809         /* preconditions */
1810         assert(p_stream != 00);
1811         assert(p_j2k != 00);
1812         assert(p_manager != 00);
1813
1814         l_image = p_j2k->m_private_image;
1815         cp = &(p_j2k->m_cp);
1816         l_size_len = 40 + 3 * l_image->numcomps;
1817         l_img_comp = l_image->comps;
1818
1819         if (l_size_len > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
1820
1821                 OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_size_len);
1822                 if (! new_header_tile_data) {
1823                         opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
1824                         p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL;
1825                         p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
1826                         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory for the SIZ marker\n");
1827                         return OPJ_FALSE;
1828                 }
1829                 p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
1830                 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_size_len;
1831         }
1832
1833         l_current_ptr = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
1834
1835         /* write SOC identifier */
1836         opj_write_bytes(l_current_ptr,J2K_MS_SIZ,2);    /* SIZ */
1837         l_current_ptr+=2;
1838
1839         opj_write_bytes(l_current_ptr,l_size_len-2,2); /* L_SIZ */
1840         l_current_ptr+=2;
1841
1842         opj_write_bytes(l_current_ptr, cp->rsiz, 2);    /* Rsiz (capabilities) */
1843         l_current_ptr+=2;
1844
1845         opj_write_bytes(l_current_ptr, l_image->x1, 4); /* Xsiz */
1846         l_current_ptr+=4;
1847
1848         opj_write_bytes(l_current_ptr, l_image->y1, 4); /* Ysiz */
1849         l_current_ptr+=4;
1850
1851         opj_write_bytes(l_current_ptr, l_image->x0, 4); /* X0siz */
1852         l_current_ptr+=4;
1853
1854         opj_write_bytes(l_current_ptr, l_image->y0, 4); /* Y0siz */
1855         l_current_ptr+=4;
1856
1857         opj_write_bytes(l_current_ptr, cp->tdx, 4);             /* XTsiz */
1858         l_current_ptr+=4;
1859
1860         opj_write_bytes(l_current_ptr, cp->tdy, 4);             /* YTsiz */
1861         l_current_ptr+=4;
1862
1863         opj_write_bytes(l_current_ptr, cp->tx0, 4);             /* XT0siz */
1864         l_current_ptr+=4;
1865
1866         opj_write_bytes(l_current_ptr, cp->ty0, 4);             /* YT0siz */
1867         l_current_ptr+=4;
1868
1869         opj_write_bytes(l_current_ptr, l_image->numcomps, 2);   /* Csiz */
1870         l_current_ptr+=2;
1871
1872         for (i = 0; i < l_image->numcomps; ++i) {
1873                 /* TODO here with MCT ? */
1874                 opj_write_bytes(l_current_ptr, l_img_comp->prec - 1 + (l_img_comp->sgnd << 7), 1);      /* Ssiz_i */
1875                 ++l_current_ptr;
1876
1877                 opj_write_bytes(l_current_ptr, l_img_comp->dx, 1);      /* XRsiz_i */
1878                 ++l_current_ptr;
1879
1880                 opj_write_bytes(l_current_ptr, l_img_comp->dy, 1);      /* YRsiz_i */
1881                 ++l_current_ptr;
1882
1883                 ++l_img_comp;
1884         }
1885
1886         if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_size_len,p_manager) != l_size_len) {
1887                 return OPJ_FALSE;
1888         }
1889
1890         return OPJ_TRUE;
1891 }
1892
1893 /**
1894  * Reads a SIZ marker (image and tile size)
1895  * @param       p_j2k           the jpeg2000 file codec.
1896  * @param       p_header_data   the data contained in the SIZ box.
1897  * @param       p_header_size   the size of the data contained in the SIZ marker.
1898  * @param       p_manager       the user event manager.
1899 */
1900 static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k,
1901                                  OPJ_BYTE * p_header_data,
1902                                  OPJ_UINT32 p_header_size,
1903                                  opj_event_mgr_t * p_manager
1904                                  )
1905 {
1906         OPJ_UINT32 i;
1907         OPJ_UINT32 l_nb_comp;
1908         OPJ_UINT32 l_nb_comp_remain;
1909         OPJ_UINT32 l_remaining_size;
1910         OPJ_UINT32 l_nb_tiles;
1911         OPJ_UINT32 l_tmp;
1912         opj_image_t *l_image = 00;
1913         opj_cp_t *l_cp = 00;
1914         opj_image_comp_t * l_img_comp = 00;
1915         opj_tcp_t * l_current_tile_param = 00;
1916
1917         /* preconditions */
1918         assert(p_j2k != 00);
1919         assert(p_manager != 00);
1920         assert(p_header_data != 00);
1921
1922         l_image = p_j2k->m_private_image;
1923         l_cp = &(p_j2k->m_cp);
1924
1925         /* minimum size == 39 - 3 (= minimum component parameter) */
1926         if (p_header_size < 36) {
1927                 opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker size\n");
1928                 return OPJ_FALSE;
1929         }
1930
1931         l_remaining_size = p_header_size - 36;
1932         l_nb_comp = l_remaining_size / 3;
1933         l_nb_comp_remain = l_remaining_size % 3;
1934         if (l_nb_comp_remain != 0){
1935                 opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker size\n");
1936                 return OPJ_FALSE;
1937         }
1938
1939         opj_read_bytes(p_header_data,&l_tmp ,2);                                                /* Rsiz (capabilities) */
1940         p_header_data+=2;
1941         l_cp->rsiz = (OPJ_RSIZ_CAPABILITIES) l_tmp;
1942         opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_image->x1, 4);   /* Xsiz */
1943         p_header_data+=4;
1944         opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_image->y1, 4);   /* Ysiz */
1945         p_header_data+=4;
1946         opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_image->x0, 4);   /* X0siz */
1947         p_header_data+=4;
1948         opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_image->y0, 4);   /* Y0siz */
1949         p_header_data+=4;
1950         opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_cp->tdx, 4);             /* XTsiz */
1951         p_header_data+=4;
1952         opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_cp->tdy, 4);             /* YTsiz */
1953         p_header_data+=4;
1954         opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_cp->tx0, 4);             /* XT0siz */
1955         p_header_data+=4;
1956         opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_cp->ty0, 4);             /* YT0siz */
1957         p_header_data+=4;
1958         opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_tmp, 2);                 /* Csiz */
1959         p_header_data+=2;
1960         if (l_tmp < 16385)
1961                 l_image->numcomps = (OPJ_UINT16) l_tmp;
1962         else {
1963                 opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker: number of component is illegal -> %d\n", l_tmp);
1964                 return OPJ_FALSE;
1965         }
1966
1967         if (l_image->numcomps != l_nb_comp) {
1968                 opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker: number of component is not compatible with the remaining number of parameters ( %d vs %d)\n", l_image->numcomps, l_nb_comp);
1969                 return OPJ_FALSE;
1970         }
1971
1972         /* testcase 4035.pdf.SIGSEGV.d8b.3375 */
1973         if (l_image->x0 > l_image->x1 || l_image->y0 > l_image->y1) {
1974                 opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker: negative image size (%d x %d)\n", l_image->x1 - l_image->x0, l_image->y1 - l_image->y0);
1975                 return OPJ_FALSE;
1976         }
1977         /* testcase 2539.pdf.SIGFPE.706.1712 (also 3622.pdf.SIGFPE.706.2916 and 4008.pdf.SIGFPE.706.3345 and maybe more) */
1978         if (!(l_cp->tdx * l_cp->tdy)) {
1979                 opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker: invalid tile size (tdx: %d, tdy: %d)\n", l_cp->tdx, l_cp->tdy);
1980                 return OPJ_FALSE;
1981         }
1982
1983         /* testcase 1610.pdf.SIGSEGV.59c.681 */
1984         if (((OPJ_UINT64)l_image->x1) * ((OPJ_UINT64)l_image->y1) != (l_image->x1 * l_image->y1)) {
1985                 opj_event_msg(p_manager, EVT_ERROR, "Prevent buffer overflow (x1: %d, y1: %d)", l_image->x1, l_image->y1);
1986                 return OPJ_FALSE;
1987         }
1988
1989 #ifdef USE_JPWL
1990         if (l_cp->correct) {
1991                 /* if JPWL is on, we check whether TX errors have damaged
1992                   too much the SIZ parameters */
1993                 if (!(l_image->x1 * l_image->y1)) {
1994                         opj_event_msg(p_manager, EVT_ERROR,
1995                                 "JPWL: bad image size (%d x %d)\n",
1996                                 l_image->x1, l_image->y1);
1997                         if (!JPWL_ASSUME || JPWL_ASSUME) {
1998                                 opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
1999                                 return OPJ_FALSE;
2000                         }
2001                 }
2002
2003         /* FIXME check previously in the function so why keep this piece of code ? Need by the norm ?
2004                 if (l_image->numcomps != ((len - 38) / 3)) {
2005                         opj_event_msg(p_manager, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
2006                                 "JPWL: Csiz is %d => space in SIZ only for %d comps.!!!\n",
2007                                 l_image->numcomps, ((len - 38) / 3));
2008                         if (!JPWL_ASSUME) {
2009                                 opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
2010                                 return OPJ_FALSE;
2011                         }
2012         */              /* we try to correct */
2013         /*              opj_event_msg(p_manager, EVT_WARNING, "- trying to adjust this\n");
2014                         if (l_image->numcomps < ((len - 38) / 3)) {
2015                                 len = 38 + 3 * l_image->numcomps;
2016                                 opj_event_msg(p_manager, EVT_WARNING, "- setting Lsiz to %d => HYPOTHESIS!!!\n",
2017                                         len);
2018                         } else {
2019                                 l_image->numcomps = ((len - 38) / 3);
2020                                 opj_event_msg(p_manager, EVT_WARNING, "- setting Csiz to %d => HYPOTHESIS!!!\n",
2021                                         l_image->numcomps);
2022                         }
2023                 }
2024         */
2025
2026                 /* update components number in the jpwl_exp_comps filed */
2027                 l_cp->exp_comps = l_image->numcomps;
2028         }
2029 #endif /* USE_JPWL */
2030
2031         /* Allocate the resulting image components */
2032         l_image->comps = (opj_image_comp_t*) opj_calloc(l_image->numcomps, sizeof(opj_image_comp_t));
2033         if (l_image->comps == 00){
2034                 l_image->numcomps = 0;
2035                 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
2036                 return OPJ_FALSE;
2037         }
2038
2039         memset(l_image->comps,0,l_image->numcomps * sizeof(opj_image_comp_t));
2040         l_img_comp = l_image->comps;
2041
2042         /* Read the component information */
2043         for (i = 0; i < l_image->numcomps; ++i){
2044                 OPJ_UINT32 tmp;
2045                 opj_read_bytes(p_header_data,&tmp,1);   /* Ssiz_i */
2046                 ++p_header_data;
2047                 l_img_comp->prec = (tmp & 0x7f) + 1;
2048                 l_img_comp->sgnd = tmp >> 7;
2049                 opj_read_bytes(p_header_data,&tmp,1);   /* XRsiz_i */
2050                 ++p_header_data;
2051                 l_img_comp->dx = (OPJ_INT32)tmp; /* should be between 1 and 255 */
2052                 opj_read_bytes(p_header_data,&tmp,1);   /* YRsiz_i */
2053                 ++p_header_data;
2054                 l_img_comp->dy = (OPJ_INT32)tmp; /* should be between 1 and 255 */
2055                 if( l_img_comp->dx < 1 || l_img_comp->dx > 255 ||
2056                     l_img_comp->dy < 1 || l_img_comp->dy > 255 ) {
2057                     opj_event_msg(p_manager, EVT_ERROR,
2058                                   "Invalid values for comp = %d : dx=%u dy=%u\n (should be between 1 and 255 according the JPEG2000 norm)",
2059                                   i, l_img_comp->dx, l_img_comp->dy);
2060                     return OPJ_FALSE;
2061                 }
2062
2063 #ifdef USE_JPWL
2064                 if (l_cp->correct) {
2065                 /* if JPWL is on, we check whether TX errors have damaged
2066                         too much the SIZ parameters, again */
2067                         if (!(l_image->comps[i].dx * l_image->comps[i].dy)) {
2068                                 opj_event_msg(p_manager, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
2069                                         "JPWL: bad XRsiz_%d/YRsiz_%d (%d x %d)\n",
2070                                         i, i, l_image->comps[i].dx, l_image->comps[i].dy);
2071                                 if (!JPWL_ASSUME) {
2072                                         opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
2073                                         return OPJ_FALSE;
2074                                 }
2075                                 /* we try to correct */
2076                                 opj_event_msg(p_manager, EVT_WARNING, "- trying to adjust them\n");
2077                                 if (!l_image->comps[i].dx) {
2078                                         l_image->comps[i].dx = 1;
2079                                         opj_event_msg(p_manager, EVT_WARNING, "- setting XRsiz_%d to %d => HYPOTHESIS!!!\n",
2080                                                 i, l_image->comps[i].dx);
2081                                 }
2082                                 if (!l_image->comps[i].dy) {
2083                                         l_image->comps[i].dy = 1;
2084                                         opj_event_msg(p_manager, EVT_WARNING, "- setting YRsiz_%d to %d => HYPOTHESIS!!!\n",
2085                                                 i, l_image->comps[i].dy);
2086                                 }
2087                         }
2088                 }
2089 #endif /* USE_JPWL */
2090                 l_img_comp->resno_decoded = 0;                                                          /* number of resolution decoded */
2091                 l_img_comp->factor = l_cp->m_specific_param.m_dec.m_reduce; /* reducing factor per component */
2092                 ++l_img_comp;
2093         }
2094
2095         /* Compute the number of tiles */
2096         l_cp->tw = opj_int_ceildiv(l_image->x1 - l_cp->tx0, l_cp->tdx);
2097         l_cp->th = opj_int_ceildiv(l_image->y1 - l_cp->ty0, l_cp->tdy);
2098
2099         /* Check that the number of tiles is valid */
2100         if (l_cp->tw == 0 || l_cp->th == 0 || l_cp->tw > 65535 / l_cp->th) {
2101             opj_event_msg(  p_manager, EVT_ERROR, 
2102                             "Invalid number of tiles : %u x %u (maximum fixed by jpeg2000 norm is 65535 tiles)\n",
2103                             l_cp->tw, l_cp->th);
2104             return OPJ_FALSE;
2105         }
2106         l_nb_tiles = l_cp->tw * l_cp->th;
2107
2108         /* Define the tiles which will be decoded */
2109         if (p_j2k->m_specific_param.m_decoder.m_discard_tiles) {
2110                 p_j2k->m_specific_param.m_decoder.m_start_tile_x = (p_j2k->m_specific_param.m_decoder.m_start_tile_x - l_cp->tx0) / l_cp->tdx;
2111                 p_j2k->m_specific_param.m_decoder.m_start_tile_y = (p_j2k->m_specific_param.m_decoder.m_start_tile_y - l_cp->ty0) / l_cp->tdy;
2112                 p_j2k->m_specific_param.m_decoder.m_end_tile_x = opj_int_ceildiv((p_j2k->m_specific_param.m_decoder.m_end_tile_x - l_cp->tx0), l_cp->tdx);
2113                 p_j2k->m_specific_param.m_decoder.m_end_tile_y = opj_int_ceildiv((p_j2k->m_specific_param.m_decoder.m_end_tile_y - l_cp->ty0), l_cp->tdy);
2114         }
2115         else {
2116                 p_j2k->m_specific_param.m_decoder.m_start_tile_x = 0;
2117                 p_j2k->m_specific_param.m_decoder.m_start_tile_y = 0;
2118                 p_j2k->m_specific_param.m_decoder.m_end_tile_x = l_cp->tw;
2119                 p_j2k->m_specific_param.m_decoder.m_end_tile_y = l_cp->th;
2120         }
2121
2122 #ifdef USE_JPWL
2123         if (l_cp->correct) {
2124                 /* if JPWL is on, we check whether TX errors have damaged
2125                   too much the SIZ parameters */
2126                 if ((l_cp->tw < 1) || (l_cp->th < 1) || (l_cp->tw > l_cp->max_tiles) || (l_cp->th > l_cp->max_tiles)) {
2127                         opj_event_msg(p_manager, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
2128                                 "JPWL: bad number of tiles (%d x %d)\n",
2129                                 l_cp->tw, l_cp->th);
2130                         if (!JPWL_ASSUME) {
2131                                 opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
2132                                 return OPJ_FALSE;
2133                         }
2134                         /* we try to correct */
2135                         opj_event_msg(p_manager, EVT_WARNING, "- trying to adjust them\n");
2136                         if (l_cp->tw < 1) {
2137                                 l_cp->tw= 1;
2138                                 opj_event_msg(p_manager, EVT_WARNING, "- setting %d tiles in x => HYPOTHESIS!!!\n",
2139                                                 l_cp->tw);
2140                         }
2141                         if (l_cp->tw > l_cp->max_tiles) {
2142                                 l_cp->tw= 1;
2143                                 opj_event_msg(p_manager, EVT_WARNING, "- too large x, increase expectance of %d\n"
2144                                         "- setting %d tiles in x => HYPOTHESIS!!!\n",
2145                                         l_cp->max_tiles, l_cp->tw);
2146                         }
2147                         if (l_cp->th < 1) {
2148                                 l_cp->th= 1;
2149                                 opj_event_msg(p_manager, EVT_WARNING, "- setting %d tiles in y => HYPOTHESIS!!!\n",
2150                                                 l_cp->th);
2151                         }
2152                         if (l_cp->th > l_cp->max_tiles) {
2153                                 l_cp->th= 1;
2154                                 opj_event_msg(p_manager, EVT_WARNING, "- too large y, increase expectance of %d to continue\n",
2155                                         "- setting %d tiles in y => HYPOTHESIS!!!\n",
2156                                         l_cp->max_tiles, l_cp->th);
2157                         }
2158                 }
2159         }
2160 #endif /* USE_JPWL */
2161
2162         /* memory allocations */
2163         l_cp->tcps = (opj_tcp_t*) opj_calloc(l_nb_tiles, sizeof(opj_tcp_t));
2164         if (l_cp->tcps == 00) {
2165                 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
2166                 return OPJ_FALSE;
2167         }
2168         memset(l_cp->tcps,0,l_nb_tiles*sizeof(opj_tcp_t));
2169
2170 #ifdef USE_JPWL
2171         if (l_cp->correct) {
2172                 if (!l_cp->tcps) {
2173                         opj_event_msg(p_manager, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
2174                                 "JPWL: could not alloc tcps field of cp\n");
2175                         if (!JPWL_ASSUME || JPWL_ASSUME) {
2176                                 opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
2177                                 return OPJ_FALSE;
2178                         }
2179                 }
2180         }
2181 #endif /* USE_JPWL */
2182
2183         p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps =
2184                         (opj_tccp_t*) opj_calloc(l_image->numcomps, sizeof(opj_tccp_t));
2185         if(p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps  == 00) {
2186                 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
2187                 return OPJ_FALSE;
2188         }
2189         memset(p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps ,0,l_image->numcomps*sizeof(opj_tccp_t));
2190
2191         p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mct_records =
2192                         (opj_mct_data_t*)opj_malloc(OPJ_J2K_MCT_DEFAULT_NB_RECORDS * sizeof(opj_mct_data_t));
2193
2194         if (! p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mct_records) {
2195                 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
2196                 return OPJ_FALSE;
2197         }
2198         memset(p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mct_records,0,OPJ_J2K_MCT_DEFAULT_NB_RECORDS * sizeof(opj_mct_data_t));
2199         p_j2k->m_specific_param.m_decoder.m_default_tcp->m_nb_max_mct_records = OPJ_J2K_MCT_DEFAULT_NB_RECORDS;
2200
2201         p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mcc_records =
2202                         (opj_simple_mcc_decorrelation_data_t*)
2203                         opj_malloc(OPJ_J2K_MCC_DEFAULT_NB_RECORDS * sizeof(opj_simple_mcc_decorrelation_data_t));
2204
2205         if (! p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mcc_records) {
2206                 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
2207                 return OPJ_FALSE;
2208         }
2209         memset(p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mcc_records,0,OPJ_J2K_MCC_DEFAULT_NB_RECORDS * sizeof(opj_simple_mcc_decorrelation_data_t));
2210         p_j2k->m_specific_param.m_decoder.m_default_tcp->m_nb_max_mcc_records = OPJ_J2K_MCC_DEFAULT_NB_RECORDS;
2211
2212         /* set up default dc level shift */
2213         for (i=0;i<l_image->numcomps;++i) {
2214                 if (! l_image->comps[i].sgnd) {
2215                         p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps[i].m_dc_level_shift = 1 << (l_image->comps[i].prec - 1);
2216                 }
2217         }
2218
2219         l_current_tile_param = l_cp->tcps;
2220         for     (i = 0; i < l_nb_tiles; ++i) {
2221                 l_current_tile_param->tccps = (opj_tccp_t*) opj_malloc(l_image->numcomps * sizeof(opj_tccp_t));
2222                 if (l_current_tile_param->tccps == 00) {
2223                         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
2224                         return OPJ_FALSE;
2225                 }
2226                 memset(l_current_tile_param->tccps,0,l_image->numcomps * sizeof(opj_tccp_t));
2227
2228                 ++l_current_tile_param;
2229         }
2230
2231         p_j2k->m_specific_param.m_decoder.m_state =  J2K_STATE_MH; /* FIXME J2K_DEC_STATE_MH; */
2232         opj_image_comp_header_update(l_image,l_cp);
2233
2234         return OPJ_TRUE;
2235 }
2236
2237 OPJ_BOOL opj_j2k_write_com(     opj_j2k_t *p_j2k,
2238                                                         opj_stream_private_t *p_stream,
2239                                                         opj_event_mgr_t * p_manager
2240                             )
2241 {
2242         OPJ_UINT32 l_comment_size;
2243         OPJ_UINT32 l_total_com_size;
2244         const OPJ_CHAR *l_comment;
2245         OPJ_BYTE * l_current_ptr = 00;
2246
2247         /* preconditions */
2248         assert(p_j2k != 00);
2249         assert(p_stream != 00);
2250         assert(p_manager != 00);
2251
2252         l_comment = p_j2k->m_cp.comment;
2253         l_comment_size = (OPJ_UINT32)strlen(l_comment);
2254         l_total_com_size = l_comment_size + 6;
2255
2256         if (l_total_com_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
2257                 OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_total_com_size);
2258                 if (! new_header_tile_data) {
2259                         opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
2260                         p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL;
2261                         p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
2262                         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write the COM marker\n");
2263                         return OPJ_FALSE;
2264                 }
2265                 p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
2266                 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_total_com_size;
2267         }
2268
2269         l_current_ptr = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
2270
2271         opj_write_bytes(l_current_ptr,J2K_MS_COM , 2);  /* COM */
2272         l_current_ptr+=2;
2273
2274         opj_write_bytes(l_current_ptr,l_total_com_size - 2 , 2);        /* L_COM */
2275         l_current_ptr+=2;
2276
2277         opj_write_bytes(l_current_ptr,1 , 2);   /* General use (IS 8859-15:1999 (Latin) values) */
2278         l_current_ptr+=2;
2279
2280         memcpy( l_current_ptr,l_comment,l_comment_size);
2281
2282         if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_total_com_size,p_manager) != l_total_com_size) {
2283                 return OPJ_FALSE;
2284         }
2285
2286         return OPJ_TRUE;
2287 }
2288
2289 /**
2290  * Reads a COM marker (comments)
2291  * @param       p_j2k           the jpeg2000 file codec.
2292  * @param       p_header_data   the data contained in the COM box.
2293  * @param       p_header_size   the size of the data contained in the COM marker.
2294  * @param       p_manager               the user event manager.
2295 */
2296 static OPJ_BOOL opj_j2k_read_com (  opj_j2k_t *p_j2k,
2297                                     OPJ_BYTE * p_header_data,
2298                                     OPJ_UINT32 p_header_size,
2299                                     opj_event_mgr_t * p_manager
2300                                     )
2301 {
2302         /* preconditions */
2303         assert(p_j2k != 00);
2304         assert(p_manager != 00);
2305         assert(p_header_data != 00);
2306   (void)p_header_size;
2307
2308         return OPJ_TRUE;
2309 }
2310
2311 OPJ_BOOL opj_j2k_write_cod(     opj_j2k_t *p_j2k,
2312                                                         opj_stream_private_t *p_stream,
2313                                                         opj_event_mgr_t * p_manager )
2314 {
2315         opj_cp_t *l_cp = 00;
2316         opj_tcp_t *l_tcp = 00;
2317         OPJ_UINT32 l_code_size,l_remaining_size;
2318         OPJ_BYTE * l_current_data = 00;
2319
2320         /* preconditions */
2321         assert(p_j2k != 00);
2322         assert(p_manager != 00);
2323         assert(p_stream != 00);
2324
2325         l_cp = &(p_j2k->m_cp);
2326         l_tcp = &l_cp->tcps[p_j2k->m_current_tile_number];
2327         l_code_size = 9 + opj_j2k_get_SPCod_SPCoc_size(p_j2k,p_j2k->m_current_tile_number,0);
2328         l_remaining_size = l_code_size;
2329
2330         if (l_code_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
2331                 OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_code_size);
2332                 if (! new_header_tile_data) {
2333                         opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
2334                         p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL;
2335                         p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
2336                         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write COD marker\n");
2337                         return OPJ_FALSE;
2338                 }
2339                 p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
2340                 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_code_size;
2341         }
2342
2343         l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
2344
2345         opj_write_bytes(l_current_data,J2K_MS_COD,2);           /* COD */
2346         l_current_data += 2;
2347
2348         opj_write_bytes(l_current_data,l_code_size-2,2);        /* L_COD */
2349         l_current_data += 2;
2350
2351         opj_write_bytes(l_current_data,l_tcp->csty,1);          /* Scod */
2352         ++l_current_data;
2353
2354         opj_write_bytes(l_current_data,l_tcp->prg,1);           /* SGcod (A) */
2355         ++l_current_data;
2356
2357         opj_write_bytes(l_current_data,l_tcp->numlayers,2);     /* SGcod (B) */
2358         l_current_data+=2;
2359
2360         opj_write_bytes(l_current_data,l_tcp->mct,1);           /* SGcod (C) */
2361         ++l_current_data;
2362
2363         l_remaining_size -= 9;
2364
2365         if (! opj_j2k_write_SPCod_SPCoc(p_j2k,p_j2k->m_current_tile_number,0,l_current_data,&l_remaining_size,p_manager)) {
2366                 opj_event_msg(p_manager, EVT_ERROR, "Error writing COD marker\n");
2367                 return OPJ_FALSE;
2368         }
2369
2370         if (l_remaining_size != 0) {
2371                 opj_event_msg(p_manager, EVT_ERROR, "Error writing COD marker\n");
2372                 return OPJ_FALSE;
2373         }
2374
2375         if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_code_size,p_manager) != l_code_size) {
2376                 return OPJ_FALSE;
2377         }
2378
2379         return OPJ_TRUE;
2380 }
2381
2382 /**
2383  * Reads a COD marker (Coding Styke defaults)
2384  * @param       p_header_data   the data contained in the COD box.
2385  * @param       p_j2k                   the jpeg2000 codec.
2386  * @param       p_header_size   the size of the data contained in the COD marker.
2387  * @param       p_manager               the user event manager.
2388 */
2389 static OPJ_BOOL opj_j2k_read_cod (  opj_j2k_t *p_j2k,
2390                                     OPJ_BYTE * p_header_data,
2391                                     OPJ_UINT32 p_header_size,
2392                                     opj_event_mgr_t * p_manager
2393                                     )
2394 {
2395         /* loop */
2396         OPJ_UINT32 i;
2397         OPJ_UINT32 l_tmp;
2398         opj_cp_t *l_cp = 00;
2399         opj_tcp_t *l_tcp = 00;
2400         opj_image_t *l_image = 00;
2401
2402         /* preconditions */
2403         assert(p_header_data != 00);
2404         assert(p_j2k != 00);
2405         assert(p_manager != 00);
2406
2407         l_image = p_j2k->m_private_image;
2408         l_cp = &(p_j2k->m_cp);
2409
2410         /* If we are in the first tile-part header of the current tile */
2411         l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH) ?
2412                                 &l_cp->tcps[p_j2k->m_current_tile_number] :
2413                                 p_j2k->m_specific_param.m_decoder.m_default_tcp;
2414
2415         /* Make sure room is sufficient */
2416         if (p_header_size < 5) {
2417                 opj_event_msg(p_manager, EVT_ERROR, "Error reading COD marker\n");
2418                 return OPJ_FALSE;
2419         }
2420
2421         opj_read_bytes(p_header_data,&l_tcp->csty,1);           /* Scod */
2422         ++p_header_data;
2423         opj_read_bytes(p_header_data,&l_tmp,1);                         /* SGcod (A) */
2424         ++p_header_data;
2425         l_tcp->prg = (OPJ_PROG_ORDER) l_tmp;
2426         opj_read_bytes(p_header_data,&l_tcp->numlayers,2);      /* SGcod (B) */
2427         p_header_data+=2;
2428
2429         /* If user didn't set a number layer to decode take the max specify in the codestream. */
2430         if      (l_cp->m_specific_param.m_dec.m_layer) {
2431                 l_tcp->num_layers_to_decode = l_cp->m_specific_param.m_dec.m_layer;
2432         }
2433         else {
2434                 l_tcp->num_layers_to_decode = l_tcp->numlayers;
2435         }
2436
2437         opj_read_bytes(p_header_data,&l_tcp->mct,1);            /* SGcod (C) */
2438         ++p_header_data;
2439
2440         p_header_size -= 5;
2441         for     (i = 0; i < l_image->numcomps; ++i) {
2442                 l_tcp->tccps[i].csty = l_tcp->csty & J2K_CCP_CSTY_PRT;
2443         }
2444
2445         if (! opj_j2k_read_SPCod_SPCoc(p_j2k,0,p_header_data,&p_header_size,p_manager)) {
2446                 opj_event_msg(p_manager, EVT_ERROR, "Error reading COD marker\n");
2447                 return OPJ_FALSE;
2448         }
2449
2450         if (p_header_size != 0) {
2451                 opj_event_msg(p_manager, EVT_ERROR, "Error reading COD marker\n");
2452                 return OPJ_FALSE;
2453         }
2454
2455         /* Apply the coding style to other components of the current tile or the m_default_tcp*/
2456         opj_j2k_copy_tile_component_parameters(p_j2k);
2457
2458         /* Index */
2459 #ifdef WIP_REMOVE_MSD
2460         if (p_j2k->cstr_info) {
2461                 /*opj_codestream_info_t *l_cstr_info = p_j2k->cstr_info;*/
2462                 p_j2k->cstr_info->prog = l_tcp->prg;
2463                 p_j2k->cstr_info->numlayers = l_tcp->numlayers;
2464                 p_j2k->cstr_info->numdecompos = (OPJ_INT32*) opj_malloc(l_image->numcomps * sizeof(OPJ_UINT32));
2465                 for     (i = 0; i < l_image->numcomps; ++i) {
2466                         p_j2k->cstr_info->numdecompos[i] = l_tcp->tccps[i].numresolutions - 1;
2467                 }
2468         }
2469 #endif
2470
2471         return OPJ_TRUE;
2472 }
2473
2474 #if 0
2475 OPJ_BOOL opj_j2k_write_coc( opj_j2k_t *p_j2k,
2476                                                 OPJ_UINT32 p_comp_no,
2477                                                 opj_stream_private_t *p_stream,
2478                                                 opj_event_mgr_t * p_manager )
2479 {
2480         OPJ_UINT32 l_coc_size,l_remaining_size;
2481         OPJ_UINT32 l_comp_room;
2482
2483         /* preconditions */
2484         assert(p_j2k != 00);
2485         assert(p_manager != 00);
2486         assert(p_stream != 00);
2487
2488         l_comp_room = (p_j2k->m_private_image->numcomps <= 256) ? 1 : 2;
2489
2490         l_coc_size = 5 + l_comp_room + opj_j2k_get_SPCod_SPCoc_size(p_j2k,p_j2k->m_current_tile_number,p_comp_no);
2491
2492         if (l_coc_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
2493                 OPJ_BYTE *new_header_tile_data;
2494                 /*p_j2k->m_specific_param.m_encoder.m_header_tile_data
2495                         = (OPJ_BYTE*)opj_realloc(
2496                                 p_j2k->m_specific_param.m_encoder.m_header_tile_data,
2497                                 l_coc_size);*/
2498
2499                 new_header_tile_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_coc_size);
2500                 if (! new_header_tile_data) {
2501                         opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
2502                         p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL;
2503                         p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
2504                         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write COC marker\n");
2505                         return OPJ_FALSE;
2506                 }
2507                 p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
2508                 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_coc_size;
2509         }
2510
2511         opj_j2k_write_coc_in_memory(p_j2k,p_comp_no,p_j2k->m_specific_param.m_encoder.m_header_tile_data,&l_remaining_size,p_manager);
2512
2513         if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_coc_size,p_manager) != l_coc_size) {
2514                 return OPJ_FALSE;
2515         }
2516
2517         return OPJ_TRUE;
2518 }
2519 #endif
2520
2521 #if 0
2522 void opj_j2k_write_coc_in_memory(   opj_j2k_t *p_j2k,
2523                                                 OPJ_UINT32 p_comp_no,
2524                                                 OPJ_BYTE * p_data,
2525                                                 OPJ_UINT32 * p_data_written,
2526                                                 opj_event_mgr_t * p_manager
2527                                     )
2528 {
2529         opj_cp_t *l_cp = 00;
2530         opj_tcp_t *l_tcp = 00;
2531         OPJ_UINT32 l_coc_size,l_remaining_size;
2532         OPJ_BYTE * l_current_data = 00;
2533         opj_image_t *l_image = 00;
2534         OPJ_UINT32 l_comp_room;
2535
2536         /* preconditions */
2537         assert(p_j2k != 00);
2538         assert(p_manager != 00);
2539
2540         l_cp = &(p_j2k->m_cp);
2541         l_tcp = &l_cp->tcps[p_j2k->m_current_tile_number];
2542         l_image = p_j2k->m_private_image;
2543         l_comp_room = (l_image->numcomps <= 256) ? 1 : 2;
2544
2545         l_coc_size = 5 + l_comp_room + opj_j2k_get_SPCod_SPCoc_size(p_j2k,p_j2k->m_current_tile_number,p_comp_no);
2546         l_remaining_size = l_coc_size;
2547
2548         l_current_data = p_data;
2549
2550         opj_write_bytes(l_current_data,J2K_MS_COC,2);                           /* COC */
2551         l_current_data += 2;
2552
2553         opj_write_bytes(l_current_data,l_coc_size-2,2);                         /* L_COC */
2554         l_current_data += 2;
2555
2556         opj_write_bytes(l_current_data,p_comp_no, l_comp_room);         /* Ccoc */
2557         l_current_data+=l_comp_room;
2558
2559         opj_write_bytes(l_current_data, l_tcp->tccps[p_comp_no].csty, 1);               /* Scoc */
2560         ++l_current_data;
2561
2562         l_remaining_size -= (5 + l_comp_room);
2563         opj_j2k_write_SPCod_SPCoc(p_j2k,p_j2k->m_current_tile_number,0,l_current_data,&l_remaining_size,p_manager);
2564         * p_data_written = l_coc_size;
2565 }
2566 #endif
2567
2568 OPJ_UINT32 opj_j2k_get_max_coc_size(opj_j2k_t *p_j2k)
2569 {
2570         OPJ_UINT32 i,j;
2571         OPJ_UINT32 l_nb_comp;
2572         OPJ_UINT32 l_nb_tiles;
2573         OPJ_UINT32 l_max = 0;
2574
2575         /* preconditions */
2576
2577         l_nb_tiles = p_j2k->m_cp.tw * p_j2k->m_cp.th ;
2578         l_nb_comp = p_j2k->m_private_image->numcomps;
2579
2580         for (i=0;i<l_nb_tiles;++i) {
2581                 for (j=0;j<l_nb_comp;++j) {
2582                         l_max = opj_uint_max(l_max,opj_j2k_get_SPCod_SPCoc_size(p_j2k,i,j));
2583                 }
2584         }
2585
2586         return 6 + l_max;
2587 }
2588
2589 /**
2590  * Reads a COC marker (Coding Style Component)
2591  * @param       p_header_data   the data contained in the COC box.
2592  * @param       p_j2k                   the jpeg2000 codec.
2593  * @param       p_header_size   the size of the data contained in the COC marker.
2594  * @param       p_manager               the user event manager.
2595 */
2596 static OPJ_BOOL opj_j2k_read_coc (  opj_j2k_t *p_j2k,
2597                                     OPJ_BYTE * p_header_data,
2598                                     OPJ_UINT32 p_header_size,
2599                                     opj_event_mgr_t * p_manager
2600                                     )
2601 {
2602         opj_cp_t *l_cp = NULL;
2603         opj_tcp_t *l_tcp = NULL;
2604         opj_image_t *l_image = NULL;
2605         OPJ_UINT32 l_comp_room;
2606         OPJ_UINT32 l_comp_no;
2607
2608         /* preconditions */
2609         assert(p_header_data != 00);
2610         assert(p_j2k != 00);
2611         assert(p_manager != 00);
2612
2613         l_cp = &(p_j2k->m_cp);
2614         l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH ) ? /*FIXME J2K_DEC_STATE_TPH*/
2615                                 &l_cp->tcps[p_j2k->m_current_tile_number] :
2616                                 p_j2k->m_specific_param.m_decoder.m_default_tcp;
2617         l_image = p_j2k->m_private_image;
2618
2619         l_comp_room = l_image->numcomps <= 256 ? 1 : 2;
2620
2621         /* make sure room is sufficient*/
2622         if (p_header_size < l_comp_room + 1) {
2623                 opj_event_msg(p_manager, EVT_ERROR, "Error reading COC marker\n");
2624                 return OPJ_FALSE;
2625         }
2626         p_header_size -= l_comp_room + 1;
2627
2628         opj_read_bytes(p_header_data,&l_comp_no,l_comp_room);                   /* Ccoc */
2629         p_header_data += l_comp_room;
2630         if (l_comp_no >= l_image->numcomps) {
2631                 opj_event_msg(p_manager, EVT_ERROR, "Error reading COC marker (bad number of components)\n");
2632                 return OPJ_FALSE;
2633         }
2634
2635         opj_read_bytes(p_header_data,&l_tcp->tccps[l_comp_no].csty,1);                  /* Scoc */
2636         ++p_header_data ;
2637
2638         if (! opj_j2k_read_SPCod_SPCoc(p_j2k,l_comp_no,p_header_data,&p_header_size,p_manager)) {
2639                 opj_event_msg(p_manager, EVT_ERROR, "Error reading COC marker\n");
2640                 return OPJ_FALSE;
2641         }
2642
2643         if (p_header_size != 0) {
2644                 opj_event_msg(p_manager, EVT_ERROR, "Error reading COC marker\n");
2645                 return OPJ_FALSE;
2646         }
2647         return OPJ_TRUE;
2648 }
2649
2650 OPJ_BOOL opj_j2k_write_qcd(     opj_j2k_t *p_j2k,
2651                                                         opj_stream_private_t *p_stream,
2652                                                         opj_event_mgr_t * p_manager
2653                             )
2654 {
2655         OPJ_UINT32 l_qcd_size,l_remaining_size;
2656         OPJ_BYTE * l_current_data = 00;
2657
2658         /* preconditions */
2659         assert(p_j2k != 00);
2660         assert(p_manager != 00);
2661         assert(p_stream != 00);
2662
2663         l_qcd_size = 4 + opj_j2k_get_SQcd_SQcc_size(p_j2k,p_j2k->m_current_tile_number,0);
2664         l_remaining_size = l_qcd_size;
2665
2666         if (l_qcd_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
2667                 OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_qcd_size);
2668                 if (! new_header_tile_data) {
2669                         opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
2670                         p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL;
2671                         p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
2672                         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write QCD marker\n");
2673                         return OPJ_FALSE;
2674                 }
2675                 p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
2676                 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_qcd_size;
2677         }
2678
2679         l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
2680
2681         opj_write_bytes(l_current_data,J2K_MS_QCD,2);           /* QCD */
2682         l_current_data += 2;
2683
2684         opj_write_bytes(l_current_data,l_qcd_size-2,2);         /* L_QCD */
2685         l_current_data += 2;
2686
2687         l_remaining_size -= 4;
2688
2689         if (! opj_j2k_write_SQcd_SQcc(p_j2k,p_j2k->m_current_tile_number,0,l_current_data,&l_remaining_size,p_manager)) {
2690                 opj_event_msg(p_manager, EVT_ERROR, "Error writing QCD marker\n");
2691                 return OPJ_FALSE;
2692         }
2693
2694         if (l_remaining_size != 0) {
2695                 opj_event_msg(p_manager, EVT_ERROR, "Error writing QCD marker\n");
2696                 return OPJ_FALSE;
2697         }
2698
2699         if (opj_stream_write_data(p_stream, p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_qcd_size,p_manager) != l_qcd_size) {
2700                 return OPJ_FALSE;
2701         }
2702
2703         return OPJ_TRUE;
2704 }
2705
2706 /**
2707  * Reads a QCD marker (Quantization defaults)
2708  * @param       p_header_data   the data contained in the QCD box.
2709  * @param       p_j2k                   the jpeg2000 codec.
2710  * @param       p_header_size   the size of the data contained in the QCD marker.
2711  * @param       p_manager               the user event manager.
2712 */
2713 static OPJ_BOOL opj_j2k_read_qcd (  opj_j2k_t *p_j2k,
2714                                     OPJ_BYTE * p_header_data,
2715                                     OPJ_UINT32 p_header_size,
2716                                     opj_event_mgr_t * p_manager
2717                                     )
2718 {
2719         /* preconditions */
2720         assert(p_header_data != 00);
2721         assert(p_j2k != 00);
2722         assert(p_manager != 00);
2723
2724         if (! opj_j2k_read_SQcd_SQcc(p_j2k,0,p_header_data,&p_header_size,p_manager)) {
2725                 opj_event_msg(p_manager, EVT_ERROR, "Error reading QCD marker\n");
2726                 return OPJ_FALSE;
2727         }
2728
2729         if (p_header_size != 0) {
2730                 opj_event_msg(p_manager, EVT_ERROR, "Error reading QCD marker\n");
2731                 return OPJ_FALSE;
2732         }
2733
2734         /* Apply the quantization parameters to other components of the current tile or the m_default_tcp */
2735         opj_j2k_copy_tile_quantization_parameters(p_j2k);
2736
2737         return OPJ_TRUE;
2738 }
2739
2740 #if 0
2741 OPJ_BOOL opj_j2k_write_qcc(     opj_j2k_t *p_j2k,
2742                                                 OPJ_UINT32 p_comp_no,
2743                                                 opj_stream_private_t *p_stream,
2744                                                 opj_event_mgr_t * p_manager
2745                             )
2746 {
2747         OPJ_UINT32 l_qcc_size,l_remaining_size;
2748
2749         /* preconditions */
2750         assert(p_j2k != 00);
2751         assert(p_manager != 00);
2752         assert(p_stream != 00);
2753
2754         l_qcc_size = 5 + opj_j2k_get_SQcd_SQcc_size(p_j2k,p_j2k->m_current_tile_number,p_comp_no);
2755         l_qcc_size += p_j2k->m_private_image->numcomps <= 256 ? 0:1;
2756         l_remaining_size = l_qcc_size;
2757
2758         if (l_qcc_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
2759                 OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_qcc_size);
2760                 if (! new_header_tile_data) {
2761                         opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
2762                         p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL;
2763                         p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
2764                         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write QCC marker\n");
2765                         return OPJ_FALSE;
2766                 }
2767                 p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
2768                 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_qcc_size;
2769         }
2770
2771         opj_j2k_write_qcc_in_memory(p_j2k,p_comp_no,p_j2k->m_specific_param.m_encoder.m_header_tile_data,&l_remaining_size,p_manager);
2772
2773         if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_qcc_size,p_manager) != l_qcc_size) {
2774                 return OPJ_FALSE;
2775         }
2776
2777         return OPJ_TRUE;
2778 }
2779 #endif
2780
2781 #if 0
2782 void opj_j2k_write_qcc_in_memory(   opj_j2k_t *p_j2k,
2783                                                                 OPJ_UINT32 p_comp_no,
2784                                                                 OPJ_BYTE * p_data,
2785                                                                 OPJ_UINT32 * p_data_written,
2786                                                                 opj_event_mgr_t * p_manager
2787                                     )
2788 {
2789         OPJ_UINT32 l_qcc_size,l_remaining_size;
2790         OPJ_BYTE * l_current_data = 00;
2791
2792         /* preconditions */
2793         assert(p_j2k != 00);
2794         assert(p_manager != 00);
2795
2796         l_qcc_size = 6 + opj_j2k_get_SQcd_SQcc_size(p_j2k,p_j2k->m_current_tile_number,p_comp_no);
2797         l_remaining_size = l_qcc_size;
2798
2799         l_current_data = p_data;
2800
2801         opj_write_bytes(l_current_data,J2K_MS_QCC,2);           /* QCC */
2802         l_current_data += 2;
2803
2804         if (p_j2k->m_private_image->numcomps <= 256) {
2805                 --l_qcc_size;
2806
2807                 opj_write_bytes(l_current_data,l_qcc_size-2,2);         /* L_QCC */
2808                 l_current_data += 2;
2809
2810                 opj_write_bytes(l_current_data, p_comp_no, 1);  /* Cqcc */
2811                 ++l_current_data;
2812
2813                 /* in the case only one byte is sufficient the last byte allocated is useless -> still do -6 for available */
2814                 l_remaining_size -= 6;
2815         }
2816         else {
2817                 opj_write_bytes(l_current_data,l_qcc_size-2,2);         /* L_QCC */
2818                 l_current_data += 2;
2819
2820                 opj_write_bytes(l_current_data, p_comp_no, 2);  /* Cqcc */
2821                 l_current_data+=2;
2822
2823                 l_remaining_size -= 6;
2824         }
2825
2826         opj_j2k_write_SQcd_SQcc(p_j2k,p_j2k->m_current_tile_number,p_comp_no,l_current_data,&l_remaining_size,p_manager);
2827
2828         *p_data_written = l_qcc_size;
2829 }
2830 #endif
2831
2832 OPJ_UINT32 opj_j2k_get_max_qcc_size (opj_j2k_t *p_j2k)
2833 {
2834         return opj_j2k_get_max_coc_size(p_j2k);
2835 }
2836
2837 /**
2838  * Reads a QCC marker (Quantization component)
2839  * @param       p_header_data   the data contained in the QCC box.
2840  * @param       p_j2k                   the jpeg2000 codec.
2841  * @param       p_header_size   the size of the data contained in the QCC marker.
2842  * @param       p_manager               the user event manager.
2843 */
2844 static OPJ_BOOL opj_j2k_read_qcc(   opj_j2k_t *p_j2k,
2845                                     OPJ_BYTE * p_header_data,
2846                                     OPJ_UINT32 p_header_size,
2847                                     opj_event_mgr_t * p_manager
2848                                     )
2849 {
2850         OPJ_UINT32 l_num_comp,l_comp_no;
2851
2852         /* preconditions */
2853         assert(p_header_data != 00);
2854         assert(p_j2k != 00);
2855         assert(p_manager != 00);
2856
2857         l_num_comp = p_j2k->m_private_image->numcomps;
2858
2859         if (l_num_comp <= 256) {
2860                 if (p_header_size < 1) {
2861                         opj_event_msg(p_manager, EVT_ERROR, "Error reading QCC marker\n");
2862                         return OPJ_FALSE;
2863                 }
2864                 opj_read_bytes(p_header_data,&l_comp_no,1);
2865                 ++p_header_data;
2866                 --p_header_size;
2867         }
2868         else {
2869                 if (p_header_size < 2) {
2870                         opj_event_msg(p_manager, EVT_ERROR, "Error reading QCC marker\n");
2871                         return OPJ_FALSE;
2872                 }
2873                 opj_read_bytes(p_header_data,&l_comp_no,2);
2874                 p_header_data+=2;
2875                 p_header_size-=2;
2876         }
2877
2878 #ifdef USE_JPWL
2879         if (p_j2k->m_cp.correct) {
2880
2881                 static OPJ_UINT32 backup_compno = 0;
2882
2883                 /* compno is negative or larger than the number of components!!! */
2884                 if (/*(l_comp_no < 0) ||*/ (l_comp_no >= l_num_comp)) {
2885                         opj_event_msg(p_manager, EVT_ERROR,
2886                                 "JPWL: bad component number in QCC (%d out of a maximum of %d)\n",
2887                                 l_comp_no, l_num_comp);
2888                         if (!JPWL_ASSUME) {
2889                                 opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
2890                                 return OPJ_FALSE;
2891                         }
2892                         /* we try to correct */
2893                         l_comp_no = backup_compno % l_num_comp;
2894                         opj_event_msg(p_manager, EVT_WARNING, "- trying to adjust this\n"
2895                                 "- setting component number to %d\n",
2896                                 l_comp_no);
2897                 }
2898
2899                 /* keep your private count of tiles */
2900                 backup_compno++;
2901         };
2902 #endif /* USE_JPWL */
2903
2904         if (l_comp_no >= p_j2k->m_private_image->numcomps) {
2905                 opj_event_msg(p_manager, EVT_ERROR,
2906                               "Invalid component number: %d, regarding the number of components %d\n",
2907                               l_comp_no, p_j2k->m_private_image->numcomps);
2908                 return OPJ_FALSE;
2909         }
2910
2911         if (! opj_j2k_read_SQcd_SQcc(p_j2k,l_comp_no,p_header_data,&p_header_size,p_manager)) {
2912                 opj_event_msg(p_manager, EVT_ERROR, "Error reading QCC marker\n");
2913                 return OPJ_FALSE;
2914         }
2915
2916         if (p_header_size != 0) {
2917                 opj_event_msg(p_manager, EVT_ERROR, "Error reading QCC marker\n");
2918                 return OPJ_FALSE;
2919         }
2920
2921         return OPJ_TRUE;
2922 }
2923
2924 OPJ_BOOL opj_j2k_write_poc(     opj_j2k_t *p_j2k,
2925                                                         opj_stream_private_t *p_stream,
2926                                                         opj_event_mgr_t * p_manager
2927                             )
2928 {
2929         OPJ_UINT32 l_nb_comp;
2930         OPJ_UINT32 l_nb_poc;
2931         OPJ_UINT32 l_poc_size;
2932         OPJ_UINT32 l_written_size = 0;
2933         opj_tcp_t *l_tcp = 00;
2934         OPJ_UINT32 l_poc_room;
2935
2936         /* preconditions */
2937         assert(p_j2k != 00);
2938         assert(p_manager != 00);
2939         assert(p_stream != 00);
2940
2941         l_tcp = &p_j2k->m_cp.tcps[p_j2k->m_current_tile_number];
2942         l_nb_comp = p_j2k->m_private_image->numcomps;
2943         l_nb_poc = 1 + l_tcp->numpocs;
2944
2945         if (l_nb_comp <= 256) {
2946                 l_poc_room = 1;
2947         }
2948         else {
2949                 l_poc_room = 2;
2950         }
2951         l_poc_size = 4 + (5 + 2 * l_poc_room) * l_nb_poc;
2952
2953         if (l_poc_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
2954                 OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_poc_size);
2955                 if (! new_header_tile_data) {
2956                         opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
2957                         p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL;
2958                         p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
2959                         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write POC marker\n");
2960                         return OPJ_FALSE;
2961                 }
2962                 p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
2963                 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_poc_size;
2964         }
2965
2966         opj_j2k_write_poc_in_memory(p_j2k,p_j2k->m_specific_param.m_encoder.m_header_tile_data,&l_written_size,p_manager);
2967
2968         if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_poc_size,p_manager) != l_poc_size) {
2969                 return OPJ_FALSE;
2970         }
2971
2972         return OPJ_TRUE;
2973 }
2974
2975 void opj_j2k_write_poc_in_memory(   opj_j2k_t *p_j2k,
2976                                                                 OPJ_BYTE * p_data,
2977                                                                 OPJ_UINT32 * p_data_written,
2978                                                                 opj_event_mgr_t * p_manager
2979                                     )
2980 {
2981         OPJ_UINT32 i;
2982         OPJ_BYTE * l_current_data = 00;
2983         OPJ_UINT32 l_nb_comp;
2984         OPJ_UINT32 l_nb_poc;
2985         OPJ_UINT32 l_poc_size;
2986         opj_image_t *l_image = 00;
2987         opj_tcp_t *l_tcp = 00;
2988         opj_tccp_t *l_tccp = 00;
2989         opj_poc_t *l_current_poc = 00;
2990         OPJ_UINT32 l_poc_room;
2991
2992         /* preconditions */
2993         assert(p_j2k != 00);
2994         assert(p_manager != 00);
2995
2996         l_tcp = &p_j2k->m_cp.tcps[p_j2k->m_current_tile_number];
2997         l_tccp = &l_tcp->tccps[0];
2998         l_image = p_j2k->m_private_image;
2999         l_nb_comp = l_image->numcomps;
3000         l_nb_poc = 1 + l_tcp->numpocs;
3001
3002         if (l_nb_comp <= 256) {
3003                 l_poc_room = 1;
3004         }
3005         else {
3006                 l_poc_room = 2;
3007         }
3008
3009         l_poc_size = 4 + (5 + 2 * l_poc_room) * l_nb_poc;
3010
3011         l_current_data = p_data;
3012
3013         opj_write_bytes(l_current_data,J2K_MS_POC,2);                                   /* POC  */
3014         l_current_data += 2;
3015
3016         opj_write_bytes(l_current_data,l_poc_size-2,2);                                 /* Lpoc */
3017         l_current_data += 2;
3018
3019         l_current_poc =  l_tcp->pocs;
3020         for (i = 0; i < l_nb_poc; ++i) {
3021                 opj_write_bytes(l_current_data,l_current_poc->resno0,1);                                /* RSpoc_i */
3022                 ++l_current_data;
3023
3024                 opj_write_bytes(l_current_data,l_current_poc->compno0,l_poc_room);              /* CSpoc_i */
3025                 l_current_data+=l_poc_room;
3026
3027                 opj_write_bytes(l_current_data,l_current_poc->layno1,2);                                /* LYEpoc_i */
3028                 l_current_data+=2;
3029
3030                 opj_write_bytes(l_current_data,l_current_poc->resno1,1);                                /* REpoc_i */
3031                 ++l_current_data;
3032
3033                 opj_write_bytes(l_current_data,l_current_poc->compno1,l_poc_room);              /* CEpoc_i */
3034                 l_current_data+=l_poc_room;
3035
3036                 opj_write_bytes(l_current_data,l_current_poc->prg,1);                                   /* Ppoc_i */
3037                 ++l_current_data;
3038
3039                 /* change the value of the max layer according to the actual number of layers in the file, components and resolutions*/
3040                 l_current_poc->layno1 = opj_int_min(l_current_poc->layno1, l_tcp->numlayers);
3041                 l_current_poc->resno1 = opj_int_min(l_current_poc->resno1, l_tccp->numresolutions);
3042                 l_current_poc->compno1 = opj_int_min(l_current_poc->compno1, l_nb_comp);
3043
3044                 ++l_current_poc;
3045         }
3046
3047         *p_data_written = l_poc_size;
3048 }
3049
3050 OPJ_UINT32 opj_j2k_get_max_poc_size(opj_j2k_t *p_j2k)
3051 {
3052         opj_tcp_t * l_tcp = 00;
3053         OPJ_UINT32 l_nb_tiles = 0;
3054         OPJ_UINT32 l_max_poc = 0;
3055         OPJ_UINT32 i;
3056
3057         l_tcp = p_j2k->m_cp.tcps;
3058         l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
3059
3060         for (i=0;i<l_nb_tiles;++i) {
3061                 l_max_poc = opj_uint_max(l_max_poc,l_tcp->numpocs);
3062                 ++l_tcp;
3063         }
3064
3065         ++l_max_poc;
3066
3067         return 4 + 9 * l_max_poc;
3068 }
3069
3070 OPJ_UINT32 opj_j2k_get_max_toc_size (opj_j2k_t *p_j2k)
3071 {
3072         OPJ_UINT32 i;
3073         OPJ_UINT32 l_nb_tiles;
3074         OPJ_UINT32 l_max = 0;
3075         opj_tcp_t * l_tcp = 00;
3076
3077         l_tcp = p_j2k->m_cp.tcps;
3078         l_nb_tiles = p_j2k->m_cp.tw * p_j2k->m_cp.th ;
3079
3080         for (i=0;i<l_nb_tiles;++i) {
3081                 l_max = opj_uint_max(l_max,l_tcp->m_nb_tile_parts);
3082
3083                 ++l_tcp;
3084         }
3085
3086         return 12 * l_max;
3087 }
3088
3089 OPJ_UINT32 opj_j2k_get_specific_header_sizes(opj_j2k_t *p_j2k)
3090 {
3091         OPJ_UINT32 l_nb_bytes = 0;
3092         OPJ_UINT32 l_nb_comps;
3093         OPJ_UINT32 l_coc_bytes,l_qcc_bytes;
3094
3095         l_nb_comps = p_j2k->m_private_image->numcomps - 1;
3096         l_nb_bytes += opj_j2k_get_max_toc_size(p_j2k);
3097
3098         if (p_j2k->m_cp.m_specific_param.m_enc.m_cinema == 0) {
3099                 l_coc_bytes = opj_j2k_get_max_coc_size(p_j2k);
3100                 l_nb_bytes += l_nb_comps * l_coc_bytes;
3101
3102                 l_qcc_bytes = opj_j2k_get_max_qcc_size(p_j2k);
3103                 l_nb_bytes += l_nb_comps * l_qcc_bytes;
3104         }
3105
3106         l_nb_bytes += opj_j2k_get_max_poc_size(p_j2k);
3107
3108         /*** DEVELOPER CORNER, Add room for your headers ***/
3109
3110         return l_nb_bytes;
3111 }
3112
3113 /**
3114  * Reads a POC marker (Progression Order Change)
3115  *
3116  * @param       p_header_data   the data contained in the POC box.
3117  * @param       p_j2k                   the jpeg2000 codec.
3118  * @param       p_header_size   the size of the data contained in the POC marker.
3119  * @param       p_manager               the user event manager.
3120 */
3121 static OPJ_BOOL opj_j2k_read_poc (  opj_j2k_t *p_j2k,
3122                                     OPJ_BYTE * p_header_data,
3123                                     OPJ_UINT32 p_header_size,
3124                                     opj_event_mgr_t * p_manager
3125                                     )
3126 {
3127         OPJ_UINT32 i, l_nb_comp, l_tmp;
3128         opj_image_t * l_image = 00;
3129         OPJ_UINT32 l_old_poc_nb, l_current_poc_nb, l_current_poc_remaining;
3130         OPJ_UINT32 l_chunk_size, l_comp_room;
3131
3132         opj_cp_t *l_cp = 00;
3133         opj_tcp_t *l_tcp = 00;
3134         opj_poc_t *l_current_poc = 00;
3135
3136         /* preconditions */
3137         assert(p_header_data != 00);
3138         assert(p_j2k != 00);
3139         assert(p_manager != 00);
3140
3141         l_image = p_j2k->m_private_image;
3142         l_nb_comp = l_image->numcomps;
3143         if (l_nb_comp <= 256) {
3144                 l_comp_room = 1;
3145         }
3146         else {
3147                 l_comp_room = 2;
3148         }
3149         l_chunk_size = 5 + 2 * l_comp_room;
3150         l_current_poc_nb = p_header_size / l_chunk_size;
3151         l_current_poc_remaining = p_header_size % l_chunk_size;
3152
3153         if ((l_current_poc_nb <= 0) || (l_current_poc_remaining != 0)) {
3154                 opj_event_msg(p_manager, EVT_ERROR, "Error reading POC marker\n");
3155                 return OPJ_FALSE;
3156         }
3157
3158         l_cp = &(p_j2k->m_cp);
3159         l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH) ?
3160                                 &l_cp->tcps[p_j2k->m_current_tile_number] :
3161                                 p_j2k->m_specific_param.m_decoder.m_default_tcp;
3162         l_old_poc_nb = l_tcp->POC ? l_tcp->numpocs + 1 : 0;
3163         l_current_poc_nb += l_old_poc_nb;
3164
3165         assert(l_current_poc_nb < 32);
3166
3167         /* now poc is in use.*/
3168         l_tcp->POC = 1;
3169
3170         l_current_poc = &l_tcp->pocs[l_old_poc_nb];
3171         for     (i = l_old_poc_nb; i < l_current_poc_nb; ++i) {
3172                 opj_read_bytes(p_header_data,&(l_current_poc->resno0),1);                               /* RSpoc_i */
3173                 ++p_header_data;
3174                 opj_read_bytes(p_header_data,&(l_current_poc->compno0),l_comp_room);    /* CSpoc_i */
3175                 p_header_data+=l_comp_room;
3176                 opj_read_bytes(p_header_data,&(l_current_poc->layno1),2);                               /* LYEpoc_i */
3177                 p_header_data+=2;
3178                 opj_read_bytes(p_header_data,&(l_current_poc->resno1),1);                               /* REpoc_i */
3179                 ++p_header_data;
3180                 opj_read_bytes(p_header_data,&(l_current_poc->compno1),l_comp_room);    /* CEpoc_i */
3181                 p_header_data+=l_comp_room;
3182                 opj_read_bytes(p_header_data,&l_tmp,1);                                                                 /* Ppoc_i */
3183                 ++p_header_data;
3184                 l_current_poc->prg = (OPJ_PROG_ORDER) l_tmp;
3185                 /* make sure comp is in acceptable bounds */
3186                 l_current_poc->compno1 = opj_uint_min(l_current_poc->compno1, l_nb_comp);
3187                 ++l_current_poc;
3188         }
3189
3190         l_tcp->numpocs = l_current_poc_nb - 1;
3191         return OPJ_TRUE;
3192 }
3193
3194 /**
3195  * Reads a CRG marker (Component registration)
3196  *
3197  * @param       p_header_data   the data contained in the TLM box.
3198  * @param       p_j2k                   the jpeg2000 codec.
3199  * @param       p_header_size   the size of the data contained in the TLM marker.
3200  * @param       p_manager               the user event manager.
3201 */
3202 static OPJ_BOOL opj_j2k_read_crg (  opj_j2k_t *p_j2k,
3203                                     OPJ_BYTE * p_header_data,
3204                                     OPJ_UINT32 p_header_size,
3205                                     opj_event_mgr_t * p_manager
3206                                     )
3207 {
3208         OPJ_UINT32 l_nb_comp;
3209         /* preconditions */
3210         assert(p_header_data != 00);
3211         assert(p_j2k != 00);
3212         assert(p_manager != 00);
3213
3214         l_nb_comp = p_j2k->m_private_image->numcomps;
3215
3216         if (p_header_size != l_nb_comp *4) {
3217                 opj_event_msg(p_manager, EVT_ERROR, "Error reading CRG marker\n");
3218                 return OPJ_FALSE;
3219         }
3220         /* Do not care of this at the moment since only local variables are set here */
3221         /*
3222         for
3223                 (i = 0; i < l_nb_comp; ++i)
3224         {
3225                 opj_read_bytes(p_header_data,&l_Xcrg_i,2);                              // Xcrg_i
3226                 p_header_data+=2;
3227                 opj_read_bytes(p_header_data,&l_Ycrg_i,2);                              // Xcrg_i
3228                 p_header_data+=2;
3229         }
3230         */
3231         return OPJ_TRUE;
3232 }
3233
3234 /**
3235  * Reads a TLM marker (Tile Length Marker)
3236  *
3237  * @param       p_header_data   the data contained in the TLM box.
3238  * @param       p_j2k                   the jpeg2000 codec.
3239  * @param       p_header_size   the size of the data contained in the TLM marker.
3240  * @param       p_manager               the user event manager.
3241 */
3242 static OPJ_BOOL opj_j2k_read_tlm (  opj_j2k_t *p_j2k,
3243                                     OPJ_BYTE * p_header_data,
3244                                     OPJ_UINT32 p_header_size,
3245                                     opj_event_mgr_t * p_manager
3246                                     )
3247 {
3248         OPJ_UINT32 l_Ztlm, l_Stlm, l_ST, l_SP, l_tot_num_tp_remaining, l_quotient, l_Ptlm_size;
3249         /* preconditions */
3250         assert(p_header_data != 00);
3251         assert(p_j2k != 00);
3252         assert(p_manager != 00);
3253
3254         if (p_header_size < 2) {
3255                 opj_event_msg(p_manager, EVT_ERROR, "Error reading TLM marker\n");
3256                 return OPJ_FALSE;
3257         }
3258         p_header_size -= 2;
3259
3260         opj_read_bytes(p_header_data,&l_Ztlm,1);                                /* Ztlm */
3261         ++p_header_data;
3262         opj_read_bytes(p_header_data,&l_Stlm,1);                                /* Stlm */
3263         ++p_header_data;
3264
3265         l_ST = ((l_Stlm >> 4) & 0x3);
3266         l_SP = (l_Stlm >> 6) & 0x1;
3267
3268         l_Ptlm_size = (l_SP + 1) * 2;
3269         l_quotient = l_Ptlm_size + l_ST;
3270
3271         l_tot_num_tp_remaining = p_header_size % l_quotient;
3272
3273         if (l_tot_num_tp_remaining != 0) {
3274                 opj_event_msg(p_manager, EVT_ERROR, "Error reading TLM marker\n");
3275                 return OPJ_FALSE;
3276         }
3277         /* FIXME Do not care of this at the moment since only local variables are set here */
3278         /*
3279         for
3280                 (i = 0; i < l_tot_num_tp; ++i)
3281         {
3282                 opj_read_bytes(p_header_data,&l_Ttlm_i,l_ST);                           // Ttlm_i
3283                 p_header_data += l_ST;
3284                 opj_read_bytes(p_header_data,&l_Ptlm_i,l_Ptlm_size);            // Ptlm_i
3285                 p_header_data += l_Ptlm_size;
3286         }*/
3287         return OPJ_TRUE;
3288 }
3289
3290 /**
3291  * Reads a PLM marker (Packet length, main header marker)
3292  *
3293  * @param       p_header_data   the data contained in the TLM box.
3294  * @param       p_j2k                   the jpeg2000 codec.
3295  * @param       p_header_size   the size of the data contained in the TLM marker.
3296  * @param       p_manager               the user event manager.
3297 */
3298 static OPJ_BOOL opj_j2k_read_plm (  opj_j2k_t *p_j2k,
3299                                     OPJ_BYTE * p_header_data,
3300                                     OPJ_UINT32 p_header_size,
3301                                     opj_event_mgr_t * p_manager
3302                                     )
3303 {
3304         /* preconditions */
3305         assert(p_header_data != 00);
3306         assert(p_j2k != 00);
3307         assert(p_manager != 00);
3308
3309         if (p_header_size < 1) {
3310                 opj_event_msg(p_manager, EVT_ERROR, "Error reading PLM marker\n");
3311                 return OPJ_FALSE;
3312         }
3313         /* Do not care of this at the moment since only local variables are set here */
3314         /*
3315         opj_read_bytes(p_header_data,&l_Zplm,1);                                        // Zplm
3316         ++p_header_data;
3317         --p_header_size;
3318
3319         while
3320                 (p_header_size > 0)
3321         {
3322                 opj_read_bytes(p_header_data,&l_Nplm,1);                                // Nplm
3323                 ++p_header_data;
3324                 p_header_size -= (1+l_Nplm);
3325                 if
3326                         (p_header_size < 0)
3327                 {
3328                         opj_event_msg(p_manager, EVT_ERROR, "Error reading PLM marker\n");
3329                         return false;
3330                 }
3331                 for
3332                         (i = 0; i < l_Nplm; ++i)
3333                 {
3334                         opj_read_bytes(p_header_data,&l_tmp,1);                         // Iplm_ij
3335                         ++p_header_data;
3336                         // take only the last seven bytes
3337                         l_packet_len |= (l_tmp & 0x7f);
3338                         if
3339                                 (l_tmp & 0x80)
3340                         {
3341                                 l_packet_len <<= 7;
3342                         }
3343                         else
3344                         {
3345                 // store packet length and proceed to next packet
3346                                 l_packet_len = 0;
3347                         }
3348                 }
3349                 if
3350                         (l_packet_len != 0)
3351                 {
3352                         opj_event_msg(p_manager, EVT_ERROR, "Error reading PLM marker\n");
3353                         return false;
3354                 }
3355         }
3356         */
3357         return OPJ_TRUE;
3358 }
3359
3360 /**
3361  * Reads a PLT marker (Packet length, tile-part header)
3362  *
3363  * @param       p_header_data   the data contained in the PLT box.
3364  * @param       p_j2k                   the jpeg2000 codec.
3365  * @param       p_header_size   the size of the data contained in the PLT marker.
3366  * @param       p_manager               the user event manager.
3367 */
3368 static OPJ_BOOL opj_j2k_read_plt (  opj_j2k_t *p_j2k,
3369                                     OPJ_BYTE * p_header_data,
3370                                     OPJ_UINT32 p_header_size,
3371                                     opj_event_mgr_t * p_manager
3372                                     )
3373 {
3374         OPJ_UINT32 l_Zplt, l_tmp, l_packet_len = 0, i;
3375
3376         /* preconditions */
3377         assert(p_header_data != 00);
3378         assert(p_j2k != 00);
3379         assert(p_manager != 00);
3380
3381         if (p_header_size < 1) {
3382                 opj_event_msg(p_manager, EVT_ERROR, "Error reading PLT marker\n");
3383                 return OPJ_FALSE;
3384         }
3385
3386         opj_read_bytes(p_header_data,&l_Zplt,1);                /* Zplt */
3387         ++p_header_data;
3388         --p_header_size;
3389
3390         for (i = 0; i < p_header_size; ++i) {
3391                 opj_read_bytes(p_header_data,&l_tmp,1);         /* Iplt_ij */
3392                 ++p_header_data;
3393                 /* take only the last seven bytes */
3394                 l_packet_len |= (l_tmp & 0x7f);
3395                 if (l_tmp & 0x80) {
3396                         l_packet_len <<= 7;
3397                 }
3398                 else {
3399             /* store packet length and proceed to next packet */
3400                         l_packet_len = 0;
3401                 }
3402         }
3403
3404         if (l_packet_len != 0) {
3405                 opj_event_msg(p_manager, EVT_ERROR, "Error reading PLT marker\n");
3406                 return OPJ_FALSE;
3407         }
3408
3409         return OPJ_TRUE;
3410 }
3411
3412 #if 0
3413 OPJ_BOOL j2k_read_ppm_v2 (
3414                                                 opj_j2k_t *p_j2k,
3415                                                 OPJ_BYTE * p_header_data,
3416                                                 OPJ_UINT32 p_header_size,
3417                                                 struct opj_event_mgr * p_manager
3418                                         )
3419 {
3420
3421         opj_cp_t *l_cp = 00;
3422         OPJ_UINT32 l_remaining_data, l_Z_ppm, l_N_ppm;
3423
3424         /* preconditions */
3425         assert(p_header_data != 00);
3426         assert(p_j2k != 00);
3427         assert(p_manager != 00);
3428
3429         if (p_header_size < 1) {
3430                 opj_event_msg(p_manager, EVT_ERROR, "Error reading PPM marker\n");
3431                 return OPJ_FALSE;
3432         }
3433
3434         l_cp = &(p_j2k->m_cp);
3435         l_cp->ppm = 1;
3436
3437         opj_read_bytes(p_header_data,&l_Z_ppm,1);               /* Z_ppm */
3438         ++p_header_data;
3439         --p_header_size;
3440
3441         /* First PPM marker */
3442         if (l_Z_ppm == 0) {
3443                 if (p_header_size < 4) {
3444                         opj_event_msg(p_manager, EVT_ERROR, "Error reading PPM marker\n");
3445                         return OPJ_FALSE;
3446                 }
3447
3448                 opj_read_bytes(p_header_data,&l_N_ppm,4);               /* N_ppm */
3449                 p_header_data+=4;
3450                 p_header_size-=4;
3451
3452                 /* First PPM marker: Initialization */
3453                 l_cp->ppm_len = l_N_ppm;
3454                 l_cp->ppm_data_size = 0;
3455
3456                 l_cp->ppm_buffer = (OPJ_BYTE *) opj_malloc(l_cp->ppm_len);
3457                 if (l_cp->ppm_buffer == 00) {
3458                         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory reading ppm marker\n");
3459                         return OPJ_FALSE;
3460                 }
3461                 memset(l_cp->ppm_buffer,0,l_cp->ppm_len);
3462
3463                 l_cp->ppm_data = l_cp->ppm_buffer;
3464         }
3465
3466         while (1) {
3467                 if (l_cp->ppm_data_size == l_cp->ppm_len) {
3468                         if (p_header_size >= 4) {
3469                                 /* read a N_ppm */
3470                                 opj_read_bytes(p_header_data,&l_N_ppm,4);               /* N_ppm */
3471                                 p_header_data+=4;
3472                                 p_header_size-=4;
3473                                 l_cp->ppm_len += l_N_ppm ;
3474
3475                                 OPJ_BYTE *new_ppm_buffer = (OPJ_BYTE *) opj_realloc(l_cp->ppm_buffer, l_cp->ppm_len);
3476                                 if (! new_ppm_buffer) {
3477                                         opj_free(l_cp->ppm_buffer);
3478                                         l_cp->ppm_buffer = NULL;
3479                                         l_cp->ppm_len = 0;
3480                                         l_cp->ppm_data = NULL;
3481                                         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory reading ppm marker\n");
3482                                         return OPJ_FALSE;
3483                                 }
3484                                 l_cp->ppm_buffer = new_ppm_buffer;
3485                                 memset(l_cp->ppm_buffer+l_cp->ppm_data_size,0,l_N_ppm);
3486                                 l_cp->ppm_data = l_cp->ppm_buffer;
3487                         }
3488                         else {
3489                                 return OPJ_FALSE;
3490                         }
3491                 }
3492
3493                 l_remaining_data = l_cp->ppm_len - l_cp->ppm_data_size;
3494
3495                 if (l_remaining_data <= p_header_size) {
3496                         /* we must store less information than available in the packet */
3497                         memcpy(l_cp->ppm_buffer + l_cp->ppm_data_size , p_header_data , l_remaining_data);
3498                         l_cp->ppm_data_size = l_cp->ppm_len;
3499                         p_header_size -= l_remaining_data;
3500                         p_header_data += l_remaining_data;
3501                 }
3502                 else {
3503                         memcpy(l_cp->ppm_buffer + l_cp->ppm_data_size , p_header_data , p_header_size);
3504                         l_cp->ppm_data_size += p_header_size;
3505                         p_header_data += p_header_size;
3506                         p_header_size = 0;
3507                         break;
3508                 }
3509         }
3510
3511         return OPJ_TRUE;
3512 }
3513 #endif
3514
3515 OPJ_BOOL j2k_read_ppm_v3 (
3516                                                 opj_j2k_t *p_j2k,
3517                                                 OPJ_BYTE * p_header_data,
3518                                                 OPJ_UINT32 p_header_size,
3519                                                 struct opj_event_mgr * p_manager
3520                                         )
3521 {
3522         opj_cp_t *l_cp = 00;
3523         OPJ_UINT32 l_remaining_data, l_Z_ppm, l_N_ppm;
3524
3525         /* preconditions */
3526         assert(p_header_data != 00);
3527         assert(p_j2k != 00);
3528         assert(p_manager != 00);
3529
3530         /* Minimum size of PPM marker is equal to the size of Zppm element */
3531         if (p_header_size < 1) {
3532                 opj_event_msg(p_manager, EVT_ERROR, "Error reading PPM marker\n");
3533                 return OPJ_FALSE;
3534         }
3535
3536         l_cp = &(p_j2k->m_cp);
3537         l_cp->ppm = 1;
3538
3539         opj_read_bytes(p_header_data,&l_Z_ppm,1);               /* Z_ppm */
3540         ++p_header_data;
3541         --p_header_size;
3542
3543         /* First PPM marker */
3544         if (l_Z_ppm == 0) {
3545                 /* We need now at least the Nppm^0 element */
3546                 if (p_header_size < 4) {
3547                         opj_event_msg(p_manager, EVT_ERROR, "Error reading PPM marker\n");
3548                         return OPJ_FALSE;
3549                 }
3550
3551                 opj_read_bytes(p_header_data,&l_N_ppm,4);               /* First N_ppm */
3552                 p_header_data+=4;
3553                 p_header_size-=4;
3554
3555                 /* First PPM marker: Initialization */
3556                 l_cp->ppm_len = l_N_ppm;
3557                 l_cp->ppm_data_read = 0;
3558
3559                 l_cp->ppm_data = (OPJ_BYTE *) opj_malloc(l_cp->ppm_len);
3560                 l_cp->ppm_buffer = l_cp->ppm_data;
3561                 if (l_cp->ppm_data == 00) {
3562                         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read ppm marker\n");
3563                         return OPJ_FALSE;
3564                 }
3565                 memset(l_cp->ppm_data,0,l_cp->ppm_len);
3566
3567                 l_cp->ppm_data_current = l_cp->ppm_data;
3568
3569                 /*l_cp->ppm_data = l_cp->ppm_buffer;*/
3570         }
3571         else {
3572                 if (p_header_size < 4) {
3573                         opj_event_msg(p_manager, EVT_WARNING, "Empty PPM marker\n");
3574                         return OPJ_TRUE;
3575                 }
3576                 else {
3577                         /* Uncompleted Ippm series in the previous PPM marker?*/
3578                         if (l_cp->ppm_data_read < l_cp->ppm_len) {
3579                                 /* Get the place where add the remaining Ippm series*/
3580                                 l_cp->ppm_data_current = &(l_cp->ppm_data[l_cp->ppm_data_read]);
3581                                 l_N_ppm = l_cp->ppm_len - l_cp->ppm_data_read;
3582                         }
3583                         else {
3584                                 OPJ_BYTE *new_ppm_data;
3585                                 opj_read_bytes(p_header_data,&l_N_ppm,4);               /* First N_ppm */
3586                                 p_header_data+=4;
3587                                 p_header_size-=4;
3588
3589                                 /* Increase the size of ppm_data to add the new Ippm series*/
3590                                 assert(l_cp->ppm_data == l_cp->ppm_buffer && "We need ppm_data and ppm_buffer to be the same when reallocating");
3591                                 new_ppm_data = (OPJ_BYTE *) opj_realloc(l_cp->ppm_data, l_cp->ppm_len + l_N_ppm);
3592                                 if (! new_ppm_data) {
3593                                         opj_free(l_cp->ppm_data);
3594                                         l_cp->ppm_data = NULL;
3595                                         l_cp->ppm_buffer = NULL;  /* TODO: no need for a new local variable: ppm_buffer and ppm_data are enough */
3596                                         l_cp->ppm_len = 0;
3597                                         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to increase the size of ppm_data to add the new Ippm series\n");
3598                                         return OPJ_FALSE;
3599                                 }
3600                                 l_cp->ppm_data = new_ppm_data;
3601                                 l_cp->ppm_buffer = l_cp->ppm_data;
3602
3603                                 /* Keep the position of the place where concatenate the new series*/
3604                                 l_cp->ppm_data_current = &(l_cp->ppm_data[l_cp->ppm_len]);
3605                                 l_cp->ppm_len += l_N_ppm;
3606                         }
3607                 }
3608         }
3609
3610         l_remaining_data = p_header_size;
3611
3612         while (l_remaining_data >= l_N_ppm) {
3613                 /* read a complete Ippm series*/
3614                 memcpy(l_cp->ppm_data_current, p_header_data, l_N_ppm);
3615                 p_header_size -= l_N_ppm;
3616                 p_header_data += l_N_ppm;
3617
3618                 l_cp->ppm_data_read += l_N_ppm; /* Increase the number of data read*/
3619
3620                 if (p_header_size)
3621                 {
3622                         opj_read_bytes(p_header_data,&l_N_ppm,4);               /* N_ppm^i */
3623                         p_header_data+=4;
3624                         p_header_size-=4;
3625                 }
3626                 else {
3627                         l_remaining_data = p_header_size;
3628                         break;
3629                 }
3630
3631                 l_remaining_data = p_header_size;
3632
3633                 /* Next Ippm series is a complete series ?*/
3634                 if (l_remaining_data > l_N_ppm) {
3635                         OPJ_BYTE *new_ppm_data;
3636                         /* Increase the size of ppm_data to add the new Ippm series*/
3637                         assert(l_cp->ppm_data == l_cp->ppm_buffer && "We need ppm_data and ppm_buffer to be the same when reallocating");
3638                         new_ppm_data = (OPJ_BYTE *) opj_realloc(l_cp->ppm_data, l_cp->ppm_len + l_N_ppm);
3639                         if (! new_ppm_data) {
3640                                 opj_free(l_cp->ppm_data);
3641                                 l_cp->ppm_data = NULL;
3642                                 l_cp->ppm_buffer = NULL;  /* TODO: no need for a new local variable: ppm_buffer and ppm_data are enough */
3643                                 l_cp->ppm_len = 0;
3644                                 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to increase the size of ppm_data to add the new (complete) Ippm series\n");
3645                                 return OPJ_FALSE;
3646                         }
3647                         l_cp->ppm_data = new_ppm_data;
3648                         l_cp->ppm_buffer = l_cp->ppm_data;
3649
3650                         /* Keep the position of the place where concatenate the new series */
3651                         l_cp->ppm_data_current = &(l_cp->ppm_data[l_cp->ppm_len]);
3652                         l_cp->ppm_len += l_N_ppm;
3653                 }
3654
3655         }
3656
3657         /* Need to read an incomplete Ippm series*/
3658         if (l_remaining_data) {
3659                 OPJ_BYTE *new_ppm_data;
3660                 assert(l_cp->ppm_data == l_cp->ppm_buffer && "We need ppm_data and ppm_buffer to be the same when reallocating");
3661                 new_ppm_data = (OPJ_BYTE *) opj_realloc(l_cp->ppm_data, l_cp->ppm_len + l_N_ppm);
3662                 if (! new_ppm_data) {
3663                         opj_free(l_cp->ppm_data);
3664                         l_cp->ppm_data = NULL;
3665                         l_cp->ppm_buffer = NULL;  /* TODO: no need for a new local variable: ppm_buffer and ppm_data are enough */
3666                         l_cp->ppm_len = 0;
3667                         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to increase the size of ppm_data to add the new (incomplete) Ippm series\n");
3668                         return OPJ_FALSE;
3669                 }
3670                 l_cp->ppm_data = new_ppm_data;
3671                 l_cp->ppm_buffer = l_cp->ppm_data;
3672
3673                 /* Keep the position of the place where concatenate the new series*/
3674                 l_cp->ppm_data_current = &(l_cp->ppm_data[l_cp->ppm_len]);
3675                 l_cp->ppm_len += l_N_ppm;
3676
3677                 /* Read incomplete Ippm series*/
3678                 memcpy(l_cp->ppm_data_current, p_header_data, l_remaining_data);
3679                 p_header_size -= l_remaining_data;
3680                 p_header_data += l_remaining_data;
3681
3682                 l_cp->ppm_data_read += l_remaining_data; /* Increase the number of data read*/
3683         }
3684
3685 #ifdef CLEAN_MSD
3686
3687                 if (l_cp->ppm_data_size == l_cp->ppm_len) {
3688                         if (p_header_size >= 4) {
3689                                 /* read a N_ppm*/
3690                                 opj_read_bytes(p_header_data,&l_N_ppm,4);               /* N_ppm */
3691                                 p_header_data+=4;
3692                                 p_header_size-=4;
3693                                 l_cp->ppm_len += l_N_ppm ;
3694
3695                                 OPJ_BYTE *new_ppm_buffer = (OPJ_BYTE *) opj_realloc(l_cp->ppm_buffer, l_cp->ppm_len);
3696                                 if (! new_ppm_buffer) {
3697                                         opj_free(l_cp->ppm_buffer);
3698                                         l_cp->ppm_buffer = NULL;
3699                                         l_cp->ppm_len = 0;
3700                                         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read ppm marker\n");
3701                                         return OPJ_FALSE;
3702                                 }
3703                                 l_cp->ppm_buffer = new_ppm_buffer;
3704                                 memset(l_cp->ppm_buffer+l_cp->ppm_data_size,0,l_N_ppm);
3705
3706                                 l_cp->ppm_data = l_cp->ppm_buffer;
3707                         }
3708                         else {
3709                                 return OPJ_FALSE;
3710                         }
3711                 }
3712
3713                 l_remaining_data = l_cp->ppm_len - l_cp->ppm_data_size;
3714
3715                 if (l_remaining_data <= p_header_size) {
3716                         /* we must store less information than available in the packet */
3717                         memcpy(l_cp->ppm_buffer + l_cp->ppm_data_size , p_header_data , l_remaining_data);
3718                         l_cp->ppm_data_size = l_cp->ppm_len;
3719                         p_header_size -= l_remaining_data;
3720                         p_header_data += l_remaining_data;
3721                 }
3722                 else {
3723                         memcpy(l_cp->ppm_buffer + l_cp->ppm_data_size , p_header_data , p_header_size);
3724                         l_cp->ppm_data_size += p_header_size;
3725                         p_header_data += p_header_size;
3726                         p_header_size = 0;
3727                         break;
3728                 }
3729         }
3730 #endif
3731         return OPJ_TRUE;
3732 }
3733
3734 /**
3735  * Reads a PPT marker (Packed packet headers, tile-part header)
3736  *
3737  * @param       p_header_data   the data contained in the PPT box.
3738  * @param       p_j2k                   the jpeg2000 codec.
3739  * @param       p_header_size   the size of the data contained in the PPT marker.
3740  * @param       p_manager               the user event manager.
3741 */
3742 static OPJ_BOOL opj_j2k_read_ppt (  opj_j2k_t *p_j2k,
3743                                     OPJ_BYTE * p_header_data,
3744                                     OPJ_UINT32 p_header_size,
3745                                     opj_event_mgr_t * p_manager
3746                                     )
3747 {
3748         opj_cp_t *l_cp = 00;
3749         opj_tcp_t *l_tcp = 00;
3750         OPJ_UINT32 l_Z_ppt;
3751
3752         /* preconditions */
3753         assert(p_header_data != 00);
3754         assert(p_j2k != 00);
3755         assert(p_manager != 00);
3756
3757         /* We need to have the Z_ppt element at minimum */
3758         if (p_header_size < 1) {
3759                 opj_event_msg(p_manager, EVT_ERROR, "Error reading PPT marker\n");
3760                 return OPJ_FALSE;
3761         }
3762
3763         l_cp = &(p_j2k->m_cp);
3764         if (l_cp->ppm){
3765                 opj_event_msg(p_manager, EVT_ERROR, "Error reading PPT marker: packet header have been previously found in the main header (PPM marker).\n");
3766                 return OPJ_FALSE;
3767         }
3768
3769         l_tcp = &(l_cp->tcps[p_j2k->m_current_tile_number]);
3770         l_tcp->ppt = 1;
3771
3772         opj_read_bytes(p_header_data,&l_Z_ppt,1);               /* Z_ppt */
3773         ++p_header_data;
3774         --p_header_size;
3775
3776         /* Allocate buffer to read the packet header */
3777         if (l_Z_ppt == 0) {
3778                 /* First PPT marker */
3779                 l_tcp->ppt_data_size = 0;
3780                 l_tcp->ppt_len = p_header_size;
3781
3782                 l_tcp->ppt_buffer = (OPJ_BYTE *) opj_calloc(l_tcp->ppt_len, sizeof(OPJ_BYTE) );
3783                 if (l_tcp->ppt_buffer == 00) {
3784                         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
3785                         return OPJ_FALSE;
3786                 }
3787                 l_tcp->ppt_data = l_tcp->ppt_buffer;
3788
3789                 /* memset(l_tcp->ppt_buffer,0,l_tcp->ppt_len); */
3790         }
3791         else {
3792                 OPJ_BYTE *new_ppt_buffer;
3793                 l_tcp->ppt_len += p_header_size;
3794
3795                 new_ppt_buffer = (OPJ_BYTE *) opj_realloc(l_tcp->ppt_buffer, l_tcp->ppt_len);
3796                 if (! new_ppt_buffer) {
3797                         opj_free(l_tcp->ppt_buffer);
3798                         l_tcp->ppt_buffer = NULL;
3799                         l_tcp->ppt_len = 0;
3800                         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
3801                         return OPJ_FALSE;
3802                 }
3803                 l_tcp->ppt_buffer = new_ppt_buffer;
3804                 l_tcp->ppt_data = l_tcp->ppt_buffer;
3805
3806                 memset(l_tcp->ppt_buffer+l_tcp->ppt_data_size,0,p_header_size);
3807         }
3808
3809         /* Read packet header from buffer */
3810         memcpy(l_tcp->ppt_buffer+l_tcp->ppt_data_size,p_header_data,p_header_size);
3811
3812         l_tcp->ppt_data_size += p_header_size;
3813
3814         return OPJ_TRUE;
3815 }
3816
3817 OPJ_BOOL opj_j2k_write_tlm(     opj_j2k_t *p_j2k,
3818                                                         opj_stream_private_t *p_stream,
3819                                                         opj_event_mgr_t * p_manager
3820                             )
3821 {
3822         OPJ_BYTE * l_current_data = 00;
3823         OPJ_UINT32 l_tlm_size;
3824
3825         /* preconditions */
3826         assert(p_j2k != 00);
3827         assert(p_manager != 00);
3828         assert(p_stream != 00);
3829
3830         l_tlm_size = 6 + (5*p_j2k->m_specific_param.m_encoder.m_total_tile_parts);
3831
3832         if (l_tlm_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
3833                 OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_tlm_size);
3834                 if (! new_header_tile_data) {
3835                         opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
3836                         p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL;
3837                         p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
3838                         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write TLM marker\n");
3839                         return OPJ_FALSE;
3840                 }
3841                 p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
3842                 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_tlm_size;
3843         }
3844
3845         l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
3846
3847         /* change the way data is written to avoid seeking if possible */
3848         /* TODO */
3849         p_j2k->m_specific_param.m_encoder.m_tlm_start = opj_stream_tell(p_stream);
3850
3851         opj_write_bytes(l_current_data,J2K_MS_TLM,2);                                   /* TLM */
3852         l_current_data += 2;
3853
3854         opj_write_bytes(l_current_data,l_tlm_size-2,2);                                 /* Lpoc */
3855         l_current_data += 2;
3856
3857         opj_write_bytes(l_current_data,0,1);                                                    /* Ztlm=0*/
3858         ++l_current_data;
3859
3860         opj_write_bytes(l_current_data,0x50,1);                                                 /* Stlm ST=1(8bits-255 tiles max),SP=1(Ptlm=32bits) */
3861         ++l_current_data;
3862
3863         /* do nothing on the 5 * l_j2k->m_specific_param.m_encoder.m_total_tile_parts remaining data */
3864         if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_tlm_size,p_manager) != l_tlm_size) {
3865                 return OPJ_FALSE;
3866         }
3867
3868         return OPJ_TRUE;
3869 }
3870
3871 OPJ_BOOL opj_j2k_write_sot(     opj_j2k_t *p_j2k,
3872                                                         OPJ_BYTE * p_data,
3873                                                         OPJ_UINT32 * p_data_written,
3874                                                         const opj_stream_private_t *p_stream,
3875                                                         opj_event_mgr_t * p_manager
3876                             )
3877 {
3878         /* preconditions */
3879         assert(p_j2k != 00);
3880         assert(p_manager != 00);
3881         assert(p_stream != 00);
3882
3883         opj_write_bytes(p_data,J2K_MS_SOT,2);                                   /* SOT */
3884         p_data += 2;
3885
3886         opj_write_bytes(p_data,10,2);                                                   /* Lsot */
3887         p_data += 2;
3888
3889         opj_write_bytes(p_data, p_j2k->m_current_tile_number,2);                        /* Isot */
3890         p_data += 2;
3891
3892         /* Psot  */
3893         p_data += 4;
3894
3895         opj_write_bytes(p_data, p_j2k->m_specific_param.m_encoder.m_current_tile_part_number,1);                        /* TPsot */
3896         ++p_data;
3897
3898         opj_write_bytes(p_data, p_j2k->m_cp.tcps[p_j2k->m_current_tile_number].m_nb_tile_parts,1);                      /* TNsot */
3899         ++p_data;
3900
3901         /* UniPG>> */
3902 #ifdef USE_JPWL
3903         /* update markers struct */
3904 /*
3905         OPJ_BOOL res = j2k_add_marker(p_j2k->cstr_info, J2K_MS_SOT, p_j2k->sot_start, len + 2);
3906 */
3907   assert( 0 && "TODO" );
3908 #endif /* USE_JPWL */
3909
3910         * p_data_written = 12;
3911
3912         return OPJ_TRUE;
3913 }
3914
3915 OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_j2k,
3916                             OPJ_BYTE * p_header_data,
3917                             OPJ_UINT32 p_header_size,
3918                             opj_event_mgr_t * p_manager )
3919 {
3920         opj_cp_t *l_cp = 00;
3921         opj_tcp_t *l_tcp = 00;
3922         OPJ_UINT32 l_tot_len, l_num_parts = 0;
3923         OPJ_UINT32 l_current_part;
3924         OPJ_UINT32 l_tile_x,l_tile_y;
3925
3926         /* preconditions */
3927         assert(p_header_data != 00);
3928         assert(p_j2k != 00);
3929         assert(p_manager != 00);
3930
3931         /* Size of this marker is fixed = 12 (we have already read marker and its size)*/
3932         if (p_header_size != 8) {
3933                 opj_event_msg(p_manager, EVT_ERROR, "Error reading SOT marker\n");
3934                 return OPJ_FALSE;
3935         }
3936
3937         l_cp = &(p_j2k->m_cp);
3938         opj_read_bytes(p_header_data,&(p_j2k->m_current_tile_number),2);                /* Isot */
3939         p_header_data+=2;
3940
3941         /* testcase 2.pdf.SIGFPE.706.1112 */
3942         if (p_j2k->m_current_tile_number >= l_cp->tw * l_cp->th) {
3943                 opj_event_msg(p_manager, EVT_ERROR, "Invalid tile number %d\n", p_j2k->m_current_tile_number);
3944                 return OPJ_FALSE;
3945         }
3946
3947         l_tcp = &l_cp->tcps[p_j2k->m_current_tile_number];
3948         l_tile_x = p_j2k->m_current_tile_number % l_cp->tw;
3949         l_tile_y = p_j2k->m_current_tile_number / l_cp->tw;
3950
3951 #ifdef USE_JPWL
3952         if (l_cp->correct) {
3953
3954                 OPJ_UINT32 tileno = p_j2k->m_current_tile_number;
3955                 static OPJ_UINT32 backup_tileno = 0;
3956
3957                 /* tileno is negative or larger than the number of tiles!!! */
3958                 if (tileno > (l_cp->tw * l_cp->th)) {
3959                         opj_event_msg(p_manager, EVT_ERROR,
3960                                         "JPWL: bad tile number (%d out of a maximum of %d)\n",
3961                                         tileno, (l_cp->tw * l_cp->th));
3962                         if (!JPWL_ASSUME) {
3963                                 opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
3964                                 return OPJ_FALSE;
3965                         }
3966                         /* we try to correct */
3967                         tileno = backup_tileno;
3968                         opj_event_msg(p_manager, EVT_WARNING, "- trying to adjust this\n"
3969                                         "- setting tile number to %d\n",
3970                                         tileno);
3971                 }
3972
3973                 /* keep your private count of tiles */
3974                 backup_tileno++;
3975         };
3976 #endif /* USE_JPWL */
3977
3978         /* look for the tile in the list of already processed tile (in parts). */
3979         /* Optimization possible here with a more complex data structure and with the removing of tiles */
3980         /* since the time taken by this function can only grow at the time */
3981
3982         opj_read_bytes(p_header_data,&l_tot_len,4);             /* Psot */
3983         p_header_data+=4;
3984
3985         /* PSot should be equal to zero or >=14 or <= 2^32-1 */
3986         if ((l_tot_len !=0 ) && (l_tot_len < 14) )
3987         {
3988             if (l_tot_len == 12 ) /* MSD: Special case for the PHR data which are read by kakadu*/
3989             {
3990                 opj_event_msg(p_manager, EVT_WARNING, "Empty SOT marker detected: Psot=%d.\n", l_tot_len);
3991             }
3992             else
3993             {
3994                 opj_event_msg(p_manager, EVT_ERROR, "Psot value is not correct regards to the JPEG2000 norm: %d.\n", l_tot_len);
3995                 return OPJ_FALSE;
3996             }
3997         }
3998
3999 #ifdef USE_JPWL
4000         if (l_cp->correct) {
4001
4002                 /* totlen is negative or larger than the bytes left!!! */
4003                 if (/*(l_tot_len < 0) ||*/ (l_tot_len > p_header_size ) ) { /* FIXME it seems correct; for info in V1 -> (p_stream_numbytesleft(p_stream) + 8))) { */
4004                         opj_event_msg(p_manager, EVT_ERROR,
4005                                         "JPWL: bad tile byte size (%d bytes against %d bytes left)\n",
4006                                         l_tot_len, p_header_size ); /* FIXME it seems correct; for info in V1 -> p_stream_numbytesleft(p_stream) + 8); */
4007                         if (!JPWL_ASSUME) {
4008                                 opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
4009                                 return OPJ_FALSE;
4010                         }
4011                         /* we try to correct */
4012                         l_tot_len = 0;
4013                         opj_event_msg(p_manager, EVT_WARNING, "- trying to adjust this\n"
4014                                         "- setting Psot to %d => assuming it is the last tile\n",
4015                                         l_tot_len);
4016                 }
4017                 };
4018 #endif /* USE_JPWL */
4019
4020                 /* Ref A.4.2: Psot could be equal zero if it is the last tile-part of the codestream.*/
4021                 if (!l_tot_len) {
4022                         opj_event_msg(p_manager, EVT_INFO, "Psot value of the current tile-part is equal to zero, "
4023                                         "we assuming it is the last tile-part of the codestream.\n");
4024                         p_j2k->m_specific_param.m_decoder.m_last_tile_part = 1;
4025                 }
4026
4027                 opj_read_bytes(p_header_data,&l_current_part ,1);       /* TPsot */
4028                 ++p_header_data;
4029
4030                 opj_read_bytes(p_header_data,&l_num_parts ,1);          /* TNsot */
4031                 ++p_header_data;
4032
4033                 if (l_num_parts != 0) { /* Number of tile-part header is provided by this tile-part header */
4034                         /* Useful to manage the case of textGBR.jp2 file because two values of TNSot are allowed: the correct numbers of
4035                          * tile-parts for that tile and zero (A.4.2 of 15444-1 : 2002). */
4036                         if (l_tcp->m_nb_tile_parts) {
4037                                 if (l_current_part >= l_tcp->m_nb_tile_parts){
4038                                         opj_event_msg(p_manager, EVT_ERROR, "In SOT marker, TPSot (%d) is not valid regards to the current "
4039                                                         "number of tile-part (%d), giving up\n", l_current_part, l_tcp->m_nb_tile_parts );
4040                                         p_j2k->m_specific_param.m_decoder.m_last_tile_part = 1;
4041                                         return OPJ_FALSE;
4042                                 }
4043                         }
4044                         if( l_current_part >= l_num_parts ) {
4045                           /* testcase 451.pdf.SIGSEGV.ce9.3723 */
4046                           opj_event_msg(p_manager, EVT_ERROR, "In SOT marker, TPSot (%d) is not valid regards to the current "
4047                             "number of tile-part (header) (%d), giving up\n", l_current_part, l_num_parts );
4048                           p_j2k->m_specific_param.m_decoder.m_last_tile_part = 1;
4049                           return OPJ_FALSE;
4050                         }
4051                         l_tcp->m_nb_tile_parts = l_num_parts;
4052                 }
4053
4054                 /* If know the number of tile part header we will check if we didn't read the last*/
4055                 if (l_tcp->m_nb_tile_parts) {
4056                         if (l_tcp->m_nb_tile_parts == (l_current_part+1)) {
4057                                 p_j2k->m_specific_param.m_decoder.m_can_decode = 1; /* Process the last tile-part header*/
4058                         }
4059                 }
4060
4061                 if (!p_j2k->m_specific_param.m_decoder.m_last_tile_part){
4062                         /* Keep the size of data to skip after this marker */
4063                         p_j2k->m_specific_param.m_decoder.m_sot_length = l_tot_len - 12; /* SOT_marker_size = 12 */
4064                 }
4065                 else {
4066                         /* FIXME: need to be computed from the number of bytes remaining in the codestream */
4067                         p_j2k->m_specific_param.m_decoder.m_sot_length = 0;
4068                 }
4069
4070                 p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_TPH;
4071
4072                 /* Check if the current tile is outside the area we want decode or not corresponding to the tile index*/
4073                 if (p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec == -1) {
4074                         p_j2k->m_specific_param.m_decoder.m_skip_data =
4075                                 (l_tile_x < p_j2k->m_specific_param.m_decoder.m_start_tile_x)
4076                                 ||      (l_tile_x >= p_j2k->m_specific_param.m_decoder.m_end_tile_x)
4077                                 ||  (l_tile_y < p_j2k->m_specific_param.m_decoder.m_start_tile_y)
4078                                 ||      (l_tile_y >= p_j2k->m_specific_param.m_decoder.m_end_tile_y);
4079                 }
4080                 else {
4081                         assert( p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec >= 0 );
4082                         p_j2k->m_specific_param.m_decoder.m_skip_data =
4083                                 (p_j2k->m_current_tile_number != (OPJ_UINT32)p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec);
4084                 }
4085
4086                 /* Index */
4087                 if (p_j2k->cstr_index)
4088                 {
4089                         assert(p_j2k->cstr_index->tile_index != 00);
4090                         p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tileno = p_j2k->m_current_tile_number;
4091                         p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_tpsno = l_current_part;
4092
4093                         if (l_num_parts != 0){
4094                                 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].nb_tps = l_num_parts;
4095                                 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps = l_num_parts;
4096
4097                                 if (!p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index) {
4098                                         p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index =
4099                                                 (opj_tp_index_t*)opj_calloc(l_num_parts, sizeof(opj_tp_index_t));
4100                                 }
4101                                 else {
4102                                         opj_tp_index_t *new_tp_index = (opj_tp_index_t *) opj_realloc(
4103                                                         p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index, l_num_parts* sizeof(opj_tp_index_t));
4104                                         if (! new_tp_index) {
4105                                                 opj_free(p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index);
4106                                                 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index = NULL;
4107                                                 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
4108                                                 return OPJ_FALSE;
4109                                         }
4110                                         p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index = new_tp_index;
4111                                 }
4112                         }
4113                         else{
4114                                 /*if (!p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index)*/ {
4115
4116                                         if (!p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index) {
4117                                                 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps = 10;
4118                                                 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index =
4119                                                         (opj_tp_index_t*)opj_calloc( p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps,
4120                                                                         sizeof(opj_tp_index_t));
4121                                         }
4122
4123                                         if ( l_current_part >= p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps ){
4124                                                 opj_tp_index_t *new_tp_index;
4125                                                 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps = l_current_part + 1;
4126                                                 new_tp_index = (opj_tp_index_t *) opj_realloc(
4127                                                                 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index,
4128                                                                 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps * sizeof(opj_tp_index_t));
4129                                                 if (! new_tp_index) {
4130                                                         opj_free(p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index);
4131                                                         p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index = NULL;
4132                                                         p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps = 0;
4133                                                         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
4134                                                         return OPJ_FALSE;
4135                                                 }
4136                                                 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index = new_tp_index;
4137                                         }
4138                                 }
4139
4140                         }
4141
4142                 }
4143
4144                 /* FIXME move this onto a separate method to call before reading any SOT, remove part about main_end header, use a index struct inside p_j2k */
4145                 /* if (p_j2k->cstr_info) {
4146                    if (l_tcp->first) {
4147                    if (tileno == 0) {
4148                    p_j2k->cstr_info->main_head_end = p_stream_tell(p_stream) - 13;
4149                    }
4150
4151                    p_j2k->cstr_info->tile[tileno].tileno = tileno;
4152                    p_j2k->cstr_info->tile[tileno].start_pos = p_stream_tell(p_stream) - 12;
4153                    p_j2k->cstr_info->tile[tileno].end_pos = p_j2k->cstr_info->tile[tileno].start_pos + totlen - 1;
4154                    p_j2k->cstr_info->tile[tileno].num_tps = numparts;
4155
4156                    if (numparts) {
4157                    p_j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_malloc(numparts * sizeof(opj_tp_info_t));
4158                    }
4159                    else {
4160                    p_j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_malloc(10 * sizeof(opj_tp_info_t)); // Fixme (10)
4161                    }
4162                    }
4163                    else {
4164                    p_j2k->cstr_info->tile[tileno].end_pos += totlen;
4165                    }
4166
4167                    p_j2k->cstr_info->tile[tileno].tp[partno].tp_start_pos = p_stream_tell(p_stream) - 12;
4168                    p_j2k->cstr_info->tile[tileno].tp[partno].tp_end_pos =
4169                    p_j2k->cstr_info->tile[tileno].tp[partno].tp_start_pos + totlen - 1;
4170                    }*/
4171                 return OPJ_TRUE;
4172         }
4173
4174 OPJ_BOOL opj_j2k_write_sod(     opj_j2k_t *p_j2k,
4175                                                         opj_tcd_t * p_tile_coder,
4176                                                         OPJ_BYTE * p_data,
4177                                                         OPJ_UINT32 * p_data_written,
4178                                                         OPJ_UINT32 p_total_data_size,
4179                                                         const opj_stream_private_t *p_stream,
4180                                                         opj_event_mgr_t * p_manager
4181                             )
4182 {
4183         opj_codestream_info_t *l_cstr_info = 00;
4184         OPJ_UINT32 l_remaining_data;
4185
4186         /* preconditions */
4187         assert(p_j2k != 00);
4188         assert(p_manager != 00);
4189         assert(p_stream != 00);
4190
4191         opj_write_bytes(p_data,J2K_MS_SOD,2);                                   /* SOD */
4192         p_data += 2;
4193
4194         /* make room for the EOF marker */
4195         l_remaining_data =  p_total_data_size - 4;
4196
4197         /* update tile coder */
4198         p_tile_coder->tp_num = p_j2k->m_specific_param.m_encoder.m_current_poc_tile_part_number ;
4199         p_tile_coder->cur_tp_num = p_j2k->m_specific_param.m_encoder.m_current_tile_part_number;
4200
4201          /* INDEX >> */
4202         /* TODO mergeV2: check this part which use cstr_info */
4203         /*l_cstr_info = p_j2k->cstr_info;
4204         if (l_cstr_info) {
4205                 if (!p_j2k->m_specific_param.m_encoder.m_current_tile_part_number ) {
4206                         //TODO cstr_info->tile[p_j2k->m_current_tile_number].end_header = p_stream_tell(p_stream) + p_j2k->pos_correction - 1;
4207                         l_cstr_info->tile[p_j2k->m_current_tile_number].tileno = p_j2k->m_current_tile_number;
4208                 }
4209                 else {*/
4210                         /*
4211                         TODO
4212                         if
4213                                 (cstr_info->tile[p_j2k->m_current_tile_number].packet[cstr_info->packno - 1].end_pos < p_stream_tell(p_stream))
4214                         {
4215                                 cstr_info->tile[p_j2k->m_current_tile_number].packet[cstr_info->packno].start_pos = p_stream_tell(p_stream);
4216                         }*/
4217                 /*}*/
4218                 /* UniPG>> */
4219 #ifdef USE_JPWL
4220                 /* update markers struct */
4221                 /*OPJ_BOOL res = j2k_add_marker(p_j2k->cstr_info, J2K_MS_SOD, p_j2k->sod_start, 2);
4222 */
4223   assert( 0 && "TODO" );
4224 #endif /* USE_JPWL */
4225                 /* <<UniPG */
4226         /*}*/
4227         /* << INDEX */
4228
4229         if (p_j2k->m_specific_param.m_encoder.m_current_tile_part_number == 0) {
4230                 p_tile_coder->tcd_image->tiles->packno = 0;
4231                 if (l_cstr_info) {
4232                         l_cstr_info->packno = 0;
4233                 }
4234         }
4235
4236         *p_data_written = 0;
4237
4238         if (! opj_tcd_encode_tile(p_tile_coder, p_j2k->m_current_tile_number, p_data, p_data_written, l_remaining_data , l_cstr_info)) {
4239                 opj_event_msg(p_manager, EVT_ERROR, "Cannot encode tile\n");
4240                 return OPJ_FALSE;
4241         }
4242
4243         *p_data_written += 2;
4244
4245         return OPJ_TRUE;
4246 }
4247
4248 OPJ_BOOL opj_j2k_read_sod (opj_j2k_t *p_j2k,
4249                            opj_stream_private_t *p_stream,
4250                                                    opj_event_mgr_t * p_manager
4251                            )
4252 {
4253         OPJ_SIZE_T l_current_read_size;
4254         opj_codestream_index_t * l_cstr_index = 00;
4255         OPJ_BYTE ** l_current_data = 00;
4256         opj_tcp_t * l_tcp = 00;
4257         OPJ_UINT32 * l_tile_len = 00;
4258         OPJ_BOOL l_sot_length_pb_detected = OPJ_FALSE;
4259
4260         /* preconditions */
4261         assert(p_j2k != 00);
4262         assert(p_manager != 00);
4263         assert(p_stream != 00);
4264
4265         l_tcp = &(p_j2k->m_cp.tcps[p_j2k->m_current_tile_number]);
4266
4267         if (p_j2k->m_specific_param.m_decoder.m_last_tile_part) {
4268                 /* opj_stream_get_number_byte_left returns OPJ_OFF_T
4269                 // but we are in the last tile part,
4270                 // so its result will fit on OPJ_UINT32 unless we find
4271                 // a file with a single tile part of more than 4 GB...*/
4272                 p_j2k->m_specific_param.m_decoder.m_sot_length = (OPJ_UINT32)(opj_stream_get_number_byte_left(p_stream) - 2);
4273         }
4274         else {
4275             /* Check to avoid pass the limit of OPJ_UINT32 */
4276             if (p_j2k->m_specific_param.m_decoder.m_sot_length >= 2 )
4277                 p_j2k->m_specific_param.m_decoder.m_sot_length -= 2;
4278             else {
4279                 /* MSD: case commented to support empty SOT marker (PHR data) */
4280             }
4281         }
4282
4283         l_current_data = &(l_tcp->m_data);
4284         l_tile_len = &l_tcp->m_data_size;
4285
4286         /* Patch to support new PHR data */
4287         if (p_j2k->m_specific_param.m_decoder.m_sot_length) {
4288             if (! *l_current_data) {
4289                 /* LH: oddly enough, in this path, l_tile_len!=0.
4290                  * TODO: If this was consistant, we could simplify the code to only use realloc(), as realloc(0,...) default to malloc(0,...).
4291                  */
4292                 *l_current_data = (OPJ_BYTE*) opj_malloc(p_j2k->m_specific_param.m_decoder.m_sot_length);
4293             }
4294             else {
4295                 OPJ_BYTE *l_new_current_data = (OPJ_BYTE *) opj_realloc(*l_current_data, *l_tile_len + p_j2k->m_specific_param.m_decoder.m_sot_length);
4296                 if (! l_new_current_data) {
4297                         opj_free(*l_current_data);
4298                         /*nothing more is done as l_current_data will be set to null, and just
4299                           afterward we enter in the error path
4300                           and the actual tile_len is updated (committed) at the end of the
4301                           function. */
4302                 }
4303                 *l_current_data = l_new_current_data;
4304             }
4305             
4306             if (*l_current_data == 00) {
4307                 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to decode tile\n");
4308                 return OPJ_FALSE;
4309             }
4310         }
4311         else {
4312             l_sot_length_pb_detected = OPJ_TRUE;
4313         }
4314
4315         /* Index */
4316         l_cstr_index = p_j2k->cstr_index;
4317         if (l_cstr_index) {
4318                 OPJ_OFF_T l_current_pos = opj_stream_tell(p_stream) - 2;
4319
4320                 OPJ_UINT32 l_current_tile_part = l_cstr_index->tile_index[p_j2k->m_current_tile_number].current_tpsno;
4321                 l_cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index[l_current_tile_part].end_header =
4322                                 l_current_pos;
4323                 l_cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index[l_current_tile_part].end_pos =
4324                                 l_current_pos + p_j2k->m_specific_param.m_decoder.m_sot_length + 2;
4325
4326                 if (OPJ_FALSE == opj_j2k_add_tlmarker(p_j2k->m_current_tile_number,
4327                                         l_cstr_index,
4328                                         J2K_MS_SOD,
4329                                         l_current_pos,
4330                                         p_j2k->m_specific_param.m_decoder.m_sot_length + 2)) {
4331                         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to add tl marker\n");
4332                         return OPJ_FALSE;
4333                 }
4334
4335                 /*l_cstr_index->packno = 0;*/
4336         }
4337
4338         /* Patch to support new PHR data */
4339         if (!l_sot_length_pb_detected) {
4340             l_current_read_size = opj_stream_read_data(
4341                         p_stream,
4342                         *l_current_data + *l_tile_len,
4343                         p_j2k->m_specific_param.m_decoder.m_sot_length,
4344                         p_manager);
4345         }
4346         else
4347         {
4348             l_current_read_size = 0;
4349         }
4350
4351         if (l_current_read_size != p_j2k->m_specific_param.m_decoder.m_sot_length) {
4352                 p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_NEOC;
4353         }
4354         else {
4355                 p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_TPHSOT;
4356         }
4357
4358         *l_tile_len += (OPJ_UINT32)l_current_read_size;
4359
4360         return OPJ_TRUE;
4361 }
4362
4363  OPJ_BOOL opj_j2k_write_rgn(opj_j2k_t *p_j2k,
4364                             OPJ_UINT32 p_tile_no,
4365                             OPJ_UINT32 p_comp_no,
4366                             OPJ_UINT32 nb_comps,
4367                             opj_stream_private_t *p_stream,
4368                             opj_event_mgr_t * p_manager
4369                             )
4370 {
4371         OPJ_BYTE * l_current_data = 00;
4372         OPJ_UINT32 l_rgn_size;
4373         opj_cp_t *l_cp = 00;
4374         opj_tcp_t *l_tcp = 00;
4375         opj_tccp_t *l_tccp = 00;
4376         OPJ_UINT32 l_comp_room;
4377
4378         /* preconditions */
4379         assert(p_j2k != 00);
4380         assert(p_manager != 00);
4381         assert(p_stream != 00);
4382
4383         l_cp = &(p_j2k->m_cp);
4384         l_tcp = &l_cp->tcps[p_tile_no];
4385         l_tccp = &l_tcp->tccps[p_comp_no];
4386
4387         if (nb_comps <= 256) {
4388                 l_comp_room = 1;
4389         }
4390         else {
4391                 l_comp_room = 2;
4392         }
4393
4394         l_rgn_size = 6 + l_comp_room;
4395
4396         l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
4397
4398         opj_write_bytes(l_current_data,J2K_MS_RGN,2);                                   /* RGN  */
4399         l_current_data += 2;
4400
4401         opj_write_bytes(l_current_data,l_rgn_size-2,2);                                 /* Lrgn */
4402         l_current_data += 2;
4403
4404         opj_write_bytes(l_current_data,p_comp_no,l_comp_room);                          /* Crgn */
4405         l_current_data+=l_comp_room;
4406
4407         opj_write_bytes(l_current_data, 0,1);                                           /* Srgn */
4408         ++l_current_data;
4409
4410         opj_write_bytes(l_current_data, l_tccp->roishift,1);                            /* SPrgn */
4411         ++l_current_data;
4412
4413         if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_rgn_size,p_manager) != l_rgn_size) {
4414                 return OPJ_FALSE;
4415         }
4416
4417         return OPJ_TRUE;
4418 }
4419
4420 OPJ_BOOL opj_j2k_write_eoc(     opj_j2k_t *p_j2k,
4421                             opj_stream_private_t *p_stream,
4422                             opj_event_mgr_t * p_manager
4423                             )
4424 {
4425         /* preconditions */
4426         assert(p_j2k != 00);
4427         assert(p_manager != 00);
4428         assert(p_stream != 00);
4429
4430         opj_write_bytes(p_j2k->m_specific_param.m_encoder.m_header_tile_data,J2K_MS_EOC,2);                                     /* EOC */
4431
4432 /* UniPG>> */
4433 #ifdef USE_JPWL
4434         /* update markers struct */
4435         /*
4436         OPJ_BOOL res = j2k_add_marker(p_j2k->cstr_info, J2K_MS_EOC, p_stream_tell(p_stream) - 2, 2);
4437 */
4438 #endif /* USE_JPWL */
4439
4440         if ( opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,2,p_manager) != 2) {
4441                 return OPJ_FALSE;
4442         }
4443
4444         if ( ! opj_stream_flush(p_stream,p_manager) ) {
4445                 return OPJ_FALSE;
4446         }
4447
4448         return OPJ_TRUE;
4449 }
4450
4451 /**
4452  * Reads a RGN marker (Region Of Interest)
4453  *
4454  * @param       p_header_data   the data contained in the POC box.
4455  * @param       p_j2k                   the jpeg2000 codec.
4456  * @param       p_header_size   the size of the data contained in the POC marker.
4457  * @param       p_manager               the user event manager.
4458 */
4459 static OPJ_BOOL opj_j2k_read_rgn (opj_j2k_t *p_j2k,
4460                                   OPJ_BYTE * p_header_data,
4461                                   OPJ_UINT32 p_header_size,
4462                                   opj_event_mgr_t * p_manager
4463                                   )
4464 {
4465         OPJ_UINT32 l_nb_comp;
4466         opj_image_t * l_image = 00;
4467
4468         opj_cp_t *l_cp = 00;
4469         opj_tcp_t *l_tcp = 00;
4470         OPJ_UINT32 l_comp_room, l_comp_no, l_roi_sty;
4471
4472         /* preconditions*/
4473         assert(p_header_data != 00);
4474         assert(p_j2k != 00);
4475         assert(p_manager != 00);
4476
4477         l_image = p_j2k->m_private_image;
4478         l_nb_comp = l_image->numcomps;
4479
4480         if (l_nb_comp <= 256) {
4481                 l_comp_room = 1; }
4482         else {
4483                 l_comp_room = 2; }
4484
4485         if (p_header_size != 2 + l_comp_room) {
4486                 opj_event_msg(p_manager, EVT_ERROR, "Error reading RGN marker\n");
4487                 return OPJ_FALSE;
4488         }
4489
4490         l_cp = &(p_j2k->m_cp);
4491         l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH) ?
4492                                 &l_cp->tcps[p_j2k->m_current_tile_number] :
4493                                 p_j2k->m_specific_param.m_decoder.m_default_tcp;
4494
4495         opj_read_bytes(p_header_data,&l_comp_no,l_comp_room);           /* Crgn */
4496         p_header_data+=l_comp_room;
4497         opj_read_bytes(p_header_data,&l_roi_sty,1);                                     /* Srgn */
4498         ++p_header_data;
4499
4500 #ifdef USE_JPWL
4501         if (l_cp->correct) {
4502                 /* totlen is negative or larger than the bytes left!!! */
4503                 if (l_comp_room >= l_nb_comp) {
4504                         opj_event_msg(p_manager, EVT_ERROR,
4505                                 "JPWL: bad component number in RGN (%d when there are only %d)\n",
4506                                 l_comp_room, l_nb_comp);
4507                         if (!JPWL_ASSUME || JPWL_ASSUME) {
4508                                 opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
4509                                 return OPJ_FALSE;
4510                         }
4511                 }
4512         };
4513 #endif /* USE_JPWL */
4514
4515         /* testcase 3635.pdf.asan.77.2930 */
4516         if (l_comp_no >= l_nb_comp) {
4517                 opj_event_msg(p_manager, EVT_ERROR,
4518                         "bad component number in RGN (%d when there are only %d)\n",
4519                         l_comp_no, l_nb_comp);
4520                 return OPJ_FALSE;
4521         }
4522
4523         opj_read_bytes(p_header_data,(OPJ_UINT32 *) (&(l_tcp->tccps[l_comp_no].roishift)),1);   /* SPrgn */
4524         ++p_header_data;
4525
4526         return OPJ_TRUE;
4527
4528 }
4529
4530 OPJ_FLOAT32 opj_j2k_get_tp_stride (opj_tcp_t * p_tcp)
4531 {
4532         return (OPJ_FLOAT32) ((p_tcp->m_nb_tile_parts - 1) * 14);
4533 }
4534
4535 OPJ_FLOAT32 opj_j2k_get_default_stride (opj_tcp_t * p_tcp)
4536 {
4537     (void)p_tcp;
4538     return 0;
4539 }
4540
4541 OPJ_BOOL opj_j2k_update_rates(  opj_j2k_t *p_j2k,
4542                                                             opj_stream_private_t *p_stream,
4543                                                             opj_event_mgr_t * p_manager )
4544 {
4545         opj_cp_t * l_cp = 00;
4546         opj_image_t * l_image = 00;
4547         opj_tcp_t * l_tcp = 00;
4548         opj_image_comp_t * l_img_comp = 00;
4549
4550         OPJ_UINT32 i,j,k;
4551         OPJ_INT32 l_x0,l_y0,l_x1,l_y1;
4552         OPJ_FLOAT32 * l_rates = 0;
4553         OPJ_FLOAT32 l_sot_remove;
4554         OPJ_UINT32 l_bits_empty, l_size_pixel;
4555         OPJ_UINT32 l_tile_size = 0;
4556         OPJ_UINT32 l_last_res;
4557         OPJ_FLOAT32 (* l_tp_stride_func)(opj_tcp_t *) = 00;
4558
4559         /* preconditions */
4560         assert(p_j2k != 00);
4561         assert(p_manager != 00);
4562         assert(p_stream != 00);
4563
4564         l_cp = &(p_j2k->m_cp);
4565         l_image = p_j2k->m_private_image;
4566         l_tcp = l_cp->tcps;
4567
4568         l_bits_empty = 8 * l_image->comps->dx * l_image->comps->dy;
4569         l_size_pixel = l_image->numcomps * l_image->comps->prec;
4570         l_sot_remove = (OPJ_FLOAT32) opj_stream_tell(p_stream) / (OPJ_FLOAT32)(l_cp->th * l_cp->tw);
4571
4572         if (l_cp->m_specific_param.m_enc.m_tp_on) {
4573                 l_tp_stride_func = opj_j2k_get_tp_stride;
4574         }
4575         else {
4576                 l_tp_stride_func = opj_j2k_get_default_stride;
4577         }
4578
4579         for (i=0;i<l_cp->th;++i) {
4580                 for (j=0;j<l_cp->tw;++j) {
4581                         OPJ_FLOAT32 l_offset = (OPJ_FLOAT32)(*l_tp_stride_func)(l_tcp) / (OPJ_FLOAT32)l_tcp->numlayers;
4582
4583                         /* 4 borders of the tile rescale on the image if necessary */
4584                         l_x0 = opj_int_max(l_cp->tx0 + j * l_cp->tdx, l_image->x0);
4585                         l_y0 = opj_int_max(l_cp->ty0 + i * l_cp->tdy, l_image->y0);
4586                         l_x1 = opj_int_min(l_cp->tx0 + (j + 1) * l_cp->tdx, l_image->x1);
4587                         l_y1 = opj_int_min(l_cp->ty0 + (i + 1) * l_cp->tdy, l_image->y1);
4588
4589                         l_rates = l_tcp->rates;
4590
4591                         /* Modification of the RATE >> */
4592                         if (*l_rates) {
4593                                 *l_rates =              (( (OPJ_FLOAT32) (l_size_pixel * (l_x1 - l_x0) * (l_y1 - l_y0)))
4594                                                                 /
4595                                                                 ((*l_rates) * l_bits_empty)
4596                                                                 )
4597                                                                 -
4598                                                                 l_offset;
4599                         }
4600
4601                         ++l_rates;
4602
4603                         for (k = 1; k < l_tcp->numlayers; ++k) {
4604                                 if (*l_rates) {
4605                                         *l_rates =              (( (OPJ_FLOAT32) (l_size_pixel * (l_x1 - l_x0) * (l_y1 - l_y0)))
4606                                                                         /
4607                                                                                 ((*l_rates) * l_bits_empty)
4608                                                                         )
4609                                                                         -
4610                                                                         l_offset;
4611                                 }
4612
4613                                 ++l_rates;
4614                         }
4615
4616                         ++l_tcp;
4617
4618                 }
4619         }
4620
4621         l_tcp = l_cp->tcps;
4622
4623         for (i=0;i<l_cp->th;++i) {
4624                 for     (j=0;j<l_cp->tw;++j) {
4625                         l_rates = l_tcp->rates;
4626
4627                         if (*l_rates) {
4628                                 *l_rates -= l_sot_remove;
4629
4630                                 if (*l_rates < 30) {
4631                                         *l_rates = 30;
4632                                 }
4633                         }
4634
4635                         ++l_rates;
4636
4637                         l_last_res = l_tcp->numlayers - 1;
4638
4639                         for (k = 1; k < l_last_res; ++k) {
4640
4641                                 if (*l_rates) {
4642                                         *l_rates -= l_sot_remove;
4643
4644                                         if (*l_rates < *(l_rates - 1) + 10) {
4645                                                 *l_rates  = (*(l_rates - 1)) + 20;
4646                                         }
4647                                 }
4648
4649                                 ++l_rates;
4650                         }
4651
4652                         if (*l_rates) {
4653                                 *l_rates -= (l_sot_remove + 2.f);
4654
4655                                 if (*l_rates < *(l_rates - 1) + 10) {
4656                                         *l_rates  = (*(l_rates - 1)) + 20;
4657                                 }
4658                         }
4659
4660                         ++l_tcp;
4661                 }
4662         }
4663
4664         l_img_comp = l_image->comps;
4665         l_tile_size = 0;
4666
4667         for (i=0;i<l_image->numcomps;++i) {
4668                 l_tile_size += (        opj_uint_ceildiv(l_cp->tdx,l_img_comp->dx)
4669                                                         *
4670                                                         opj_uint_ceildiv(l_cp->tdy,l_img_comp->dy)
4671                                                         *
4672                                                         l_img_comp->prec
4673                                                 );
4674
4675                 ++l_img_comp;
4676         }
4677
4678         l_tile_size = (OPJ_UINT32) (l_tile_size * 0.1625); /* 1.3/8 = 0.1625 */
4679
4680         l_tile_size += opj_j2k_get_specific_header_sizes(p_j2k);
4681
4682         p_j2k->m_specific_param.m_encoder.m_encoded_tile_size = l_tile_size;
4683         p_j2k->m_specific_param.m_encoder.m_encoded_tile_data =
4684                         (OPJ_BYTE *) opj_malloc(p_j2k->m_specific_param.m_encoder.m_encoded_tile_size);
4685         if (p_j2k->m_specific_param.m_encoder.m_encoded_tile_data == 00) {
4686                 return OPJ_FALSE;
4687         }
4688
4689         if (l_cp->m_specific_param.m_enc.m_cinema) {
4690                 p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer =
4691                                 (OPJ_BYTE *) opj_malloc(5*p_j2k->m_specific_param.m_encoder.m_total_tile_parts);
4692                 if (! p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer) {
4693                         return OPJ_FALSE;
4694                 }
4695
4696                 p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current =
4697                                 p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer;
4698         }
4699
4700         return OPJ_TRUE;
4701 }
4702
4703 #if 0
4704 OPJ_BOOL opj_j2k_read_eoc (     opj_j2k_t *p_j2k,
4705                                                         opj_stream_private_t *p_stream,
4706                                                         opj_event_mgr_t * p_manager )
4707 {
4708         OPJ_UINT32 i;
4709         opj_tcd_t * l_tcd = 00;
4710         OPJ_UINT32 l_nb_tiles;
4711         opj_tcp_t * l_tcp = 00;
4712         OPJ_BOOL l_success;
4713
4714         /* preconditions */
4715         assert(p_j2k != 00);
4716         assert(p_manager != 00);
4717         assert(p_stream != 00);
4718
4719         l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
4720         l_tcp = p_j2k->m_cp.tcps;
4721
4722         l_tcd = opj_tcd_create(OPJ_TRUE);
4723         if (l_tcd == 00) {
4724                 opj_event_msg(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n");
4725                 return OPJ_FALSE;
4726         }
4727
4728         for (i = 0; i < l_nb_tiles; ++i) {
4729                 if (l_tcp->m_data) {
4730                         if (! opj_tcd_init_decode_tile(l_tcd, i)) {
4731                                 opj_tcd_destroy(l_tcd);
4732                                 opj_event_msg(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n");
4733                                 return OPJ_FALSE;
4734                         }
4735
4736                         l_success = opj_tcd_decode_tile(l_tcd, l_tcp->m_data, l_tcp->m_data_size, i, p_j2k->cstr_index);
4737                         /* cleanup */
4738
4739                         if (! l_success) {
4740                                 p_j2k->m_specific_param.m_decoder.m_state |= J2K_STATE_ERR;
4741                                 break;
4742                         }
4743                 }
4744
4745                 opj_j2k_tcp_destroy(l_tcp);
4746                 ++l_tcp;
4747         }
4748
4749         opj_tcd_destroy(l_tcd);
4750         return OPJ_TRUE;
4751 }
4752 #endif
4753
4754 OPJ_BOOL opj_j2k_get_end_header(opj_j2k_t *p_j2k,
4755                                                         struct opj_stream_private *p_stream,
4756                                                         struct opj_event_mgr * p_manager )
4757 {
4758         /* preconditions */
4759         assert(p_j2k != 00);
4760         assert(p_manager != 00);
4761         assert(p_stream != 00);
4762
4763         p_j2k->cstr_index->main_head_end = opj_stream_tell(p_stream);
4764
4765         return OPJ_TRUE;
4766 }
4767
4768 OPJ_BOOL opj_j2k_write_mct_data_group(  opj_j2k_t *p_j2k,
4769                                                                         struct opj_stream_private *p_stream,
4770                                                                         struct opj_event_mgr * p_manager )
4771 {
4772         OPJ_UINT32 i;
4773         opj_simple_mcc_decorrelation_data_t * l_mcc_record;
4774         opj_mct_data_t * l_mct_record;
4775         opj_tcp_t * l_tcp;
4776
4777         /* preconditions */
4778         assert(p_j2k != 00);
4779         assert(p_stream != 00);
4780         assert(p_manager != 00);
4781
4782         if (! opj_j2k_write_cbd(p_j2k,p_stream,p_manager)) {
4783                 return OPJ_FALSE;
4784         }
4785
4786         l_tcp = &(p_j2k->m_cp.tcps[p_j2k->m_current_tile_number]);
4787         l_mct_record = l_tcp->m_mct_records;
4788
4789         for (i=0;i<l_tcp->m_nb_mct_records;++i) {
4790
4791                 if (! opj_j2k_write_mct_record(p_j2k,l_mct_record,p_stream,p_manager)) {
4792                         return OPJ_FALSE;
4793                 }
4794
4795                 ++l_mct_record;
4796         }
4797
4798         l_mcc_record = l_tcp->m_mcc_records;
4799
4800         for     (i=0;i<l_tcp->m_nb_mcc_records;++i) {
4801
4802                 if (! opj_j2k_write_mcc_record(p_j2k,l_mcc_record,p_stream,p_manager)) {
4803                         return OPJ_FALSE;
4804                 }
4805
4806                 ++l_mcc_record;
4807         }
4808
4809         if (! opj_j2k_write_mco(p_j2k,p_stream,p_manager)) {
4810                 return OPJ_FALSE;
4811         }
4812
4813         return OPJ_TRUE;
4814 }
4815
4816 #if 0
4817 OPJ_BOOL opj_j2k_write_all_coc(opj_j2k_t *p_j2k,
4818                                                                         struct opj_stream_private *p_stream,
4819                                                                         struct opj_event_mgr * p_manager )
4820 {
4821         OPJ_UINT32 compno;
4822
4823         /* preconditions */
4824         assert(p_j2k != 00);
4825         assert(p_manager != 00);
4826         assert(p_stream != 00);
4827
4828         for (compno = 0; compno < p_j2k->m_private_image->numcomps; ++compno)
4829         {
4830                 if (! opj_j2k_write_coc(p_j2k,compno,p_stream, p_manager)) {
4831                         return OPJ_FALSE;
4832                 }
4833         }
4834
4835         return OPJ_TRUE;
4836 }
4837 #endif
4838
4839 #if 0
4840 OPJ_BOOL opj_j2k_write_all_qcc(opj_j2k_t *p_j2k,
4841                                                                         struct opj_stream_private *p_stream,
4842                                                                         struct opj_event_mgr * p_manager )
4843 {
4844         OPJ_UINT32 compno;
4845
4846         /* preconditions */
4847         assert(p_j2k != 00);
4848         assert(p_manager != 00);
4849         assert(p_stream != 00);
4850
4851         for (compno = 0; compno < p_j2k->m_private_image->numcomps; ++compno)
4852         {
4853                 if (! opj_j2k_write_qcc(p_j2k,compno,p_stream, p_manager)) {
4854                         return OPJ_FALSE;
4855                 }
4856         }
4857
4858         return OPJ_TRUE;
4859 }
4860 #endif
4861
4862
4863 OPJ_BOOL opj_j2k_write_regions( opj_j2k_t *p_j2k,
4864                                                         struct opj_stream_private *p_stream,
4865                                                         struct opj_event_mgr * p_manager )
4866 {
4867         OPJ_UINT32 compno;
4868         const opj_tccp_t *l_tccp = 00;
4869
4870         /* preconditions */
4871         assert(p_j2k != 00);
4872         assert(p_manager != 00);
4873         assert(p_stream != 00);
4874
4875         l_tccp = p_j2k->m_cp.tcps->tccps;
4876
4877         for     (compno = 0; compno < p_j2k->m_private_image->numcomps; ++compno)  {
4878                 if (l_tccp->roishift) {
4879
4880                         if (! opj_j2k_write_rgn(p_j2k,0,compno,p_j2k->m_private_image->numcomps,p_stream,p_manager)) {
4881                                 return OPJ_FALSE;
4882                         }
4883                 }
4884
4885                 ++l_tccp;
4886         }
4887
4888         return OPJ_TRUE;
4889 }
4890
4891 OPJ_BOOL opj_j2k_write_epc(     opj_j2k_t *p_j2k,
4892                                                 struct opj_stream_private *p_stream,
4893                                                 struct opj_event_mgr * p_manager )
4894 {
4895         opj_codestream_index_t * l_cstr_index = 00;
4896
4897         /* preconditions */
4898         assert(p_j2k != 00);
4899         assert(p_manager != 00);
4900         assert(p_stream != 00);
4901
4902         l_cstr_index = p_j2k->cstr_index;
4903         if (l_cstr_index) {
4904                 l_cstr_index->codestream_size = opj_stream_tell(p_stream);
4905                 /* UniPG>> */
4906                 /* The following adjustment is done to adjust the codestream size */
4907                 /* if SOD is not at 0 in the buffer. Useful in case of JP2, where */
4908                 /* the first bunch of bytes is not in the codestream              */
4909                 l_cstr_index->codestream_size -= l_cstr_index->main_head_start;
4910                 /* <<UniPG */
4911         }
4912
4913 #ifdef USE_JPWL
4914         /* preparation of JPWL marker segments */
4915 #if 0
4916         if(cp->epc_on) {
4917
4918                 /* encode according to JPWL */
4919                 jpwl_encode(p_j2k, p_stream, image);
4920
4921         }
4922 #endif
4923   assert( 0 && "TODO" );
4924 #endif /* USE_JPWL */
4925
4926         return OPJ_TRUE;
4927 }
4928
4929 OPJ_BOOL opj_j2k_read_unk (     opj_j2k_t *p_j2k,
4930                                                         opj_stream_private_t *p_stream,
4931                                                         OPJ_UINT32 *output_marker,
4932                                                         opj_event_mgr_t * p_manager
4933                                                         )
4934 {
4935         OPJ_UINT32 l_unknown_marker;
4936         const opj_dec_memory_marker_handler_t * l_marker_handler;
4937         OPJ_UINT32 l_size_unk = 2;
4938
4939         /* preconditions*/
4940         assert(p_j2k != 00);
4941         assert(p_manager != 00);
4942         assert(p_stream != 00);
4943
4944         opj_event_msg(p_manager, EVT_WARNING, "Unknown marker\n");
4945
4946         while(1) {
4947                 /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer*/
4948                 if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
4949                         opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
4950                         return OPJ_FALSE;
4951                 }
4952
4953                 /* read 2 bytes as the new marker ID*/
4954                 opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_unknown_marker,2);
4955
4956                 if (!(l_unknown_marker < 0xff00)) {
4957
4958                         /* Get the marker handler from the marker ID*/
4959                         l_marker_handler = opj_j2k_get_marker_handler(l_unknown_marker);
4960
4961                         if (!(p_j2k->m_specific_param.m_decoder.m_state & l_marker_handler->states)) {
4962                                 opj_event_msg(p_manager, EVT_ERROR, "Marker is not compliant with its position\n");
4963                                 return OPJ_FALSE;
4964                         }
4965                         else {
4966                                 if (l_marker_handler->id != J2K_MS_UNK) {
4967                                         /* Add the marker to the codestream index*/
4968                                         if (l_marker_handler->id != J2K_MS_SOT)
4969                                         {
4970                                                 OPJ_BOOL res = opj_j2k_add_mhmarker(p_j2k->cstr_index, J2K_MS_UNK,
4971                                                                 (OPJ_UINT32) opj_stream_tell(p_stream) - l_size_unk,
4972                                                                 l_size_unk);
4973                                                 if (res == OPJ_FALSE) {
4974                                                         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to add mh marker\n");
4975                                                         return OPJ_FALSE;
4976                                                 }
4977                                         }
4978                                         break; /* next marker is known and well located */
4979                                 }
4980                                 else
4981                                         l_size_unk += 2;
4982                         }
4983                 }
4984         }
4985
4986         *output_marker = l_marker_handler->id ;
4987
4988         return OPJ_TRUE;
4989 }
4990
4991 OPJ_BOOL opj_j2k_write_mct_record(      opj_j2k_t *p_j2k,
4992                                                                 opj_mct_data_t * p_mct_record,
4993                                                                 struct opj_stream_private *p_stream,
4994                                                                 struct opj_event_mgr * p_manager )
4995 {
4996         OPJ_UINT32 l_mct_size;
4997         OPJ_BYTE * l_current_data = 00;
4998         OPJ_UINT32 l_tmp;
4999
5000         /* preconditions */
5001         assert(p_j2k != 00);
5002         assert(p_manager != 00);
5003         assert(p_stream != 00);
5004
5005         l_mct_size = 10 + p_mct_record->m_data_size;
5006
5007         if (l_mct_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
5008                 OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_mct_size);
5009                 if (! new_header_tile_data) {
5010                         opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
5011                         p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL;
5012                         p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
5013                         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write MCT marker\n");
5014                         return OPJ_FALSE;
5015                 }
5016                 p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
5017                 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_mct_size;
5018         }
5019
5020         l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
5021
5022         opj_write_bytes(l_current_data,J2K_MS_MCT,2);                                   /* MCT */
5023         l_current_data += 2;
5024
5025         opj_write_bytes(l_current_data,l_mct_size-2,2);                                 /* Lmct */
5026         l_current_data += 2;
5027
5028         opj_write_bytes(l_current_data,0,2);                                                    /* Zmct */
5029         l_current_data += 2;
5030
5031         /* only one marker atm */
5032         l_tmp = (p_mct_record->m_index & 0xff) | (p_mct_record->m_array_type << 8) | (p_mct_record->m_element_type << 10);
5033
5034         opj_write_bytes(l_current_data,l_tmp,2);
5035         l_current_data += 2;
5036
5037         opj_write_bytes(l_current_data,0,2);                                                    /* Ymct */
5038         l_current_data+=2;
5039
5040         memcpy(l_current_data,p_mct_record->m_data,p_mct_record->m_data_size);
5041
5042         if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_mct_size,p_manager) != l_mct_size) {
5043                 return OPJ_FALSE;
5044         }
5045
5046         return OPJ_TRUE;
5047 }
5048
5049 /**
5050  * Reads a MCT marker (Multiple Component Transform)
5051  *
5052  * @param       p_header_data   the data contained in the MCT box.
5053  * @param       p_j2k                   the jpeg2000 codec.
5054  * @param       p_header_size   the size of the data contained in the MCT marker.
5055  * @param       p_manager               the user event manager.
5056 */
5057 static OPJ_BOOL opj_j2k_read_mct (      opj_j2k_t *p_j2k,
5058                                                                     OPJ_BYTE * p_header_data,
5059                                                                     OPJ_UINT32 p_header_size,
5060                                                                     opj_event_mgr_t * p_manager
5061                                     )
5062 {
5063         OPJ_UINT32 i;
5064         opj_tcp_t *l_tcp = 00;
5065         OPJ_UINT32 l_tmp;
5066         OPJ_UINT32 l_indix;
5067         opj_mct_data_t * l_mct_data;
5068
5069         /* preconditions */
5070         assert(p_header_data != 00);
5071         assert(p_j2k != 00);
5072
5073         l_tcp = p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH ?
5074                         &p_j2k->m_cp.tcps[p_j2k->m_current_tile_number] :
5075                         p_j2k->m_specific_param.m_decoder.m_default_tcp;
5076
5077         if (p_header_size < 2) {
5078                 opj_event_msg(p_manager, EVT_ERROR, "Error reading MCT marker\n");
5079                 return OPJ_FALSE;
5080         }
5081
5082         /* first marker */
5083         opj_read_bytes(p_header_data,&l_tmp,2);                         /* Zmct */
5084         p_header_data += 2;
5085         if (l_tmp != 0) {
5086                 opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge mct data within multiple MCT records\n");
5087                 return OPJ_TRUE;
5088         }
5089
5090         if(p_header_size <= 6) {
5091                 opj_event_msg(p_manager, EVT_ERROR, "Error reading MCT marker\n");
5092                 return OPJ_FALSE;
5093         }
5094
5095         /* Imct -> no need for other values, take the first, type is double with decorrelation x0000 1101 0000 0000*/
5096         opj_read_bytes(p_header_data,&l_tmp,2);                         /* Imct */
5097         p_header_data += 2;
5098
5099         l_indix = l_tmp & 0xff;
5100         l_mct_data = l_tcp->m_mct_records;
5101
5102         for (i=0;i<l_tcp->m_nb_mct_records;++i) {
5103                 if (l_mct_data->m_index == l_indix) {
5104                         break;
5105                 }
5106                 ++l_mct_data;
5107         }
5108
5109         /* NOT FOUND */
5110         if (i == l_tcp->m_nb_mct_records) {
5111                 if (l_tcp->m_nb_mct_records == l_tcp->m_nb_max_mct_records) {
5112                         opj_mct_data_t *new_mct_records;
5113                         l_tcp->m_nb_max_mct_records += OPJ_J2K_MCT_DEFAULT_NB_RECORDS;
5114
5115                         new_mct_records = (opj_mct_data_t *) opj_realloc(l_tcp->m_mct_records, l_tcp->m_nb_max_mct_records * sizeof(opj_mct_data_t));
5116                         if (! new_mct_records) {
5117                                 opj_free(l_tcp->m_mct_records);
5118                                 l_tcp->m_mct_records = NULL;
5119                                 l_tcp->m_nb_max_mct_records = 0;
5120                                 l_tcp->m_nb_mct_records = 0;
5121                                 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read MCT marker\n");
5122                                 return OPJ_FALSE;
5123                         }
5124                         l_tcp->m_mct_records = new_mct_records;
5125                         l_mct_data = l_tcp->m_mct_records + l_tcp->m_nb_mct_records;
5126                         memset(l_mct_data ,0,(l_tcp->m_nb_max_mct_records - l_tcp->m_nb_mct_records) * sizeof(opj_mct_data_t));
5127                 }
5128
5129                 l_mct_data = l_tcp->m_mct_records + l_tcp->m_nb_mct_records;
5130         }
5131
5132         if (l_mct_data->m_data) {
5133                 opj_free(l_mct_data->m_data);
5134                 l_mct_data->m_data = 00;
5135         }
5136
5137         l_mct_data->m_index = l_indix;
5138         l_mct_data->m_array_type = (J2K_MCT_ARRAY_TYPE)((l_tmp  >> 8) & 3);
5139         l_mct_data->m_element_type = (J2K_MCT_ELEMENT_TYPE)((l_tmp  >> 10) & 3);
5140
5141         opj_read_bytes(p_header_data,&l_tmp,2);                         /* Ymct */
5142         p_header_data+=2;
5143         if (l_tmp != 0) {
5144                 opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge multiple MCT markers\n");
5145                 return OPJ_TRUE;
5146         }
5147
5148         p_header_size -= 6;
5149
5150         l_mct_data->m_data = (OPJ_BYTE*)opj_malloc(p_header_size);
5151         if (! l_mct_data->m_data) {
5152                 opj_event_msg(p_manager, EVT_ERROR, "Error reading MCT marker\n");
5153                 return OPJ_FALSE;
5154         }
5155         memcpy(l_mct_data->m_data,p_header_data,p_header_size);
5156
5157         l_mct_data->m_data_size = p_header_size;
5158         ++l_tcp->m_nb_mct_records;
5159
5160         return OPJ_TRUE;
5161 }
5162
5163 OPJ_BOOL opj_j2k_write_mcc_record(      opj_j2k_t *p_j2k,
5164                                                                 struct opj_simple_mcc_decorrelation_data * p_mcc_record,
5165                                                                 struct opj_stream_private *p_stream,
5166                                                                 struct opj_event_mgr * p_manager )
5167 {
5168         OPJ_UINT32 i;
5169         OPJ_UINT32 l_mcc_size;
5170         OPJ_BYTE * l_current_data = 00;
5171         OPJ_UINT32 l_nb_bytes_for_comp;
5172         OPJ_UINT32 l_mask;
5173         OPJ_UINT32 l_tmcc;
5174
5175         /* preconditions */
5176         assert(p_j2k != 00);
5177         assert(p_manager != 00);
5178         assert(p_stream != 00);
5179
5180         if (p_mcc_record->m_nb_comps > 255 ) {
5181         l_nb_bytes_for_comp = 2;
5182                 l_mask = 0x8000;
5183         }
5184         else {
5185                 l_nb_bytes_for_comp = 1;
5186                 l_mask = 0;
5187         }
5188
5189         l_mcc_size = p_mcc_record->m_nb_comps * 2 * l_nb_bytes_for_comp + 19;
5190         if (l_mcc_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size)
5191         {
5192                 OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_mcc_size);
5193                 if (! new_header_tile_data) {
5194                         opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
5195                         p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL;
5196                         p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
5197                         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write MCC marker\n");
5198                         return OPJ_FALSE;
5199                 }
5200                 p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
5201                 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_mcc_size;
5202         }
5203
5204         l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
5205
5206         opj_write_bytes(l_current_data,J2K_MS_MCC,2);                                   /* MCC */
5207         l_current_data += 2;
5208
5209         opj_write_bytes(l_current_data,l_mcc_size-2,2);                                 /* Lmcc */
5210         l_current_data += 2;
5211
5212         /* first marker */
5213         opj_write_bytes(l_current_data,0,2);                                    /* Zmcc */
5214         l_current_data += 2;
5215
5216         opj_write_bytes(l_current_data,p_mcc_record->m_index,1);                                        /* Imcc -> no need for other values, take the first */
5217         ++l_current_data;
5218
5219         /* only one marker atm */
5220         opj_write_bytes(l_current_data,0,2);                                    /* Ymcc */
5221         l_current_data+=2;
5222
5223         opj_write_bytes(l_current_data,1,2);                                    /* Qmcc -> number of collections -> 1 */
5224         l_current_data+=2;
5225
5226         opj_write_bytes(l_current_data,0x1,1);                                  /* Xmcci type of component transformation -> array based decorrelation */
5227         ++l_current_data;
5228
5229         opj_write_bytes(l_current_data,p_mcc_record->m_nb_comps | l_mask,2);    /* Nmcci number of input components involved and size for each component offset = 8 bits */
5230         l_current_data+=2;
5231
5232         for (i=0;i<p_mcc_record->m_nb_comps;++i) {
5233                 opj_write_bytes(l_current_data,i,l_nb_bytes_for_comp);                          /* Cmccij Component offset*/
5234                 l_current_data+=l_nb_bytes_for_comp;
5235         }
5236
5237         opj_write_bytes(l_current_data,p_mcc_record->m_nb_comps|l_mask,2);      /* Mmcci number of output components involved and size for each component offset = 8 bits */
5238         l_current_data+=2;
5239
5240         for (i=0;i<p_mcc_record->m_nb_comps;++i)
5241         {
5242                 opj_write_bytes(l_current_data,i,l_nb_bytes_for_comp);                          /* Wmccij Component offset*/
5243                 l_current_data+=l_nb_bytes_for_comp;
5244         }
5245
5246         l_tmcc = ((!p_mcc_record->m_is_irreversible)&1)<<16;
5247
5248         if (p_mcc_record->m_decorrelation_array) {
5249                 l_tmcc |= p_mcc_record->m_decorrelation_array->m_index;
5250         }
5251
5252         if (p_mcc_record->m_offset_array) {
5253                 l_tmcc |= ((p_mcc_record->m_offset_array->m_index)<<8);
5254         }
5255
5256         opj_write_bytes(l_current_data,l_tmcc,3);       /* Tmcci : use MCT defined as number 1 and irreversible array based. */
5257         l_current_data+=3;
5258
5259         if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_mcc_size,p_manager) != l_mcc_size) {
5260                 return OPJ_FALSE;
5261         }
5262
5263         return OPJ_TRUE;
5264 }
5265
5266 OPJ_BOOL opj_j2k_read_mcc (     opj_j2k_t *p_j2k,
5267                                                 OPJ_BYTE * p_header_data,
5268                                                 OPJ_UINT32 p_header_size,
5269                                                 opj_event_mgr_t * p_manager )
5270 {
5271         OPJ_UINT32 i,j;
5272         OPJ_UINT32 l_tmp;
5273         OPJ_UINT32 l_indix;
5274         opj_tcp_t * l_tcp;
5275         opj_simple_mcc_decorrelation_data_t * l_mcc_record;
5276         opj_mct_data_t * l_mct_data;
5277         OPJ_UINT32 l_nb_collections;
5278         OPJ_UINT32 l_nb_comps;
5279         OPJ_UINT32 l_nb_bytes_by_comp;
5280
5281         /* preconditions */
5282         assert(p_header_data != 00);
5283         assert(p_j2k != 00);
5284         assert(p_manager != 00);
5285
5286         l_tcp = p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH ?
5287                         &p_j2k->m_cp.tcps[p_j2k->m_current_tile_number] :
5288                         p_j2k->m_specific_param.m_decoder.m_default_tcp;
5289
5290         if (p_header_size < 2) {
5291                 opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n");
5292                 return OPJ_FALSE;
5293         }
5294
5295         /* first marker */
5296         opj_read_bytes(p_header_data,&l_tmp,2);                         /* Zmcc */
5297         p_header_data += 2;
5298         if (l_tmp != 0) {
5299                 opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge multiple data spanning\n");
5300                 return OPJ_TRUE;
5301         }
5302
5303         if (p_header_size < 7) {
5304                 opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n");
5305                 return OPJ_FALSE;
5306         }
5307
5308         opj_read_bytes(p_header_data,&l_indix,1); /* Imcc -> no need for other values, take the first */
5309         ++p_header_data;
5310
5311         l_mcc_record = l_tcp->m_mcc_records;
5312
5313         for(i=0;i<l_tcp->m_nb_mcc_records;++i) {
5314                 if (l_mcc_record->m_index == l_indix) {
5315                         break;
5316                 }
5317                 ++l_mcc_record;
5318         }
5319
5320         /** NOT FOUND */
5321         if (i == l_tcp->m_nb_mcc_records) {
5322                 if (l_tcp->m_nb_mcc_records == l_tcp->m_nb_max_mcc_records) {
5323                         opj_simple_mcc_decorrelation_data_t *new_mcc_records;
5324                         l_tcp->m_nb_max_mcc_records += OPJ_J2K_MCC_DEFAULT_NB_RECORDS;
5325
5326                         new_mcc_records = (opj_simple_mcc_decorrelation_data_t *) opj_realloc(
5327                                         l_tcp->m_mcc_records, l_tcp->m_nb_max_mcc_records * sizeof(opj_simple_mcc_decorrelation_data_t));
5328                         if (! new_mcc_records) {
5329                                 opj_free(l_tcp->m_mcc_records);
5330                                 l_tcp->m_mcc_records = NULL;
5331                                 l_tcp->m_nb_max_mcc_records = 0;
5332                                 l_tcp->m_nb_mcc_records = 0;
5333                                 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read MCC marker\n");
5334                                 return OPJ_FALSE;
5335                         }
5336                         l_tcp->m_mcc_records = new_mcc_records;
5337                         l_mcc_record = l_tcp->m_mcc_records + l_tcp->m_nb_mcc_records;
5338                         memset(l_mcc_record,0,(l_tcp->m_nb_max_mcc_records-l_tcp->m_nb_mcc_records) * sizeof(opj_simple_mcc_decorrelation_data_t));
5339                 }
5340                 l_mcc_record = l_tcp->m_mcc_records + l_tcp->m_nb_mcc_records;
5341         }
5342         l_mcc_record->m_index = l_indix;
5343
5344         /* only one marker atm */
5345         opj_read_bytes(p_header_data,&l_tmp,2);                         /* Ymcc */
5346         p_header_data+=2;
5347         if (l_tmp != 0) {
5348                 opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge multiple data spanning\n");
5349                 return OPJ_TRUE;
5350         }
5351
5352         opj_read_bytes(p_header_data,&l_nb_collections,2);                              /* Qmcc -> number of collections -> 1 */
5353         p_header_data+=2;
5354
5355         if (l_nb_collections > 1) {
5356                 opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge multiple collections\n");
5357                 return OPJ_TRUE;
5358         }
5359
5360         p_header_size -= 7;
5361
5362         for (i=0;i<l_nb_collections;++i) {
5363                 if (p_header_size < 3) {
5364                         opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n");
5365                         return OPJ_FALSE;
5366                 }
5367
5368                 opj_read_bytes(p_header_data,&l_tmp,1); /* Xmcci type of component transformation -> array based decorrelation */
5369                 ++p_header_data;
5370
5371                 if (l_tmp != 1) {
5372                         opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge collections other than array decorrelation\n");
5373                         return OPJ_TRUE;
5374                 }
5375
5376                 opj_read_bytes(p_header_data,&l_nb_comps,2);
5377
5378                 p_header_data+=2;
5379                 p_header_size-=3;
5380
5381                 l_nb_bytes_by_comp = 1 + (l_nb_comps>>15);
5382                 l_mcc_record->m_nb_comps = l_nb_comps & 0x7fff;
5383
5384                 if (p_header_size < (l_nb_bytes_by_comp * l_mcc_record->m_nb_comps + 2)) {
5385                         opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n");
5386                         return OPJ_FALSE;
5387                 }
5388
5389                 p_header_size -= (l_nb_bytes_by_comp * l_mcc_record->m_nb_comps + 2);
5390
5391                 for (j=0;j<l_mcc_record->m_nb_comps;++j) {
5392                         opj_read_bytes(p_header_data,&l_tmp,l_nb_bytes_by_comp);        /* Cmccij Component offset*/
5393                         p_header_data+=l_nb_bytes_by_comp;
5394
5395                         if (l_tmp != j) {
5396                                 opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge collections with indix shuffle\n");
5397                                 return OPJ_TRUE;
5398                         }
5399                 }
5400
5401                 opj_read_bytes(p_header_data,&l_nb_comps,2);
5402                 p_header_data+=2;
5403
5404                 l_nb_bytes_by_comp = 1 + (l_nb_comps>>15);
5405                 l_nb_comps &= 0x7fff;
5406
5407                 if (l_nb_comps != l_mcc_record->m_nb_comps) {
5408                         opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge collections without same number of indixes\n");
5409                         return OPJ_TRUE;
5410                 }
5411
5412                 if (p_header_size < (l_nb_bytes_by_comp * l_mcc_record->m_nb_comps + 3)) {
5413                         opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n");
5414                         return OPJ_FALSE;
5415                 }
5416
5417                 p_header_size -= (l_nb_bytes_by_comp * l_mcc_record->m_nb_comps + 3);
5418
5419                 for (j=0;j<l_mcc_record->m_nb_comps;++j) {
5420                         opj_read_bytes(p_header_data,&l_tmp,l_nb_bytes_by_comp);        /* Wmccij Component offset*/
5421                         p_header_data+=l_nb_bytes_by_comp;
5422
5423                         if (l_tmp != j) {
5424                                 opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge collections with indix shuffle\n");
5425                                 return OPJ_TRUE;
5426                         }
5427                 }
5428
5429                 opj_read_bytes(p_header_data,&l_tmp,3); /* Wmccij Component offset*/
5430                 p_header_data += 3;
5431
5432                 l_mcc_record->m_is_irreversible = ! ((l_tmp>>16) & 1);
5433                 l_mcc_record->m_decorrelation_array = 00;
5434                 l_mcc_record->m_offset_array = 00;
5435
5436                 l_indix = l_tmp & 0xff;
5437                 if (l_indix != 0) {
5438                         l_mct_data = l_tcp->m_mct_records;
5439                         for (j=0;j<l_tcp->m_nb_mct_records;++j) {
5440                                 if (l_mct_data->m_index == l_indix) {
5441                                         l_mcc_record->m_decorrelation_array = l_mct_data;
5442                                         break;
5443                                 }
5444                                 ++l_mct_data;
5445                         }
5446
5447                         if (l_mcc_record->m_decorrelation_array == 00) {
5448                                 opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n");
5449                                 return OPJ_FALSE;
5450                         }
5451                 }
5452
5453                 l_indix = (l_tmp >> 8) & 0xff;
5454                 if (l_indix != 0) {
5455                         l_mct_data = l_tcp->m_mct_records;
5456                         for (j=0;j<l_tcp->m_nb_mct_records;++j) {
5457                                 if (l_mct_data->m_index == l_indix) {
5458                                         l_mcc_record->m_offset_array = l_mct_data;
5459                                         break;
5460                                 }
5461                                 ++l_mct_data;
5462                         }
5463
5464                         if (l_mcc_record->m_offset_array == 00) {
5465                                 opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n");
5466                                 return OPJ_FALSE;
5467                         }
5468                 }
5469         }
5470
5471         if (p_header_size != 0) {
5472                 opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n");
5473                 return OPJ_FALSE;
5474         }
5475
5476         ++l_tcp->m_nb_mcc_records;
5477
5478         return OPJ_TRUE;
5479 }
5480
5481 OPJ_BOOL opj_j2k_write_mco(     opj_j2k_t *p_j2k,
5482                                                 struct opj_stream_private *p_stream,
5483                                                 struct opj_event_mgr * p_manager
5484                                   )
5485 {
5486         OPJ_BYTE * l_current_data = 00;
5487         OPJ_UINT32 l_mco_size;
5488         opj_tcp_t * l_tcp = 00;
5489         opj_simple_mcc_decorrelation_data_t * l_mcc_record;
5490         OPJ_UINT32 i;
5491
5492         /* preconditions */
5493         assert(p_j2k != 00);
5494         assert(p_manager != 00);
5495         assert(p_stream != 00);
5496
5497         l_tcp =&(p_j2k->m_cp.tcps[p_j2k->m_current_tile_number]);
5498         l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
5499
5500         l_mco_size = 5 + l_tcp->m_nb_mcc_records;
5501         if (l_mco_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
5502
5503                 OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_mco_size);
5504                 if (! new_header_tile_data) {
5505                         opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
5506                         p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL;
5507                         p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
5508                         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write MCO marker\n");
5509                         return OPJ_FALSE;
5510                 }
5511                 p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
5512                 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_mco_size;
5513         }
5514
5515         opj_write_bytes(l_current_data,J2K_MS_MCO,2);                   /* MCO */
5516         l_current_data += 2;
5517
5518         opj_write_bytes(l_current_data,l_mco_size-2,2);                 /* Lmco */
5519         l_current_data += 2;
5520
5521         opj_write_bytes(l_current_data,l_tcp->m_nb_mcc_records,1);      /* Nmco : only one tranform stage*/
5522         ++l_current_data;
5523
5524         l_mcc_record = l_tcp->m_mcc_records;
5525         for     (i=0;i<l_tcp->m_nb_mcc_records;++i) {
5526                 opj_write_bytes(l_current_data,l_mcc_record->m_index,1);/* Imco -> use the mcc indicated by 1*/
5527                 ++l_current_data;
5528
5529                 ++l_mcc_record;
5530         }
5531
5532         if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_mco_size,p_manager) != l_mco_size) {
5533                 return OPJ_FALSE;
5534         }
5535
5536         return OPJ_TRUE;
5537 }
5538
5539 /**
5540  * Reads a MCO marker (Multiple Component Transform Ordering)
5541  *
5542  * @param       p_header_data   the data contained in the MCO box.
5543  * @param       p_j2k                   the jpeg2000 codec.
5544  * @param       p_header_size   the size of the data contained in the MCO marker.
5545  * @param       p_manager               the user event manager.
5546 */
5547 static OPJ_BOOL opj_j2k_read_mco (      opj_j2k_t *p_j2k,
5548                                                                     OPJ_BYTE * p_header_data,
5549                                                                     OPJ_UINT32 p_header_size,
5550                                                                     opj_event_mgr_t * p_manager
5551                                     )
5552 {
5553         OPJ_UINT32 l_tmp, i;
5554         OPJ_UINT32 l_nb_stages;
5555         opj_tcp_t * l_tcp;
5556         opj_tccp_t * l_tccp;
5557         opj_image_t * l_image;
5558
5559         /* preconditions */
5560         assert(p_header_data != 00);
5561         assert(p_j2k != 00);
5562         assert(p_manager != 00);
5563
5564         l_image = p_j2k->m_private_image;
5565         l_tcp = p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH ?
5566                         &p_j2k->m_cp.tcps[p_j2k->m_current_tile_number] :
5567                         p_j2k->m_specific_param.m_decoder.m_default_tcp;
5568
5569         if (p_header_size < 1) {
5570                 opj_event_msg(p_manager, EVT_ERROR, "Error reading MCO marker\n");
5571                 return OPJ_FALSE;
5572         }
5573
5574         opj_read_bytes(p_header_data,&l_nb_stages,1);                           /* Nmco : only one tranform stage*/
5575         ++p_header_data;
5576
5577         if (l_nb_stages > 1) {
5578                 opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge multiple transformation stages.\n");
5579                 return OPJ_TRUE;
5580         }
5581
5582         if (p_header_size != l_nb_stages + 1) {
5583                 opj_event_msg(p_manager, EVT_WARNING, "Error reading MCO marker\n");
5584                 return OPJ_FALSE;
5585         }
5586
5587         l_tccp = l_tcp->tccps;
5588
5589         for (i=0;i<l_image->numcomps;++i) {
5590                 l_tccp->m_dc_level_shift = 0;
5591                 ++l_tccp;
5592         }
5593
5594         if (l_tcp->m_mct_decoding_matrix) {
5595                 opj_free(l_tcp->m_mct_decoding_matrix);
5596                 l_tcp->m_mct_decoding_matrix = 00;
5597         }
5598
5599         for (i=0;i<l_nb_stages;++i) {
5600                 opj_read_bytes(p_header_data,&l_tmp,1);
5601                 ++p_header_data;
5602
5603                 if (! opj_j2k_add_mct(l_tcp,p_j2k->m_private_image,l_tmp)) {
5604                         return OPJ_FALSE;
5605                 }
5606         }
5607
5608         return OPJ_TRUE;
5609 }
5610
5611 OPJ_BOOL opj_j2k_add_mct(opj_tcp_t * p_tcp, opj_image_t * p_image, OPJ_UINT32 p_index)
5612 {
5613         OPJ_UINT32 i;
5614         opj_simple_mcc_decorrelation_data_t * l_mcc_record;
5615         opj_mct_data_t * l_deco_array, * l_offset_array;
5616         OPJ_UINT32 l_data_size,l_mct_size, l_offset_size;
5617         OPJ_UINT32 l_nb_elem;
5618         OPJ_UINT32 * l_offset_data, * l_current_offset_data;
5619         opj_tccp_t * l_tccp;
5620
5621         /* preconditions */
5622         assert(p_tcp != 00);
5623
5624         l_mcc_record = p_tcp->m_mcc_records;
5625
5626         for (i=0;i<p_tcp->m_nb_mcc_records;++i) {
5627                 if (l_mcc_record->m_index == p_index) {
5628                         break;
5629                 }
5630         }
5631
5632         if (i==p_tcp->m_nb_mcc_records) {
5633                 /** element discarded **/
5634                 return OPJ_TRUE;
5635         }
5636
5637         if (l_mcc_record->m_nb_comps != p_image->numcomps) {
5638                 /** do not support number of comps != image */
5639                 return OPJ_TRUE;
5640         }
5641
5642         l_deco_array = l_mcc_record->m_decorrelation_array;
5643
5644         if (l_deco_array) {
5645                 l_data_size = MCT_ELEMENT_SIZE[l_deco_array->m_element_type] * p_image->numcomps * p_image->numcomps;
5646                 if (l_deco_array->m_data_size != l_data_size) {
5647                         return OPJ_FALSE;
5648                 }
5649
5650                 l_nb_elem = p_image->numcomps * p_image->numcomps;
5651                 l_mct_size = l_nb_elem * (OPJ_UINT32)sizeof(OPJ_FLOAT32);
5652                 p_tcp->m_mct_decoding_matrix = (OPJ_FLOAT32*)opj_malloc(l_mct_size);
5653
5654                 if (! p_tcp->m_mct_decoding_matrix ) {
5655                         return OPJ_FALSE;
5656                 }
5657
5658                 j2k_mct_read_functions_to_float[l_deco_array->m_element_type](l_deco_array->m_data,p_tcp->m_mct_decoding_matrix,l_nb_elem);
5659         }
5660
5661         l_offset_array = l_mcc_record->m_offset_array;
5662
5663         if (l_offset_array) {
5664                 l_data_size = MCT_ELEMENT_SIZE[l_offset_array->m_element_type] * p_image->numcomps;
5665                 if (l_offset_array->m_data_size != l_data_size) {
5666                         return OPJ_FALSE;
5667                 }
5668
5669                 l_nb_elem = p_image->numcomps;
5670                 l_offset_size = l_nb_elem * (OPJ_UINT32)sizeof(OPJ_UINT32);
5671                 l_offset_data = (OPJ_UINT32*)opj_malloc(l_offset_size);
5672
5673                 if (! l_offset_data ) {
5674                         return OPJ_FALSE;
5675                 }
5676
5677                 j2k_mct_read_functions_to_int32[l_offset_array->m_element_type](l_offset_array->m_data,l_offset_data,l_nb_elem);
5678
5679                 l_tccp = p_tcp->tccps;
5680                 l_current_offset_data = l_offset_data;
5681
5682                 for (i=0;i<p_image->numcomps;++i) {
5683                         l_tccp->m_dc_level_shift = *(l_current_offset_data++);
5684                         ++l_tccp;
5685                 }
5686
5687                 opj_free(l_offset_data);
5688         }
5689
5690         return OPJ_TRUE;
5691 }
5692
5693 OPJ_BOOL opj_j2k_write_cbd( opj_j2k_t *p_j2k,
5694                                                 struct opj_stream_private *p_stream,
5695                                                 struct opj_event_mgr * p_manager )
5696 {
5697         OPJ_UINT32 i;
5698         OPJ_UINT32 l_cbd_size;
5699         OPJ_BYTE * l_current_data = 00;
5700         opj_image_t *l_image = 00;
5701         opj_image_comp_t * l_comp = 00;
5702
5703         /* preconditions */
5704         assert(p_j2k != 00);
5705         assert(p_manager != 00);
5706         assert(p_stream != 00);
5707
5708         l_image = p_j2k->m_private_image;
5709         l_cbd_size = 6 + p_j2k->m_private_image->numcomps;
5710
5711         if (l_cbd_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
5712                 OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_cbd_size);
5713                 if (! new_header_tile_data) {
5714                         opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
5715                         p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL;
5716                         p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
5717                         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write CBD marker\n");
5718                         return OPJ_FALSE;
5719                 }
5720                 p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
5721                 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_cbd_size;
5722         }
5723
5724         l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
5725
5726         opj_write_bytes(l_current_data,J2K_MS_CBD,2);                   /* CBD */
5727         l_current_data += 2;
5728
5729         opj_write_bytes(l_current_data,l_cbd_size-2,2);                 /* L_CBD */
5730         l_current_data += 2;
5731
5732         opj_write_bytes(l_current_data,l_image->numcomps, 2);           /* Ncbd */
5733         l_current_data+=2;
5734
5735         l_comp = l_image->comps;
5736
5737         for (i=0;i<l_image->numcomps;++i) {
5738                 opj_write_bytes(l_current_data, (l_comp->sgnd << 7) | (l_comp->prec - 1), 1);           /* Component bit depth */
5739                 ++l_current_data;
5740
5741                 ++l_comp;
5742         }
5743
5744         if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_cbd_size,p_manager) != l_cbd_size) {
5745                 return OPJ_FALSE;
5746         }
5747
5748         return OPJ_TRUE;
5749 }
5750
5751 /**
5752  * Reads a CBD marker (Component bit depth definition)
5753  * @param       p_header_data   the data contained in the CBD box.
5754  * @param       p_j2k                   the jpeg2000 codec.
5755  * @param       p_header_size   the size of the data contained in the CBD marker.
5756  * @param       p_manager               the user event manager.
5757 */
5758 static OPJ_BOOL opj_j2k_read_cbd (      opj_j2k_t *p_j2k,
5759                                                                 OPJ_BYTE * p_header_data,
5760                                                                 OPJ_UINT32 p_header_size,
5761                                                                 opj_event_mgr_t * p_manager
5762                                     )
5763 {
5764         OPJ_UINT32 l_nb_comp,l_num_comp;
5765         OPJ_UINT32 l_comp_def;
5766         OPJ_UINT32 i;
5767         opj_image_comp_t * l_comp = 00;
5768
5769         /* preconditions */
5770         assert(p_header_data != 00);
5771         assert(p_j2k != 00);
5772         assert(p_manager != 00);
5773
5774         l_num_comp = p_j2k->m_private_image->numcomps;
5775
5776         if (p_header_size != (p_j2k->m_private_image->numcomps + 2)) {
5777                 opj_event_msg(p_manager, EVT_ERROR, "Crror reading CBD marker\n");
5778                 return OPJ_FALSE;
5779         }
5780
5781         opj_read_bytes(p_header_data,&l_nb_comp,2);                             /* Ncbd */
5782         p_header_data+=2;
5783
5784         if (l_nb_comp != l_num_comp) {
5785                 opj_event_msg(p_manager, EVT_ERROR, "Crror reading CBD marker\n");
5786                 return OPJ_FALSE;
5787         }
5788
5789         l_comp = p_j2k->m_private_image->comps;
5790         for (i=0;i<l_num_comp;++i) {
5791                 opj_read_bytes(p_header_data,&l_comp_def,1);                    /* Component bit depth */
5792                 ++p_header_data;
5793         l_comp->sgnd = (l_comp_def>>7) & 1;
5794                 l_comp->prec = (l_comp_def&0x7f) + 1;
5795                 ++l_comp;
5796         }
5797
5798         return OPJ_TRUE;
5799 }
5800
5801 /* ----------------------------------------------------------------------- */
5802 /* J2K / JPT decoder interface                                             */
5803 /* ----------------------------------------------------------------------- */
5804
5805 void opj_j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters)
5806 {
5807         if(j2k && parameters) {
5808                 j2k->m_cp.m_specific_param.m_dec.m_layer = parameters->cp_layer;
5809                 j2k->m_cp.m_specific_param.m_dec.m_reduce = parameters->cp_reduce;
5810
5811 #ifdef USE_JPWL
5812                 j2k->m_cp.correct = parameters->jpwl_correct;
5813                 j2k->m_cp.exp_comps = parameters->jpwl_exp_comps;
5814                 j2k->m_cp.max_tiles = parameters->jpwl_max_tiles;
5815 #endif /* USE_JPWL */
5816         }
5817 }
5818
5819 /* ----------------------------------------------------------------------- */
5820 /* J2K encoder interface                                                       */
5821 /* ----------------------------------------------------------------------- */
5822
5823 opj_j2k_t* opj_j2k_create_compress(void)
5824 {
5825         opj_j2k_t *l_j2k = (opj_j2k_t*) opj_malloc(sizeof(opj_j2k_t));
5826         if (!l_j2k) {
5827                 return NULL;
5828         }
5829
5830         memset(l_j2k,0,sizeof(opj_j2k_t));
5831
5832         l_j2k->m_is_decoder = 0;
5833         l_j2k->m_cp.m_is_decoder = 0;
5834
5835         l_j2k->m_specific_param.m_encoder.m_header_tile_data = (OPJ_BYTE *) opj_malloc(OPJ_J2K_DEFAULT_HEADER_SIZE);
5836         if (! l_j2k->m_specific_param.m_encoder.m_header_tile_data) {
5837                 opj_j2k_destroy(l_j2k);
5838                 return NULL;
5839         }
5840
5841         l_j2k->m_specific_param.m_encoder.m_header_tile_data_size = OPJ_J2K_DEFAULT_HEADER_SIZE;
5842
5843         /* validation list creation*/
5844         l_j2k->m_validation_list = opj_procedure_list_create();
5845         if (! l_j2k->m_validation_list) {
5846                 opj_j2k_destroy(l_j2k);
5847                 return NULL;
5848         }
5849
5850         /* execution list creation*/
5851         l_j2k->m_procedure_list = opj_procedure_list_create();
5852         if (! l_j2k->m_procedure_list) {
5853                 opj_j2k_destroy(l_j2k);
5854                 return NULL;
5855         }
5856
5857         return l_j2k;
5858 }
5859
5860 int opj_j2k_initialise_4K_poc(opj_poc_t *POC, int numres){
5861     POC[0].tile  = 1;
5862     POC[0].resno0  = 0;
5863     POC[0].compno0 = 0;
5864     POC[0].layno1  = 1;
5865     POC[0].resno1  = numres-1;
5866     POC[0].compno1 = 3;
5867     POC[0].prg1 = OPJ_CPRL;
5868     POC[1].tile  = 1;
5869     POC[1].resno0  = numres-1;
5870     POC[1].compno0 = 0;
5871     POC[1].layno1  = 1;
5872     POC[1].resno1  = numres;
5873     POC[1].compno1 = 3;
5874     POC[1].prg1 = OPJ_CPRL;
5875     return 2;
5876 }
5877
5878 void opj_j2k_set_cinema_parameters(opj_cparameters_t *parameters, opj_image_t *image, opj_event_mgr_t *p_manager)
5879 {
5880     /* Configure cinema parameters */
5881     OPJ_FLOAT32 max_rate = 0;
5882     OPJ_FLOAT32 temp_rate = 0;
5883     int i;
5884
5885     /* profile (Rsiz) */
5886     switch (parameters->cp_cinema){
5887     case OPJ_CINEMA2K_24:
5888     case OPJ_CINEMA2K_48:
5889         parameters->cp_rsiz = OPJ_CINEMA2K;
5890         break;
5891     case OPJ_CINEMA4K_24:
5892         parameters->cp_rsiz = OPJ_CINEMA4K;
5893         break;
5894     case OPJ_OFF:
5895         assert(0);
5896         break;
5897     }
5898
5899     /* No tiling */
5900     parameters->tile_size_on = OPJ_FALSE;
5901     parameters->cp_tdx=1;
5902     parameters->cp_tdy=1;
5903
5904     /* One tile part for each component */
5905     parameters->tp_flag = 'C';
5906     parameters->tp_on = 1;
5907
5908     /* Tile and Image shall be at (0,0) */
5909     parameters->cp_tx0 = 0;
5910     parameters->cp_ty0 = 0;
5911     parameters->image_offset_x0 = 0;
5912     parameters->image_offset_y0 = 0;
5913
5914     /* Codeblock size= 32*32 */
5915     parameters->cblockw_init = 32;
5916     parameters->cblockh_init = 32;
5917
5918     /* Codeblock style: no mode switch enabled */
5919     parameters->mode = 0;
5920
5921     /* No ROI */
5922     parameters->roi_compno = -1;
5923
5924     /* No subsampling */
5925     parameters->subsampling_dx = 1;
5926     parameters->subsampling_dy = 1;
5927
5928     /* 9-7 transform */
5929     parameters->irreversible = 1;
5930
5931     /* Number of layers */
5932     if (parameters->tcp_numlayers > 1){
5933         opj_event_msg(p_manager, EVT_WARNING,
5934                 "JPEG 2000 Profile-3 and 4 (2k/4k dc profile) requires:\n"
5935                 "1 single quality layer"
5936                 "-> Number of layers forced to 1 (rather than %d)\n",
5937                 parameters->tcp_numlayers);
5938         parameters->tcp_numlayers = 1;
5939     }
5940
5941     /* Resolution levels */
5942     switch (parameters->cp_cinema){
5943     case OPJ_CINEMA2K_24:
5944     case OPJ_CINEMA2K_48:
5945         if(parameters->numresolution > 6){
5946             opj_event_msg(p_manager, EVT_WARNING,
5947                     "JPEG 2000 Profile-3 (2k dc profile) requires:\n"
5948                     "Number of decomposition levels <= 5\n"
5949                     "-> Number of decomposition levels forced to 5 (rather than %d)\n",
5950                     parameters->numresolution+1);
5951             parameters->numresolution = 6;
5952         }
5953         break;
5954     case OPJ_CINEMA4K_24:
5955         if(parameters->numresolution < 2){
5956             opj_event_msg(p_manager, EVT_WARNING,
5957                     "JPEG 2000 Profile-4 (4k dc profile) requires:\n"
5958                     "Number of decomposition levels >= 1 && <= 6\n"
5959                     "-> Number of decomposition levels forced to 1 (rather than %d)\n",
5960                     parameters->numresolution+1);
5961             parameters->numresolution = 1;
5962         }else if(parameters->numresolution > 7){
5963             opj_event_msg(p_manager, EVT_WARNING,
5964                     "JPEG 2000 Profile-4 (4k dc profile) requires:\n"
5965                     "Number of decomposition levels >= 1 && <= 6\n"
5966                     "-> Number of decomposition levels forced to 6 (rather than %d)\n",
5967                     parameters->numresolution+1);
5968             parameters->numresolution = 7;
5969         }
5970         break;
5971     default :
5972         break;
5973     }
5974
5975     /* Precincts */
5976     parameters->csty |= 0x01;
5977     parameters->res_spec = parameters->numresolution-1;
5978     for (i = 0; i<parameters->res_spec; i++) {
5979         parameters->prcw_init[i] = 256;
5980         parameters->prch_init[i] = 256;
5981     }
5982
5983     /* The progression order shall be CPRL */
5984     parameters->prog_order = OPJ_CPRL;
5985
5986     /* Progression order changes for 4K, disallowed for 2K */
5987     if (parameters->cp_cinema == OPJ_CINEMA4K_24) {
5988         parameters->numpocs = opj_j2k_initialise_4K_poc(parameters->POC,parameters->numresolution);
5989     } else {
5990         parameters->numpocs = 0;
5991     }
5992
5993     /* Limited bit-rate */
5994     parameters->cp_disto_alloc = 1;
5995     switch (parameters->cp_cinema){
5996     case OPJ_CINEMA2K_24:
5997     case OPJ_CINEMA4K_24:
5998         max_rate = (OPJ_FLOAT32) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec)/
5999                 (OPJ_FLOAT32)(CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
6000         if (parameters->tcp_rates[0] == 0){
6001             parameters->tcp_rates[0] = max_rate;
6002         }else{
6003             temp_rate =(OPJ_FLOAT32)(image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec)/
6004                     (OPJ_FLOAT32)(parameters->tcp_rates[0] * 8 * image->comps[0].dx * image->comps[0].dy);
6005             if (temp_rate > CINEMA_24_CS ){
6006                 opj_event_msg(p_manager, EVT_WARNING,
6007                         "JPEG 2000 Profile-3 and 4 (2k/4k dc profile) requires:\n"
6008                         "Maximum 1302083 compressed bytes @ 24fps\n"
6009                         "-> Specified rate (%3.1f) exceeds this limit. Rate will be forced to %3.1f.\n",
6010                         parameters->tcp_rates[0], max_rate);
6011                 parameters->tcp_rates[0]= max_rate;
6012             }else{
6013                 opj_event_msg(p_manager, EVT_WARNING,
6014                         "JPEG 2000 Profile-3 and 4 (2k/4k dc profile):\n"
6015                         "INFO : Specified rate (%3.1f) is below the 2k/4k limit @ 24fps.\n",
6016                         parameters->tcp_rates[0]);
6017             }
6018         }
6019         parameters->max_comp_size = COMP_24_CS;
6020         break;
6021     case OPJ_CINEMA2K_48:
6022         max_rate = ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
6023                 (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
6024         if (parameters->tcp_rates[0] == 0){
6025             parameters->tcp_rates[0] = max_rate;
6026         }else{
6027             temp_rate =((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
6028                     (parameters->tcp_rates[0] * 8 * image->comps[0].dx * image->comps[0].dy);
6029             if (temp_rate > CINEMA_48_CS ){
6030                 opj_event_msg(p_manager, EVT_WARNING,
6031                         "JPEG 2000 Profile-3 (2k dc profile) requires:\n"
6032                         "Maximum 651041 compressed bytes @ 48fps\n"
6033                         "-> Specified rate (%3.1f) exceeds this limit. Rate will be forced to %3.1f.\n",
6034                         parameters->tcp_rates[0], max_rate);
6035                 parameters->tcp_rates[0]= max_rate;
6036             }else{
6037                 opj_event_msg(p_manager, EVT_WARNING,
6038                         "JPEG 2000 Profile-3 (2k dc profile):\n"
6039                         "INFO : Specified rate (%3.1f) is below the 2k limit @ 48 fps.\n",
6040                         parameters->tcp_rates[0]);
6041             }
6042         }
6043         parameters->max_comp_size = COMP_48_CS;
6044         break;
6045     default:
6046         break;
6047     }
6048 }
6049
6050 OPJ_BOOL opj_j2k_is_cinema_compliant(opj_image_t *image, OPJ_CINEMA_MODE cinema_mode, opj_event_mgr_t *p_manager)
6051 {
6052     OPJ_UINT32 i;
6053
6054     /* Number of components */
6055     if (image->numcomps != 3){
6056         opj_event_msg(p_manager, EVT_WARNING,
6057                 "JPEG 2000 Profile-3 (2k dc profile) requires:\n"
6058                 "3 components"
6059                 "-> Number of components of input image (%d) is not compliant\n"
6060                 "-> Non-profile-3 codestream will be generated\n",
6061                 image->numcomps);
6062         return OPJ_FALSE;
6063     }
6064
6065     /* Bitdepth */
6066     for (i = 0; i < image->numcomps; i++) {
6067         if ((image->comps[i].bpp != 12) | (image->comps[i].sgnd)){
6068             char signed_str[] = "signed";
6069             char unsigned_str[] = "unsigned";
6070             char *tmp_str = image->comps[i].sgnd?signed_str:unsigned_str;
6071             opj_event_msg(p_manager, EVT_WARNING,
6072                     "JPEG 2000 Profile-3 (2k dc profile) requires:\n"
6073                     "Precision of each component shall be 12 bits unsigned"
6074                     "-> At least component %d of input image (%d bits, %s) is not compliant\n"
6075                     "-> Non-profile-3 codestream will be generated\n",
6076                     i,image->comps[i].bpp, tmp_str);
6077             return OPJ_FALSE;
6078         }
6079     }
6080
6081     /* Image size */
6082     switch (cinema_mode){
6083     case OPJ_CINEMA2K_24:
6084     case OPJ_CINEMA2K_48:
6085         if (((image->comps[0].w > 2048) | (image->comps[0].h > 1080))){
6086             opj_event_msg(p_manager, EVT_WARNING,
6087                     "JPEG 2000 Profile-3 (2k dc profile) requires:\n"
6088                     "width <= 2048 and height <= 1080\n"
6089                     "-> Input image size %d x %d is not compliant\n"
6090                     "-> Non-profile-3 codestream will be generated\n",
6091                     image->comps[0].w,image->comps[0].h);
6092             return OPJ_FALSE;
6093         }
6094         break;
6095     case OPJ_CINEMA4K_24:
6096         if (((image->comps[0].w > 4096) | (image->comps[0].h > 2160))){
6097             opj_event_msg(p_manager, EVT_WARNING,
6098                     "JPEG 2000 Profile-4 (4k dc profile) requires:\n"
6099                     "width <= 4096 and height <= 2160\n"
6100                     "-> Image size %d x %d is not compliant\n"
6101                     "-> Non-profile-4 codestream will be generated\n",
6102                     image->comps[0].w,image->comps[0].h);
6103             return OPJ_FALSE;
6104         }
6105         break;
6106     default :
6107         break;
6108     }
6109
6110     return OPJ_TRUE;
6111 }
6112
6113 void opj_j2k_setup_encoder(     opj_j2k_t *p_j2k,
6114                                                     opj_cparameters_t *parameters,
6115                                                     opj_image_t *image,
6116                                                     opj_event_mgr_t * p_manager)
6117 {
6118         OPJ_UINT32 i, j, tileno, numpocs_tile;
6119         opj_cp_t *cp = 00;
6120
6121         if(!p_j2k || !parameters || ! image) {
6122                 return;
6123         }
6124
6125         /* keep a link to cp so that we can destroy it later in j2k_destroy_compress */
6126         cp = &(p_j2k->m_cp);
6127
6128         /* set default values for cp */
6129         cp->tw = 1;
6130         cp->th = 1;
6131
6132         /* set cinema parameters if required */
6133         if (parameters->cp_cinema){
6134             opj_j2k_set_cinema_parameters(parameters,image,p_manager);
6135             if (!opj_j2k_is_cinema_compliant(image,parameters->cp_cinema,p_manager)) {
6136                 parameters->cp_rsiz = OPJ_STD_RSIZ;
6137             }
6138         }
6139
6140         /*
6141         copy user encoding parameters
6142         */
6143         cp->m_specific_param.m_enc.m_cinema = parameters->cp_cinema;
6144         cp->m_specific_param.m_enc.m_max_comp_size =    parameters->max_comp_size;
6145         cp->rsiz   = parameters->cp_rsiz;
6146         cp->m_specific_param.m_enc.m_disto_alloc = parameters->cp_disto_alloc;
6147         cp->m_specific_param.m_enc.m_fixed_alloc = parameters->cp_fixed_alloc;
6148         cp->m_specific_param.m_enc.m_fixed_quality = parameters->cp_fixed_quality;
6149
6150         /* mod fixed_quality */
6151         if (parameters->cp_fixed_alloc && parameters->cp_matrice) {
6152                 size_t array_size = parameters->tcp_numlayers * parameters->numresolution * 3 * sizeof(OPJ_INT32);
6153                 cp->m_specific_param.m_enc.m_matrice = (OPJ_INT32 *) opj_malloc(array_size);
6154                 memcpy(cp->m_specific_param.m_enc.m_matrice, parameters->cp_matrice, array_size);
6155         }
6156
6157         /* tiles */
6158         cp->tdx = parameters->cp_tdx;
6159         cp->tdy = parameters->cp_tdy;
6160
6161         /* tile offset */
6162         cp->tx0 = parameters->cp_tx0;
6163         cp->ty0 = parameters->cp_ty0;
6164
6165         /* comment string */
6166         if(parameters->cp_comment) {
6167                 cp->comment = (char*)opj_malloc(strlen(parameters->cp_comment) + 1);
6168                 if(cp->comment) {
6169                         strcpy(cp->comment, parameters->cp_comment);
6170                 }
6171         }
6172
6173         /*
6174         calculate other encoding parameters
6175         */
6176
6177         if (parameters->tile_size_on) {
6178                 cp->tw = opj_int_ceildiv(image->x1 - cp->tx0, cp->tdx);
6179                 cp->th = opj_int_ceildiv(image->y1 - cp->ty0, cp->tdy);
6180         } else {
6181                 cp->tdx = image->x1 - cp->tx0;
6182                 cp->tdy = image->y1 - cp->ty0;
6183         }
6184
6185         if (parameters->tp_on) {
6186                 cp->m_specific_param.m_enc.m_tp_flag = parameters->tp_flag;
6187                 cp->m_specific_param.m_enc.m_tp_on = 1;
6188         }
6189
6190 #ifdef USE_JPWL
6191         /*
6192         calculate JPWL encoding parameters
6193         */
6194
6195         if (parameters->jpwl_epc_on) {
6196                 OPJ_INT32 i;
6197
6198                 /* set JPWL on */
6199                 cp->epc_on = OPJ_TRUE;
6200                 cp->info_on = OPJ_FALSE; /* no informative technique */
6201
6202                 /* set EPB on */
6203                 if ((parameters->jpwl_hprot_MH > 0) || (parameters->jpwl_hprot_TPH[0] > 0)) {
6204                         cp->epb_on = OPJ_TRUE;
6205
6206                         cp->hprot_MH = parameters->jpwl_hprot_MH;
6207                         for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) {
6208                                 cp->hprot_TPH_tileno[i] = parameters->jpwl_hprot_TPH_tileno[i];
6209                                 cp->hprot_TPH[i] = parameters->jpwl_hprot_TPH[i];
6210                         }
6211                         /* if tile specs are not specified, copy MH specs */
6212                         if (cp->hprot_TPH[0] == -1) {
6213                                 cp->hprot_TPH_tileno[0] = 0;
6214                                 cp->hprot_TPH[0] = parameters->jpwl_hprot_MH;
6215                         }
6216                         for (i = 0; i < JPWL_MAX_NO_PACKSPECS; i++) {
6217                                 cp->pprot_tileno[i] = parameters->jpwl_pprot_tileno[i];
6218                                 cp->pprot_packno[i] = parameters->jpwl_pprot_packno[i];
6219                                 cp->pprot[i] = parameters->jpwl_pprot[i];
6220                         }
6221                 }
6222
6223                 /* set ESD writing */
6224                 if ((parameters->jpwl_sens_size == 1) || (parameters->jpwl_sens_size == 2)) {
6225                         cp->esd_on = OPJ_TRUE;
6226
6227                         cp->sens_size = parameters->jpwl_sens_size;
6228                         cp->sens_addr = parameters->jpwl_sens_addr;
6229                         cp->sens_range = parameters->jpwl_sens_range;
6230
6231                         cp->sens_MH = parameters->jpwl_sens_MH;
6232                         for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) {
6233                                 cp->sens_TPH_tileno[i] = parameters->jpwl_sens_TPH_tileno[i];
6234                                 cp->sens_TPH[i] = parameters->jpwl_sens_TPH[i];
6235                         }
6236                 }
6237
6238                 /* always set RED writing to false: we are at the encoder */
6239                 cp->red_on = OPJ_FALSE;
6240
6241         } else {
6242                 cp->epc_on = OPJ_FALSE;
6243         }
6244 #endif /* USE_JPWL */
6245
6246         /* initialize the mutiple tiles */
6247         /* ---------------------------- */
6248         cp->tcps = (opj_tcp_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tcp_t));
6249         if (parameters->numpocs) {
6250                 /* initialisation of POC */
6251                 opj_j2k_check_poc_val(parameters->POC,parameters->numpocs, parameters->numresolution, image->numcomps, parameters->tcp_numlayers, p_manager);
6252                 /* TODO MSD use the return value*/
6253         }
6254
6255         for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
6256                 opj_tcp_t *tcp = &cp->tcps[tileno];
6257                 tcp->numlayers = parameters->tcp_numlayers;
6258
6259                 for (j = 0; j < tcp->numlayers; j++) {
6260                         if(cp->m_specific_param.m_enc.m_cinema){
6261                                 if (cp->m_specific_param.m_enc.m_fixed_quality) {
6262                                         tcp->distoratio[j] = parameters->tcp_distoratio[j];
6263                                 }
6264                                 tcp->rates[j] = parameters->tcp_rates[j];
6265                         }else{
6266                                 if (cp->m_specific_param.m_enc.m_fixed_quality) {       /* add fixed_quality */
6267                                         tcp->distoratio[j] = parameters->tcp_distoratio[j];
6268                                 } else {
6269                                         tcp->rates[j] = parameters->tcp_rates[j];
6270                                 }
6271                         }
6272                 }
6273
6274                 tcp->csty = parameters->csty;
6275                 tcp->prg = parameters->prog_order;
6276                 tcp->mct = parameters->tcp_mct;
6277
6278                 numpocs_tile = 0;
6279                 tcp->POC = 0;
6280
6281                 if (parameters->numpocs) {
6282                         /* initialisation of POC */
6283                         tcp->POC = 1;
6284                         for (i = 0; i < parameters->numpocs; i++) {
6285                                 if (tileno + 1 == parameters->POC[i].tile )  {
6286                                         opj_poc_t *tcp_poc = &tcp->pocs[numpocs_tile];
6287
6288                                         tcp_poc->resno0         = parameters->POC[numpocs_tile].resno0;
6289                                         tcp_poc->compno0        = parameters->POC[numpocs_tile].compno0;
6290                                         tcp_poc->layno1         = parameters->POC[numpocs_tile].layno1;
6291                                         tcp_poc->resno1         = parameters->POC[numpocs_tile].resno1;
6292                                         tcp_poc->compno1        = parameters->POC[numpocs_tile].compno1;
6293                                         tcp_poc->prg1           = parameters->POC[numpocs_tile].prg1;
6294                                         tcp_poc->tile           = parameters->POC[numpocs_tile].tile;
6295
6296                                         numpocs_tile++;
6297                                 }
6298                         }
6299
6300                         tcp->numpocs = numpocs_tile -1 ;
6301                 }else{
6302                         tcp->numpocs = 0;
6303                 }
6304
6305                 tcp->tccps = (opj_tccp_t*) opj_calloc(image->numcomps, sizeof(opj_tccp_t));
6306
6307                 if (parameters->mct_data) {
6308                       
6309                     OPJ_UINT32 lMctSize = image->numcomps * image->numcomps * (OPJ_UINT32)sizeof(OPJ_FLOAT32);
6310                     OPJ_FLOAT32 * lTmpBuf = (OPJ_FLOAT32*)opj_malloc(lMctSize);
6311                     OPJ_INT32 * l_dc_shift = (OPJ_INT32 *) ((OPJ_BYTE *) parameters->mct_data + lMctSize);
6312
6313                     tcp->mct = 2;
6314                     tcp->m_mct_coding_matrix = (OPJ_FLOAT32*)opj_malloc(lMctSize);
6315                     memcpy(tcp->m_mct_coding_matrix,parameters->mct_data,lMctSize);
6316                     memcpy(lTmpBuf,parameters->mct_data,lMctSize);
6317
6318                     tcp->m_mct_decoding_matrix = (OPJ_FLOAT32*)opj_malloc(lMctSize);
6319                     assert(opj_matrix_inversion_f(lTmpBuf,(tcp->m_mct_decoding_matrix),image->numcomps));
6320
6321                     tcp->mct_norms = (OPJ_FLOAT64*)
6322                                     opj_malloc(image->numcomps * sizeof(OPJ_FLOAT64));
6323
6324                     opj_calculate_norms(tcp->mct_norms,image->numcomps,tcp->m_mct_decoding_matrix);
6325                     opj_free(lTmpBuf);
6326
6327                     for (i = 0; i < image->numcomps; i++) {
6328                             opj_tccp_t *tccp = &tcp->tccps[i];
6329                             tccp->m_dc_level_shift = l_dc_shift[i];
6330                     }
6331
6332                     opj_j2k_setup_mct_encoding(tcp,image);                        
6333                 }
6334                 else {
6335                         for (i = 0; i < image->numcomps; i++) {
6336                                 opj_tccp_t *tccp = &tcp->tccps[i];
6337                                 opj_image_comp_t * l_comp = &(image->comps[i]);
6338
6339                                 if (! l_comp->sgnd) {
6340                                         tccp->m_dc_level_shift = 1 << (l_comp->prec - 1);
6341                                 }
6342                         }
6343                 }
6344
6345                 for (i = 0; i < image->numcomps; i++) {
6346                         opj_tccp_t *tccp = &tcp->tccps[i];
6347
6348                         tccp->csty = parameters->csty & 0x01;   /* 0 => one precinct || 1 => custom precinct  */
6349                         tccp->numresolutions = parameters->numresolution;
6350                         tccp->cblkw = opj_int_floorlog2(parameters->cblockw_init);
6351                         tccp->cblkh = opj_int_floorlog2(parameters->cblockh_init);
6352                         tccp->cblksty = parameters->mode;
6353                         tccp->qmfbid = parameters->irreversible ? 0 : 1;
6354                         tccp->qntsty = parameters->irreversible ? J2K_CCP_QNTSTY_SEQNT : J2K_CCP_QNTSTY_NOQNT;
6355                         tccp->numgbits = 2;
6356
6357                         if ((OPJ_INT32)i == parameters->roi_compno) {
6358                                 tccp->roishift = parameters->roi_shift;
6359                         } else {
6360                                 tccp->roishift = 0;
6361                         }
6362
6363                                 if (parameters->csty & J2K_CCP_CSTY_PRT) {
6364                                         OPJ_INT32 p = 0, it_res;
6365                                         assert( tccp->numresolutions > 0 );
6366                                         for (it_res = tccp->numresolutions - 1; it_res >= 0; it_res--) {
6367                                                 if (p < parameters->res_spec) {
6368
6369                                                         if (parameters->prcw_init[p] < 1) {
6370                                                                 tccp->prcw[it_res] = 1;
6371                                                         } else {
6372                                                                 tccp->prcw[it_res] = opj_int_floorlog2(parameters->prcw_init[p]);
6373                                                         }
6374
6375                                                         if (parameters->prch_init[p] < 1) {
6376                                                                 tccp->prch[it_res] = 1;
6377                                                         }else {
6378                                                                 tccp->prch[it_res] = opj_int_floorlog2(parameters->prch_init[p]);
6379                                                         }
6380
6381                                                 } else {
6382                                                         OPJ_INT32 res_spec = parameters->res_spec;
6383                                                         OPJ_INT32 size_prcw = 0;
6384                                                         OPJ_INT32 size_prch = 0;
6385
6386                                                         assert(res_spec>0); /* issue 189 */
6387                                                         size_prcw = parameters->prcw_init[res_spec - 1] >> (p - (res_spec - 1));
6388                                                         size_prch = parameters->prch_init[res_spec - 1] >> (p - (res_spec - 1));
6389
6390
6391                                                         if (size_prcw < 1) {
6392                                                                 tccp->prcw[it_res] = 1;
6393                                                         } else {
6394                                                                 tccp->prcw[it_res] = opj_int_floorlog2(size_prcw);
6395                                                         }
6396
6397                                                         if (size_prch < 1) {
6398                                                                 tccp->prch[it_res] = 1;
6399                                                         } else {
6400                                                                 tccp->prch[it_res] = opj_int_floorlog2(size_prch);
6401                                                         }
6402                                                 }
6403                                                 p++;
6404                                                 /*printf("\nsize precinct for level %d : %d,%d\n", it_res,tccp->prcw[it_res], tccp->prch[it_res]); */
6405                                         }       /*end for*/
6406                                 } else {
6407                                         for (j = 0; j < tccp->numresolutions; j++) {
6408                                                 tccp->prcw[j] = 15;
6409                                                 tccp->prch[j] = 15;
6410                                         }
6411                                 }
6412
6413                         opj_dwt_calc_explicit_stepsizes(tccp, image->comps[i].prec);
6414                 }
6415         }
6416
6417         if (parameters->mct_data) {
6418                 opj_free(parameters->mct_data);
6419                 parameters->mct_data = 00;
6420         }
6421 }
6422
6423 static OPJ_BOOL opj_j2k_add_mhmarker(opj_codestream_index_t *cstr_index, OPJ_UINT32 type, OPJ_OFF_T pos, OPJ_UINT32 len)
6424 {
6425         assert(cstr_index != 00);
6426
6427         /* expand the list? */
6428         if ((cstr_index->marknum + 1) > cstr_index->maxmarknum) {
6429                 opj_marker_info_t *new_marker;
6430                 cstr_index->maxmarknum = 100 + (OPJ_INT32) ((OPJ_FLOAT32) cstr_index->maxmarknum * 1.0F);
6431                 new_marker = (opj_marker_info_t *) opj_realloc(cstr_index->marker, cstr_index->maxmarknum *sizeof(opj_marker_info_t));
6432                 if (! new_marker) {
6433                         opj_free(cstr_index->marker);
6434                         cstr_index->marker = NULL;
6435                         cstr_index->maxmarknum = 0;
6436                         cstr_index->marknum = 0;
6437                         /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to add mh marker\n"); */
6438                         return OPJ_FALSE;
6439                 }
6440                 cstr_index->marker = new_marker;
6441         }
6442
6443         /* add the marker */
6444         cstr_index->marker[cstr_index->marknum].type = (OPJ_UINT16)type;
6445         cstr_index->marker[cstr_index->marknum].pos = (OPJ_INT32)pos;
6446         cstr_index->marker[cstr_index->marknum].len = (OPJ_INT32)len;
6447         cstr_index->marknum++;
6448         return OPJ_TRUE;
6449 }
6450
6451 static OPJ_BOOL opj_j2k_add_tlmarker(OPJ_UINT32 tileno, opj_codestream_index_t *cstr_index, OPJ_UINT32 type, OPJ_OFF_T pos, OPJ_UINT32 len)
6452 {
6453         assert(cstr_index != 00);
6454         assert(cstr_index->tile_index != 00);
6455
6456         /* expand the list? */
6457         if ((cstr_index->tile_index[tileno].marknum + 1) > cstr_index->tile_index[tileno].maxmarknum) {
6458                 opj_marker_info_t *new_marker;
6459                 cstr_index->tile_index[tileno].maxmarknum = 100 + (OPJ_INT32) ((OPJ_FLOAT32) cstr_index->tile_index[tileno].maxmarknum * 1.0F);
6460                 new_marker = (opj_marker_info_t *) opj_realloc(
6461                                 cstr_index->tile_index[tileno].marker,
6462                                 cstr_index->tile_index[tileno].maxmarknum *sizeof(opj_marker_info_t));
6463                 if (! new_marker) {
6464                         opj_free(cstr_index->tile_index[tileno].marker);
6465                         cstr_index->tile_index[tileno].marker = NULL;
6466                         cstr_index->tile_index[tileno].maxmarknum = 0;
6467                         cstr_index->tile_index[tileno].marknum = 0;
6468                         /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to add tl marker\n"); */
6469                         return OPJ_FALSE;
6470                 }
6471                 cstr_index->tile_index[tileno].marker = new_marker;
6472         }
6473
6474         /* add the marker */
6475         cstr_index->tile_index[tileno].marker[cstr_index->tile_index[tileno].marknum].type = (OPJ_UINT16)type;
6476         cstr_index->tile_index[tileno].marker[cstr_index->tile_index[tileno].marknum].pos = (OPJ_INT32)pos;
6477         cstr_index->tile_index[tileno].marker[cstr_index->tile_index[tileno].marknum].len = (OPJ_INT32)len;
6478         cstr_index->tile_index[tileno].marknum++;
6479
6480         if (type == J2K_MS_SOT) {
6481                 OPJ_UINT32 l_current_tile_part = cstr_index->tile_index[tileno].current_tpsno;
6482
6483                 if (cstr_index->tile_index[tileno].tp_index)
6484                         cstr_index->tile_index[tileno].tp_index[l_current_tile_part].start_pos = pos;
6485
6486         }
6487         return OPJ_TRUE;
6488 }
6489
6490 /*
6491  * -----------------------------------------------------------------------
6492  * -----------------------------------------------------------------------
6493  * -----------------------------------------------------------------------
6494  */
6495
6496 OPJ_BOOL opj_j2k_end_decompress(opj_j2k_t *p_j2k,
6497                                 opj_stream_private_t *p_stream,
6498                                 opj_event_mgr_t * p_manager
6499                                 )
6500 {
6501     (void)p_j2k;
6502     (void)p_stream;
6503     (void)p_manager;
6504     return OPJ_TRUE;
6505 }
6506
6507 OPJ_BOOL opj_j2k_read_header(   opj_stream_private_t *p_stream,
6508                                                             opj_j2k_t* p_j2k,
6509                                                             opj_image_t** p_image,
6510                                                             opj_event_mgr_t* p_manager )
6511 {
6512         /* preconditions */
6513         assert(p_j2k != 00);
6514         assert(p_stream != 00);
6515         assert(p_manager != 00);
6516
6517         /* create an empty image header */
6518         p_j2k->m_private_image = opj_image_create0();
6519         if (! p_j2k->m_private_image) {
6520                 return OPJ_FALSE;
6521         }
6522
6523         /* customization of the validation */
6524         opj_j2k_setup_decoding_validation(p_j2k);
6525
6526         /* validation of the parameters codec */
6527         if (! opj_j2k_exec(p_j2k, p_j2k->m_validation_list, p_stream,p_manager)) {
6528                 opj_image_destroy(p_j2k->m_private_image);
6529                 p_j2k->m_private_image = NULL;
6530                 return OPJ_FALSE;
6531         }
6532
6533         /* customization of the encoding */
6534         opj_j2k_setup_header_reading(p_j2k);
6535
6536         /* read header */
6537         if (! opj_j2k_exec (p_j2k,p_j2k->m_procedure_list,p_stream,p_manager)) {
6538                 opj_image_destroy(p_j2k->m_private_image);
6539                 p_j2k->m_private_image = NULL;
6540                 return OPJ_FALSE;
6541         }
6542
6543         *p_image = opj_image_create0();
6544         if (! (*p_image)) {
6545                 return OPJ_FALSE;
6546         }
6547
6548         /* Copy codestream image information to the output image */
6549         opj_copy_image_header(p_j2k->m_private_image, *p_image);
6550
6551     /*Allocate and initialize some elements of codestrem index*/
6552         if (!opj_j2k_allocate_tile_element_cstr_index(p_j2k)){
6553                 return OPJ_FALSE;
6554         }
6555
6556         return OPJ_TRUE;
6557 }
6558
6559 void opj_j2k_setup_header_reading (opj_j2k_t *p_j2k)
6560 {
6561         /* preconditions*/
6562         assert(p_j2k != 00);
6563
6564         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_read_header_procedure);
6565
6566         /* DEVELOPER CORNER, add your custom procedures */
6567         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_copy_default_tcp_and_create_tcd);
6568
6569 }
6570
6571 void opj_j2k_setup_decoding_validation (opj_j2k_t *p_j2k)
6572 {
6573         /* preconditions*/
6574         assert(p_j2k != 00);
6575
6576         opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)opj_j2k_build_decoder);
6577         opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)opj_j2k_decoding_validation);
6578         /* DEVELOPER CORNER, add your custom validation procedure */
6579
6580 }
6581
6582 OPJ_BOOL opj_j2k_mct_validation (       opj_j2k_t * p_j2k,
6583                                                                 opj_stream_private_t *p_stream,
6584                                                                 opj_event_mgr_t * p_manager )
6585 {
6586         OPJ_BOOL l_is_valid = OPJ_TRUE;
6587         OPJ_UINT32 i,j;
6588
6589         /* preconditions */
6590         assert(p_j2k != 00);
6591         assert(p_stream != 00);
6592         assert(p_manager != 00);
6593
6594         if ((p_j2k->m_cp.rsiz & 0x8200) == 0x8200) {
6595                 OPJ_UINT32 l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
6596                 opj_tcp_t * l_tcp = p_j2k->m_cp.tcps;
6597
6598                 for (i=0;i<l_nb_tiles;++i) {
6599                         if (l_tcp->mct == 2) {
6600                                 opj_tccp_t * l_tccp = l_tcp->tccps;
6601                                 l_is_valid &= (l_tcp->m_mct_coding_matrix != 00);
6602
6603                                 for (j=0;j<p_j2k->m_private_image->numcomps;++j) {
6604                                         l_is_valid &= ! (l_tccp->qmfbid & 1);
6605                                         ++l_tccp;
6606                                 }
6607                         }
6608                         ++l_tcp;
6609                 }
6610         }
6611
6612         return l_is_valid;
6613 }
6614
6615 OPJ_BOOL opj_j2k_setup_mct_encoding(opj_tcp_t * p_tcp, opj_image_t * p_image)
6616 {
6617         OPJ_UINT32 i;
6618         OPJ_UINT32 l_indix = 1;
6619         opj_mct_data_t * l_mct_deco_data = 00,* l_mct_offset_data = 00;
6620         opj_simple_mcc_decorrelation_data_t * l_mcc_data;
6621         OPJ_UINT32 l_mct_size,l_nb_elem;
6622         OPJ_FLOAT32 * l_data, * l_current_data;
6623         opj_tccp_t * l_tccp;
6624
6625         /* preconditions */
6626         assert(p_tcp != 00);
6627
6628         if (p_tcp->mct != 2) {
6629                 return OPJ_TRUE;
6630         }
6631
6632         if (p_tcp->m_mct_decoding_matrix) {
6633                 if (p_tcp->m_nb_mct_records == p_tcp->m_nb_max_mct_records) {
6634                         opj_mct_data_t *new_mct_records;
6635                         p_tcp->m_nb_max_mct_records += OPJ_J2K_MCT_DEFAULT_NB_RECORDS;
6636
6637                         new_mct_records = (opj_mct_data_t *) opj_realloc(p_tcp->m_mct_records, p_tcp->m_nb_max_mct_records * sizeof(opj_mct_data_t));
6638                         if (! new_mct_records) {
6639                                 opj_free(p_tcp->m_mct_records);
6640                                 p_tcp->m_mct_records = NULL;
6641                                 p_tcp->m_nb_max_mct_records = 0;
6642                                 p_tcp->m_nb_mct_records = 0;
6643                                 /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to setup mct encoding\n"); */
6644                                 return OPJ_FALSE;
6645                         }
6646                         p_tcp->m_mct_records = new_mct_records;
6647                         l_mct_deco_data = p_tcp->m_mct_records + p_tcp->m_nb_mct_records;
6648
6649                         memset(l_mct_deco_data ,0,(p_tcp->m_nb_max_mct_records - p_tcp->m_nb_mct_records) * sizeof(opj_mct_data_t));
6650                 }
6651                 l_mct_deco_data = p_tcp->m_mct_records + p_tcp->m_nb_mct_records;
6652
6653                 if (l_mct_deco_data->m_data) {
6654                         opj_free(l_mct_deco_data->m_data);
6655                         l_mct_deco_data->m_data = 00;
6656                 }
6657
6658                 l_mct_deco_data->m_index = l_indix++;
6659                 l_mct_deco_data->m_array_type = MCT_TYPE_DECORRELATION;
6660                 l_mct_deco_data->m_element_type = MCT_TYPE_FLOAT;
6661                 l_nb_elem = p_image->numcomps * p_image->numcomps;
6662                 l_mct_size = l_nb_elem * MCT_ELEMENT_SIZE[l_mct_deco_data->m_element_type];
6663                 l_mct_deco_data->m_data = (OPJ_BYTE*)opj_malloc(l_mct_size );
6664
6665                 if (! l_mct_deco_data->m_data) {
6666                         return OPJ_FALSE;
6667                 }
6668
6669                 j2k_mct_write_functions_from_float[l_mct_deco_data->m_element_type](p_tcp->m_mct_decoding_matrix,l_mct_deco_data->m_data,l_nb_elem);
6670
6671                 l_mct_deco_data->m_data_size = l_mct_size;
6672                 ++p_tcp->m_nb_mct_records;
6673         }
6674
6675         if (p_tcp->m_nb_mct_records == p_tcp->m_nb_max_mct_records) {
6676                 opj_mct_data_t *new_mct_records;
6677                 p_tcp->m_nb_max_mct_records += OPJ_J2K_MCT_DEFAULT_NB_RECORDS;
6678                 new_mct_records = (opj_mct_data_t *) opj_realloc(p_tcp->m_mct_records, p_tcp->m_nb_max_mct_records * sizeof(opj_mct_data_t));
6679                 if (! new_mct_records) {
6680                         opj_free(p_tcp->m_mct_records);
6681                         p_tcp->m_mct_records = NULL;
6682                         p_tcp->m_nb_max_mct_records = 0;
6683                         p_tcp->m_nb_mct_records = 0;
6684                         /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to setup mct encoding\n"); */
6685                         return OPJ_FALSE;
6686                 }
6687                 p_tcp->m_mct_records = new_mct_records;
6688                 l_mct_offset_data = p_tcp->m_mct_records + p_tcp->m_nb_mct_records;
6689
6690                 memset(l_mct_offset_data ,0,(p_tcp->m_nb_max_mct_records - p_tcp->m_nb_mct_records) * sizeof(opj_mct_data_t));
6691
6692                 if (l_mct_deco_data) {
6693                         l_mct_deco_data = l_mct_offset_data - 1;
6694                 }
6695         }
6696
6697         l_mct_offset_data = p_tcp->m_mct_records + p_tcp->m_nb_mct_records;
6698
6699         if (l_mct_offset_data->m_data) {
6700                 opj_free(l_mct_offset_data->m_data);
6701                 l_mct_offset_data->m_data = 00;
6702         }
6703
6704         l_mct_offset_data->m_index = l_indix++;
6705         l_mct_offset_data->m_array_type = MCT_TYPE_OFFSET;
6706         l_mct_offset_data->m_element_type = MCT_TYPE_FLOAT;
6707         l_nb_elem = p_image->numcomps;
6708         l_mct_size = l_nb_elem * MCT_ELEMENT_SIZE[l_mct_offset_data->m_element_type];
6709         l_mct_offset_data->m_data = (OPJ_BYTE*)opj_malloc(l_mct_size );
6710
6711         if (! l_mct_offset_data->m_data) {
6712                 return OPJ_FALSE;
6713         }
6714
6715         l_data = (OPJ_FLOAT32*)opj_malloc(l_nb_elem * sizeof(OPJ_FLOAT32));
6716         if (! l_data) {
6717                 opj_free(l_mct_offset_data->m_data);
6718                 l_mct_offset_data->m_data = 00;
6719                 return OPJ_FALSE;
6720         }
6721
6722         l_tccp = p_tcp->tccps;
6723         l_current_data = l_data;
6724
6725         for (i=0;i<l_nb_elem;++i) {
6726                 *(l_current_data++) = (OPJ_FLOAT32) (l_tccp->m_dc_level_shift);
6727                 ++l_tccp;
6728         }
6729
6730         j2k_mct_write_functions_from_float[l_mct_offset_data->m_element_type](l_data,l_mct_offset_data->m_data,l_nb_elem);
6731
6732         opj_free(l_data);
6733
6734         l_mct_offset_data->m_data_size = l_mct_size;
6735
6736         ++p_tcp->m_nb_mct_records;
6737
6738         if (p_tcp->m_nb_mcc_records == p_tcp->m_nb_max_mcc_records) {
6739                 opj_simple_mcc_decorrelation_data_t *new_mcc_records;
6740                 p_tcp->m_nb_max_mcc_records += OPJ_J2K_MCT_DEFAULT_NB_RECORDS;
6741                 new_mcc_records = (opj_simple_mcc_decorrelation_data_t *) opj_realloc(
6742                                 p_tcp->m_mcc_records, p_tcp->m_nb_max_mcc_records * sizeof(opj_simple_mcc_decorrelation_data_t));
6743                 if (! new_mcc_records) {
6744                         opj_free(p_tcp->m_mcc_records);
6745                         p_tcp->m_mcc_records = NULL;
6746                         p_tcp->m_nb_max_mcc_records = 0;
6747                         p_tcp->m_nb_mcc_records = 0;
6748                         /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to setup mct encoding\n"); */
6749                         return OPJ_FALSE;
6750                 }
6751                 p_tcp->m_mcc_records = new_mcc_records;
6752                 l_mcc_data = p_tcp->m_mcc_records + p_tcp->m_nb_mcc_records;
6753                 memset(l_mcc_data ,0,(p_tcp->m_nb_max_mcc_records - p_tcp->m_nb_mcc_records) * sizeof(opj_simple_mcc_decorrelation_data_t));
6754
6755         }
6756
6757         l_mcc_data = p_tcp->m_mcc_records + p_tcp->m_nb_mcc_records;
6758         l_mcc_data->m_decorrelation_array = l_mct_deco_data;
6759         l_mcc_data->m_is_irreversible = 1;
6760         l_mcc_data->m_nb_comps = p_image->numcomps;
6761         l_mcc_data->m_index = l_indix++;
6762         l_mcc_data->m_offset_array = l_mct_offset_data;
6763         ++p_tcp->m_nb_mcc_records;
6764
6765         return OPJ_TRUE;
6766 }
6767
6768 OPJ_BOOL opj_j2k_build_decoder (opj_j2k_t * p_j2k,
6769                                                             opj_stream_private_t *p_stream,
6770                                                             opj_event_mgr_t * p_manager )
6771 {
6772         /* add here initialization of cp
6773            copy paste of setup_decoder */
6774   (void)p_j2k;
6775   (void)p_stream;
6776   (void)p_manager;
6777         return OPJ_TRUE;
6778 }
6779
6780 OPJ_BOOL opj_j2k_build_encoder (opj_j2k_t * p_j2k,
6781                                                         opj_stream_private_t *p_stream,
6782                                                         opj_event_mgr_t * p_manager )
6783 {
6784         /* add here initialization of cp
6785            copy paste of setup_encoder */
6786   (void)p_j2k;
6787   (void)p_stream;
6788   (void)p_manager;
6789         return OPJ_TRUE;
6790 }
6791
6792 OPJ_BOOL opj_j2k_encoding_validation (  opj_j2k_t * p_j2k,
6793                                                                             opj_stream_private_t *p_stream,
6794                                                                             opj_event_mgr_t * p_manager )
6795 {
6796         OPJ_BOOL l_is_valid = OPJ_TRUE;
6797
6798         /* preconditions */
6799         assert(p_j2k != 00);
6800         assert(p_stream != 00);
6801         assert(p_manager != 00);
6802
6803         /* STATE checking */
6804         /* make sure the state is at 0 */
6805         l_is_valid &= (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_NONE);
6806
6807         /* POINTER validation */
6808         /* make sure a p_j2k codec is present */
6809         l_is_valid &= (p_j2k->m_procedure_list != 00);
6810         /* make sure a validation list is present */
6811         l_is_valid &= (p_j2k->m_validation_list != 00);
6812
6813         if ((p_j2k->m_cp.tdx) < (OPJ_UINT32) (1 << p_j2k->m_cp.tcps->tccps->numresolutions)) {
6814                 opj_event_msg(p_manager, EVT_ERROR, "Number of resolutions is too high in comparison to the size of tiles\n");
6815                 return OPJ_FALSE;
6816         }
6817
6818         if ((p_j2k->m_cp.tdy) < (OPJ_UINT32) (1 << p_j2k->m_cp.tcps->tccps->numresolutions)) {
6819                 opj_event_msg(p_manager, EVT_ERROR, "Number of resolutions is too high in comparison to the size of tiles\n");
6820                 return OPJ_FALSE;
6821         }
6822
6823         /* PARAMETER VALIDATION */
6824         return l_is_valid;
6825 }
6826
6827 OPJ_BOOL opj_j2k_decoding_validation (  opj_j2k_t *p_j2k,
6828                                         opj_stream_private_t *p_stream,
6829                                         opj_event_mgr_t * p_manager
6830                                         )
6831 {
6832         OPJ_BOOL l_is_valid = OPJ_TRUE;
6833
6834         /* preconditions*/
6835         assert(p_j2k != 00);
6836         assert(p_stream != 00);
6837         assert(p_manager != 00);
6838
6839         /* STATE checking */
6840         /* make sure the state is at 0 */
6841 #ifdef TODO_MSD
6842         l_is_valid &= (p_j2k->m_specific_param.m_decoder.m_state == J2K_DEC_STATE_NONE);
6843 #endif
6844         l_is_valid &= (p_j2k->m_specific_param.m_decoder.m_state == 0x0000);
6845
6846         /* POINTER validation */
6847         /* make sure a p_j2k codec is present */
6848         /* make sure a procedure list is present */
6849         l_is_valid &= (p_j2k->m_procedure_list != 00);
6850         /* make sure a validation list is present */
6851         l_is_valid &= (p_j2k->m_validation_list != 00);
6852
6853         /* PARAMETER VALIDATION */
6854         return l_is_valid;
6855 }
6856
6857 OPJ_BOOL opj_j2k_read_header_procedure( opj_j2k_t *p_j2k,
6858                                                                             opj_stream_private_t *p_stream,
6859                                                                             opj_event_mgr_t * p_manager)
6860 {
6861         OPJ_UINT32 l_current_marker;
6862         OPJ_UINT32 l_marker_size;
6863         const opj_dec_memory_marker_handler_t * l_marker_handler = 00;
6864
6865         /* preconditions */
6866         assert(p_stream != 00);
6867         assert(p_j2k != 00);
6868         assert(p_manager != 00);
6869
6870         /*  We enter in the main header */
6871         p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_MHSOC;
6872
6873         /* Try to read the SOC marker, the codestream must begin with SOC marker */
6874         if (! opj_j2k_read_soc(p_j2k,p_stream,p_manager)) {
6875                 opj_event_msg(p_manager, EVT_ERROR, "Expected a SOC marker \n");
6876                 return OPJ_FALSE;
6877         }
6878
6879         /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer */
6880         if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
6881                 opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
6882                 return OPJ_FALSE;
6883         }
6884
6885         /* Read 2 bytes as the new marker ID */
6886         opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_current_marker,2);
6887
6888         /* Try to read until the SOT is detected */
6889         while (l_current_marker != J2K_MS_SOT) {
6890
6891                 /* Check if the current marker ID is valid */
6892                 if (l_current_marker < 0xff00) {
6893                         opj_event_msg(p_manager, EVT_ERROR, "We expected read a marker ID (0xff--) instead of %.8x\n", l_current_marker);
6894                         return OPJ_FALSE;
6895                 }
6896
6897                 /* Get the marker handler from the marker ID */
6898                 l_marker_handler = opj_j2k_get_marker_handler(l_current_marker);
6899
6900                 /* Manage case where marker is unknown */
6901                 if (l_marker_handler->id == J2K_MS_UNK) {
6902                         if (! opj_j2k_read_unk(p_j2k, p_stream, &l_current_marker, p_manager)){
6903                                 opj_event_msg(p_manager, EVT_ERROR, "Unknow marker have been detected and generated error.\n");
6904                                 return OPJ_FALSE;
6905                         }
6906
6907                         if (l_current_marker == J2K_MS_SOT)
6908                                 break; /* SOT marker is detected main header is completely read */
6909                         else    /* Get the marker handler from the marker ID */
6910                                 l_marker_handler = opj_j2k_get_marker_handler(l_current_marker);
6911                 }
6912
6913                 /* Check if the marker is known and if it is the right place to find it */
6914                 if (! (p_j2k->m_specific_param.m_decoder.m_state & l_marker_handler->states) ) {
6915                         opj_event_msg(p_manager, EVT_ERROR, "Marker is not compliant with its position\n");
6916                         return OPJ_FALSE;
6917                 }
6918
6919                 /* Try to read 2 bytes (the marker size) from stream and copy them into the buffer */
6920                 if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
6921                         opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
6922                         return OPJ_FALSE;
6923                 }
6924
6925                 /* read 2 bytes as the marker size */
6926                 opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_marker_size,2);
6927                 l_marker_size -= 2; /* Subtract the size of the marker ID already read */
6928
6929                 /* Check if the marker size is compatible with the header data size */
6930                 if (l_marker_size > p_j2k->m_specific_param.m_decoder.m_header_data_size) {
6931                         OPJ_BYTE *new_header_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_decoder.m_header_data, l_marker_size);
6932                         if (! new_header_data) {
6933                                 opj_free(p_j2k->m_specific_param.m_decoder.m_header_data);
6934                                 p_j2k->m_specific_param.m_decoder.m_header_data = NULL;
6935                                 p_j2k->m_specific_param.m_decoder.m_header_data_size = 0;
6936                                 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read header\n");
6937                                 return OPJ_FALSE;
6938                         }
6939                         p_j2k->m_specific_param.m_decoder.m_header_data = new_header_data;
6940                         p_j2k->m_specific_param.m_decoder.m_header_data_size = l_marker_size;
6941                 }
6942
6943                 /* Try to read the rest of the marker segment from stream and copy them into the buffer */
6944                 if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,l_marker_size,p_manager) != l_marker_size) {
6945                         opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
6946                         return OPJ_FALSE;
6947                 }
6948
6949                 /* Read the marker segment with the correct marker handler */
6950                 if (! (*(l_marker_handler->handler))(p_j2k,p_j2k->m_specific_param.m_decoder.m_header_data,l_marker_size,p_manager)) {
6951                         opj_event_msg(p_manager, EVT_ERROR, "Marker handler function failed to read the marker segment\n");
6952                         return OPJ_FALSE;
6953                 }
6954
6955                 /* Add the marker to the codestream index*/
6956                 if (OPJ_FALSE == opj_j2k_add_mhmarker(
6957                                         p_j2k->cstr_index,
6958                                         l_marker_handler->id,
6959                                         (OPJ_UINT32) opj_stream_tell(p_stream) - l_marker_size - 4,
6960                                         l_marker_size + 4 )) {
6961                         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to add mh marker\n");
6962                         return OPJ_FALSE;
6963                 }
6964
6965                 /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer */
6966                 if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
6967                         opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
6968                         return OPJ_FALSE;
6969                 }
6970
6971                 /* read 2 bytes as the new marker ID */
6972                 opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_current_marker,2);
6973         }
6974
6975         opj_event_msg(p_manager, EVT_INFO, "Main header has been correctly decoded.\n");
6976
6977         /* Position of the last element if the main header */
6978         p_j2k->cstr_index->main_head_end = (OPJ_UINT32) opj_stream_tell(p_stream) - 2;
6979
6980         /* Next step: read a tile-part header */
6981         p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_TPHSOT;
6982
6983         return OPJ_TRUE;
6984 }
6985
6986 OPJ_BOOL opj_j2k_exec ( opj_j2k_t * p_j2k,
6987                                         opj_procedure_list_t * p_procedure_list,
6988                                         opj_stream_private_t *p_stream,
6989                                         opj_event_mgr_t * p_manager )
6990 {
6991         OPJ_BOOL (** l_procedure) (opj_j2k_t * ,opj_stream_private_t *,opj_event_mgr_t *) = 00;
6992         OPJ_BOOL l_result = OPJ_TRUE;
6993         OPJ_UINT32 l_nb_proc, i;
6994
6995         /* preconditions*/
6996         assert(p_procedure_list != 00);
6997         assert(p_j2k != 00);
6998         assert(p_stream != 00);
6999         assert(p_manager != 00);
7000
7001         l_nb_proc = opj_procedure_list_get_nb_procedures(p_procedure_list);
7002         l_procedure = (OPJ_BOOL (**) (opj_j2k_t * ,opj_stream_private_t *,opj_event_mgr_t *)) opj_procedure_list_get_first_procedure(p_procedure_list);
7003
7004         for     (i=0;i<l_nb_proc;++i) {
7005                 l_result = l_result && ((*l_procedure) (p_j2k,p_stream,p_manager));
7006                 ++l_procedure;
7007         }
7008
7009         /* and clear the procedure list at the end.*/
7010         opj_procedure_list_clear(p_procedure_list);
7011         return l_result;
7012 }
7013
7014 /* FIXME DOC*/
7015 static OPJ_BOOL opj_j2k_copy_default_tcp_and_create_tcd (       opj_j2k_t * p_j2k,
7016                                                             opj_stream_private_t *p_stream,
7017                                                             opj_event_mgr_t * p_manager
7018                                                             )
7019 {
7020         opj_tcp_t * l_tcp = 00;
7021         opj_tcp_t * l_default_tcp = 00;
7022         OPJ_UINT32 l_nb_tiles;
7023         OPJ_UINT32 i,j;
7024         opj_tccp_t *l_current_tccp = 00;
7025         OPJ_UINT32 l_tccp_size;
7026         OPJ_UINT32 l_mct_size;
7027         opj_image_t * l_image;
7028         OPJ_UINT32 l_mcc_records_size,l_mct_records_size;
7029         opj_mct_data_t * l_src_mct_rec, *l_dest_mct_rec;
7030         opj_simple_mcc_decorrelation_data_t * l_src_mcc_rec, *l_dest_mcc_rec;
7031         OPJ_UINT32 l_offset;
7032
7033         /* preconditions */
7034         assert(p_j2k != 00);
7035         assert(p_stream != 00);
7036         assert(p_manager != 00);
7037
7038         l_image = p_j2k->m_private_image;
7039         l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
7040         l_tcp = p_j2k->m_cp.tcps;
7041         l_tccp_size = l_image->numcomps * (OPJ_UINT32)sizeof(opj_tccp_t);
7042         l_default_tcp = p_j2k->m_specific_param.m_decoder.m_default_tcp;
7043         l_mct_size = l_image->numcomps * l_image->numcomps * (OPJ_UINT32)sizeof(OPJ_FLOAT32);
7044
7045         /* For each tile */
7046         for (i=0; i<l_nb_tiles; ++i) {
7047                 /* keep the tile-compo coding parameters pointer of the current tile coding parameters*/
7048                 l_current_tccp = l_tcp->tccps;
7049                 /*Copy default coding parameters into the current tile coding parameters*/
7050                 memcpy(l_tcp, l_default_tcp, sizeof(opj_tcp_t));
7051                 /* Initialize some values of the current tile coding parameters*/
7052                 l_tcp->ppt = 0;
7053                 l_tcp->ppt_data = 00;
7054                 /* Reconnect the tile-compo coding parameters pointer to the current tile coding parameters*/
7055                 l_tcp->tccps = l_current_tccp;
7056
7057                 /* Get the mct_decoding_matrix of the dflt_tile_cp and copy them into the current tile cp*/
7058                 if (l_default_tcp->m_mct_decoding_matrix) {
7059                         l_tcp->m_mct_decoding_matrix = (OPJ_FLOAT32*)opj_malloc(l_mct_size);
7060                         if (! l_tcp->m_mct_decoding_matrix ) {
7061                                 return OPJ_FALSE;
7062                         }
7063                         memcpy(l_tcp->m_mct_decoding_matrix,l_default_tcp->m_mct_decoding_matrix,l_mct_size);
7064                 }
7065
7066                 /* Get the mct_record of the dflt_tile_cp and copy them into the current tile cp*/
7067                 l_mct_records_size = l_default_tcp->m_nb_max_mct_records * (OPJ_UINT32)sizeof(opj_mct_data_t);
7068                 l_tcp->m_mct_records = (opj_mct_data_t*)opj_malloc(l_mct_records_size);
7069                 if (! l_tcp->m_mct_records) {
7070                         return OPJ_FALSE;
7071                 }
7072                 memcpy(l_tcp->m_mct_records, l_default_tcp->m_mct_records,l_mct_records_size);
7073
7074                 /* Copy the mct record data from dflt_tile_cp to the current tile*/
7075                 l_src_mct_rec = l_default_tcp->m_mct_records;
7076                 l_dest_mct_rec = l_tcp->m_mct_records;
7077
7078                 for (j=0;j<l_default_tcp->m_nb_mct_records;++j) {
7079
7080                         if (l_src_mct_rec->m_data) {
7081
7082                                 l_dest_mct_rec->m_data = (OPJ_BYTE*) opj_malloc(l_src_mct_rec->m_data_size);
7083                                 if(! l_dest_mct_rec->m_data) {
7084                                         return OPJ_FALSE;
7085                                 }
7086                                 memcpy(l_dest_mct_rec->m_data,l_src_mct_rec->m_data,l_src_mct_rec->m_data_size);
7087                         }
7088
7089                         ++l_src_mct_rec;
7090                         ++l_dest_mct_rec;
7091                 }
7092
7093                 /* Get the mcc_record of the dflt_tile_cp and copy them into the current tile cp*/
7094                 l_mcc_records_size = l_default_tcp->m_nb_max_mcc_records * (OPJ_UINT32)sizeof(opj_simple_mcc_decorrelation_data_t);
7095                 l_tcp->m_mcc_records = (opj_simple_mcc_decorrelation_data_t*) opj_malloc(l_mcc_records_size);
7096                 if (! l_tcp->m_mcc_records) {
7097                         return OPJ_FALSE;
7098                 }
7099                 memcpy(l_tcp->m_mcc_records,l_default_tcp->m_mcc_records,l_mcc_records_size);
7100
7101                 /* Copy the mcc record data from dflt_tile_cp to the current tile*/
7102                 l_src_mcc_rec = l_default_tcp->m_mcc_records;
7103                 l_dest_mcc_rec = l_tcp->m_mcc_records;
7104
7105                 for (j=0;j<l_default_tcp->m_nb_max_mcc_records;++j) {
7106
7107                         if (l_src_mcc_rec->m_decorrelation_array) {
7108                                 l_offset = (OPJ_UINT32)(l_src_mcc_rec->m_decorrelation_array - l_default_tcp->m_mct_records);
7109                                 l_dest_mcc_rec->m_decorrelation_array = l_tcp->m_mct_records + l_offset;
7110                         }
7111
7112                         if (l_src_mcc_rec->m_offset_array) {
7113                                 l_offset = (OPJ_UINT32)(l_src_mcc_rec->m_offset_array - l_default_tcp->m_mct_records);
7114                                 l_dest_mcc_rec->m_offset_array = l_tcp->m_mct_records + l_offset;
7115                         }
7116
7117                         ++l_src_mcc_rec;
7118                         ++l_dest_mcc_rec;
7119                 }
7120
7121                 /* Copy all the dflt_tile_compo_cp to the current tile cp */
7122                 memcpy(l_current_tccp,l_default_tcp->tccps,l_tccp_size);
7123
7124                 /* Move to next tile cp*/
7125                 ++l_tcp;
7126         }
7127
7128         /* Create the current tile decoder*/
7129         p_j2k->m_tcd = (opj_tcd_t*)opj_tcd_create(OPJ_TRUE); /* FIXME why a cast ? */
7130         if (! p_j2k->m_tcd ) {
7131                 return OPJ_FALSE;
7132         }
7133
7134         if ( !opj_tcd_init(p_j2k->m_tcd, l_image, &(p_j2k->m_cp)) ) {
7135                 opj_tcd_destroy(p_j2k->m_tcd);
7136                 p_j2k->m_tcd = 00;
7137                 opj_event_msg(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n");
7138                 return OPJ_FALSE;
7139         }
7140
7141         return OPJ_TRUE;
7142 }
7143
7144 const opj_dec_memory_marker_handler_t * opj_j2k_get_marker_handler (OPJ_UINT32 p_id)
7145 {
7146         const opj_dec_memory_marker_handler_t *e;
7147         for (e = j2k_memory_marker_handler_tab; e->id != 0; ++e) {
7148                 if (e->id == p_id) {
7149                         break; /* we find a handler corresponding to the marker ID*/
7150                 }
7151         }
7152         return e;
7153 }
7154
7155 void opj_j2k_destroy (opj_j2k_t *p_j2k)
7156 {
7157         if (p_j2k == 00) {
7158                 return;
7159         }
7160
7161         if (p_j2k->m_is_decoder) {
7162
7163                 if (p_j2k->m_specific_param.m_decoder.m_default_tcp != 00) {
7164                         opj_j2k_tcp_destroy(p_j2k->m_specific_param.m_decoder.m_default_tcp);
7165                         opj_free(p_j2k->m_specific_param.m_decoder.m_default_tcp);
7166                         p_j2k->m_specific_param.m_decoder.m_default_tcp = 00;
7167                 }
7168
7169                 if (p_j2k->m_specific_param.m_decoder.m_header_data != 00) {
7170                         opj_free(p_j2k->m_specific_param.m_decoder.m_header_data);
7171                         p_j2k->m_specific_param.m_decoder.m_header_data = 00;
7172                         p_j2k->m_specific_param.m_decoder.m_header_data_size = 0;
7173                 }
7174         }
7175         else {
7176
7177                 if (p_j2k->m_specific_param.m_encoder.m_encoded_tile_data) {
7178                         opj_free(p_j2k->m_specific_param.m_encoder.m_encoded_tile_data);
7179                         p_j2k->m_specific_param.m_encoder.m_encoded_tile_data = 00;
7180                 }
7181
7182                 if (p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer) {
7183                         opj_free(p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer);
7184                         p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer = 00;
7185                         p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current = 00;
7186                 }
7187
7188                 if (p_j2k->m_specific_param.m_encoder.m_header_tile_data) {
7189                         opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
7190                         p_j2k->m_specific_param.m_encoder.m_header_tile_data = 00;
7191                         p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
7192                 }
7193         }
7194
7195         opj_tcd_destroy(p_j2k->m_tcd);
7196
7197         opj_j2k_cp_destroy(&(p_j2k->m_cp));
7198         memset(&(p_j2k->m_cp),0,sizeof(opj_cp_t));
7199
7200         opj_procedure_list_destroy(p_j2k->m_procedure_list);
7201         p_j2k->m_procedure_list = 00;
7202
7203         opj_procedure_list_destroy(p_j2k->m_validation_list);
7204         p_j2k->m_procedure_list = 00;
7205
7206         j2k_destroy_cstr_index(p_j2k->cstr_index);
7207         p_j2k->cstr_index = NULL;
7208
7209         opj_image_destroy(p_j2k->m_private_image);
7210         p_j2k->m_private_image = NULL;
7211
7212         opj_image_destroy(p_j2k->m_output_image);
7213         p_j2k->m_output_image = NULL;
7214
7215         opj_free(p_j2k);
7216 }
7217
7218 void j2k_destroy_cstr_index (opj_codestream_index_t *p_cstr_ind)
7219 {
7220         if (p_cstr_ind) {
7221
7222                 if (p_cstr_ind->marker) {
7223                         opj_free(p_cstr_ind->marker);
7224                         p_cstr_ind->marker = NULL;
7225                 }
7226
7227                 if (p_cstr_ind->tile_index) {
7228                         OPJ_UINT32 it_tile = 0;
7229
7230                         for (it_tile=0; it_tile < p_cstr_ind->nb_of_tiles; it_tile++) {
7231
7232                                 if(p_cstr_ind->tile_index[it_tile].packet_index) {
7233                                         opj_free(p_cstr_ind->tile_index[it_tile].packet_index);
7234                                         p_cstr_ind->tile_index[it_tile].packet_index = NULL;
7235                                 }
7236
7237                                 if(p_cstr_ind->tile_index[it_tile].tp_index){
7238                                         opj_free(p_cstr_ind->tile_index[it_tile].tp_index);
7239                                         p_cstr_ind->tile_index[it_tile].tp_index = NULL;
7240                                 }
7241
7242                                 if(p_cstr_ind->tile_index[it_tile].marker){
7243                                         opj_free(p_cstr_ind->tile_index[it_tile].marker);
7244                                         p_cstr_ind->tile_index[it_tile].marker = NULL;
7245
7246                                 }
7247                         }
7248
7249                         opj_free( p_cstr_ind->tile_index);
7250                         p_cstr_ind->tile_index = NULL;
7251                 }
7252
7253                 opj_free(p_cstr_ind);
7254         }
7255 }
7256
7257 void opj_j2k_tcp_destroy (opj_tcp_t *p_tcp)
7258 {
7259         if (p_tcp == 00) {
7260                 return;
7261         }
7262
7263         if (p_tcp->ppt_buffer != 00) {
7264                 opj_free(p_tcp->ppt_buffer);
7265                 p_tcp->ppt_buffer = 00;
7266         }
7267
7268         if (p_tcp->tccps != 00) {
7269                 opj_free(p_tcp->tccps);
7270                 p_tcp->tccps = 00;
7271         }
7272
7273         if (p_tcp->m_mct_coding_matrix != 00) {
7274                 opj_free(p_tcp->m_mct_coding_matrix);
7275                 p_tcp->m_mct_coding_matrix = 00;
7276         }
7277
7278         if (p_tcp->m_mct_decoding_matrix != 00) {
7279                 opj_free(p_tcp->m_mct_decoding_matrix);
7280                 p_tcp->m_mct_decoding_matrix = 00;
7281         }
7282
7283         if (p_tcp->m_mcc_records) {
7284                 opj_free(p_tcp->m_mcc_records);
7285                 p_tcp->m_mcc_records = 00;
7286                 p_tcp->m_nb_max_mcc_records = 0;
7287                 p_tcp->m_nb_mcc_records = 0;
7288         }
7289
7290         if (p_tcp->m_mct_records) {
7291                 opj_mct_data_t * l_mct_data = p_tcp->m_mct_records;
7292                 OPJ_UINT32 i;
7293
7294                 for (i=0;i<p_tcp->m_nb_mct_records;++i) {
7295                         if (l_mct_data->m_data) {
7296                                 opj_free(l_mct_data->m_data);
7297                                 l_mct_data->m_data = 00;
7298                         }
7299
7300                         ++l_mct_data;
7301                 }
7302
7303                 opj_free(p_tcp->m_mct_records);
7304                 p_tcp->m_mct_records = 00;
7305         }
7306
7307         if (p_tcp->mct_norms != 00) {
7308                 opj_free(p_tcp->mct_norms);
7309                 p_tcp->mct_norms = 00;
7310         }
7311
7312         opj_j2k_tcp_data_destroy(p_tcp);
7313
7314 }
7315
7316 void opj_j2k_tcp_data_destroy (opj_tcp_t *p_tcp)
7317 {
7318         if (p_tcp->m_data) {
7319                 opj_free(p_tcp->m_data);
7320                 p_tcp->m_data = NULL;
7321                 p_tcp->m_data_size = 0;
7322         }
7323 }
7324
7325 void opj_j2k_cp_destroy (opj_cp_t *p_cp)
7326 {
7327         OPJ_UINT32 l_nb_tiles;
7328         opj_tcp_t * l_current_tile = 00;
7329         OPJ_UINT32 i;
7330
7331         if (p_cp == 00)
7332         {
7333                 return;
7334         }
7335         if (p_cp->tcps != 00)
7336         {
7337                 l_current_tile = p_cp->tcps;
7338                 l_nb_tiles = p_cp->th * p_cp->tw;
7339
7340                 for (i = 0; i < l_nb_tiles; ++i)
7341                 {
7342                         opj_j2k_tcp_destroy(l_current_tile);
7343                         ++l_current_tile;
7344                 }
7345                 opj_free(p_cp->tcps);
7346                 p_cp->tcps = 00;
7347         }
7348         opj_free(p_cp->ppm_buffer);
7349         p_cp->ppm_buffer = 00;
7350         p_cp->ppm_data = NULL; /* ppm_data belongs to the allocated buffer pointed by ppm_buffer */
7351         opj_free(p_cp->comment);
7352         p_cp->comment = 00;
7353         if (! p_cp->m_is_decoder)
7354         {
7355                 opj_free(p_cp->m_specific_param.m_enc.m_matrice);
7356                 p_cp->m_specific_param.m_enc.m_matrice = 00;
7357         }
7358 }
7359
7360 OPJ_BOOL opj_j2k_read_tile_header(      opj_j2k_t * p_j2k,
7361                                                                     OPJ_UINT32 * p_tile_index,
7362                                                                     OPJ_UINT32 * p_data_size,
7363                                                                     OPJ_INT32 * p_tile_x0, OPJ_INT32 * p_tile_y0,
7364                                                                     OPJ_INT32 * p_tile_x1, OPJ_INT32 * p_tile_y1,
7365                                                                     OPJ_UINT32 * p_nb_comps,
7366                                                                     OPJ_BOOL * p_go_on,
7367                                                                     opj_stream_private_t *p_stream,
7368                                                                     opj_event_mgr_t * p_manager )
7369 {
7370         OPJ_UINT32 l_current_marker = J2K_MS_SOT;
7371         OPJ_UINT32 l_marker_size;
7372         const opj_dec_memory_marker_handler_t * l_marker_handler = 00;
7373         opj_tcp_t * l_tcp = NULL;
7374         OPJ_UINT32 l_nb_tiles;
7375
7376         /* preconditions */
7377         assert(p_stream != 00);
7378         assert(p_j2k != 00);
7379         assert(p_manager != 00);
7380
7381         /* Reach the End Of Codestream ?*/
7382         if (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_EOC){
7383                 l_current_marker = J2K_MS_EOC;
7384         }
7385         /* We need to encounter a SOT marker (a new tile-part header) */
7386         else if (p_j2k->m_specific_param.m_decoder.m_state != J2K_STATE_TPHSOT){
7387                 return OPJ_FALSE;
7388         }
7389
7390         /* Read into the codestream until reach the EOC or ! can_decode ??? FIXME */
7391         while ( (!p_j2k->m_specific_param.m_decoder.m_can_decode) && (l_current_marker != J2K_MS_EOC) ) {
7392
7393                 /* Try to read until the Start Of Data is detected */
7394                 while (l_current_marker != J2K_MS_SOD) {
7395                     
7396                     if(opj_stream_get_number_byte_left(p_stream) == 0)
7397                     {
7398                         p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_NEOC;
7399                         break;
7400                     }
7401
7402                         /* Try to read 2 bytes (the marker size) from stream and copy them into the buffer */
7403                         if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
7404                                 opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
7405                                 return OPJ_FALSE;
7406                         }
7407
7408                         /* Read 2 bytes from the buffer as the marker size */
7409                         opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_marker_size,2);
7410
7411                         /* cf. https://code.google.com/p/openjpeg/issues/detail?id=226 */
7412                         if (l_current_marker == 0x8080 && opj_stream_get_number_byte_left(p_stream) == 0) {
7413                                 p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_NEOC;
7414                                 break;
7415                         }
7416
7417                         /* Why this condition? FIXME */
7418                         if (p_j2k->m_specific_param.m_decoder.m_state & J2K_STATE_TPH){
7419                                 p_j2k->m_specific_param.m_decoder.m_sot_length -= (l_marker_size + 2);
7420                         }
7421                         l_marker_size -= 2; /* Subtract the size of the marker ID already read */
7422
7423                         /* Get the marker handler from the marker ID */
7424                         l_marker_handler = opj_j2k_get_marker_handler(l_current_marker);
7425
7426                         /* Check if the marker is known and if it is the right place to find it */
7427                         if (! (p_j2k->m_specific_param.m_decoder.m_state & l_marker_handler->states) ) {
7428                                 opj_event_msg(p_manager, EVT_ERROR, "Marker is not compliant with its position\n");
7429                                 return OPJ_FALSE;
7430                         }
7431 /* FIXME manage case of unknown marker as in the main header ? */
7432
7433                         /* Check if the marker size is compatible with the header data size */
7434                         if (l_marker_size > p_j2k->m_specific_param.m_decoder.m_header_data_size) {
7435                                 OPJ_BYTE *new_header_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_decoder.m_header_data, l_marker_size);
7436                                 if (! new_header_data) {
7437                                         opj_free(p_j2k->m_specific_param.m_decoder.m_header_data);
7438                                         p_j2k->m_specific_param.m_decoder.m_header_data = NULL;
7439                                         p_j2k->m_specific_param.m_decoder.m_header_data_size = 0;
7440                                         opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read header\n");
7441                                         return OPJ_FALSE;
7442                                 }
7443                                 p_j2k->m_specific_param.m_decoder.m_header_data = new_header_data;
7444                                 p_j2k->m_specific_param.m_decoder.m_header_data_size = l_marker_size;
7445                         }
7446
7447                         /* Try to read the rest of the marker segment from stream and copy them into the buffer */
7448                         if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,l_marker_size,p_manager) != l_marker_size) {
7449                                 opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
7450                                 return OPJ_FALSE;
7451                         }
7452
7453                         if (!l_marker_handler->handler) {
7454                                 /* See issue #175 */
7455                                 opj_event_msg(p_manager, EVT_ERROR, "Not sure how that happened.\n");
7456                                 return OPJ_FALSE;
7457                         }
7458                         /* Read the marker segment with the correct marker handler */
7459                         if (! (*(l_marker_handler->handler))(p_j2k,p_j2k->m_specific_param.m_decoder.m_header_data,l_marker_size,p_manager)) {
7460                                 opj_event_msg(p_manager, EVT_ERROR, "Fail to read the current marker segment (%#x)\n", l_current_marker);
7461                                 return OPJ_FALSE;
7462                         }
7463
7464                         /* Add the marker to the codestream index*/
7465                         if (OPJ_FALSE == opj_j2k_add_tlmarker(p_j2k->m_current_tile_number,
7466                                                 p_j2k->cstr_index,
7467                                                 l_marker_handler->id,
7468                                                 (OPJ_UINT32) opj_stream_tell(p_stream) - l_marker_size - 4,
7469                                                 l_marker_size + 4 )) {
7470                                 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to add tl marker\n");
7471                                 return OPJ_FALSE;
7472                         }
7473
7474                         /* Keep the position of the last SOT marker read */
7475                         if ( l_marker_handler->id == J2K_MS_SOT ) {
7476                                 OPJ_UINT32 sot_pos = (OPJ_UINT32) opj_stream_tell(p_stream) - l_marker_size - 4 ;
7477                                 if (sot_pos > p_j2k->m_specific_param.m_decoder.m_last_sot_read_pos)
7478                                 {
7479                                         p_j2k->m_specific_param.m_decoder.m_last_sot_read_pos = sot_pos;
7480                                 }
7481                         }
7482
7483                         if (p_j2k->m_specific_param.m_decoder.m_skip_data) {
7484                                 /* Skip the rest of the tile part header*/
7485                                 if (opj_stream_skip(p_stream,p_j2k->m_specific_param.m_decoder.m_sot_length,p_manager) != p_j2k->m_specific_param.m_decoder.m_sot_length) {
7486                                         opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
7487                                         return OPJ_FALSE;
7488                                 }
7489                                 l_current_marker = J2K_MS_SOD; /* Normally we reached a SOD */
7490                         }
7491                         else {
7492                                 /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer*/
7493                                 if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
7494                                         opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
7495                                         return OPJ_FALSE;
7496                                 }
7497                                 /* Read 2 bytes from the buffer as the new marker ID */
7498                                 opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_current_marker,2);
7499                         }
7500                 }
7501                 if(opj_stream_get_number_byte_left(p_stream) == 0
7502                     && p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_NEOC)
7503                     break;
7504
7505                 /* If we didn't skip data before, we need to read the SOD marker*/
7506                 if (! p_j2k->m_specific_param.m_decoder.m_skip_data) {
7507                         /* Try to read the SOD marker and skip data ? FIXME */
7508                         if (! opj_j2k_read_sod(p_j2k, p_stream, p_manager)) {
7509                                 return OPJ_FALSE;
7510                         }
7511
7512                         if (! p_j2k->m_specific_param.m_decoder.m_can_decode){
7513                                 /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer */
7514                                 if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
7515                                         opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
7516                                         return OPJ_FALSE;
7517                                 }
7518
7519                                 /* Read 2 bytes from buffer as the new marker ID */
7520                                 opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_current_marker,2);
7521                         }
7522                 }
7523                 else {
7524                         /* Indicate we will try to read a new tile-part header*/
7525                         p_j2k->m_specific_param.m_decoder.m_skip_data = 0;
7526                         p_j2k->m_specific_param.m_decoder.m_can_decode = 0;
7527                         p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_TPHSOT;
7528
7529                         /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer */
7530                         if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
7531                                 opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
7532                                 return OPJ_FALSE;
7533                         }
7534
7535                         /* Read 2 bytes from buffer as the new marker ID */
7536                         opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_current_marker,2);
7537                 }
7538         }
7539
7540         /* Current marker is the EOC marker ?*/
7541         if (l_current_marker == J2K_MS_EOC) {
7542                 if (p_j2k->m_specific_param.m_decoder.m_state != J2K_STATE_EOC ){
7543                         p_j2k->m_current_tile_number = 0;
7544                         p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_EOC;
7545                 }
7546         }
7547
7548         /* FIXME DOC ???*/
7549         if ( ! p_j2k->m_specific_param.m_decoder.m_can_decode) {
7550                 l_tcp = p_j2k->m_cp.tcps + p_j2k->m_current_tile_number;
7551                 l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
7552
7553                 while( (p_j2k->m_current_tile_number < l_nb_tiles) && (l_tcp->m_data == 00) ) {
7554                         ++p_j2k->m_current_tile_number;
7555                         ++l_tcp;
7556                 }
7557
7558                 if (p_j2k->m_current_tile_number == l_nb_tiles) {
7559                         *p_go_on = OPJ_FALSE;
7560                         return OPJ_TRUE;
7561                 }
7562         }
7563
7564         /*FIXME ???*/
7565         if (! opj_tcd_init_decode_tile(p_j2k->m_tcd, p_j2k->m_current_tile_number)) {
7566                 opj_event_msg(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n");
7567                 return OPJ_FALSE;
7568         }
7569
7570         opj_event_msg(p_manager, EVT_INFO, "Header of tile %d / %d has been read.\n",
7571                         p_j2k->m_current_tile_number, (p_j2k->m_cp.th * p_j2k->m_cp.tw) - 1);
7572
7573         *p_tile_index = p_j2k->m_current_tile_number;
7574         *p_go_on = OPJ_TRUE;
7575         *p_data_size = opj_tcd_get_decoded_tile_size(p_j2k->m_tcd);
7576         *p_tile_x0 = p_j2k->m_tcd->tcd_image->tiles->x0;
7577         *p_tile_y0 = p_j2k->m_tcd->tcd_image->tiles->y0;
7578         *p_tile_x1 = p_j2k->m_tcd->tcd_image->tiles->x1;
7579         *p_tile_y1 = p_j2k->m_tcd->tcd_image->tiles->y1;
7580         *p_nb_comps = p_j2k->m_tcd->tcd_image->tiles->numcomps;
7581
7582          p_j2k->m_specific_param.m_decoder.m_state |= 0x0080;/* FIXME J2K_DEC_STATE_DATA;*/
7583
7584         return OPJ_TRUE;
7585 }
7586
7587 OPJ_BOOL opj_j2k_decode_tile (  opj_j2k_t * p_j2k,
7588                                                         OPJ_UINT32 p_tile_index,
7589                                                         OPJ_BYTE * p_data,
7590                                                         OPJ_UINT32 p_data_size,
7591                                                         opj_stream_private_t *p_stream,
7592                                                         opj_event_mgr_t * p_manager )
7593 {
7594         OPJ_UINT32 l_current_marker;
7595         OPJ_BYTE l_data [2];
7596         opj_tcp_t * l_tcp;
7597
7598         /* preconditions */
7599         assert(p_stream != 00);
7600         assert(p_j2k != 00);
7601         assert(p_manager != 00);
7602
7603         if ( !(p_j2k->m_specific_param.m_decoder.m_state & 0x0080/*FIXME J2K_DEC_STATE_DATA*/)
7604                 || (p_tile_index != p_j2k->m_current_tile_number) ) {
7605                 return OPJ_FALSE;
7606         }
7607
7608         l_tcp = &(p_j2k->m_cp.tcps[p_tile_index]);
7609         if (! l_tcp->m_data) {
7610                 opj_j2k_tcp_destroy(l_tcp);
7611                 return OPJ_FALSE;
7612         }
7613
7614         if (! opj_tcd_decode_tile(      p_j2k->m_tcd,
7615                                                                 l_tcp->m_data,
7616                                                                 l_tcp->m_data_size,
7617                                                                 p_tile_index,
7618                                                                 p_j2k->cstr_index) ) {
7619                 opj_j2k_tcp_destroy(l_tcp);
7620                 p_j2k->m_specific_param.m_decoder.m_state |= 0x8000;/*FIXME J2K_DEC_STATE_ERR;*/
7621                 return OPJ_FALSE;
7622         }
7623
7624         if (! opj_tcd_update_tile_data(p_j2k->m_tcd,p_data,p_data_size)) {
7625                 return OPJ_FALSE;
7626         }
7627
7628         /* To avoid to destroy the tcp which can be useful when we try to decode a tile decoded before (cf j2k_random_tile_access)
7629          * we destroy just the data which will be re-read in read_tile_header*/
7630         /*opj_j2k_tcp_destroy(l_tcp);
7631         p_j2k->m_tcd->tcp = 0;*/
7632         opj_j2k_tcp_data_destroy(l_tcp);
7633
7634         p_j2k->m_specific_param.m_decoder.m_can_decode = 0;
7635         p_j2k->m_specific_param.m_decoder.m_state &= (~ (0x0080));/* FIXME J2K_DEC_STATE_DATA);*/
7636
7637         if(opj_stream_get_number_byte_left(p_stream) == 0 
7638             && p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_NEOC){
7639             return OPJ_TRUE;
7640         }
7641
7642         if (p_j2k->m_specific_param.m_decoder.m_state != 0x0100){ /*FIXME J2K_DEC_STATE_EOC)*/
7643                 if (opj_stream_read_data(p_stream,l_data,2,p_manager) != 2) {
7644                         opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
7645                         return OPJ_FALSE;
7646                 }
7647
7648                 opj_read_bytes(l_data,&l_current_marker,2);
7649
7650                 if (l_current_marker == J2K_MS_EOC) {
7651                         p_j2k->m_current_tile_number = 0;
7652                         p_j2k->m_specific_param.m_decoder.m_state =  0x0100;/*FIXME J2K_DEC_STATE_EOC;*/
7653                 }
7654                 else if (l_current_marker != J2K_MS_SOT)
7655                 {
7656                         opj_event_msg(p_manager, EVT_ERROR, "Stream too short, expected SOT\n");
7657                         
7658                         if(opj_stream_get_number_byte_left(p_stream) == 0) {
7659                             p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_NEOC;
7660                             return OPJ_TRUE;
7661                         }
7662                         return OPJ_FALSE;
7663                 }
7664         }
7665
7666         return OPJ_TRUE;
7667 }
7668
7669 OPJ_BOOL opj_j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data, opj_image_t* p_output_image)
7670 {
7671         OPJ_UINT32 i,j,k = 0;
7672         OPJ_UINT32 l_width_src,l_height_src;
7673         OPJ_UINT32 l_width_dest,l_height_dest;
7674         OPJ_INT32 l_offset_x0_src, l_offset_y0_src, l_offset_x1_src, l_offset_y1_src;
7675         OPJ_INT32 l_start_offset_src, l_line_offset_src, l_end_offset_src ;
7676         OPJ_UINT32 l_start_x_dest , l_start_y_dest;
7677         OPJ_UINT32 l_x0_dest, l_y0_dest, l_x1_dest, l_y1_dest;
7678         OPJ_INT32 l_start_offset_dest, l_line_offset_dest;
7679
7680         opj_image_comp_t * l_img_comp_src = 00;
7681         opj_image_comp_t * l_img_comp_dest = 00;
7682
7683         opj_tcd_tilecomp_t * l_tilec = 00;
7684         opj_image_t * l_image_src = 00;
7685         OPJ_UINT32 l_size_comp, l_remaining;
7686         OPJ_INT32 * l_dest_ptr;
7687         opj_tcd_resolution_t* l_res= 00;
7688
7689         l_tilec = p_tcd->tcd_image->tiles->comps;
7690         l_image_src = p_tcd->image;
7691         l_img_comp_src = l_image_src->comps;
7692
7693         l_img_comp_dest = p_output_image->comps;
7694
7695         for (i=0; i<l_image_src->numcomps; i++) {
7696
7697                 /* Allocate output component buffer if necessary */
7698                 if (!l_img_comp_dest->data) {
7699
7700                         l_img_comp_dest->data = (OPJ_INT32*) opj_calloc(l_img_comp_dest->w * l_img_comp_dest->h, sizeof(OPJ_INT32));
7701                         if (! l_img_comp_dest->data) {
7702                                 return OPJ_FALSE;
7703                         }
7704                 }
7705
7706                 /* Copy info from decoded comp image to output image */
7707                 l_img_comp_dest->resno_decoded = l_img_comp_src->resno_decoded;
7708
7709                 /*-----*/
7710                 /* Compute the precision of the output buffer */
7711                 l_size_comp = l_img_comp_src->prec >> 3; /*(/ 8)*/
7712                 l_remaining = l_img_comp_src->prec & 7;  /* (%8) */
7713                 l_res = l_tilec->resolutions + l_img_comp_src->resno_decoded;
7714
7715                 if (l_remaining) {
7716                         ++l_size_comp;
7717                 }
7718
7719                 if (l_size_comp == 3) {
7720                         l_size_comp = 4;
7721                 }
7722                 /*-----*/
7723
7724                 /* Current tile component size*/
7725                 /*if (i == 0) {
7726                 fprintf(stdout, "SRC: l_res_x0=%d, l_res_x1=%d, l_res_y0=%d, l_res_y1=%d\n",
7727                                 l_res->x0, l_res->x1, l_res->y0, l_res->y1);
7728                 }*/
7729
7730                 l_width_src = (l_res->x1 - l_res->x0);
7731                 l_height_src = (l_res->y1 - l_res->y0);
7732
7733                 /* Border of the current output component*/
7734                 l_x0_dest = opj_int_ceildivpow2(l_img_comp_dest->x0, l_img_comp_dest->factor);
7735                 l_y0_dest = opj_int_ceildivpow2(l_img_comp_dest->y0, l_img_comp_dest->factor);
7736                 l_x1_dest = l_x0_dest + l_img_comp_dest->w;
7737                 l_y1_dest = l_y0_dest + l_img_comp_dest->h;
7738
7739                 /*if (i == 0) {
7740                 fprintf(stdout, "DEST: l_x0_dest=%d, l_x1_dest=%d, l_y0_dest=%d, l_y1_dest=%d (%d)\n",
7741                                 l_x0_dest, l_x1_dest, l_y0_dest, l_y1_dest, l_img_comp_dest->factor );
7742                 }*/
7743
7744                 /*-----*/
7745                 /* Compute the area (l_offset_x0_src, l_offset_y0_src, l_offset_x1_src, l_offset_y1_src)
7746                  * of the input buffer (decoded tile component) which will be move
7747                  * in the output buffer. Compute the area of the output buffer (l_start_x_dest,
7748                  * l_start_y_dest, l_width_dest, l_height_dest)  which will be modified
7749                  * by this input area.
7750                  * */
7751                 assert( l_res->x0 >= 0);
7752                 assert( l_res->x1 >= 0);
7753                 if ( l_x0_dest < (OPJ_UINT32)l_res->x0 ) {
7754                         l_start_x_dest = l_res->x0 - l_x0_dest;
7755                         l_offset_x0_src = 0;
7756
7757                         if ( l_x1_dest >= (OPJ_UINT32)l_res->x1 ) {
7758                                 l_width_dest = l_width_src;
7759                                 l_offset_x1_src = 0;
7760                         }
7761                         else {
7762                                 l_width_dest = l_x1_dest - l_res->x0 ;
7763                                 l_offset_x1_src = l_width_src - l_width_dest;
7764                         }
7765                 }
7766                 else {
7767                         l_start_x_dest = 0 ;
7768                         l_offset_x0_src = l_x0_dest - l_res->x0;
7769
7770                         if ( l_x1_dest >= (OPJ_UINT32)l_res->x1 ) {
7771                                 l_width_dest = l_width_src - l_offset_x0_src;
7772                                 l_offset_x1_src = 0;
7773                         }
7774                         else {
7775                                 l_width_dest = l_img_comp_dest->w ;
7776                                 l_offset_x1_src = l_res->x1 - l_x1_dest;
7777                         }
7778                 }
7779
7780                 if ( l_y0_dest < (OPJ_UINT32)l_res->y0 ) {
7781                         l_start_y_dest = l_res->y0 - l_y0_dest;
7782                         l_offset_y0_src = 0;
7783
7784                         if ( l_y1_dest >= (OPJ_UINT32)l_res->y1 ) {
7785                                 l_height_dest = l_height_src;
7786                                 l_offset_y1_src = 0;
7787                         }
7788                         else {
7789                                 l_height_dest = l_y1_dest - l_res->y0 ;
7790                                 l_offset_y1_src =  l_height_src - l_height_dest;
7791                         }
7792                 }
7793                 else {
7794                         l_start_y_dest = 0 ;
7795                         l_offset_y0_src = l_y0_dest - l_res->y0;
7796
7797                         if ( l_y1_dest >= (OPJ_UINT32)l_res->y1 ) {
7798                                 l_height_dest = l_height_src - l_offset_y0_src;
7799                                 l_offset_y1_src = 0;
7800                         }
7801                         else {
7802                                 l_height_dest = l_img_comp_dest->h ;
7803                                 l_offset_y1_src = l_res->y1 - l_y1_dest;
7804                         }
7805                 }
7806
7807                 if( (l_offset_x0_src < 0 ) || (l_offset_y0_src < 0 ) || (l_offset_x1_src < 0 ) || (l_offset_y1_src < 0 ) ){
7808                         return OPJ_FALSE;
7809                 }
7810                 /* testcase 2977.pdf.asan.67.2198 */
7811                 if ((OPJ_INT32)l_width_dest < 0 || (OPJ_INT32)l_height_dest < 0) {
7812                         return OPJ_FALSE;
7813                 }
7814                 /*-----*/
7815
7816                 /* Compute the input buffer offset */
7817                 l_start_offset_src = l_offset_x0_src + l_offset_y0_src * l_width_src;
7818                 l_line_offset_src = l_offset_x1_src + l_offset_x0_src;
7819                 l_end_offset_src = l_offset_y1_src * l_width_src - l_offset_x0_src;
7820
7821                 /* Compute the output buffer offset */
7822                 l_start_offset_dest = l_start_x_dest + l_start_y_dest * l_img_comp_dest->w;
7823                 l_line_offset_dest = l_img_comp_dest->w - l_width_dest;
7824
7825                 /* Move the output buffer to the first place where we will write*/
7826                 l_dest_ptr = l_img_comp_dest->data + l_start_offset_dest;
7827
7828                 /*if (i == 0) {
7829                         fprintf(stdout, "COMPO[%d]:\n",i);
7830                         fprintf(stdout, "SRC: l_start_x_src=%d, l_start_y_src=%d, l_width_src=%d, l_height_src=%d\n"
7831                                         "\t tile offset:%d, %d, %d, %d\n"
7832                                         "\t buffer offset: %d; %d, %d\n",
7833                                         l_res->x0, l_res->y0, l_width_src, l_height_src,
7834                                         l_offset_x0_src, l_offset_y0_src, l_offset_x1_src, l_offset_y1_src,
7835                                         l_start_offset_src, l_line_offset_src, l_end_offset_src);
7836
7837                         fprintf(stdout, "DEST: l_start_x_dest=%d, l_start_y_dest=%d, l_width_dest=%d, l_height_dest=%d\n"
7838                                         "\t start offset: %d, line offset= %d\n",
7839                                         l_start_x_dest, l_start_y_dest, l_width_dest, l_height_dest, l_start_offset_dest, l_line_offset_dest);
7840                 }*/
7841
7842                 switch (l_size_comp) {
7843                         case 1:
7844                                 {
7845                                         OPJ_CHAR * l_src_ptr = (OPJ_CHAR*) p_data;
7846                                         l_src_ptr += l_start_offset_src; /* Move to the first place where we will read*/
7847
7848                                         if (l_img_comp_src->sgnd) {
7849                                                 for (j = 0 ; j < l_height_dest ; ++j) {
7850                                                         for ( k = 0 ; k < l_width_dest ; ++k) {
7851                                                                 *(l_dest_ptr++) = (OPJ_INT32) (*(l_src_ptr++)); /* Copy only the data needed for the output image */
7852                                                         }
7853
7854                                                         l_dest_ptr+= l_line_offset_dest; /* Move to the next place where we will write */
7855                                                         l_src_ptr += l_line_offset_src ; /* Move to the next place where we will read */
7856                                                 }
7857                                         }
7858                                         else {
7859                                                 for ( j = 0 ; j < l_height_dest ; ++j ) {
7860                                                         for ( k = 0 ; k < l_width_dest ; ++k) {
7861                                                                 *(l_dest_ptr++) = (OPJ_INT32) ((*(l_src_ptr++))&0xff);
7862                                                         }
7863
7864                                                         l_dest_ptr+= l_line_offset_dest;
7865                                                         l_src_ptr += l_line_offset_src;
7866                                                 }
7867                                         }
7868
7869                                         l_src_ptr += l_end_offset_src; /* Move to the end of this component-part of the input buffer */
7870                                         p_data = (OPJ_BYTE*) l_src_ptr; /* Keep the current position for the next component-part */
7871                                 }
7872                                 break;
7873                         case 2:
7874                                 {
7875                                         OPJ_INT16 * l_src_ptr = (OPJ_INT16 *) p_data;
7876                                         l_src_ptr += l_start_offset_src;
7877
7878                                         if (l_img_comp_src->sgnd) {
7879                                                 for (j=0;j<l_height_dest;++j) {
7880                                                         for (k=0;k<l_width_dest;++k) {
7881                                                                 *(l_dest_ptr++) = *(l_src_ptr++);
7882                                                         }
7883
7884                                                         l_dest_ptr+= l_line_offset_dest;
7885                                                         l_src_ptr += l_line_offset_src ;
7886                                                 }
7887                                         }
7888                                         else {
7889                                                 for (j=0;j<l_height_dest;++j) {
7890                                                         for (k=0;k<l_width_dest;++k) {
7891                                                                 *(l_dest_ptr++) = (*(l_src_ptr++))&0xffff;
7892                                                         }
7893
7894                                                         l_dest_ptr+= l_line_offset_dest;
7895                                                         l_src_ptr += l_line_offset_src ;
7896                                                 }
7897                                         }
7898
7899                                         l_src_ptr += l_end_offset_src;
7900                                         p_data = (OPJ_BYTE*) l_src_ptr;
7901                                 }
7902                                 break;
7903                         case 4:
7904                                 {
7905                                         OPJ_INT32 * l_src_ptr = (OPJ_INT32 *) p_data;
7906                                         l_src_ptr += l_start_offset_src;
7907
7908                                         for (j=0;j<l_height_dest;++j) {
7909                                                 for (k=0;k<l_width_dest;++k) {
7910                                                         *(l_dest_ptr++) = (*(l_src_ptr++));
7911                                                 }
7912
7913                                                 l_dest_ptr+= l_line_offset_dest;
7914                                                 l_src_ptr += l_line_offset_src ;
7915                                         }
7916
7917                                         l_src_ptr += l_end_offset_src;
7918                                         p_data = (OPJ_BYTE*) l_src_ptr;
7919                                 }
7920                                 break;
7921                 }
7922
7923                 ++l_img_comp_dest;
7924                 ++l_img_comp_src;
7925                 ++l_tilec;
7926         }
7927
7928         return OPJ_TRUE;
7929 }
7930
7931 OPJ_BOOL opj_j2k_set_decode_area(       opj_j2k_t *p_j2k,
7932                                                                     opj_image_t* p_image,
7933                                                                     OPJ_INT32 p_start_x, OPJ_INT32 p_start_y,
7934                                                                     OPJ_INT32 p_end_x, OPJ_INT32 p_end_y,
7935                                                                     opj_event_mgr_t * p_manager )
7936 {
7937         opj_cp_t * l_cp = &(p_j2k->m_cp);
7938         opj_image_t * l_image = p_j2k->m_private_image;
7939
7940         OPJ_UINT32 it_comp;
7941         OPJ_INT32 l_comp_x1, l_comp_y1;
7942         opj_image_comp_t* l_img_comp = NULL;
7943
7944         /* Check if we are read the main header */
7945         if (p_j2k->m_specific_param.m_decoder.m_state != J2K_STATE_TPHSOT) { /* FIXME J2K_DEC_STATE_TPHSOT)*/
7946                 opj_event_msg(p_manager, EVT_ERROR, "Need to decode the main header before begin to decode the remaining codestream");
7947                 return OPJ_FALSE;
7948         }
7949
7950         if ( !p_start_x && !p_start_y && !p_end_x && !p_end_y){
7951                 opj_event_msg(p_manager, EVT_INFO, "No decoded area parameters, set the decoded area to the whole image\n");
7952
7953                 p_j2k->m_specific_param.m_decoder.m_start_tile_x = 0;
7954                 p_j2k->m_specific_param.m_decoder.m_start_tile_y = 0;
7955                 p_j2k->m_specific_param.m_decoder.m_end_tile_x = l_cp->tw;
7956                 p_j2k->m_specific_param.m_decoder.m_end_tile_y = l_cp->th;
7957
7958                 return OPJ_TRUE;
7959         }
7960
7961         /* ----- */
7962         /* Check if the positions provided by the user are correct */
7963
7964         /* Left */
7965         assert(p_start_x >= 0 );
7966         assert(p_start_y >= 0 );
7967
7968         if ((OPJ_UINT32)p_start_x > l_image->x1 ) {
7969                 opj_event_msg(p_manager, EVT_ERROR,
7970                         "Left position of the decoded area (region_x0=%d) is outside the image area (Xsiz=%d).\n",
7971                         p_start_x, l_image->x1);
7972                 return OPJ_FALSE;
7973         }
7974         else if ((OPJ_UINT32)p_start_x < l_image->x0){
7975                 opj_event_msg(p_manager, EVT_WARNING,
7976                                 "Left position of the decoded area (region_x0=%d) is outside the image area (XOsiz=%d).\n",
7977                                 p_start_x, l_image->x0);
7978                 p_j2k->m_specific_param.m_decoder.m_start_tile_x = 0;
7979                 p_image->x0 = l_image->x0;
7980         }
7981         else {
7982                 p_j2k->m_specific_param.m_decoder.m_start_tile_x = (p_start_x - l_cp->tx0) / l_cp->tdx;
7983                 p_image->x0 = p_start_x;
7984         }
7985
7986         /* Up */
7987         if ((OPJ_UINT32)p_start_y > l_image->y1){
7988                 opj_event_msg(p_manager, EVT_ERROR,
7989                                 "Up position of the decoded area (region_y0=%d) is outside the image area (Ysiz=%d).\n",
7990                                 p_start_y, l_image->y1);
7991                 return OPJ_FALSE;
7992         }
7993         else if ((OPJ_UINT32)p_start_y < l_image->y0){
7994                 opj_event_msg(p_manager, EVT_WARNING,
7995                                 "Up position of the decoded area (region_y0=%d) is outside the image area (YOsiz=%d).\n",
7996                                 p_start_y, l_image->y0);
7997                 p_j2k->m_specific_param.m_decoder.m_start_tile_y = 0;
7998                 p_image->y0 = l_image->y0;
7999         }
8000         else {
8001                 p_j2k->m_specific_param.m_decoder.m_start_tile_y = (p_start_y - l_cp->ty0) / l_cp->tdy;
8002                 p_image->y0 = p_start_y;
8003         }
8004
8005         /* Right */
8006         assert((OPJ_UINT32)p_end_x > 0);
8007         assert((OPJ_UINT32)p_end_y > 0);
8008         if ((OPJ_UINT32)p_end_x < l_image->x0) {
8009                 opj_event_msg(p_manager, EVT_ERROR,
8010                         "Right position of the decoded area (region_x1=%d) is outside the image area (XOsiz=%d).\n",
8011                         p_end_x, l_image->x0);
8012                 return OPJ_FALSE;
8013         }
8014         else if ((OPJ_UINT32)p_end_x > l_image->x1) {
8015                 opj_event_msg(p_manager, EVT_WARNING,
8016                         "Right position of the decoded area (region_x1=%d) is outside the image area (Xsiz=%d).\n",
8017                         p_end_x, l_image->x1);
8018                 p_j2k->m_specific_param.m_decoder.m_end_tile_x = l_cp->tw;
8019                 p_image->x1 = l_image->x1;
8020         }
8021         else {
8022                 p_j2k->m_specific_param.m_decoder.m_end_tile_x = opj_int_ceildiv((p_end_x - l_cp->tx0), l_cp->tdx);
8023                 p_image->x1 = p_end_x;
8024         }
8025
8026         /* Bottom */
8027         if ((OPJ_UINT32)p_end_y < l_image->y0) {
8028                 opj_event_msg(p_manager, EVT_ERROR,
8029                         "Bottom position of the decoded area (region_y1=%d) is outside the image area (YOsiz=%d).\n",
8030                         p_end_y, l_image->y0);
8031                 return OPJ_FALSE;
8032         }
8033         if ((OPJ_UINT32)p_end_y > l_image->y1){
8034                 opj_event_msg(p_manager, EVT_WARNING,
8035                         "Bottom position of the decoded area (region_y1=%d) is outside the image area (Ysiz=%d).\n",
8036                         p_end_y, l_image->y1);
8037                 p_j2k->m_specific_param.m_decoder.m_end_tile_y = l_cp->th;
8038                 p_image->y1 = l_image->y1;
8039         }
8040         else{
8041                 p_j2k->m_specific_param.m_decoder.m_end_tile_y = opj_int_ceildiv((p_end_y - l_cp->ty0), l_cp->tdy);
8042                 p_image->y1 = p_end_y;
8043         }
8044         /* ----- */
8045
8046         p_j2k->m_specific_param.m_decoder.m_discard_tiles = 1;
8047
8048         l_img_comp = p_image->comps;
8049         for (it_comp=0; it_comp < p_image->numcomps; ++it_comp)
8050         {
8051                 OPJ_INT32 l_h,l_w;
8052
8053                 l_img_comp->x0 = opj_int_ceildiv(p_image->x0, l_img_comp->dx);
8054                 l_img_comp->y0 = opj_int_ceildiv(p_image->y0, l_img_comp->dy);
8055                 l_comp_x1 = opj_int_ceildiv(p_image->x1, l_img_comp->dx);
8056                 l_comp_y1 = opj_int_ceildiv(p_image->y1, l_img_comp->dy);
8057
8058                 l_w = opj_int_ceildivpow2(l_comp_x1, l_img_comp->factor)
8059                                 - opj_int_ceildivpow2(l_img_comp->x0, l_img_comp->factor);
8060                 if (l_w < 0){
8061                         opj_event_msg(p_manager, EVT_ERROR,
8062                                 "Size x of the decoded component image is incorrect (comp[%d].w=%d).\n",
8063                                 it_comp, l_w);
8064                         return OPJ_FALSE;
8065                 }
8066                 l_img_comp->w = l_w;
8067
8068                 l_h = opj_int_ceildivpow2(l_comp_y1, l_img_comp->factor)
8069                                 - opj_int_ceildivpow2(l_img_comp->y0, l_img_comp->factor);
8070                 if (l_h < 0){
8071                         opj_event_msg(p_manager, EVT_ERROR,
8072                                 "Size y of the decoded component image is incorrect (comp[%d].h=%d).\n",
8073                                 it_comp, l_h);
8074                         return OPJ_FALSE;
8075                 }
8076                 l_img_comp->h = l_h;
8077
8078                 l_img_comp++;
8079         }
8080
8081         opj_event_msg( p_manager, EVT_INFO,"Setting decoding area to %d,%d,%d,%d\n",
8082                         p_image->x0, p_image->y0, p_image->x1, p_image->y1);
8083
8084         return OPJ_TRUE;
8085 }
8086
8087 opj_j2k_t* opj_j2k_create_decompress(void)
8088 {
8089         opj_j2k_t *l_j2k = (opj_j2k_t*) opj_malloc(sizeof(opj_j2k_t));
8090         if (!l_j2k) {
8091                 return 00;
8092         }
8093         memset(l_j2k,0,sizeof(opj_j2k_t));
8094
8095         l_j2k->m_is_decoder = 1;
8096         l_j2k->m_cp.m_is_decoder = 1;
8097
8098         l_j2k->m_specific_param.m_decoder.m_default_tcp = (opj_tcp_t*) opj_malloc(sizeof(opj_tcp_t));
8099         if (!l_j2k->m_specific_param.m_decoder.m_default_tcp) {
8100                 opj_j2k_destroy(l_j2k);
8101                 return 00;
8102         }
8103         memset(l_j2k->m_specific_param.m_decoder.m_default_tcp,0,sizeof(opj_tcp_t));
8104
8105         l_j2k->m_specific_param.m_decoder.m_header_data = (OPJ_BYTE *) opj_malloc(OPJ_J2K_DEFAULT_HEADER_SIZE);
8106         if (! l_j2k->m_specific_param.m_decoder.m_header_data) {
8107                 opj_j2k_destroy(l_j2k);
8108                 return 00;
8109         }
8110
8111         l_j2k->m_specific_param.m_decoder.m_header_data_size = OPJ_J2K_DEFAULT_HEADER_SIZE;
8112
8113         l_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec = -1 ;
8114
8115         l_j2k->m_specific_param.m_decoder.m_last_sot_read_pos = 0 ;
8116
8117         /* codestream index creation */
8118         l_j2k->cstr_index = opj_j2k_create_cstr_index();
8119
8120                         /*(opj_codestream_index_t*) opj_malloc(sizeof(opj_codestream_index_t));
8121         if (!l_j2k->cstr_index){
8122                 opj_j2k_destroy(l_j2k);
8123                 return NULL;
8124         }
8125
8126         l_j2k->cstr_index->marker = (opj_marker_info_t*) opj_malloc(100 * sizeof(opj_marker_info_t));
8127 */
8128
8129         /* validation list creation */
8130         l_j2k->m_validation_list = opj_procedure_list_create();
8131         if (! l_j2k->m_validation_list) {
8132                 opj_j2k_destroy(l_j2k);
8133                 return 00;
8134         }
8135
8136         /* execution list creation */
8137         l_j2k->m_procedure_list = opj_procedure_list_create();
8138         if (! l_j2k->m_procedure_list) {
8139                 opj_j2k_destroy(l_j2k);
8140                 return 00;
8141         }
8142
8143         return l_j2k;
8144 }
8145
8146 opj_codestream_index_t* opj_j2k_create_cstr_index(void)
8147 {
8148         opj_codestream_index_t* cstr_index = (opj_codestream_index_t*)
8149                         opj_calloc(1,sizeof(opj_codestream_index_t));
8150         if (!cstr_index)
8151                 return NULL;
8152
8153         cstr_index->maxmarknum = 100;
8154         cstr_index->marknum = 0;
8155         cstr_index->marker = (opj_marker_info_t*)
8156                         opj_calloc(cstr_index->maxmarknum, sizeof(opj_marker_info_t));
8157         if (!cstr_index-> marker)
8158                 return NULL;
8159
8160         cstr_index->tile_index = NULL;
8161
8162         return cstr_index;
8163 }
8164
8165 OPJ_UINT32 opj_j2k_get_SPCod_SPCoc_size (       opj_j2k_t *p_j2k,
8166                                                                                 OPJ_UINT32 p_tile_no,
8167                                                                                 OPJ_UINT32 p_comp_no )
8168 {
8169         opj_cp_t *l_cp = 00;
8170         opj_tcp_t *l_tcp = 00;
8171         opj_tccp_t *l_tccp = 00;
8172
8173         /* preconditions */
8174         assert(p_j2k != 00);
8175
8176         l_cp = &(p_j2k->m_cp);
8177         l_tcp = &l_cp->tcps[p_tile_no];
8178         l_tccp = &l_tcp->tccps[p_comp_no];
8179
8180         /* preconditions again */
8181         assert(p_tile_no < (l_cp->tw * l_cp->th));
8182         assert(p_comp_no < p_j2k->m_private_image->numcomps);
8183
8184         if (l_tccp->csty & J2K_CCP_CSTY_PRT) {
8185                 return 5 + l_tccp->numresolutions;
8186         }
8187         else {
8188                 return 5;
8189         }
8190 }
8191
8192 OPJ_BOOL opj_j2k_write_SPCod_SPCoc(     opj_j2k_t *p_j2k,
8193                                                                     OPJ_UINT32 p_tile_no,
8194                                                                     OPJ_UINT32 p_comp_no,
8195                                                                     OPJ_BYTE * p_data,
8196                                                                     OPJ_UINT32 * p_header_size,
8197                                                                     struct opj_event_mgr * p_manager )
8198 {
8199         OPJ_UINT32 i;
8200         opj_cp_t *l_cp = 00;
8201         opj_tcp_t *l_tcp = 00;
8202         opj_tccp_t *l_tccp = 00;
8203
8204         /* preconditions */
8205         assert(p_j2k != 00);
8206         assert(p_header_size != 00);
8207         assert(p_manager != 00);
8208         assert(p_data != 00);
8209
8210         l_cp = &(p_j2k->m_cp);
8211         l_tcp = &l_cp->tcps[p_tile_no];
8212         l_tccp = &l_tcp->tccps[p_comp_no];
8213
8214         /* preconditions again */
8215         assert(p_tile_no < (l_cp->tw * l_cp->th));
8216         assert(p_comp_no <(p_j2k->m_private_image->numcomps));
8217
8218         if (*p_header_size < 5) {
8219                 opj_event_msg(p_manager, EVT_ERROR, "Error writing SPCod SPCoc element\n");
8220                 return OPJ_FALSE;
8221         }
8222
8223         opj_write_bytes(p_data,l_tccp->numresolutions - 1, 1);  /* SPcoc (D) */
8224         ++p_data;
8225
8226         opj_write_bytes(p_data,l_tccp->cblkw - 2, 1);                   /* SPcoc (E) */
8227         ++p_data;
8228
8229         opj_write_bytes(p_data,l_tccp->cblkh - 2, 1);                   /* SPcoc (F) */
8230         ++p_data;
8231
8232         opj_write_bytes(p_data,l_tccp->cblksty, 1);                             /* SPcoc (G) */
8233         ++p_data;
8234
8235         opj_write_bytes(p_data,l_tccp->qmfbid, 1);                              /* SPcoc (H) */
8236         ++p_data;
8237
8238         *p_header_size = *p_header_size - 5;
8239
8240         if (l_tccp->csty & J2K_CCP_CSTY_PRT) {
8241
8242                 if (*p_header_size < l_tccp->numresolutions) {
8243                         opj_event_msg(p_manager, EVT_ERROR, "Error writing SPCod SPCoc element\n");
8244                         return OPJ_FALSE;
8245                 }
8246
8247                 for (i = 0; i < l_tccp->numresolutions; ++i) {
8248                         opj_write_bytes(p_data,l_tccp->prcw[i] + (l_tccp->prch[i] << 4), 1);    /* SPcoc (I_i) */
8249                         ++p_data;
8250                 }
8251
8252                 *p_header_size = *p_header_size - l_tccp->numresolutions;
8253         }
8254
8255         return OPJ_TRUE;
8256 }
8257
8258 OPJ_BOOL opj_j2k_read_SPCod_SPCoc(  opj_j2k_t *p_j2k,
8259                                                                 OPJ_UINT32 compno,
8260                                                                 OPJ_BYTE * p_header_data,
8261                                                                 OPJ_UINT32 * p_header_size,
8262                                                                 opj_event_mgr_t * p_manager)
8263 {
8264         OPJ_UINT32 i, l_tmp;
8265         opj_cp_t *l_cp = NULL;
8266         opj_tcp_t *l_tcp = NULL;
8267         opj_tccp_t *l_tccp = NULL;
8268         OPJ_BYTE * l_current_ptr = NULL;
8269
8270         /* preconditions */
8271         assert(p_j2k != 00);
8272         assert(p_manager != 00);
8273         assert(p_header_data != 00);
8274
8275         l_cp = &(p_j2k->m_cp);
8276         l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH) ?
8277                                 &l_cp->tcps[p_j2k->m_current_tile_number] :
8278                                 p_j2k->m_specific_param.m_decoder.m_default_tcp;
8279
8280         /* precondition again */
8281         assert(compno < p_j2k->m_private_image->numcomps);
8282
8283         l_tccp = &l_tcp->tccps[compno];
8284         l_current_ptr = p_header_data;
8285
8286         /* make sure room is sufficient */
8287         if (*p_header_size < 5) {
8288                 opj_event_msg(p_manager, EVT_ERROR, "Error reading SPCod SPCoc element\n");
8289                 return OPJ_FALSE;
8290         }
8291
8292         opj_read_bytes(l_current_ptr, &l_tccp->numresolutions ,1);              /* SPcox (D) */
8293         ++l_tccp->numresolutions;                                                                               /* tccp->numresolutions = read() + 1 */
8294         if (l_tccp->numresolutions > OPJ_J2K_MAXRLVLS) {
8295                 opj_event_msg(p_manager, EVT_ERROR,
8296                               "Invalid value for numresolutions : %d, max value is set in openjpeg.h at %d\n",
8297                               l_tccp->numresolutions, OPJ_J2K_MAXRLVLS);
8298                 return OPJ_FALSE;
8299         }
8300         ++l_current_ptr;
8301
8302         /* If user wants to remove more resolutions than the codestream contains, return error */
8303         if (l_cp->m_specific_param.m_dec.m_reduce >= l_tccp->numresolutions) {
8304                 opj_event_msg(p_manager, EVT_ERROR, "Error decoding component %d.\nThe number of resolutions to remove is higher than the number "
8305                                         "of resolutions of this component\nModify the cp_reduce parameter.\n\n", compno);
8306                 p_j2k->m_specific_param.m_decoder.m_state |= 0x8000;/* FIXME J2K_DEC_STATE_ERR;*/
8307                 return OPJ_FALSE;
8308         }
8309
8310         opj_read_bytes(l_current_ptr,&l_tccp->cblkw ,1);                /* SPcoc (E) */
8311         ++l_current_ptr;
8312         l_tccp->cblkw += 2;
8313
8314         opj_read_bytes(l_current_ptr,&l_tccp->cblkh ,1);                /* SPcoc (F) */
8315         ++l_current_ptr;
8316         l_tccp->cblkh += 2;
8317
8318         opj_read_bytes(l_current_ptr,&l_tccp->cblksty ,1);              /* SPcoc (G) */
8319         ++l_current_ptr;
8320
8321         opj_read_bytes(l_current_ptr,&l_tccp->qmfbid ,1);               /* SPcoc (H) */
8322         ++l_current_ptr;
8323
8324         *p_header_size = *p_header_size - 5;
8325
8326         /* use custom precinct size ? */
8327         if (l_tccp->csty & J2K_CCP_CSTY_PRT) {
8328                 if (*p_header_size < l_tccp->numresolutions) {
8329                         opj_event_msg(p_manager, EVT_ERROR, "Error reading SPCod SPCoc element\n");
8330                         return OPJ_FALSE;
8331                 }
8332
8333                 for     (i = 0; i < l_tccp->numresolutions; ++i) {
8334                         opj_read_bytes(l_current_ptr,&l_tmp ,1);                /* SPcoc (I_i) */
8335                         ++l_current_ptr;
8336                         l_tccp->prcw[i] = l_tmp & 0xf;
8337                         l_tccp->prch[i] = l_tmp >> 4;
8338                 }
8339
8340                 *p_header_size = *p_header_size - l_tccp->numresolutions;
8341         }
8342         else {
8343                 /* set default size for the precinct width and height */
8344                 for     (i = 0; i < l_tccp->numresolutions; ++i) {
8345                         l_tccp->prcw[i] = 15;
8346                         l_tccp->prch[i] = 15;
8347                 }
8348         }
8349
8350 #ifdef WIP_REMOVE_MSD
8351         /* INDEX >> */
8352         if (p_j2k->cstr_info && compno == 0) {
8353                 OPJ_UINT32 l_data_size = l_tccp->numresolutions * sizeof(OPJ_UINT32);
8354
8355                 p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].tccp_info[compno].cblkh = l_tccp->cblkh;
8356                 p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].tccp_info[compno].cblkw = l_tccp->cblkw;
8357                 p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].tccp_info[compno].numresolutions = l_tccp->numresolutions;
8358                 p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].tccp_info[compno].cblksty = l_tccp->cblksty;
8359                 p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].tccp_info[compno].qmfbid = l_tccp->qmfbid;
8360
8361                 memcpy(p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].pdx,l_tccp->prcw, l_data_size);
8362                 memcpy(p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].pdy,l_tccp->prch, l_data_size);
8363         }
8364         /* << INDEX */
8365 #endif
8366
8367         return OPJ_TRUE;
8368 }
8369
8370 void opj_j2k_copy_tile_component_parameters( opj_j2k_t *p_j2k )
8371 {
8372         /* loop */
8373         OPJ_UINT32 i;
8374         opj_cp_t *l_cp = NULL;
8375         opj_tcp_t *l_tcp = NULL;
8376         opj_tccp_t *l_ref_tccp = NULL, *l_copied_tccp = NULL;
8377         OPJ_UINT32 l_prc_size;
8378
8379         /* preconditions */
8380         assert(p_j2k != 00);
8381
8382         l_cp = &(p_j2k->m_cp);
8383         l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH) ? /* FIXME J2K_DEC_STATE_TPH*/
8384                                 &l_cp->tcps[p_j2k->m_current_tile_number] :
8385                                 p_j2k->m_specific_param.m_decoder.m_default_tcp;
8386
8387         l_ref_tccp = &l_tcp->tccps[0];
8388         l_copied_tccp = l_ref_tccp + 1;
8389         l_prc_size = l_ref_tccp->numresolutions * (OPJ_UINT32)sizeof(OPJ_UINT32);
8390
8391         for     (i=1; i<p_j2k->m_private_image->numcomps; ++i) {
8392                 l_copied_tccp->numresolutions = l_ref_tccp->numresolutions;
8393                 l_copied_tccp->cblkw = l_ref_tccp->cblkw;
8394                 l_copied_tccp->cblkh = l_ref_tccp->cblkh;
8395                 l_copied_tccp->cblksty = l_ref_tccp->cblksty;
8396                 l_copied_tccp->qmfbid = l_ref_tccp->qmfbid;
8397                 memcpy(l_copied_tccp->prcw,l_ref_tccp->prcw,l_prc_size);
8398                 memcpy(l_copied_tccp->prch,l_ref_tccp->prch,l_prc_size);
8399                 ++l_copied_tccp;
8400         }
8401 }
8402
8403 OPJ_UINT32 opj_j2k_get_SQcd_SQcc_size ( opj_j2k_t *p_j2k,
8404                                                                         OPJ_UINT32 p_tile_no,
8405                                                                         OPJ_UINT32 p_comp_no )
8406 {
8407         OPJ_UINT32 l_num_bands;
8408
8409         opj_cp_t *l_cp = 00;
8410         opj_tcp_t *l_tcp = 00;
8411         opj_tccp_t *l_tccp = 00;
8412
8413         /* preconditions */
8414         assert(p_j2k != 00);
8415
8416         l_cp = &(p_j2k->m_cp);
8417         l_tcp = &l_cp->tcps[p_tile_no];
8418         l_tccp = &l_tcp->tccps[p_comp_no];
8419
8420         /* preconditions again */
8421         assert(p_tile_no < l_cp->tw * l_cp->th);
8422         assert(p_comp_no < p_j2k->m_private_image->numcomps);
8423
8424         l_num_bands = (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? 1 : (l_tccp->numresolutions * 3 - 2);
8425
8426         if (l_tccp->qntsty == J2K_CCP_QNTSTY_NOQNT)  {
8427                 return 1 + l_num_bands;
8428         }
8429         else {
8430                 return 1 + 2*l_num_bands;
8431         }
8432 }
8433
8434 OPJ_BOOL opj_j2k_write_SQcd_SQcc(       opj_j2k_t *p_j2k,
8435                                                                 OPJ_UINT32 p_tile_no,
8436                                                                 OPJ_UINT32 p_comp_no,
8437                                                                 OPJ_BYTE * p_data,
8438                                                                 OPJ_UINT32 * p_header_size,
8439                                                                 struct opj_event_mgr * p_manager )
8440 {
8441         OPJ_UINT32 l_header_size;
8442         OPJ_UINT32 l_band_no, l_num_bands;
8443         OPJ_UINT32 l_expn,l_mant;
8444
8445         opj_cp_t *l_cp = 00;
8446         opj_tcp_t *l_tcp = 00;
8447         opj_tccp_t *l_tccp = 00;
8448
8449         /* preconditions */
8450         assert(p_j2k != 00);
8451         assert(p_header_size != 00);
8452         assert(p_manager != 00);
8453         assert(p_data != 00);
8454
8455         l_cp = &(p_j2k->m_cp);
8456         l_tcp = &l_cp->tcps[p_tile_no];
8457         l_tccp = &l_tcp->tccps[p_comp_no];
8458
8459         /* preconditions again */
8460         assert(p_tile_no < l_cp->tw * l_cp->th);
8461         assert(p_comp_no <p_j2k->m_private_image->numcomps);
8462
8463         l_num_bands = (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? 1 : (l_tccp->numresolutions * 3 - 2);
8464
8465         if (l_tccp->qntsty == J2K_CCP_QNTSTY_NOQNT)  {
8466                 l_header_size = 1 + l_num_bands;
8467
8468                 if (*p_header_size < l_header_size) {
8469                         opj_event_msg(p_manager, EVT_ERROR, "Error writing SQcd SQcc element\n");
8470                         return OPJ_FALSE;
8471                 }
8472
8473                 opj_write_bytes(p_data,l_tccp->qntsty + (l_tccp->numgbits << 5), 1);    /* Sqcx */
8474                 ++p_data;
8475
8476                 for (l_band_no = 0; l_band_no < l_num_bands; ++l_band_no) {
8477                         l_expn = l_tccp->stepsizes[l_band_no].expn;
8478                         opj_write_bytes(p_data, l_expn << 3, 1);        /* SPqcx_i */
8479                         ++p_data;
8480                 }
8481         }
8482         else {
8483                 l_header_size = 1 + 2*l_num_bands;
8484
8485                 if (*p_header_size < l_header_size) {
8486                         opj_event_msg(p_manager, EVT_ERROR, "Error writing SQcd SQcc element\n");
8487                         return OPJ_FALSE;
8488                 }
8489
8490                 opj_write_bytes(p_data,l_tccp->qntsty + (l_tccp->numgbits << 5), 1);    /* Sqcx */
8491                 ++p_data;
8492
8493                 for (l_band_no = 0; l_band_no < l_num_bands; ++l_band_no) {
8494                         l_expn = l_tccp->stepsizes[l_band_no].expn;
8495                         l_mant = l_tccp->stepsizes[l_band_no].mant;
8496
8497                         opj_write_bytes(p_data, (l_expn << 11) + l_mant, 2);    /* SPqcx_i */
8498                         p_data += 2;
8499                 }
8500         }
8501
8502         *p_header_size = *p_header_size - l_header_size;
8503
8504         return OPJ_TRUE;
8505 }
8506
8507 OPJ_BOOL opj_j2k_read_SQcd_SQcc(opj_j2k_t *p_j2k,
8508                                                             OPJ_UINT32 p_comp_no,
8509                                                             OPJ_BYTE* p_header_data,
8510                                                             OPJ_UINT32 * p_header_size,
8511                                                             opj_event_mgr_t * p_manager
8512                                                             )
8513 {
8514         /* loop*/
8515         OPJ_UINT32 l_band_no;
8516         opj_cp_t *l_cp = 00;
8517         opj_tcp_t *l_tcp = 00;
8518         opj_tccp_t *l_tccp = 00;
8519         OPJ_BYTE * l_current_ptr = 00;
8520         OPJ_UINT32 l_tmp, l_num_band;
8521
8522         /* preconditions*/
8523         assert(p_j2k != 00);
8524         assert(p_manager != 00);
8525         assert(p_header_data != 00);
8526
8527         l_cp = &(p_j2k->m_cp);
8528         /* come from tile part header or main header ?*/
8529         l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH) ? /*FIXME J2K_DEC_STATE_TPH*/
8530                                 &l_cp->tcps[p_j2k->m_current_tile_number] :
8531                                 p_j2k->m_specific_param.m_decoder.m_default_tcp;
8532
8533         /* precondition again*/
8534         assert(p_comp_no <  p_j2k->m_private_image->numcomps);
8535
8536         l_tccp = &l_tcp->tccps[p_comp_no];
8537         l_current_ptr = p_header_data;
8538
8539         if (*p_header_size < 1) {
8540                 opj_event_msg(p_manager, EVT_ERROR, "Error reading SQcd or SQcc element\n");
8541                 return OPJ_FALSE;
8542         }
8543         *p_header_size -= 1;
8544
8545         opj_read_bytes(l_current_ptr, &l_tmp ,1);                       /* Sqcx */
8546         ++l_current_ptr;
8547
8548         l_tccp->qntsty = l_tmp & 0x1f;
8549         l_tccp->numgbits = l_tmp >> 5;
8550         if (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) {
8551         l_num_band = 1;
8552         }
8553         else {
8554                 l_num_band = (l_tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) ?
8555                         (*p_header_size) :
8556                         (*p_header_size) / 2;
8557
8558                 if( l_num_band > OPJ_J2K_MAXBANDS ) {
8559                         opj_event_msg(p_manager, EVT_WARNING, "While reading CCP_QNTSTY element inside QCD or QCC marker segment, "
8560                                 "number of subbands (%d) is greater to OPJ_J2K_MAXBANDS (%d). So we limit the number of elements stored to "
8561                                 "OPJ_J2K_MAXBANDS (%d) and skip the rest. \n", l_num_band, OPJ_J2K_MAXBANDS, OPJ_J2K_MAXBANDS);
8562                         /*return OPJ_FALSE;*/
8563                 }
8564         }
8565
8566 #ifdef USE_JPWL
8567         if (l_cp->correct) {
8568
8569                 /* if JPWL is on, we check whether there are too many subbands */
8570                 if (/*(l_num_band < 0) ||*/ (l_num_band >= OPJ_J2K_MAXBANDS)) {
8571                         opj_event_msg(p_manager, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
8572                                 "JPWL: bad number of subbands in Sqcx (%d)\n",
8573                                 l_num_band);
8574                         if (!JPWL_ASSUME) {
8575                                 opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
8576                                 return OPJ_FALSE;
8577                         }
8578                         /* we try to correct */
8579                         l_num_band = 1;
8580                         opj_event_msg(p_manager, EVT_WARNING, "- trying to adjust them\n"
8581                                 "- setting number of bands to %d => HYPOTHESIS!!!\n",
8582                                 l_num_band);
8583                 };
8584
8585         };
8586 #endif /* USE_JPWL */
8587
8588         if (l_tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) {
8589                 for     (l_band_no = 0; l_band_no < l_num_band; l_band_no++) {
8590                         opj_read_bytes(l_current_ptr, &l_tmp ,1);                       /* SPqcx_i */
8591                         ++l_current_ptr;
8592                         if (l_band_no < OPJ_J2K_MAXBANDS){
8593                                 l_tccp->stepsizes[l_band_no].expn = l_tmp>>3;
8594                                 l_tccp->stepsizes[l_band_no].mant = 0;
8595                         }
8596                 }
8597                 *p_header_size = *p_header_size - l_num_band;
8598         }
8599         else {
8600                 for     (l_band_no = 0; l_band_no < l_num_band; l_band_no++) {
8601                         opj_read_bytes(l_current_ptr, &l_tmp ,2);                       /* SPqcx_i */
8602                         l_current_ptr+=2;
8603                         if (l_band_no < OPJ_J2K_MAXBANDS){
8604                                 l_tccp->stepsizes[l_band_no].expn = l_tmp >> 11;
8605                                 l_tccp->stepsizes[l_band_no].mant = l_tmp & 0x7ff;
8606                         }
8607                 }
8608                 *p_header_size = *p_header_size - 2*l_num_band;
8609         }
8610
8611         /* Add Antonin : if scalar_derived -> compute other stepsizes */
8612         if (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) {
8613                 for (l_band_no = 1; l_band_no < OPJ_J2K_MAXBANDS; l_band_no++) {
8614                         l_tccp->stepsizes[l_band_no].expn =
8615                                 ((l_tccp->stepsizes[0].expn) - ((l_band_no - 1) / 3) > 0) ?
8616                                         (l_tccp->stepsizes[0].expn) - ((l_band_no - 1) / 3) : 0;
8617                         l_tccp->stepsizes[l_band_no].mant = l_tccp->stepsizes[0].mant;
8618                 }
8619         }
8620
8621         return OPJ_TRUE;
8622 }
8623
8624 void opj_j2k_copy_tile_quantization_parameters( opj_j2k_t *p_j2k )
8625 {
8626         OPJ_UINT32 i;
8627         opj_cp_t *l_cp = NULL;
8628         opj_tcp_t *l_tcp = NULL;
8629         opj_tccp_t *l_ref_tccp = NULL;
8630         opj_tccp_t *l_copied_tccp = NULL;
8631         OPJ_UINT32 l_size;
8632
8633         /* preconditions */
8634         assert(p_j2k != 00);
8635
8636         l_cp = &(p_j2k->m_cp);
8637         l_tcp = p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH ?
8638                         &l_cp->tcps[p_j2k->m_current_tile_number] :
8639                         p_j2k->m_specific_param.m_decoder.m_default_tcp;
8640
8641         l_ref_tccp = &l_tcp->tccps[0];
8642         l_copied_tccp = l_ref_tccp + 1;
8643         l_size = OPJ_J2K_MAXBANDS * sizeof(opj_stepsize_t);
8644
8645         for     (i=1;i<p_j2k->m_private_image->numcomps;++i) {
8646                 l_copied_tccp->qntsty = l_ref_tccp->qntsty;
8647                 l_copied_tccp->numgbits = l_ref_tccp->numgbits;
8648                 memcpy(l_copied_tccp->stepsizes,l_ref_tccp->stepsizes,l_size);
8649                 ++l_copied_tccp;
8650         }
8651 }
8652
8653 void j2k_dump (opj_j2k_t* p_j2k, OPJ_INT32 flag, FILE* out_stream)
8654 {
8655         /* Check if the flag is compatible with j2k file*/
8656         if ( (flag & OPJ_JP2_INFO) || (flag & OPJ_JP2_IND)){
8657                 fprintf(out_stream, "Wrong flag\n");
8658                 return;
8659         }
8660
8661         /* Dump the image_header */
8662         if (flag & OPJ_IMG_INFO){
8663                 if (p_j2k->m_private_image)
8664                         j2k_dump_image_header(p_j2k->m_private_image, 0, out_stream);
8665         }
8666
8667         /* Dump the codestream info from main header */
8668         if (flag & OPJ_J2K_MH_INFO){
8669                 opj_j2k_dump_MH_info(p_j2k, out_stream);
8670         }
8671
8672         /* Dump the codestream info of the current tile */
8673         if (flag & OPJ_J2K_TH_INFO){
8674
8675         }
8676
8677         /* Dump the codestream index from main header */
8678         if (flag & OPJ_J2K_MH_IND){
8679                 opj_j2k_dump_MH_index(p_j2k, out_stream);
8680         }
8681
8682         /* Dump the codestream index of the current tile */
8683         if (flag & OPJ_J2K_TH_IND){
8684
8685         }
8686
8687 }
8688
8689 void opj_j2k_dump_MH_index(opj_j2k_t* p_j2k, FILE* out_stream)
8690 {
8691         opj_codestream_index_t* cstr_index = p_j2k->cstr_index;
8692         OPJ_UINT32 it_marker, it_tile, it_tile_part;
8693
8694         fprintf(out_stream, "Codestream index from main header: {\n");
8695
8696         fprintf(out_stream, "\t Main header start position=%" PRIi64 "\n"
8697                                     "\t Main header end position=%" PRIi64 "\n",
8698                         cstr_index->main_head_start, cstr_index->main_head_end);
8699
8700         fprintf(out_stream, "\t Marker list: {\n");
8701
8702         if (cstr_index->marker){
8703                 for (it_marker=0; it_marker < cstr_index->marknum ; it_marker++){
8704                         fprintf(out_stream, "\t\t type=%#x, pos=%" PRIi64 ", len=%d\n",
8705                                         cstr_index->marker[it_marker].type,
8706                                         cstr_index->marker[it_marker].pos,
8707                                         cstr_index->marker[it_marker].len );
8708                 }
8709         }
8710
8711         fprintf(out_stream, "\t }\n");
8712
8713         if (cstr_index->tile_index){
8714
8715         /* Simple test to avoid to write empty information*/
8716         OPJ_UINT32 l_acc_nb_of_tile_part = 0;
8717         for (it_tile=0; it_tile < cstr_index->nb_of_tiles ; it_tile++){
8718                         l_acc_nb_of_tile_part += cstr_index->tile_index[it_tile].nb_tps;
8719         }
8720
8721         if (l_acc_nb_of_tile_part)
8722         {
8723             fprintf(out_stream, "\t Tile index: {\n");
8724
8725                     for (it_tile=0; it_tile < cstr_index->nb_of_tiles ; it_tile++){
8726                             OPJ_UINT32 nb_of_tile_part = cstr_index->tile_index[it_tile].nb_tps;
8727
8728                             fprintf(out_stream, "\t\t nb of tile-part in tile [%d]=%d\n", it_tile, nb_of_tile_part);
8729
8730                             if (cstr_index->tile_index[it_tile].tp_index){
8731                                     for (it_tile_part =0; it_tile_part < nb_of_tile_part; it_tile_part++){
8732                                             fprintf(out_stream, "\t\t\t tile-part[%d]: star_pos=%" PRIi64 ", end_header=%" PRIi64 ", end_pos=%" PRIi64 ".\n",
8733                                                             it_tile_part,
8734                                                             cstr_index->tile_index[it_tile].tp_index[it_tile_part].start_pos,
8735                                                             cstr_index->tile_index[it_tile].tp_index[it_tile_part].end_header,
8736                                                             cstr_index->tile_index[it_tile].tp_index[it_tile_part].end_pos);
8737                                     }
8738                             }
8739
8740                             if (cstr_index->tile_index[it_tile].marker){
8741                                     for (it_marker=0; it_marker < cstr_index->tile_index[it_tile].marknum ; it_marker++){
8742                                             fprintf(out_stream, "\t\t type=%#x, pos=%" PRIi64 ", len=%d\n",
8743                                                             cstr_index->tile_index[it_tile].marker[it_marker].type,
8744                                                             cstr_index->tile_index[it_tile].marker[it_marker].pos,
8745                                                             cstr_index->tile_index[it_tile].marker[it_marker].len );
8746                                     }
8747                             }
8748                     }
8749                     fprintf(out_stream,"\t }\n");
8750         }
8751         }
8752
8753         fprintf(out_stream,"}\n");
8754
8755 }
8756
8757 void opj_j2k_dump_MH_info(opj_j2k_t* p_j2k, FILE* out_stream)
8758 {
8759         opj_tcp_t * l_default_tile=NULL;
8760
8761         fprintf(out_stream, "Codestream info from main header: {\n");
8762
8763         fprintf(out_stream, "\t tx0=%d, ty0=%d\n", p_j2k->m_cp.tx0, p_j2k->m_cp.ty0);
8764         fprintf(out_stream, "\t tdx=%d, tdy=%d\n", p_j2k->m_cp.tdx, p_j2k->m_cp.tdy);
8765         fprintf(out_stream, "\t tw=%d, th=%d\n", p_j2k->m_cp.tw, p_j2k->m_cp.th);
8766
8767         l_default_tile = p_j2k->m_specific_param.m_decoder.m_default_tcp;
8768         if (l_default_tile)
8769         {
8770                 OPJ_INT32 compno;
8771                 OPJ_INT32 numcomps = p_j2k->m_private_image->numcomps;
8772
8773                 fprintf(out_stream, "\t default tile {\n");
8774                 fprintf(out_stream, "\t\t csty=%#x\n", l_default_tile->csty);
8775                 fprintf(out_stream, "\t\t prg=%#x\n", l_default_tile->prg);
8776                 fprintf(out_stream, "\t\t numlayers=%d\n", l_default_tile->numlayers);
8777                 fprintf(out_stream, "\t\t mct=%x\n", l_default_tile->mct);
8778
8779                 for (compno = 0; compno < numcomps; compno++) {
8780                         opj_tccp_t *l_tccp = &(l_default_tile->tccps[compno]);
8781                         OPJ_UINT32 resno;
8782       OPJ_INT32 bandno, numbands;
8783
8784                         /* coding style*/
8785                         fprintf(out_stream, "\t\t comp %d {\n", compno);
8786                         fprintf(out_stream, "\t\t\t csty=%#x\n", l_tccp->csty);
8787                         fprintf(out_stream, "\t\t\t numresolutions=%d\n", l_tccp->numresolutions);
8788                         fprintf(out_stream, "\t\t\t cblkw=2^%d\n", l_tccp->cblkw);
8789                         fprintf(out_stream, "\t\t\t cblkh=2^%d\n", l_tccp->cblkh);
8790                         fprintf(out_stream, "\t\t\t cblksty=%#x\n", l_tccp->cblksty);
8791                         fprintf(out_stream, "\t\t\t qmfbid=%d\n", l_tccp->qmfbid);
8792
8793                         fprintf(out_stream, "\t\t\t preccintsize (w,h)=");
8794                         for (resno = 0; resno < l_tccp->numresolutions; resno++) {
8795                                 fprintf(out_stream, "(%d,%d) ", l_tccp->prcw[resno], l_tccp->prch[resno]);
8796                         }
8797                         fprintf(out_stream, "\n");
8798
8799                         /* quantization style*/
8800                         fprintf(out_stream, "\t\t\t qntsty=%d\n", l_tccp->qntsty);
8801                         fprintf(out_stream, "\t\t\t numgbits=%d\n", l_tccp->numgbits);
8802                         fprintf(out_stream, "\t\t\t stepsizes (m,e)=");
8803                         numbands = (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? 1 : l_tccp->numresolutions * 3 - 2;
8804                         for (bandno = 0; bandno < numbands; bandno++) {
8805                                 fprintf(out_stream, "(%d,%d) ", l_tccp->stepsizes[bandno].mant,
8806                                         l_tccp->stepsizes[bandno].expn);
8807                         }
8808                         fprintf(out_stream, "\n");
8809
8810                         /* RGN value*/
8811                         fprintf(out_stream, "\t\t\t roishift=%d\n", l_tccp->roishift);
8812
8813                         fprintf(out_stream, "\t\t }\n");
8814                 } /*end of component of default tile*/
8815                 fprintf(out_stream, "\t }\n"); /*end of default tile*/
8816
8817         }
8818
8819         fprintf(out_stream, "}\n");
8820
8821 }
8822
8823 void j2k_dump_image_header(opj_image_t* img_header, OPJ_BOOL dev_dump_flag, FILE* out_stream)
8824 {
8825         char tab[2];
8826
8827         if (dev_dump_flag){
8828                 fprintf(stdout, "[DEV] Dump an image_header struct {\n");
8829                 tab[0] = '\0';
8830         }
8831         else {
8832                 fprintf(out_stream, "Image info {\n");
8833                 tab[0] = '\t';tab[1] = '\0';
8834         }
8835
8836         fprintf(out_stream, "%s x0=%d, y0=%d\n", tab, img_header->x0, img_header->y0);
8837         fprintf(out_stream,     "%s x1=%d, y1=%d\n", tab, img_header->x1, img_header->y1);
8838         fprintf(out_stream, "%s numcomps=%d\n", tab, img_header->numcomps);
8839
8840         if (img_header->comps){
8841                 OPJ_UINT32 compno;
8842                 for (compno = 0; compno < img_header->numcomps; compno++) {
8843                         fprintf(out_stream, "%s\t component %d {\n", tab, compno);
8844                         j2k_dump_image_comp_header(&(img_header->comps[compno]), dev_dump_flag, out_stream);
8845                         fprintf(out_stream,"%s}\n",tab);
8846                 }
8847         }
8848
8849         fprintf(out_stream, "}\n");
8850 }
8851
8852 void j2k_dump_image_comp_header(opj_image_comp_t* comp_header, OPJ_BOOL dev_dump_flag, FILE* out_stream)
8853 {
8854         char tab[3];
8855
8856         if (dev_dump_flag){
8857                 fprintf(stdout, "[DEV] Dump an image_comp_header struct {\n");
8858                 tab[0] = '\0';
8859         }       else {
8860                 tab[0] = '\t';tab[1] = '\t';tab[2] = '\0';
8861         }
8862
8863         fprintf(out_stream, "%s dx=%d, dy=%d\n", tab, comp_header->dx, comp_header->dy);
8864         fprintf(out_stream, "%s prec=%d\n", tab, comp_header->prec);
8865         fprintf(out_stream, "%s sgnd=%d\n", tab, comp_header->sgnd);
8866
8867         if (dev_dump_flag)
8868                 fprintf(out_stream, "}\n");
8869 }
8870
8871 opj_codestream_info_v2_t* j2k_get_cstr_info(opj_j2k_t* p_j2k)
8872 {
8873         OPJ_UINT32 compno;
8874         OPJ_UINT32 numcomps = p_j2k->m_private_image->numcomps;
8875         opj_tcp_t *l_default_tile;
8876         opj_codestream_info_v2_t* cstr_info = (opj_codestream_info_v2_t*) opj_calloc(1,sizeof(opj_codestream_info_v2_t));
8877                 if (!cstr_info)
8878                         return NULL;
8879
8880         cstr_info->nbcomps = p_j2k->m_private_image->numcomps;
8881
8882         cstr_info->tx0 = p_j2k->m_cp.tx0;
8883         cstr_info->ty0 = p_j2k->m_cp.ty0;
8884         cstr_info->tdx = p_j2k->m_cp.tdx;
8885         cstr_info->tdy = p_j2k->m_cp.tdy;
8886         cstr_info->tw = p_j2k->m_cp.tw;
8887         cstr_info->th = p_j2k->m_cp.th;
8888
8889         cstr_info->tile_info = NULL; /* Not fill from the main header*/
8890
8891         l_default_tile = p_j2k->m_specific_param.m_decoder.m_default_tcp;
8892
8893         cstr_info->m_default_tile_info.csty = l_default_tile->csty;
8894         cstr_info->m_default_tile_info.prg = l_default_tile->prg;
8895         cstr_info->m_default_tile_info.numlayers = l_default_tile->numlayers;
8896         cstr_info->m_default_tile_info.mct = l_default_tile->mct;
8897
8898         cstr_info->m_default_tile_info.tccp_info = (opj_tccp_info_t*) opj_calloc(cstr_info->nbcomps, sizeof(opj_tccp_info_t));
8899                 if (!cstr_info->m_default_tile_info.tccp_info)
8900                 {
8901                         opj_destroy_cstr_info(&cstr_info);
8902                         return NULL;
8903                 }
8904
8905         for (compno = 0; compno < numcomps; compno++) {
8906                 opj_tccp_t *l_tccp = &(l_default_tile->tccps[compno]);
8907                 opj_tccp_info_t *l_tccp_info = &(cstr_info->m_default_tile_info.tccp_info[compno]);
8908                 OPJ_INT32 bandno, numbands;
8909
8910                 /* coding style*/
8911                 l_tccp_info->csty = l_tccp->csty;
8912                 l_tccp_info->numresolutions = l_tccp->numresolutions;
8913                 l_tccp_info->cblkw = l_tccp->cblkw;
8914                 l_tccp_info->cblkh = l_tccp->cblkh;
8915                 l_tccp_info->cblksty = l_tccp->cblksty;
8916                 l_tccp_info->qmfbid = l_tccp->qmfbid;
8917                 if (l_tccp->numresolutions < OPJ_J2K_MAXRLVLS)
8918                 {
8919                         memcpy(l_tccp_info->prch, l_tccp->prch, l_tccp->numresolutions);
8920                         memcpy(l_tccp_info->prcw, l_tccp->prcw, l_tccp->numresolutions);
8921                 }
8922
8923                 /* quantization style*/
8924                 l_tccp_info->qntsty = l_tccp->qntsty;
8925                 l_tccp_info->numgbits = l_tccp->numgbits;
8926
8927                 numbands = (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? 1 : l_tccp->numresolutions * 3 - 2;
8928                 if (numbands < OPJ_J2K_MAXBANDS) {
8929                         for (bandno = 0; bandno < numbands; bandno++) {
8930                                 l_tccp_info->stepsizes_mant[bandno] = l_tccp->stepsizes[bandno].mant;
8931                                 l_tccp_info->stepsizes_expn[bandno] = l_tccp->stepsizes[bandno].expn;
8932                         }
8933                 }
8934
8935                 /* RGN value*/
8936                 l_tccp_info->roishift = l_tccp->roishift;
8937         }
8938
8939         return cstr_info;
8940 }
8941
8942 opj_codestream_index_t* j2k_get_cstr_index(opj_j2k_t* p_j2k)
8943 {
8944         opj_codestream_index_t* l_cstr_index = (opj_codestream_index_t*)
8945                         opj_calloc(1,sizeof(opj_codestream_index_t));
8946         if (!l_cstr_index)
8947                 return NULL;
8948
8949         l_cstr_index->main_head_start = p_j2k->cstr_index->main_head_start;
8950         l_cstr_index->main_head_end = p_j2k->cstr_index->main_head_end;
8951         l_cstr_index->codestream_size = p_j2k->cstr_index->codestream_size;
8952
8953         l_cstr_index->marknum = p_j2k->cstr_index->marknum;
8954         l_cstr_index->marker = (opj_marker_info_t*)opj_malloc(l_cstr_index->marknum*sizeof(opj_marker_info_t));
8955         if (!l_cstr_index->marker){
8956                 opj_free( l_cstr_index);
8957                 return NULL;
8958         }
8959
8960         if (p_j2k->cstr_index->marker)
8961                 memcpy(l_cstr_index->marker, p_j2k->cstr_index->marker, l_cstr_index->marknum * sizeof(opj_marker_info_t) );
8962         else{
8963                 opj_free(l_cstr_index->marker);
8964                 l_cstr_index->marker = NULL;
8965         }
8966
8967         l_cstr_index->nb_of_tiles = p_j2k->cstr_index->nb_of_tiles;
8968         l_cstr_index->tile_index = (opj_tile_index_t*)opj_calloc(l_cstr_index->nb_of_tiles, sizeof(opj_tile_index_t) );
8969         if (!l_cstr_index->tile_index){
8970                 opj_free( l_cstr_index->marker);
8971                 opj_free( l_cstr_index);
8972                 return NULL;
8973         }
8974
8975         if (!p_j2k->cstr_index->tile_index){
8976                 opj_free(l_cstr_index->tile_index);
8977                 l_cstr_index->tile_index = NULL;
8978         }
8979         else {
8980                 OPJ_UINT32 it_tile = 0;
8981                 for (it_tile = 0; it_tile < l_cstr_index->nb_of_tiles; it_tile++ ){
8982
8983                         /* Tile Marker*/
8984                         l_cstr_index->tile_index[it_tile].marknum = p_j2k->cstr_index->tile_index[it_tile].marknum;
8985
8986                         l_cstr_index->tile_index[it_tile].marker =
8987                                 (opj_marker_info_t*)opj_malloc(l_cstr_index->tile_index[it_tile].marknum*sizeof(opj_marker_info_t));
8988
8989                         if (!l_cstr_index->tile_index[it_tile].marker) {
8990                                 OPJ_UINT32 it_tile_free;
8991
8992                                 for (it_tile_free=0; it_tile_free < it_tile; it_tile_free++){
8993                                         opj_free(l_cstr_index->tile_index[it_tile_free].marker);
8994                                 }
8995
8996                                 opj_free( l_cstr_index->tile_index);
8997                                 opj_free( l_cstr_index->marker);
8998                                 opj_free( l_cstr_index);
8999                                 return NULL;
9000                         }
9001
9002                         if (p_j2k->cstr_index->tile_index[it_tile].marker)
9003                                 memcpy( l_cstr_index->tile_index[it_tile].marker,
9004                                                 p_j2k->cstr_index->tile_index[it_tile].marker,
9005                                                 l_cstr_index->tile_index[it_tile].marknum * sizeof(opj_marker_info_t) );
9006                         else{
9007                                 opj_free(l_cstr_index->tile_index[it_tile].marker);
9008                                 l_cstr_index->tile_index[it_tile].marker = NULL;
9009                         }
9010
9011                         /* Tile part index*/
9012                         l_cstr_index->tile_index[it_tile].nb_tps = p_j2k->cstr_index->tile_index[it_tile].nb_tps;
9013
9014                         l_cstr_index->tile_index[it_tile].tp_index =
9015                                 (opj_tp_index_t*)opj_malloc(l_cstr_index->tile_index[it_tile].nb_tps*sizeof(opj_tp_index_t));
9016
9017                         if(!l_cstr_index->tile_index[it_tile].tp_index){
9018                                 OPJ_UINT32 it_tile_free;
9019
9020                                 for (it_tile_free=0; it_tile_free < it_tile; it_tile_free++){
9021                                         opj_free(l_cstr_index->tile_index[it_tile_free].marker);
9022                                         opj_free(l_cstr_index->tile_index[it_tile_free].tp_index);
9023                                 }
9024
9025                                 opj_free( l_cstr_index->tile_index);
9026                                 opj_free( l_cstr_index->marker);
9027                                 opj_free( l_cstr_index);
9028                                 return NULL;
9029                         }
9030
9031                         if (p_j2k->cstr_index->tile_index[it_tile].tp_index){
9032                                 memcpy( l_cstr_index->tile_index[it_tile].tp_index,
9033                                                 p_j2k->cstr_index->tile_index[it_tile].tp_index,
9034                                                 l_cstr_index->tile_index[it_tile].nb_tps * sizeof(opj_tp_index_t) );
9035                         }
9036                         else{
9037                                 opj_free(l_cstr_index->tile_index[it_tile].tp_index);
9038                                 l_cstr_index->tile_index[it_tile].tp_index = NULL;
9039                         }
9040
9041                         /* Packet index (NOT USED)*/
9042                         l_cstr_index->tile_index[it_tile].nb_packet = 0;
9043                         l_cstr_index->tile_index[it_tile].packet_index = NULL;
9044
9045                 }
9046         }
9047
9048         return l_cstr_index;
9049 }
9050
9051 OPJ_BOOL opj_j2k_allocate_tile_element_cstr_index(opj_j2k_t *p_j2k)
9052 {
9053         OPJ_UINT32 it_tile=0;
9054
9055         p_j2k->cstr_index->nb_of_tiles = p_j2k->m_cp.tw * p_j2k->m_cp.th;
9056         p_j2k->cstr_index->tile_index = (opj_tile_index_t*)opj_calloc(p_j2k->cstr_index->nb_of_tiles, sizeof(opj_tile_index_t));
9057         if (!p_j2k->cstr_index->tile_index)
9058                 return OPJ_FALSE;
9059
9060         for (it_tile=0; it_tile < p_j2k->cstr_index->nb_of_tiles; it_tile++){
9061                 p_j2k->cstr_index->tile_index[it_tile].maxmarknum = 100;
9062                 p_j2k->cstr_index->tile_index[it_tile].marknum = 0;
9063                 p_j2k->cstr_index->tile_index[it_tile].marker = (opj_marker_info_t*)
9064                                 opj_calloc(p_j2k->cstr_index->tile_index[it_tile].maxmarknum, sizeof(opj_marker_info_t));
9065                 if (!p_j2k->cstr_index->tile_index[it_tile].marker)
9066                         return OPJ_FALSE;
9067         }
9068
9069         return OPJ_TRUE;
9070 }
9071
9072 OPJ_BOOL opj_j2k_decode_tiles ( opj_j2k_t *p_j2k,
9073                                                             opj_stream_private_t *p_stream,
9074                                                             opj_event_mgr_t * p_manager)
9075 {
9076         OPJ_BOOL l_go_on = OPJ_TRUE;
9077         OPJ_UINT32 l_current_tile_no;
9078         OPJ_UINT32 l_data_size,l_max_data_size;
9079         OPJ_INT32 l_tile_x0,l_tile_y0,l_tile_x1,l_tile_y1;
9080         OPJ_UINT32 l_nb_comps;
9081         OPJ_BYTE * l_current_data;
9082         OPJ_UINT32 nr_tiles = 0;
9083
9084         l_current_data = (OPJ_BYTE*)opj_malloc(1000);
9085         if (! l_current_data) {
9086                 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to decode tiles\n");
9087                 return OPJ_FALSE;
9088         }
9089         l_max_data_size = 1000;
9090
9091         while (OPJ_TRUE) {
9092                 if (! opj_j2k_read_tile_header( p_j2k,
9093                                         &l_current_tile_no,
9094                                         &l_data_size,
9095                                         &l_tile_x0, &l_tile_y0,
9096                                         &l_tile_x1, &l_tile_y1,
9097                                         &l_nb_comps,
9098                                         &l_go_on,
9099                                         p_stream,
9100                                         p_manager)) {
9101                         opj_free(l_current_data);
9102                         return OPJ_FALSE;
9103                 }
9104
9105                 if (! l_go_on) {
9106                         break;
9107                 }
9108
9109                 if (l_data_size > l_max_data_size) {
9110                         OPJ_BYTE *l_new_current_data = (OPJ_BYTE *) opj_realloc(l_current_data, l_data_size);
9111                         if (! l_new_current_data) {
9112                                 opj_free(l_current_data);
9113                                 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to decode tile %d/%d\n", l_current_tile_no +1, p_j2k->m_cp.th * p_j2k->m_cp.tw);
9114                                 return OPJ_FALSE;
9115                         }
9116                         l_current_data = l_new_current_data;
9117                         l_max_data_size = l_data_size;
9118                 }
9119
9120                 if (! opj_j2k_decode_tile(p_j2k,l_current_tile_no,l_current_data,l_data_size,p_stream,p_manager)) {
9121                         opj_free(l_current_data);
9122                         return OPJ_FALSE;
9123                 }
9124                 opj_event_msg(p_manager, EVT_INFO, "Tile %d/%d has been decoded.\n", l_current_tile_no +1, p_j2k->m_cp.th * p_j2k->m_cp.tw);
9125
9126                 if (! opj_j2k_update_image_data(p_j2k->m_tcd,l_current_data, p_j2k->m_output_image)) {
9127                         opj_free(l_current_data);
9128                         return OPJ_FALSE;
9129                 }
9130                 opj_event_msg(p_manager, EVT_INFO, "Image data has been updated with tile %d.\n\n", l_current_tile_no + 1);
9131                 
9132                 if(opj_stream_get_number_byte_left(p_stream) == 0  
9133                     && p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_NEOC)
9134                     break;
9135                 if(++nr_tiles ==  p_j2k->m_cp.th * p_j2k->m_cp.tw) 
9136                     break;
9137         }
9138
9139         opj_free(l_current_data);
9140
9141         return OPJ_TRUE;
9142 }
9143
9144 /**
9145  * Sets up the procedures to do on decoding data. Developpers wanting to extend the library can add their own reading procedures.
9146  */
9147 static void opj_j2k_setup_decoding (opj_j2k_t *p_j2k)
9148 {
9149         /* preconditions*/
9150         assert(p_j2k != 00);
9151
9152         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_decode_tiles);
9153         /* DEVELOPER CORNER, add your custom procedures */
9154
9155 }
9156
9157 /*
9158  * Read and decode one tile.
9159  */
9160 static OPJ_BOOL opj_j2k_decode_one_tile (       opj_j2k_t *p_j2k,
9161                                                                             opj_stream_private_t *p_stream,
9162                                                                             opj_event_mgr_t * p_manager)
9163 {
9164         OPJ_BOOL l_go_on = OPJ_TRUE;
9165         OPJ_UINT32 l_current_tile_no;
9166         OPJ_UINT32 l_tile_no_to_dec;
9167         OPJ_UINT32 l_data_size,l_max_data_size;
9168         OPJ_INT32 l_tile_x0,l_tile_y0,l_tile_x1,l_tile_y1;
9169         OPJ_UINT32 l_nb_comps;
9170         OPJ_BYTE * l_current_data;
9171
9172         l_current_data = (OPJ_BYTE*)opj_malloc(1000);
9173         if (! l_current_data) {
9174                 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to decode one tile\n");
9175                 return OPJ_FALSE;
9176         }
9177         l_max_data_size = 1000;
9178
9179         /*Allocate and initialize some elements of codestrem index if not already done*/
9180         if( !p_j2k->cstr_index->tile_index)
9181         {
9182                 if (!opj_j2k_allocate_tile_element_cstr_index(p_j2k)){
9183                         opj_free(l_current_data);
9184                         return OPJ_FALSE;
9185                 }
9186         }
9187         /* Move into the codestream to the first SOT used to decode the desired tile */
9188         l_tile_no_to_dec = p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec;
9189         if (p_j2k->cstr_index->tile_index)
9190                 if(p_j2k->cstr_index->tile_index->tp_index)
9191                 {
9192                         if ( ! p_j2k->cstr_index->tile_index[l_tile_no_to_dec].nb_tps) {
9193                                 /* the index for this tile has not been built,
9194                                  *  so move to the last SOT read */
9195                                 if ( !(opj_stream_read_seek(p_stream, p_j2k->m_specific_param.m_decoder.m_last_sot_read_pos+2, p_manager)) ){
9196                                         opj_event_msg(p_manager, EVT_ERROR, "Problem with seek function\n");
9197                                         return OPJ_FALSE;
9198                                 }
9199                         }
9200                         else{
9201                                 if ( !(opj_stream_read_seek(p_stream, p_j2k->cstr_index->tile_index[l_tile_no_to_dec].tp_index[0].start_pos+2, p_manager)) ) {
9202                                         opj_event_msg(p_manager, EVT_ERROR, "Problem with seek function\n");
9203                                         return OPJ_FALSE;
9204                                 }
9205                         }
9206                         /* Special case if we have previously read the EOC marker (if the previous tile getted is the last ) */
9207                         if(p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_EOC)
9208                                 p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_TPHSOT;
9209                 }
9210
9211         while (OPJ_TRUE) {
9212                 if (! opj_j2k_read_tile_header( p_j2k,
9213                                         &l_current_tile_no,
9214                                         &l_data_size,
9215                                         &l_tile_x0, &l_tile_y0,
9216                                         &l_tile_x1, &l_tile_y1,
9217                                         &l_nb_comps,
9218                                         &l_go_on,
9219                                         p_stream,
9220                                         p_manager)) {
9221                         opj_free(l_current_data);
9222                         return OPJ_FALSE;
9223                 }
9224
9225                 if (! l_go_on) {
9226                         break;
9227                 }
9228
9229                 if (l_data_size > l_max_data_size) {
9230                         OPJ_BYTE *l_new_current_data = (OPJ_BYTE *) opj_realloc(l_current_data, l_data_size);
9231                         if (! l_new_current_data) {
9232                                 opj_free(l_current_data);
9233                                 l_current_data = NULL;
9234                                 /* TODO: LH: why tile numbering policy used in messages differs from
9235                                    the one used in opj_j2k_decode_tiles() ? */
9236                                 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to decode tile %d/%d\n", l_current_tile_no, (p_j2k->m_cp.th * p_j2k->m_cp.tw) - 1);
9237                                 return OPJ_FALSE;
9238                         }
9239                         l_current_data = l_new_current_data;
9240                         l_max_data_size = l_data_size;
9241                 }
9242
9243                 if (! opj_j2k_decode_tile(p_j2k,l_current_tile_no,l_current_data,l_data_size,p_stream,p_manager)) {
9244                         opj_free(l_current_data);
9245                         return OPJ_FALSE;
9246                 }
9247                 opj_event_msg(p_manager, EVT_INFO, "Tile %d/%d has been decoded.\n", l_current_tile_no, (p_j2k->m_cp.th * p_j2k->m_cp.tw) - 1);
9248
9249                 if (! opj_j2k_update_image_data(p_j2k->m_tcd,l_current_data, p_j2k->m_output_image)) {
9250                         opj_free(l_current_data);
9251                         return OPJ_FALSE;
9252                 }
9253                 opj_event_msg(p_manager, EVT_INFO, "Image data has been updated with tile %d.\n\n", l_current_tile_no);
9254
9255                 if(l_current_tile_no == l_tile_no_to_dec)
9256                 {
9257                         /* move into the codestream to the the first SOT (FIXME or not move?)*/
9258                         if (!(opj_stream_read_seek(p_stream, p_j2k->cstr_index->main_head_end + 2, p_manager) ) ) {
9259                                 opj_event_msg(p_manager, EVT_ERROR, "Problem with seek function\n");
9260                                 return OPJ_FALSE;
9261                         }
9262                         break;
9263                 }
9264                 else {
9265                         opj_event_msg(p_manager, EVT_WARNING, "Tile read, decode and updated is not the desired (%d vs %d).\n", l_current_tile_no, l_tile_no_to_dec);
9266                 }
9267
9268         }
9269
9270         opj_free(l_current_data);
9271
9272         return OPJ_TRUE;
9273 }
9274
9275 /**
9276  * Sets up the procedures to do on decoding one tile. Developpers wanting to extend the library can add their own reading procedures.
9277  */
9278 static void opj_j2k_setup_decoding_tile (opj_j2k_t *p_j2k)
9279 {
9280         /* preconditions*/
9281         assert(p_j2k != 00);
9282
9283         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_decode_one_tile);
9284         /* DEVELOPER CORNER, add your custom procedures */
9285
9286 }
9287
9288 OPJ_BOOL opj_j2k_decode(opj_j2k_t * p_j2k,
9289                                                 opj_stream_private_t * p_stream,
9290                                                 opj_image_t * p_image,
9291                                                 opj_event_mgr_t * p_manager)
9292 {
9293         OPJ_UINT32 compno;
9294
9295         if (!p_image)
9296                 return OPJ_FALSE;
9297
9298         p_j2k->m_output_image = opj_image_create0();
9299         if (! (p_j2k->m_output_image)) {
9300                 return OPJ_FALSE;
9301         }
9302         opj_copy_image_header(p_image, p_j2k->m_output_image);
9303
9304         /* customization of the decoding */
9305         opj_j2k_setup_decoding(p_j2k);
9306
9307         /* Decode the codestream */
9308         if (! opj_j2k_exec (p_j2k,p_j2k->m_procedure_list,p_stream,p_manager)) {
9309                 opj_image_destroy(p_j2k->m_private_image);
9310                 p_j2k->m_private_image = NULL;
9311                 return OPJ_FALSE;
9312         }
9313
9314         /* Move data and copy one information from codec to output image*/
9315         for (compno = 0; compno < p_image->numcomps; compno++) {
9316                 p_image->comps[compno].resno_decoded = p_j2k->m_output_image->comps[compno].resno_decoded;
9317                 p_image->comps[compno].data = p_j2k->m_output_image->comps[compno].data;
9318                 p_j2k->m_output_image->comps[compno].data = NULL;
9319         }
9320
9321         return OPJ_TRUE;
9322 }
9323
9324 OPJ_BOOL opj_j2k_get_tile(      opj_j2k_t *p_j2k,
9325                                                     opj_stream_private_t *p_stream,
9326                                                     opj_image_t* p_image,
9327                                                     opj_event_mgr_t * p_manager,
9328                                                     OPJ_UINT32 tile_index )
9329 {
9330         OPJ_UINT32 compno;
9331         OPJ_UINT32 l_tile_x, l_tile_y;
9332         opj_image_comp_t* l_img_comp;
9333
9334         if (!p_image) {
9335                 opj_event_msg(p_manager, EVT_ERROR, "We need an image previously created.\n");
9336                 return OPJ_FALSE;
9337         }
9338
9339         if ( /*(tile_index < 0) &&*/ (tile_index >= p_j2k->m_cp.tw * p_j2k->m_cp.th) ){
9340                 opj_event_msg(p_manager, EVT_ERROR, "Tile index provided by the user is incorrect %d (max = %d) \n", tile_index, (p_j2k->m_cp.tw * p_j2k->m_cp.th) - 1);
9341                 return OPJ_FALSE;
9342         }
9343
9344         /* Compute the dimension of the desired tile*/
9345         l_tile_x = tile_index % p_j2k->m_cp.tw;
9346         l_tile_y = tile_index / p_j2k->m_cp.tw;
9347
9348         p_image->x0 = l_tile_x * p_j2k->m_cp.tdx + p_j2k->m_cp.tx0;
9349         if (p_image->x0 < p_j2k->m_private_image->x0)
9350                 p_image->x0 = p_j2k->m_private_image->x0;
9351         p_image->x1 = (l_tile_x + 1) * p_j2k->m_cp.tdx + p_j2k->m_cp.tx0;
9352         if (p_image->x1 > p_j2k->m_private_image->x1)
9353                 p_image->x1 = p_j2k->m_private_image->x1;
9354
9355         p_image->y0 = l_tile_y * p_j2k->m_cp.tdy + p_j2k->m_cp.ty0;
9356         if (p_image->y0 < p_j2k->m_private_image->y0)
9357                 p_image->y0 = p_j2k->m_private_image->y0;
9358         p_image->y1 = (l_tile_y + 1) * p_j2k->m_cp.tdy + p_j2k->m_cp.ty0;
9359         if (p_image->y1 > p_j2k->m_private_image->y1)
9360                 p_image->y1 = p_j2k->m_private_image->y1;
9361
9362         l_img_comp = p_image->comps;
9363         for (compno=0; compno < p_image->numcomps; ++compno)
9364         {
9365                 OPJ_INT32 l_comp_x1, l_comp_y1;
9366
9367                 l_img_comp->factor = p_j2k->m_private_image->comps[compno].factor;
9368
9369                 l_img_comp->x0 = opj_int_ceildiv(p_image->x0, l_img_comp->dx);
9370                 l_img_comp->y0 = opj_int_ceildiv(p_image->y0, l_img_comp->dy);
9371                 l_comp_x1 = opj_int_ceildiv(p_image->x1, l_img_comp->dx);
9372                 l_comp_y1 = opj_int_ceildiv(p_image->y1, l_img_comp->dy);
9373
9374                 l_img_comp->w = opj_int_ceildivpow2(l_comp_x1, l_img_comp->factor) - opj_int_ceildivpow2(l_img_comp->x0, l_img_comp->factor);
9375                 l_img_comp->h = opj_int_ceildivpow2(l_comp_y1, l_img_comp->factor) - opj_int_ceildivpow2(l_img_comp->y0, l_img_comp->factor);
9376
9377                 l_img_comp++;
9378         }
9379
9380         /* Destroy the previous output image*/
9381         if (p_j2k->m_output_image)
9382                 opj_image_destroy(p_j2k->m_output_image);
9383
9384         /* Create the ouput image from the information previously computed*/
9385         p_j2k->m_output_image = opj_image_create0();
9386         if (! (p_j2k->m_output_image)) {
9387                 return OPJ_FALSE;
9388         }
9389         opj_copy_image_header(p_image, p_j2k->m_output_image);
9390
9391         p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec = tile_index;
9392
9393         /* customization of the decoding */
9394         opj_j2k_setup_decoding_tile(p_j2k);
9395
9396         /* Decode the codestream */
9397         if (! opj_j2k_exec (p_j2k,p_j2k->m_procedure_list,p_stream,p_manager)) {
9398                 opj_image_destroy(p_j2k->m_private_image);
9399                 p_j2k->m_private_image = NULL;
9400                 return OPJ_FALSE;
9401         }
9402
9403         /* Move data and copy one information from codec to output image*/
9404         for (compno = 0; compno < p_image->numcomps; compno++) {
9405                 p_image->comps[compno].resno_decoded = p_j2k->m_output_image->comps[compno].resno_decoded;
9406
9407                 if (p_image->comps[compno].data)
9408                         opj_free(p_image->comps[compno].data);
9409
9410                 p_image->comps[compno].data = p_j2k->m_output_image->comps[compno].data;
9411
9412                 p_j2k->m_output_image->comps[compno].data = NULL;
9413         }
9414
9415         return OPJ_TRUE;
9416 }
9417
9418 OPJ_BOOL opj_j2k_set_decoded_resolution_factor(opj_j2k_t *p_j2k,
9419                                                OPJ_UINT32 res_factor,
9420                                                opj_event_mgr_t * p_manager)
9421 {
9422         OPJ_UINT32 it_comp;
9423
9424         p_j2k->m_cp.m_specific_param.m_dec.m_reduce = res_factor;
9425
9426         if (p_j2k->m_private_image) {
9427                 if (p_j2k->m_private_image->comps) {
9428                         if (p_j2k->m_specific_param.m_decoder.m_default_tcp) {
9429                                 if (p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps) {
9430                                         for (it_comp = 0 ; it_comp < p_j2k->m_private_image->numcomps; it_comp++) {
9431                                                 OPJ_UINT32 max_res = p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps[it_comp].numresolutions;
9432                                                 if ( res_factor >= max_res){
9433                                                         opj_event_msg(p_manager, EVT_ERROR, "Resolution factor is greater than the maximum resolution in the component.\n");
9434                                                         return OPJ_FALSE;
9435                                                 }
9436                                                 p_j2k->m_private_image->comps[it_comp].factor = res_factor;
9437                                         }
9438                                         return OPJ_TRUE;
9439                                 }
9440                         }
9441                 }
9442         }
9443
9444         return OPJ_FALSE;
9445 }
9446
9447 OPJ_BOOL opj_j2k_encode(opj_j2k_t * p_j2k,
9448                         opj_stream_private_t *p_stream,
9449                         opj_event_mgr_t * p_manager )
9450 {
9451         OPJ_UINT32 i;
9452         OPJ_UINT32 l_nb_tiles;
9453         OPJ_UINT32 l_max_tile_size, l_current_tile_size;
9454         OPJ_BYTE * l_current_data;
9455
9456         /* preconditions */
9457         assert(p_j2k != 00);
9458         assert(p_stream != 00);
9459         assert(p_manager != 00);
9460
9461         l_current_data = (OPJ_BYTE*)opj_malloc(1000);
9462         if (! l_current_data) {
9463                 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to encode all tiles\n");
9464                 return OPJ_FALSE;
9465         }
9466         l_max_tile_size = 1000;
9467
9468         l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
9469         for (i=0;i<l_nb_tiles;++i) {
9470                 if (! opj_j2k_pre_write_tile(p_j2k,i,p_stream,p_manager)) {
9471                         opj_free(l_current_data);
9472                         return OPJ_FALSE;
9473                 }
9474
9475                 l_current_tile_size = opj_tcd_get_encoded_tile_size(p_j2k->m_tcd);
9476                 if (l_current_tile_size > l_max_tile_size) {
9477                         OPJ_BYTE *l_new_current_data = (OPJ_BYTE *) opj_realloc(l_current_data, l_current_tile_size);
9478                         if (! l_new_current_data) {
9479                                 opj_free(l_current_data);
9480                                 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to encode all tiles\n");
9481                                 return OPJ_FALSE;
9482                         }
9483                         l_current_data = l_new_current_data;
9484                         l_max_tile_size = l_current_tile_size;
9485                 }
9486
9487                 opj_j2k_get_tile_data(p_j2k->m_tcd,l_current_data);
9488
9489                 if (! opj_j2k_post_write_tile (p_j2k,l_current_data,l_current_tile_size,p_stream,p_manager)) {
9490                         return OPJ_FALSE;
9491                 }
9492         }
9493
9494         opj_free(l_current_data);
9495         return OPJ_TRUE;
9496 }
9497
9498 OPJ_BOOL opj_j2k_end_compress(  opj_j2k_t *p_j2k,
9499                                                         opj_stream_private_t *p_stream,
9500                                                         opj_event_mgr_t * p_manager)
9501 {
9502         /* customization of the encoding */
9503         opj_j2k_setup_end_compress(p_j2k);
9504
9505         if (! opj_j2k_exec (p_j2k, p_j2k->m_procedure_list, p_stream, p_manager))
9506         {
9507                 return OPJ_FALSE;
9508         }
9509
9510         return OPJ_TRUE;
9511 }
9512
9513 OPJ_BOOL opj_j2k_start_compress(opj_j2k_t *p_j2k,
9514                                                             opj_stream_private_t *p_stream,
9515                                                             opj_image_t * p_image,
9516                                                             opj_event_mgr_t * p_manager)
9517 {
9518         /* preconditions */
9519         assert(p_j2k != 00);
9520         assert(p_stream != 00);
9521         assert(p_manager != 00);
9522
9523         p_j2k->m_private_image = opj_image_create0();
9524         opj_copy_image_header(p_image, p_j2k->m_private_image);
9525
9526         /* TODO_MSD: Find a better way */
9527         if (p_image->comps) {
9528                 OPJ_UINT32 it_comp;
9529                 for (it_comp = 0 ; it_comp < p_image->numcomps; it_comp++) {
9530                         if (p_image->comps[it_comp].data) {
9531                                 p_j2k->m_private_image->comps[it_comp].data =p_image->comps[it_comp].data;
9532                                 p_image->comps[it_comp].data = NULL;
9533
9534                         }
9535                 }
9536         }
9537
9538         /* customization of the validation */
9539         opj_j2k_setup_encoding_validation (p_j2k);
9540
9541         /* validation of the parameters codec */
9542         if (! opj_j2k_exec(p_j2k,p_j2k->m_validation_list,p_stream,p_manager)) {
9543                 return OPJ_FALSE;
9544         }
9545
9546         /* customization of the encoding */
9547         opj_j2k_setup_header_writing(p_j2k);
9548
9549         /* write header */
9550         if (! opj_j2k_exec (p_j2k,p_j2k->m_procedure_list,p_stream,p_manager)) {
9551                 return OPJ_FALSE;
9552         }
9553
9554         return OPJ_TRUE;
9555 }
9556
9557 OPJ_BOOL opj_j2k_pre_write_tile (       opj_j2k_t * p_j2k,
9558                                                                 OPJ_UINT32 p_tile_index,
9559                                                                 opj_stream_private_t *p_stream,
9560                                                                 opj_event_mgr_t * p_manager )
9561 {
9562   (void)p_stream;
9563         if (p_tile_index != p_j2k->m_current_tile_number) {
9564                 opj_event_msg(p_manager, EVT_ERROR, "The given tile index does not match." );
9565                 return OPJ_FALSE;
9566         }
9567
9568         opj_event_msg(p_manager, EVT_INFO, "tile number %d / %d\n", p_j2k->m_current_tile_number + 1, p_j2k->m_cp.tw * p_j2k->m_cp.th);
9569
9570         p_j2k->m_specific_param.m_encoder.m_current_tile_part_number = 0;
9571         p_j2k->m_tcd->cur_totnum_tp = p_j2k->m_cp.tcps[p_tile_index].m_nb_tile_parts;
9572         p_j2k->m_specific_param.m_encoder.m_current_poc_tile_part_number = 0;
9573
9574         /* initialisation before tile encoding  */
9575         if (! opj_tcd_init_encode_tile(p_j2k->m_tcd, p_j2k->m_current_tile_number)) {
9576                 return OPJ_FALSE;
9577         }
9578
9579         return OPJ_TRUE;
9580 }
9581
9582 void opj_j2k_get_tile_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data)
9583 {
9584         OPJ_UINT32 i,j,k = 0;
9585         OPJ_UINT32 l_width,l_height,l_stride, l_offset_x,l_offset_y, l_image_width;
9586         opj_image_comp_t * l_img_comp = 00;
9587         opj_tcd_tilecomp_t * l_tilec = 00;
9588         opj_image_t * l_image = 00;
9589         OPJ_UINT32 l_size_comp, l_remaining;
9590         OPJ_INT32 * l_src_ptr;
9591         l_tilec = p_tcd->tcd_image->tiles->comps;
9592         l_image = p_tcd->image;
9593         l_img_comp = l_image->comps;
9594
9595         for (i=0;i<p_tcd->image->numcomps;++i) {
9596                 l_size_comp = l_img_comp->prec >> 3; /* (/8) */
9597                 l_remaining = l_img_comp->prec & 7;  /* (%8) */
9598                 if (l_remaining) {
9599                         ++l_size_comp;
9600                 }
9601
9602                 if (l_size_comp == 3) {
9603                         l_size_comp = 4;
9604                 }
9605
9606                 l_width = (l_tilec->x1 - l_tilec->x0);
9607                 l_height = (l_tilec->y1 - l_tilec->y0);
9608                 l_offset_x = opj_int_ceildiv(l_image->x0, l_img_comp->dx);
9609                 l_offset_y = opj_int_ceildiv(l_image->y0, l_img_comp->dy);
9610                 l_image_width = opj_int_ceildiv(l_image->x1 - l_image->x0, l_img_comp->dx);
9611                 l_stride = l_image_width - l_width;
9612                 l_src_ptr = l_img_comp->data + (l_tilec->x0 - l_offset_x) + (l_tilec->y0 - l_offset_y) * l_image_width;
9613
9614                 switch (l_size_comp) {
9615                         case 1:
9616                                 {
9617                                         OPJ_CHAR * l_dest_ptr = (OPJ_CHAR*) p_data;
9618                                         if (l_img_comp->sgnd) {
9619                                                 for     (j=0;j<l_height;++j) {
9620                                                         for (k=0;k<l_width;++k) {
9621                                                                 *(l_dest_ptr) = (OPJ_CHAR) (*l_src_ptr);
9622                                                                 ++l_dest_ptr;
9623                                                                 ++l_src_ptr;
9624                                                         }
9625                                                         l_src_ptr += l_stride;
9626                                                 }
9627                                         }
9628                                         else {
9629                                                 for (j=0;j<l_height;++j) {
9630                                                         for (k=0;k<l_width;++k) {
9631                                                                 *(l_dest_ptr) = (OPJ_CHAR)((*l_src_ptr)&0xff);
9632                                                                 ++l_dest_ptr;
9633                                                                 ++l_src_ptr;
9634                                                         }
9635                                                         l_src_ptr += l_stride;
9636                                                 }
9637                                         }
9638
9639                                         p_data = (OPJ_BYTE*) l_dest_ptr;
9640                                 }
9641                                 break;
9642                         case 2:
9643                                 {
9644                                         OPJ_INT16 * l_dest_ptr = (OPJ_INT16 *) p_data;
9645                                         if (l_img_comp->sgnd) {
9646                                                 for (j=0;j<l_height;++j) {
9647                                                         for (k=0;k<l_width;++k) {
9648                                                                 *(l_dest_ptr++) = (OPJ_INT16) (*(l_src_ptr++));
9649                                                         }
9650                                                         l_src_ptr += l_stride;
9651                                                 }
9652                                         }
9653                                         else {
9654                                                 for (j=0;j<l_height;++j) {
9655                                                         for (k=0;k<l_width;++k) {
9656                                                                 *(l_dest_ptr++) = (OPJ_INT16)((*(l_src_ptr++)) & 0xffff);
9657                                                         }
9658                                                         l_src_ptr += l_stride;
9659                                                 }
9660                                         }
9661
9662                                         p_data = (OPJ_BYTE*) l_dest_ptr;
9663                                 }
9664                                 break;
9665                         case 4:
9666                                 {
9667                                         OPJ_INT32 * l_dest_ptr = (OPJ_INT32 *) p_data;
9668                                         for (j=0;j<l_height;++j) {
9669                                                 for (k=0;k<l_width;++k) {
9670                                                         *(l_dest_ptr++) = *(l_src_ptr++);
9671                                                 }
9672                                                 l_src_ptr += l_stride;
9673                                         }
9674
9675                                         p_data = (OPJ_BYTE*) l_dest_ptr;
9676                                 }
9677                                 break;
9678                 }
9679
9680                 ++l_img_comp;
9681                 ++l_tilec;
9682         }
9683 }
9684
9685 OPJ_BOOL opj_j2k_post_write_tile (      opj_j2k_t * p_j2k,
9686                                                                 OPJ_BYTE * p_data,
9687                                                                 OPJ_UINT32 p_data_size,
9688                                                                 opj_stream_private_t *p_stream,
9689                                                                 opj_event_mgr_t * p_manager )
9690 {
9691         opj_tcd_t * l_tcd = 00;
9692         OPJ_UINT32 l_nb_bytes_written;
9693         OPJ_BYTE * l_current_data = 00;
9694         OPJ_UINT32 l_tile_size = 0;
9695         OPJ_UINT32 l_available_data;
9696
9697         /* preconditions */
9698         assert(p_j2k->m_specific_param.m_encoder.m_encoded_tile_data);
9699
9700         l_tcd = p_j2k->m_tcd;
9701         
9702         l_tile_size = p_j2k->m_specific_param.m_encoder.m_encoded_tile_size;
9703         l_available_data = l_tile_size;
9704         l_current_data = p_j2k->m_specific_param.m_encoder.m_encoded_tile_data;
9705
9706         if (! opj_tcd_copy_tile_data(l_tcd,p_data,p_data_size)) {
9707                 opj_event_msg(p_manager, EVT_ERROR, "Size mismatch between tile data and sent data." );
9708                 return OPJ_FALSE;
9709         }
9710
9711         l_nb_bytes_written = 0;
9712         if (! opj_j2k_write_first_tile_part(p_j2k,l_current_data,&l_nb_bytes_written,l_available_data,p_stream,p_manager)) {
9713                 return OPJ_FALSE;
9714         }
9715         l_current_data += l_nb_bytes_written;
9716         l_available_data -= l_nb_bytes_written;
9717
9718         l_nb_bytes_written = 0;
9719         if (! opj_j2k_write_all_tile_parts(p_j2k,l_current_data,&l_nb_bytes_written,l_available_data,p_stream,p_manager)) {
9720                 return OPJ_FALSE;
9721         }
9722
9723         l_available_data -= l_nb_bytes_written;
9724         l_nb_bytes_written = l_tile_size - l_available_data;
9725
9726         if ( opj_stream_write_data(     p_stream,
9727                                                                 p_j2k->m_specific_param.m_encoder.m_encoded_tile_data,
9728                                                                 l_nb_bytes_written,p_manager) != l_nb_bytes_written) {
9729                 return OPJ_FALSE;
9730         }
9731
9732         ++p_j2k->m_current_tile_number;
9733
9734         return OPJ_TRUE;
9735 }
9736
9737 void opj_j2k_setup_end_compress (opj_j2k_t *p_j2k)
9738 {
9739         /* preconditions */
9740         assert(p_j2k != 00);
9741
9742         /* DEVELOPER CORNER, insert your custom procedures */
9743         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_eoc );
9744
9745         if (p_j2k->m_cp.m_specific_param.m_enc.m_cinema) {
9746                 opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_updated_tlm);
9747         }
9748
9749         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_epc );
9750         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_end_encoding );
9751         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_destroy_header_memory);
9752 }
9753
9754 void opj_j2k_setup_encoding_validation (opj_j2k_t *p_j2k)
9755 {
9756         /* preconditions */
9757         assert(p_j2k != 00);
9758
9759         opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)opj_j2k_build_encoder);
9760         opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)opj_j2k_encoding_validation);
9761
9762         /* DEVELOPER CORNER, add your custom validation procedure */
9763         opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)opj_j2k_mct_validation);
9764 }
9765
9766 void opj_j2k_setup_header_writing (opj_j2k_t *p_j2k)
9767 {
9768         /* preconditions */
9769         assert(p_j2k != 00);
9770
9771         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_init_info );
9772         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_soc );
9773         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_siz );
9774         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_cod );
9775         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_qcd );
9776
9777         if (p_j2k->m_cp.m_specific_param.m_enc.m_cinema) {
9778                 /* No need for COC or QCC, QCD and COD are used
9779                 opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_all_coc );
9780                 opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_all_qcc );
9781                 */
9782                 opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_tlm );
9783
9784                 if (p_j2k->m_cp.m_specific_param.m_enc.m_cinema == OPJ_CINEMA4K_24) {
9785                         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_poc );
9786                 }
9787         }
9788
9789         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_regions);
9790
9791         if (p_j2k->m_cp.comment != 00)  {
9792                 opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_com);
9793         }
9794
9795         /* DEVELOPER CORNER, insert your custom procedures */
9796         if (p_j2k->m_cp.rsiz & OPJ_MCT) {
9797                 opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_mct_data_group );
9798         }
9799         /* End of Developer Corner */
9800
9801         if (p_j2k->cstr_index) {
9802                 opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_get_end_header );
9803         }
9804
9805         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_create_tcd);
9806         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_update_rates);
9807 }
9808
9809 OPJ_BOOL opj_j2k_write_first_tile_part (opj_j2k_t *p_j2k,
9810                                                                         OPJ_BYTE * p_data,
9811                                                                         OPJ_UINT32 * p_data_written,
9812                                                                         OPJ_UINT32 p_total_data_size,
9813                                                                         opj_stream_private_t *p_stream,
9814                                                                         struct opj_event_mgr * p_manager )
9815 {
9816         OPJ_UINT32 l_nb_bytes_written = 0;
9817         OPJ_UINT32 l_current_nb_bytes_written;
9818         OPJ_BYTE * l_begin_data = 00;
9819
9820         opj_tcd_t * l_tcd = 00;
9821         opj_cp_t * l_cp = 00;
9822
9823         l_tcd = p_j2k->m_tcd;
9824         l_cp = &(p_j2k->m_cp);
9825
9826         l_tcd->cur_pino = 0;
9827
9828         /*Get number of tile parts*/
9829         p_j2k->m_specific_param.m_encoder.m_current_poc_tile_part_number = 0;
9830
9831         /* INDEX >> */
9832         /* << INDEX */
9833
9834         l_current_nb_bytes_written = 0;
9835         l_begin_data = p_data;
9836         if (! opj_j2k_write_sot(p_j2k,p_data,&l_current_nb_bytes_written,p_stream,p_manager))
9837         {
9838                 return OPJ_FALSE;
9839         }
9840
9841         l_nb_bytes_written += l_current_nb_bytes_written;
9842         p_data += l_current_nb_bytes_written;
9843         p_total_data_size -= l_current_nb_bytes_written;
9844
9845         if (l_cp->m_specific_param.m_enc.m_cinema == 0) {
9846 #if 0
9847                 for (compno = 1; compno < p_j2k->m_private_image->numcomps; compno++) {
9848                         l_current_nb_bytes_written = 0;
9849                         opj_j2k_write_coc_in_memory(p_j2k,compno,p_data,&l_current_nb_bytes_written,p_manager);
9850                         l_nb_bytes_written += l_current_nb_bytes_written;
9851                         p_data += l_current_nb_bytes_written;
9852                         p_total_data_size -= l_current_nb_bytes_written;
9853
9854                         l_current_nb_bytes_written = 0;
9855                         opj_j2k_write_qcc_in_memory(p_j2k,compno,p_data,&l_current_nb_bytes_written,p_manager);
9856                         l_nb_bytes_written += l_current_nb_bytes_written;
9857                         p_data += l_current_nb_bytes_written;
9858                         p_total_data_size -= l_current_nb_bytes_written;
9859                 }
9860 #endif
9861
9862                 if (l_cp->tcps[p_j2k->m_current_tile_number].numpocs) {
9863                         l_current_nb_bytes_written = 0;
9864                         opj_j2k_write_poc_in_memory(p_j2k,p_data,&l_current_nb_bytes_written,p_manager);
9865                         l_nb_bytes_written += l_current_nb_bytes_written;
9866                         p_data += l_current_nb_bytes_written;
9867                         p_total_data_size -= l_current_nb_bytes_written;
9868                 }
9869         }
9870
9871         l_current_nb_bytes_written = 0;
9872         if (! opj_j2k_write_sod(p_j2k,l_tcd,p_data,&l_current_nb_bytes_written,p_total_data_size,p_stream,p_manager)) {
9873                 return OPJ_FALSE;
9874         }
9875
9876         l_nb_bytes_written += l_current_nb_bytes_written;
9877         * p_data_written = l_nb_bytes_written;
9878
9879         /* Writing Psot in SOT marker */
9880         opj_write_bytes(l_begin_data + 6,l_nb_bytes_written,4);                                 /* PSOT */
9881
9882         if (l_cp->m_specific_param.m_enc.m_cinema){
9883                 opj_j2k_update_tlm(p_j2k,l_nb_bytes_written);
9884         }
9885
9886         return OPJ_TRUE;
9887 }
9888
9889 OPJ_BOOL opj_j2k_write_all_tile_parts(  opj_j2k_t *p_j2k,
9890                                                                         OPJ_BYTE * p_data,
9891                                                                         OPJ_UINT32 * p_data_written,
9892                                                                         OPJ_UINT32 p_total_data_size,
9893                                                                         opj_stream_private_t *p_stream,
9894                                                                         struct opj_event_mgr * p_manager
9895                                                                 )
9896 {
9897         OPJ_UINT32 tilepartno=0;
9898         OPJ_UINT32 l_nb_bytes_written = 0;
9899         OPJ_UINT32 l_current_nb_bytes_written;
9900         OPJ_UINT32 l_part_tile_size;
9901         OPJ_UINT32 tot_num_tp;
9902         OPJ_UINT32 pino;
9903
9904         OPJ_BYTE * l_begin_data;
9905         opj_tcp_t *l_tcp = 00;
9906         opj_tcd_t * l_tcd = 00;
9907         opj_cp_t * l_cp = 00;
9908
9909         l_tcd = p_j2k->m_tcd;
9910         l_cp = &(p_j2k->m_cp);
9911         l_tcp = l_cp->tcps + p_j2k->m_current_tile_number;
9912
9913         /*Get number of tile parts*/
9914         tot_num_tp = opj_j2k_get_num_tp(l_cp,0,p_j2k->m_current_tile_number);
9915
9916         /* start writing remaining tile parts */
9917         ++p_j2k->m_specific_param.m_encoder.m_current_tile_part_number;
9918         for (tilepartno = 1; tilepartno < tot_num_tp ; ++tilepartno) {
9919                 p_j2k->m_specific_param.m_encoder.m_current_poc_tile_part_number = tilepartno;
9920                 l_current_nb_bytes_written = 0;
9921                 l_part_tile_size = 0;
9922                 l_begin_data = p_data;
9923
9924                 if (! opj_j2k_write_sot(p_j2k,p_data,&l_current_nb_bytes_written,p_stream,p_manager)) {
9925                         return OPJ_FALSE;
9926                 }
9927
9928                 l_nb_bytes_written += l_current_nb_bytes_written;
9929                 p_data += l_current_nb_bytes_written;
9930                 p_total_data_size -= l_current_nb_bytes_written;
9931                 l_part_tile_size += l_current_nb_bytes_written;
9932
9933                 l_current_nb_bytes_written = 0;
9934                 if (! opj_j2k_write_sod(p_j2k,l_tcd,p_data,&l_current_nb_bytes_written,p_total_data_size,p_stream,p_manager)) {
9935                         return OPJ_FALSE;
9936                 }
9937
9938                 p_data += l_current_nb_bytes_written;
9939                 l_nb_bytes_written += l_current_nb_bytes_written;
9940                 p_total_data_size -= l_current_nb_bytes_written;
9941                 l_part_tile_size += l_current_nb_bytes_written;
9942
9943                 /* Writing Psot in SOT marker */
9944                 opj_write_bytes(l_begin_data + 6,l_part_tile_size,4);                                   /* PSOT */
9945
9946                 if (l_cp->m_specific_param.m_enc.m_cinema) {
9947                         opj_j2k_update_tlm(p_j2k,l_part_tile_size);
9948                 }
9949
9950                 ++p_j2k->m_specific_param.m_encoder.m_current_tile_part_number;
9951         }
9952
9953         for (pino = 1; pino <= l_tcp->numpocs; ++pino) {
9954                 l_tcd->cur_pino = pino;
9955
9956                 /*Get number of tile parts*/
9957                 tot_num_tp = opj_j2k_get_num_tp(l_cp,pino,p_j2k->m_current_tile_number);
9958                 for (tilepartno = 0; tilepartno < tot_num_tp ; ++tilepartno) {
9959                         p_j2k->m_specific_param.m_encoder.m_current_poc_tile_part_number = tilepartno;
9960                         l_current_nb_bytes_written = 0;
9961                         l_part_tile_size = 0;
9962                         l_begin_data = p_data;
9963
9964                         if (! opj_j2k_write_sot(p_j2k,p_data,&l_current_nb_bytes_written,p_stream,p_manager)) {
9965                                 return OPJ_FALSE;
9966                         }
9967
9968                         l_nb_bytes_written += l_current_nb_bytes_written;
9969                         p_data += l_current_nb_bytes_written;
9970                         p_total_data_size -= l_current_nb_bytes_written;
9971                         l_part_tile_size += l_current_nb_bytes_written;
9972
9973                         l_current_nb_bytes_written = 0;
9974
9975                         if (! opj_j2k_write_sod(p_j2k,l_tcd,p_data,&l_current_nb_bytes_written,p_total_data_size,p_stream,p_manager)) {
9976                                 return OPJ_FALSE;
9977                         }
9978
9979                         l_nb_bytes_written += l_current_nb_bytes_written;
9980                         p_data += l_current_nb_bytes_written;
9981                         p_total_data_size -= l_current_nb_bytes_written;
9982                         l_part_tile_size += l_current_nb_bytes_written;
9983
9984                         /* Writing Psot in SOT marker */
9985                         opj_write_bytes(l_begin_data + 6,l_part_tile_size,4);                                   /* PSOT */
9986
9987                         if (l_cp->m_specific_param.m_enc.m_cinema) {
9988                                 opj_j2k_update_tlm(p_j2k,l_part_tile_size);
9989                         }
9990
9991                         ++p_j2k->m_specific_param.m_encoder.m_current_tile_part_number;
9992                 }
9993         }
9994
9995         *p_data_written = l_nb_bytes_written;
9996
9997         return OPJ_TRUE;
9998 }
9999
10000 OPJ_BOOL opj_j2k_write_updated_tlm( opj_j2k_t *p_j2k,
10001                                                                     struct opj_stream_private *p_stream,
10002                                                                     struct opj_event_mgr * p_manager )
10003 {
10004         OPJ_UINT32 l_tlm_size;
10005         OPJ_OFF_T l_tlm_position, l_current_position;
10006
10007         /* preconditions */
10008         assert(p_j2k != 00);
10009         assert(p_manager != 00);
10010         assert(p_stream != 00);
10011
10012         l_tlm_size = 5 * p_j2k->m_specific_param.m_encoder.m_total_tile_parts;
10013         l_tlm_position = 6 + p_j2k->m_specific_param.m_encoder.m_tlm_start;
10014         l_current_position = opj_stream_tell(p_stream);
10015
10016         if (! opj_stream_seek(p_stream,l_tlm_position,p_manager)) {
10017                 return OPJ_FALSE;
10018         }
10019
10020         if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer,l_tlm_size,p_manager) != l_tlm_size) {
10021                 return OPJ_FALSE;
10022         }
10023
10024         if (! opj_stream_seek(p_stream,l_current_position,p_manager)) {
10025                 return OPJ_FALSE;
10026         }
10027
10028         return OPJ_TRUE;
10029 }
10030
10031 OPJ_BOOL opj_j2k_end_encoding(  opj_j2k_t *p_j2k,
10032                                                         struct opj_stream_private *p_stream,
10033                                                         struct opj_event_mgr * p_manager )
10034 {
10035         /* preconditions */
10036         assert(p_j2k != 00);
10037         assert(p_manager != 00);
10038         assert(p_stream != 00);
10039
10040         opj_tcd_destroy(p_j2k->m_tcd);
10041         p_j2k->m_tcd = 00;
10042
10043         if (p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer) {
10044                 opj_free(p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer);
10045                 p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer = 0;
10046                 p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current = 0;
10047         }
10048
10049         if (p_j2k->m_specific_param.m_encoder.m_encoded_tile_data) {
10050                 opj_free(p_j2k->m_specific_param.m_encoder.m_encoded_tile_data);
10051                 p_j2k->m_specific_param.m_encoder.m_encoded_tile_data = 0;
10052         }
10053
10054         p_j2k->m_specific_param.m_encoder.m_encoded_tile_size = 0;
10055
10056         return OPJ_TRUE;
10057 }
10058
10059 /**
10060  * Destroys the memory associated with the decoding of headers.
10061  */
10062 static OPJ_BOOL opj_j2k_destroy_header_memory ( opj_j2k_t * p_j2k,
10063                                                 opj_stream_private_t *p_stream,
10064                                                 opj_event_mgr_t * p_manager
10065                                                 )
10066 {
10067         /* preconditions */
10068         assert(p_j2k != 00);
10069         assert(p_stream != 00);
10070         assert(p_manager != 00);
10071
10072         if (p_j2k->m_specific_param.m_encoder.m_header_tile_data) {
10073                 opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
10074                 p_j2k->m_specific_param.m_encoder.m_header_tile_data = 0;
10075         }
10076
10077         p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
10078
10079         return OPJ_TRUE;
10080 }
10081
10082 OPJ_BOOL opj_j2k_init_info(     opj_j2k_t *p_j2k,
10083                                                 struct opj_stream_private *p_stream,
10084                                                 struct opj_event_mgr * p_manager )
10085 {
10086         opj_codestream_info_t * l_cstr_info = 00;
10087
10088         /* preconditions */
10089         assert(p_j2k != 00);
10090         assert(p_manager != 00);
10091         assert(p_stream != 00);
10092   (void)l_cstr_info;
10093
10094         /* TODO mergeV2: check this part which use cstr_info */
10095         /*l_cstr_info = p_j2k->cstr_info;
10096
10097         if (l_cstr_info)  {
10098                 OPJ_UINT32 compno;
10099                 l_cstr_info->tile = (opj_tile_info_t *) opj_malloc(p_j2k->m_cp.tw * p_j2k->m_cp.th * sizeof(opj_tile_info_t));
10100
10101                 l_cstr_info->image_w = p_j2k->m_image->x1 - p_j2k->m_image->x0;
10102                 l_cstr_info->image_h = p_j2k->m_image->y1 - p_j2k->m_image->y0;
10103
10104                 l_cstr_info->prog = (&p_j2k->m_cp.tcps[0])->prg;
10105
10106                 l_cstr_info->tw = p_j2k->m_cp.tw;
10107                 l_cstr_info->th = p_j2k->m_cp.th;
10108
10109                 l_cstr_info->tile_x = p_j2k->m_cp.tdx;*/        /* new version parser */
10110                 /*l_cstr_info->tile_y = p_j2k->m_cp.tdy;*/      /* new version parser */
10111                 /*l_cstr_info->tile_Ox = p_j2k->m_cp.tx0;*/     /* new version parser */
10112                 /*l_cstr_info->tile_Oy = p_j2k->m_cp.ty0;*/     /* new version parser */
10113
10114                 /*l_cstr_info->numcomps = p_j2k->m_image->numcomps;
10115
10116                 l_cstr_info->numlayers = (&p_j2k->m_cp.tcps[0])->numlayers;
10117
10118                 l_cstr_info->numdecompos = (OPJ_INT32*) opj_malloc(p_j2k->m_image->numcomps * sizeof(OPJ_INT32));
10119
10120                 for (compno=0; compno < p_j2k->m_image->numcomps; compno++) {
10121                         l_cstr_info->numdecompos[compno] = (&p_j2k->m_cp.tcps[0])->tccps->numresolutions - 1;
10122                 }
10123
10124                 l_cstr_info->D_max = 0.0;       */      /* ADD Marcela */
10125
10126                 /*l_cstr_info->main_head_start = opj_stream_tell(p_stream);*/ /* position of SOC */
10127
10128                 /*l_cstr_info->maxmarknum = 100;
10129                 l_cstr_info->marker = (opj_marker_info_t *) opj_malloc(l_cstr_info->maxmarknum * sizeof(opj_marker_info_t));
10130                 l_cstr_info->marknum = 0;
10131         }*/
10132
10133         return opj_j2k_calculate_tp(p_j2k,&(p_j2k->m_cp),&p_j2k->m_specific_param.m_encoder.m_total_tile_parts,p_j2k->m_private_image,p_manager);
10134 }
10135
10136 /**
10137  * Creates a tile-coder decoder.
10138  *
10139  * @param       p_stream                the stream to write data to.
10140  * @param       p_j2k                   J2K codec.
10141  * @param       p_manager               the user event manager.
10142 */
10143 static OPJ_BOOL opj_j2k_create_tcd(     opj_j2k_t *p_j2k,
10144                                                                     opj_stream_private_t *p_stream,
10145                                                                     opj_event_mgr_t * p_manager
10146                                     )
10147 {
10148         /* preconditions */
10149         assert(p_j2k != 00);
10150         assert(p_manager != 00);
10151         assert(p_stream != 00);
10152
10153         p_j2k->m_tcd = opj_tcd_create(OPJ_FALSE);
10154
10155         if (! p_j2k->m_tcd) {
10156                 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to create Tile Coder\n");
10157                 return OPJ_FALSE;
10158         }
10159
10160         if (!opj_tcd_init(p_j2k->m_tcd,p_j2k->m_private_image,&p_j2k->m_cp)) {
10161                 opj_tcd_destroy(p_j2k->m_tcd);
10162                 p_j2k->m_tcd = 00;
10163                 return OPJ_FALSE;
10164         }
10165
10166         return OPJ_TRUE;
10167 }
10168
10169 OPJ_BOOL opj_j2k_write_tile (opj_j2k_t * p_j2k,
10170                                                  OPJ_UINT32 p_tile_index,
10171                                                  OPJ_BYTE * p_data,
10172                                                  OPJ_UINT32 p_data_size,
10173                                                  opj_stream_private_t *p_stream,
10174                                                  opj_event_mgr_t * p_manager )
10175 {
10176         if (! opj_j2k_pre_write_tile(p_j2k,p_tile_index,p_stream,p_manager)) {
10177                 opj_event_msg(p_manager, EVT_ERROR, "Error while opj_j2k_pre_write_tile with tile index = %d\n", p_tile_index);
10178                 return OPJ_FALSE;
10179         }
10180         else {
10181                 if (! opj_j2k_post_write_tile(p_j2k,p_data,p_data_size,p_stream,p_manager)) {
10182                         opj_event_msg(p_manager, EVT_ERROR, "Error while opj_j2k_post_write_tile with tile index = %d\n", p_tile_index);
10183                         return OPJ_FALSE;
10184                 }
10185         }
10186
10187         return OPJ_TRUE;
10188 }