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