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