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