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