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