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