(no commit message)
[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, 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 void j2k_setup_header_reading (opj_j2k_v2_t *p_j2k);
48
49 /**
50  * The read header procedure.
51  */
52 opj_bool j2k_read_header_procedure(
53                                                             opj_j2k_v2_t *p_j2k,
54                                                                 struct opj_stream_private *p_stream,
55                                                                 struct opj_event_mgr * p_manager);
56
57 /**
58  * The default encoding validation procedure without any extension.
59  *
60  * @param       p_j2k                   the jpeg2000 codec to validate.
61  * @param       p_stream                                the input stream to validate.
62  * @param       p_manager               the user event manager.
63  *
64  * @return true if the parameters are correct.
65  */
66 opj_bool j2k_encoding_validation (      opj_j2k_v2_t * p_j2k,
67                                                                         opj_stream_private_t *p_stream,
68                                                                         opj_event_mgr_t * p_manager );
69
70 /**
71  * The default decoding validation procedure without any extension.
72  *
73  * @param       p_j2k                   the jpeg2000 codec to validate.
74  * @param       p_stream                                the input stream to validate.
75  * @param       p_manager               the user event manager.
76  *
77  * @return true if the parameters are correct.
78  */
79 opj_bool j2k_decoding_validation (
80                                                                 opj_j2k_v2_t * p_j2k,
81                                                                 opj_stream_private_t *p_stream,
82                                                                 opj_event_mgr_t * p_manager
83                                                         );
84
85 /**
86  * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
87  * are valid. Developpers wanting to extend the library can add their own validation procedures.
88  */
89 static void j2k_setup_encoding_validation (opj_j2k_v2_t *p_j2k);
90
91 /**
92  * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
93  * are valid. Developpers wanting to extend the library can add their own validation procedures.
94  */
95 static void j2k_setup_decoding_validation (opj_j2k_v2_t *p_j2k);
96
97 /**
98  * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
99  * are valid. Developpers wanting to extend the library can add their own validation procedures.
100  */
101 static void j2k_setup_end_compress (opj_j2k_v2_t *p_j2k);
102
103 /**
104  * The mct encoding validation procedure.
105  *
106  * @param       p_j2k                   the jpeg2000 codec to validate.
107  * @param       p_stream                                the input stream to validate.
108  * @param       p_manager               the user event manager.
109  *
110  * @return true if the parameters are correct.
111  */
112 opj_bool j2k_mct_validation (   opj_j2k_v2_t * p_j2k,
113                                                                 opj_stream_private_t *p_stream,
114                                                                 opj_event_mgr_t * p_manager );
115
116 /**
117  * Builds the tcd decoder to use to decode tile.
118  */
119 opj_bool j2k_build_decoder (opj_j2k_v2_t * p_j2k,
120                                                         opj_stream_private_t *p_stream,
121                                                         opj_event_mgr_t * p_manager );
122 /**
123  * Builds the tcd encoder to use to encode tile.
124  */
125 opj_bool j2k_build_encoder (opj_j2k_v2_t * p_j2k,
126                                                         opj_stream_private_t *p_stream,
127                                                         opj_event_mgr_t * p_manager );
128
129 /**
130  * Creates a tile-coder decoder.
131  *
132  * @param       p_stream                                the stream to write data to.
133  * @param       p_j2k                           J2K codec.
134  * @param       p_manager               the user event manager.
135 */
136 static opj_bool j2k_create_tcd( opj_j2k_v2_t *p_j2k,
137                                                                 struct opj_stream_private *p_stream,
138                                                                 struct opj_event_mgr * p_manager );
139
140 /**
141  * Excutes the given procedures on the given codec.
142  *
143  * @param       p_procedure_list        the list of procedures to execute
144  * @param       p_j2k                                   the jpeg2000 codec to execute the procedures on.
145  * @param       p_stream                                        the stream to execute the procedures on.
146  * @param       p_manager                       the user manager.
147  *
148  * @return      true                            if all the procedures were successfully executed.
149  */
150 static opj_bool j2k_exec (
151                                         opj_j2k_v2_t * p_j2k,
152                                         opj_procedure_list_t * p_procedure_list,
153                                         opj_stream_private_t *p_stream,
154                                         opj_event_mgr_t * p_manager
155                                   );
156
157 /**
158  * Updates the rates of the tcp.
159  *
160  * @param       p_stream                                the stream to write data to.
161  * @param       p_j2k                           J2K codec.
162  * @param       p_manager               the user event manager.
163 */
164 static opj_bool j2k_update_rates(       opj_j2k_v2_t *p_j2k,
165                                                                         struct opj_stream_private *p_stream,
166                                                                         struct opj_event_mgr * p_manager );
167
168 /**
169  * Copies the decoding tile parameters onto all the tile parameters.
170  * Creates also the tile decoder.
171  */
172 opj_bool j2k_copy_default_tcp_and_create_tcd (  opj_j2k_v2_t * p_j2k,
173                                                                                                 opj_stream_private_t *p_stream,
174                                                                                                 opj_event_mgr_t * p_manager );
175
176 /**
177  * Destroys the memory associated with the decoding of headers.
178  */
179 opj_bool j2k_destroy_header_memory (opj_j2k_v2_t * p_j2k,
180                                                                         opj_stream_private_t *p_stream,
181                                                                         opj_event_mgr_t * p_manager );
182
183 /**
184  * Reads the lookup table containing all the marker, status and action, and returns the handler associated
185  * with the marker value.
186  * @param       p_id            Marker value to look up
187  *
188  * @return      the handler associated with the id.
189 */
190 static const struct opj_dec_memory_marker_handler * j2k_get_marker_handler (OPJ_UINT32 p_id);
191
192 /**
193  * Destroys a tile coding parameter structure.
194  *
195  * @param       p_tcp           the tile coding parameter to destroy.
196  */
197 static void j2k_tcp_destroy (opj_tcp_v2_t *p_tcp);
198
199 /**
200  * Destroys the data inside a tile coding parameter structure.
201  *
202  * @param       p_tcp           the tile coding parameter which contain data to destroy.
203  */
204 static void j2k_tcp_data_destroy (opj_tcp_v2_t *p_tcp);
205
206 /**
207  * Destroys a coding parameter structure.
208  *
209  * @param       p_cp            the coding parameter to destroy.
210  */
211 static void j2k_cp_destroy (opj_cp_v2_t *p_cp);
212
213
214 /**
215  * Writes a SPCod or SPCoc element, i.e. the coding style of a given component of a tile.
216  *
217  * @param       p_comp_no       the component number to output.
218  * @param       p_stream                        the stream to write data to.
219  * @param       p_j2k                   J2K codec.
220  * @param       p_manager       the user event manager.
221  *
222 */
223 static opj_bool j2k_write_SPCod_SPCoc(  opj_j2k_v2_t *p_j2k,
224                                                                                 OPJ_UINT32 p_tile_no,
225                                                                                 OPJ_UINT32 p_comp_no,
226                                                                                 OPJ_BYTE * p_data,
227                                                                                 OPJ_UINT32 * p_header_size,
228                                                                                 struct opj_event_mgr * p_manager );
229
230 /**
231  * Gets the size taken by writing a SPCod or SPCoc for the given tile and component.
232  *
233  * @param       p_tile_no               the tile index.
234  * @param       p_comp_no               the component being outputted.
235  * @param       p_j2k                   the J2K codec.
236  *
237  * @return      the number of bytes taken by the SPCod element.
238  */
239 static OPJ_UINT32 j2k_get_SPCod_SPCoc_size (opj_j2k_v2_t *p_j2k,
240                                                                                         OPJ_UINT32 p_tile_no,
241                                                                                         OPJ_UINT32 p_comp_no );
242
243 /**
244  * Reads a SPCod or SPCoc element, i.e. the coding style of a given component of a tile.
245  * @param       p_header_data   the data contained in the COM box.
246  * @param       p_j2k                   the jpeg2000 codec.
247  * @param       p_header_size   the size of the data contained in the COM marker.
248  * @param       p_manager               the user event manager.
249 */
250 static opj_bool j2k_read_SPCod_SPCoc(
251                                                         opj_j2k_v2_t *p_j2k,
252                                                         OPJ_UINT32 compno,
253                                                         OPJ_BYTE * p_header_data,
254                                                         OPJ_UINT32 * p_header_size,
255                                                         struct opj_event_mgr * p_manager
256                                                         );
257
258 /**
259  * Gets the size taken by writing SQcd or SQcc element, i.e. the quantization values of a band in the QCD or QCC.
260  *
261  * @param       p_tile_no               the tile index.
262  * @param       p_comp_no               the component being outputted.
263  * @param       p_j2k                   the J2K codec.
264  *
265  * @return      the number of bytes taken by the SPCod element.
266  */
267 static OPJ_UINT32 j2k_get_SQcd_SQcc_size (      opj_j2k_v2_t *p_j2k,
268                                                                                 OPJ_UINT32 p_tile_no,
269                                                                                 OPJ_UINT32 p_comp_no );
270
271 /**
272  * Writes a SQcd or SQcc element, i.e. the quantization values of a band in the QCD or QCC.
273  *
274  * @param       p_tile_no               the tile to output.
275  * @param       p_comp_no               the component number to output.
276  * @param       p_data                  the data buffer.
277  * @param       p_header_size   pointer to the size of the data buffer, it is changed by the function.
278  * @param       p_j2k                   J2K codec.
279  * @param       p_manager               the user event manager.
280  *
281 */
282 static opj_bool j2k_write_SQcd_SQcc(opj_j2k_v2_t *p_j2k,
283                                                                         OPJ_UINT32 p_tile_no,
284                                                                         OPJ_UINT32 p_comp_no,
285                                                                         OPJ_BYTE * p_data,
286                                                                         OPJ_UINT32 * p_header_size,
287                                                                         struct opj_event_mgr * p_manager
288                                                                         );
289
290 /**
291  * Updates the Tile Length Marker.
292  */
293 static void j2k_update_tlm ( opj_j2k_v2_t * p_j2k, OPJ_UINT32 p_tile_part_size);
294
295 /**
296  * Reads a SQcd or SQcc element, i.e. the quantization values of a band in the QCD or QCC.
297  *
298  * @param       p_tile_no               the tile to output.
299  * @param       p_comp_no               the component number to output.
300  * @param       p_data                  the data buffer.
301  * @param       p_header_size   pointer to the size of the data buffer, it is changed by the function.
302  * @param       p_j2k                           J2K codec.
303  * @param       p_manager               the user event manager.
304  *
305 */
306 static opj_bool j2k_read_SQcd_SQcc(
307                                                         opj_j2k_v2_t *p_j2k,
308                                                         OPJ_UINT32 compno,
309                                                         OPJ_BYTE * p_header_data,
310                                                         OPJ_UINT32 * p_header_size,
311                                                         struct opj_event_mgr * p_manager
312                                         );
313
314 /**
315  * Copies the tile component parameters of all the component from the first tile component.
316  *
317  * @param               p_j2k           the J2k codec.
318  */
319 static void j2k_copy_tile_component_parameters(
320                                                         opj_j2k_v2_t *p_j2k
321                                                         );
322
323 /**
324  * Copies the tile quantization parameters of all the component from the first tile component.
325  *
326  * @param               p_j2k           the J2k codec.
327  */
328 static void j2k_copy_tile_quantization_parameters(
329                                                         opj_j2k_v2_t *p_j2k
330                                                         );
331
332 /**
333  * Reads the tiles.
334  */
335 opj_bool j2k_decode_tiles (     opj_j2k_v2_t *p_j2k,
336                                                         opj_stream_private_t *p_stream,
337                                                         opj_event_mgr_t * p_manager);
338
339
340 static opj_bool j2k_pre_write_tile ( opj_j2k_v2_t * p_j2k,
341                                                                          OPJ_UINT32 p_tile_index,
342                                                                          opj_stream_private_t *p_stream,
343                                                                          opj_event_mgr_t * p_manager );
344
345 static opj_bool j2k_update_image_data (opj_tcd_v2_t * p_tcd, OPJ_BYTE * p_data, opj_image_t* p_output_image);
346
347 static void j2k_get_tile_data (opj_tcd_v2_t * p_tcd, OPJ_BYTE * p_data);
348
349 static opj_bool j2k_post_write_tile (opj_j2k_v2_t * p_j2k,
350                                                                          OPJ_BYTE * p_data,
351                                                                          OPJ_UINT32 p_data_size,
352                                                                          opj_stream_private_t *p_stream,
353                                                                          opj_event_mgr_t * p_manager );
354
355 /**
356  * Sets up the procedures to do on writing header.
357  * Developers wanting to extend the library can add their own writing procedures.
358  */
359 void j2k_setup_header_writting (opj_j2k_v2_t *p_j2k);
360
361 static opj_bool j2k_write_first_tile_part(      opj_j2k_v2_t *p_j2k,
362                                                                                         OPJ_BYTE * p_data,
363                                                                                         OPJ_UINT32 * p_data_written,
364                                                                                         OPJ_UINT32 p_total_data_size,
365                                                                                         opj_stream_private_t *p_stream,
366                                                                                         struct opj_event_mgr * p_manager );
367
368 static opj_bool j2k_write_all_tile_parts(       opj_j2k_v2_t *p_j2k,
369                                                                                         OPJ_BYTE * p_data,
370                                                                                         OPJ_UINT32 * p_data_written,
371                                                                                         OPJ_UINT32 p_total_data_size,
372                                                                                         opj_stream_private_t *p_stream,
373                                                                                         struct opj_event_mgr * p_manager );
374
375 /**
376  * Gets the offset of the header.
377  *
378  * @param       p_stream                the stream to write data to.
379  * @param       p_j2k                   J2K codec.
380  * @param       p_manager               the user event manager.
381 */
382 static opj_bool j2k_get_end_header(     opj_j2k_v2_t *p_j2k,
383                                                                         struct opj_stream_private *p_stream,
384                                                                         struct opj_event_mgr * p_manager );
385
386 /*
387  * -----------------------------------------------------------------------
388  * -----------------------------------------------------------------------
389  * -----------------------------------------------------------------------
390  */
391
392 /**
393 Write the SOC marker (Start Of Codestream)
394 @param j2k J2K handle
395 */
396 static void j2k_write_soc(opj_j2k_t *j2k);
397
398 /**
399  * Writes the SOC marker (Start Of Codestream)
400  *
401  * @param       p_stream                        the stream to write data to.
402  * @param       p_j2k                   J2K codec.
403  * @param       p_manager       the user event manager.
404 */
405 static opj_bool j2k_write_soc_v2(       opj_j2k_v2_t *p_j2k,
406                                                                         struct opj_stream_private *p_stream,
407                                                                         struct opj_event_mgr * p_manager );
408
409 /**
410 Read the SOC marker (Start of Codestream)
411 @param j2k J2K handle
412 */
413 static void j2k_read_soc(opj_j2k_t *j2k);
414
415 /**
416  * Reads a SOC marker (Start of Codestream)
417  * @param       p_header_data   the data contained in the SOC box.
418  * @param       jp2                             the jpeg2000 file codec.
419  * @param       p_header_size   the size of the data contained in the SOC marker.
420  * @param       p_manager               the user event manager.
421 */
422 static opj_bool j2k_read_soc_v2(
423                                         opj_j2k_v2_t *p_j2k,
424                                         struct opj_stream_private *p_stream,
425                                         struct opj_event_mgr * p_manager
426                                  );
427
428 /**
429 Write the SIZ marker (image and tile size)
430 @param j2k J2K handle
431 */
432 static void j2k_write_siz(opj_j2k_t *j2k);
433
434 /**
435  * Writes the SIZ marker (image and tile size)
436  *
437  * @param       p_stream                        the stream to write data to.
438  * @param       p_j2k                   J2K codec.
439  * @param       p_manager       the user event manager.
440 */
441 static opj_bool j2k_write_siz_v2(       opj_j2k_v2_t *p_j2k,
442                                                                         struct opj_stream_private *p_stream,
443                                                                         struct opj_event_mgr * p_manager );
444
445 /**
446 Read the SIZ marker (image and tile size)
447 @param j2k J2K handle
448 */
449 static void j2k_read_siz(opj_j2k_t *j2k);
450
451 /**
452  * Reads a SIZ marker (image and tile size)
453  * @param       p_header_data   the data contained in the SIZ box.
454  * @param       jp2                             the jpeg2000 file codec.
455  * @param       p_header_size   the size of the data contained in the SIZ marker.
456  * @param       p_manager               the user event manager.
457 */
458 static opj_bool j2k_read_siz_v2 (
459                                                   opj_j2k_v2_t *p_j2k,
460                                                   OPJ_BYTE * p_header_data,
461                                                   OPJ_UINT32 p_header_size,
462                                                   struct opj_event_mgr * p_manager
463                                         );
464
465 /**
466 Write the COM marker (comment)
467 @param j2k J2K handle
468 */
469 static void j2k_write_com(opj_j2k_t *j2k);
470
471 /**
472  * Writes the COM marker (comment)
473  * 
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 j2k_write_com_v2(       opj_j2k_v2_t *p_j2k,
479                                                                         struct opj_stream_private *p_stream,
480                                                                         struct opj_event_mgr * p_manager );
481
482 /**
483 Read the COM marker (comment)
484 @param j2k J2K handle
485 */
486 static void j2k_read_com(opj_j2k_t *j2k);
487 /**
488  * Reads a COM marker (comments)
489  * @param       p_header_data   the data contained in the COM box.
490  * @param       jp2                             the jpeg2000 file codec.
491  * @param       p_header_size   the size of the data contained in the COM marker.
492  * @param       p_manager               the user event manager.
493 */
494 static opj_bool j2k_read_com_v2 (
495                                         opj_j2k_v2_t *p_j2k,
496                                         OPJ_BYTE * p_header_data,
497                                         OPJ_UINT32 p_header_size,
498                                         struct opj_event_mgr * p_manager
499                                         );
500 /**
501 Write the value concerning the specified component in the marker COD and COC
502 @param j2k J2K handle
503 @param compno Number of the component concerned by the information written
504 */
505 static void j2k_write_cox(opj_j2k_t *j2k, int compno);
506 /**
507 Read the value concerning the specified component in the marker COD and COC
508 @param j2k J2K handle
509 @param compno Number of the component concerned by the information read
510 */
511 static void j2k_read_cox(opj_j2k_t *j2k, int compno);
512 /**
513 Write the COD marker (coding style default)
514 @param j2k J2K handle
515 */
516 static void j2k_write_cod(opj_j2k_t *j2k);
517
518 /**
519  * Writes the COD marker (Coding style default)
520  *
521  * @param       p_stream                        the stream to write data to.
522  * @param       p_j2k                   J2K codec.
523  * @param       p_manager       the user event manager.
524 */
525 static opj_bool j2k_write_cod_v2(       opj_j2k_v2_t *p_j2k,
526                                                                         struct opj_stream_private *p_stream,
527                                                                         struct opj_event_mgr * p_manager );
528
529 /**
530 Read the COD marker (coding style default)
531 @param j2k J2K handle
532 */
533 static void j2k_read_cod(opj_j2k_t *j2k);
534
535 /**
536  * Reads a COD marker (Coding Styke defaults)
537  * @param       p_header_data   the data contained in the COD box.
538  * @param       p_j2k                   the jpeg2000 codec.
539  * @param       p_header_size   the size of the data contained in the COD marker.
540  * @param       p_manager               the user event manager.
541 */
542 static opj_bool j2k_read_cod_v2 (
543                                         opj_j2k_v2_t *p_j2k,
544                                         OPJ_BYTE * p_header_data,
545                                         OPJ_UINT32 p_header_size,
546                                         struct opj_event_mgr * p_manager
547                                         );
548
549 /**
550 Write the COC marker (coding style component)
551 @param j2k J2K handle
552 @param compno Number of the component concerned by the information written
553 */
554 static void j2k_write_coc(opj_j2k_t *j2k, int compno);
555
556 /**
557  * Writes the COC marker (Coding style component)
558  *
559  * @param       p_comp_number   the index of the component to output.
560  * @param       p_stream                                the stream to write data to.
561  * @param       p_j2k                           J2K codec.
562  * @param       p_manager               the user event manager.
563 */
564 static opj_bool j2k_write_coc_v2( opj_j2k_v2_t *p_j2k,
565                                                         OPJ_UINT32 p_comp_number,
566                                                         struct opj_stream_private *p_stream,
567                                                         struct opj_event_mgr * p_manager
568                                                   );
569 /**
570  * Writes the COC marker (Coding style component)
571  *
572  * @param       p_comp_no               the index of the component to output.
573  * @param       p_stream                the stream to write data to.
574  * @param       p_j2k                   J2K codec.
575  * @param       p_manager               the user event manager.
576 */
577 static void j2k_write_coc_in_memory(opj_j2k_v2_t *p_j2k,
578                                                                         OPJ_UINT32 p_comp_no,
579                                                                         OPJ_BYTE * p_data,
580                                                                         OPJ_UINT32 * p_data_written,
581                                                                         struct opj_event_mgr * p_manager );
582
583 /**
584  * Gets the maximum size taken by a coc.
585  *
586  * @param       p_j2k   the jpeg2000 codec to use.
587  */
588 static OPJ_UINT32 j2k_get_max_coc_size(opj_j2k_v2_t *p_j2k);
589
590 /**
591 Read the COC marker (coding style component)
592 @param j2k J2K handle
593 */
594 static void j2k_read_coc(opj_j2k_t *j2k);
595
596 /**
597  * Reads a COC marker (Coding Style Component)
598  * @param       p_header_data   the data contained in the COC box.
599  * @param       p_j2k                   the jpeg2000 codec.
600  * @param       p_header_size   the size of the data contained in the COC marker.
601  * @param       p_manager               the user event manager.
602 */
603 static opj_bool j2k_read_coc_v2 (
604                                         opj_j2k_v2_t *p_j2k,
605                                         OPJ_BYTE * p_header_data,
606                                         OPJ_UINT32 p_header_size,
607                                         struct opj_event_mgr * p_manager
608                                         );
609
610 /**
611 Write the value concerning the specified component in the marker QCD and QCC
612 @param j2k J2K handle
613 @param compno Number of the component concerned by the information written
614 */
615 static void j2k_write_qcx(opj_j2k_t *j2k, int compno);
616 /**
617 Read the value concerning the specified component in the marker QCD and QCC
618 @param j2k J2K handle
619 @param compno Number of the component concern by the information read
620 @param len Length of the information in the QCX part of the marker QCD/QCC
621 */
622 static void j2k_read_qcx(opj_j2k_t *j2k, int compno, int len);
623 /**
624 Write the QCD marker (quantization default)
625 @param j2k J2K handle
626 */
627 static void j2k_write_qcd(opj_j2k_t *j2k);
628
629 /**
630  * Writes the QCD marker (quantization default)
631  *
632  * @param       p_comp_number   the index of the component to output.
633  * @param       p_stream                the stream to write data to.
634  * @param       p_j2k                   J2K codec.
635  * @param       p_manager               the user event manager.
636 */
637 static opj_bool j2k_write_qcd_v2(       opj_j2k_v2_t *p_j2k,
638                                                                         struct opj_stream_private *p_stream,
639                                                                         struct opj_event_mgr * p_manager );
640
641 /**
642 Read the QCD marker (quantization default)
643 @param j2k J2K handle
644 */
645 static void j2k_read_qcd(opj_j2k_t *j2k);
646
647 /**
648  * Reads a QCD marker (Quantization defaults)
649  * @param       p_header_data   the data contained in the QCD box.
650  * @param       p_j2k                   the jpeg2000 codec.
651  * @param       p_header_size   the size of the data contained in the QCD marker.
652  * @param       p_manager               the user event manager.
653 */
654 static opj_bool j2k_read_qcd_v2 (
655                                         opj_j2k_v2_t *p_j2k,
656                                         OPJ_BYTE * p_header_data,
657                                         OPJ_UINT32 p_header_size,
658                                         struct opj_event_mgr * p_manager
659                                         );
660
661 /**
662 Write the QCC marker (quantization component)
663 @param j2k J2K handle
664 @param compno Number of the component concerned by the information written
665 */
666 static void j2k_write_qcc(opj_j2k_t *j2k, int compno);
667
668 /**
669  * Writes the QCC marker (quantization component)
670  *
671  * @param       p_comp_no       the index of the component to output.
672  * @param       p_stream                the stream to write data to.
673  * @param       p_j2k                   J2K codec.
674  * @param       p_manager               the user event manager.
675 */
676 static opj_bool j2k_write_qcc_v2(       opj_j2k_v2_t *p_j2k,
677                                                                         OPJ_UINT32 p_comp_no,
678                                                                         struct opj_stream_private *p_stream,
679                                                                         struct opj_event_mgr * p_manager );
680
681 /**
682  * Writes the QCC marker (quantization component)
683  *
684  * @param       p_comp_no       the index of the component to output.
685  * @param       p_stream                the stream to write data to.
686  * @param       p_j2k                   J2K codec.
687  * @param       p_manager               the user event manager.
688 */
689 static void j2k_write_qcc_in_memory(opj_j2k_v2_t *p_j2k,
690                                                                         OPJ_UINT32 p_comp_no,
691                                                                         OPJ_BYTE * p_data,
692                                                                         OPJ_UINT32 * p_data_written,
693                                                                         struct opj_event_mgr * p_manager );
694
695 /**
696  * Gets the maximum size taken by a qcc.
697  */
698 static OPJ_UINT32 j2k_get_max_qcc_size (opj_j2k_v2_t *p_j2k);
699
700 /**
701 Read the QCC marker (quantization component)
702 @param j2k J2K handle
703 */
704 static void j2k_read_qcc(opj_j2k_t *j2k);
705 /**
706  * Reads a QCC marker (Quantization component)
707  * @param       p_header_data   the data contained in the QCC box.
708  * @param       p_j2k                   the jpeg2000 codec.
709  * @param       p_header_size   the size of the data contained in the QCC marker.
710  * @param       p_manager               the user event manager.
711 */
712 static opj_bool j2k_read_qcc_v2(
713                                                         opj_j2k_v2_t *p_j2k,
714                                                         OPJ_BYTE * p_header_data,
715                                                         OPJ_UINT32 p_header_size,
716                                                         struct opj_event_mgr * p_manager);
717
718 /**
719 Write the POC marker (progression order change)
720 @param j2k J2K handle
721 */
722 static void j2k_write_poc(opj_j2k_t *j2k);
723
724 /**
725  * Writes the POC marker (Progression Order Change)
726  * 
727  * @param       p_stream                                the stream to write data to.
728  * @param       p_j2k                           J2K codec.
729  * @param       p_manager               the user event manager.
730 */
731 static opj_bool j2k_write_poc_v2(       opj_j2k_v2_t *p_j2k,
732                                                                         struct opj_stream_private *p_stream,
733                                                                         struct opj_event_mgr * p_manager );
734
735 /**
736  * Writes the POC marker (Progression Order Change)
737  *
738  * @param       p_stream                the stream to write data to.
739  * @param       p_j2k                   J2K codec.
740  * @param       p_manager               the user event manager.
741  */
742 static void j2k_write_poc_in_memory(opj_j2k_v2_t *p_j2k,
743                                                                         OPJ_BYTE * p_data,
744                                                                         OPJ_UINT32 * p_data_written,
745                                                                         struct opj_event_mgr * p_manager );
746
747 /**
748  * Gets the maximum size taken by the writting of a POC.
749  */
750 static OPJ_UINT32 j2k_get_max_poc_size(opj_j2k_v2_t *p_j2k);
751
752 /**
753  * Gets the maximum size taken by the toc headers of all the tile parts of any given tile.
754  */
755 static OPJ_UINT32 j2k_get_max_toc_size (opj_j2k_v2_t *p_j2k);
756
757 /**
758  * Gets the maximum size taken by the headers of the SOT.
759  *
760  * @param       p_j2k   the jpeg2000 codec to use.
761  */
762 static OPJ_UINT32 j2k_get_specific_header_sizes(opj_j2k_v2_t *p_j2k);
763
764 /**
765 Read the POC marker (progression order change)
766 @param j2k J2K handle
767 */
768 static void j2k_read_poc(opj_j2k_t *j2k);
769 /**
770  * Reads a POC marker (Progression Order Change)
771  *
772  * @param       p_header_data   the data contained in the POC box.
773  * @param       p_j2k                   the jpeg2000 codec.
774  * @param       p_header_size   the size of the data contained in the POC marker.
775  * @param       p_manager               the user event manager.
776 */
777 static opj_bool j2k_read_poc_v2 (
778                                                 opj_j2k_v2_t *p_j2k,
779                                                 OPJ_BYTE * p_header_data,
780                                                 OPJ_UINT32 p_header_size,
781                                                 struct opj_event_mgr * p_manager
782                                         );
783
784 /**
785 Read the CRG marker (component registration)
786 @param j2k J2K handle
787 */
788 static void j2k_read_crg(opj_j2k_t *j2k);
789 /**
790  * Reads a CRG marker (Component registration)
791  *
792  * @param       p_header_data   the data contained in the TLM box.
793  * @param       p_j2k                   the jpeg2000 codec.
794  * @param       p_header_size   the size of the data contained in the TLM marker.
795  * @param       p_manager               the user event manager.
796 */
797 static opj_bool j2k_read_crg_v2 (
798                                                 opj_j2k_v2_t *p_j2k,
799                                                 OPJ_BYTE * p_header_data,
800                                                 OPJ_UINT32 p_header_size,
801                                                 struct opj_event_mgr * p_manager
802                                         );
803 /**
804 Read the TLM marker (tile-part lengths)
805 @param j2k J2K handle
806 */
807 static void j2k_read_tlm(opj_j2k_t *j2k);
808 /**
809  * Reads a TLM marker (Tile Length Marker)
810  *
811  * @param       p_header_data   the data contained in the TLM box.
812  * @param       p_j2k                   the jpeg2000 codec.
813  * @param       p_header_size   the size of the data contained in the TLM marker.
814  * @param       p_manager               the user event manager.
815 */
816 static opj_bool j2k_read_tlm_v2 (
817                                                 opj_j2k_v2_t *p_j2k,
818                                                 OPJ_BYTE * p_header_data,
819                                                 OPJ_UINT32 p_header_size,
820                                                 struct opj_event_mgr * p_manager
821                                         );
822
823 /**
824  * Writes the updated tlm.
825  *
826  * @param       p_stream                the stream to write data to.
827  * @param       p_j2k                   J2K codec.
828  * @param       p_manager               the user event manager.
829 */
830 static opj_bool j2k_write_updated_tlm(  opj_j2k_v2_t *p_j2k,
831                                                                                 struct opj_stream_private *p_stream,
832                                                                                 struct opj_event_mgr * p_manager );
833
834 /**
835 Read the PLM marker (packet length, main header)
836 @param j2k J2K handle
837 */
838 static void j2k_read_plm(opj_j2k_t *j2k);
839
840 /**
841  * Reads a PLM marker (Packet length, main header marker)
842  *
843  * @param       p_header_data   the data contained in the TLM box.
844  * @param       p_j2k                   the jpeg2000 codec.
845  * @param       p_header_size   the size of the data contained in the TLM marker.
846  * @param       p_manager               the user event manager.
847 */
848 static opj_bool j2k_read_plm_v2 (
849                                                 opj_j2k_v2_t *p_j2k,
850                                                 OPJ_BYTE * p_header_data,
851                                                 OPJ_UINT32 p_header_size,
852                                                 struct opj_event_mgr * p_manager
853                                         );
854 /**
855 Read the PLT marker (packet length, tile-part header)
856 @param j2k J2K handle
857 */
858 static void j2k_read_plt(opj_j2k_t *j2k);
859 /**
860  * Reads a PLT marker (Packet length, tile-part header)
861  *
862  * @param       p_header_data   the data contained in the PLT box.
863  * @param       p_j2k                   the jpeg2000 codec.
864  * @param       p_header_size   the size of the data contained in the PLT marker.
865  * @param       p_manager               the user event manager.
866 */
867 static opj_bool j2k_read_plt_v2 (
868                                                 opj_j2k_v2_t *p_j2k,
869                                                 OPJ_BYTE * p_header_data,
870                                                 OPJ_UINT32 p_header_size,
871                                                 struct opj_event_mgr * p_manager
872                                         );
873 /**
874 Read the PPM marker (packet packet headers, main header)
875 @param j2k J2K handle
876 */
877 static void j2k_read_ppm(opj_j2k_t *j2k);
878 /**
879  * Reads a PPM marker (Packed packet headers, main header)
880  *
881  * @param       p_header_data   the data contained in the POC box.
882  * @param       p_j2k                   the jpeg2000 codec.
883  * @param       p_header_size   the size of the data contained in the POC marker.
884  * @param       p_manager               the user event manager.
885 */
886 #if 0
887 static opj_bool j2k_read_ppm_v2 (
888                                                 opj_j2k_v2_t *p_j2k,
889                                                 OPJ_BYTE * p_header_data,
890                                                 OPJ_UINT32 p_header_size,
891                                                 struct opj_event_mgr * p_manager
892                                         );
893 #endif
894
895 static opj_bool j2k_read_ppm_v3 (
896                                                 opj_j2k_v2_t *p_j2k,
897                                                 OPJ_BYTE * p_header_data,
898                                                 OPJ_UINT32 p_header_size,
899                                                 struct opj_event_mgr * p_manager
900                                         );
901
902 /**
903 Read the PPT marker (packet packet headers, tile-part header)
904 @param j2k J2K handle
905 */
906 static void j2k_read_ppt(opj_j2k_t *j2k);
907 /**
908  * Reads a PPT marker (Packed packet headers, tile-part header)
909  *
910  * @param       p_header_data   the data contained in the PPT box.
911  * @param       p_j2k                   the jpeg2000 codec.
912  * @param       p_header_size   the size of the data contained in the PPT marker.
913  * @param       p_manager               the user event manager.
914 */
915 static opj_bool j2k_read_ppt_v2 (
916                                                 opj_j2k_v2_t *p_j2k,
917                                                 OPJ_BYTE * p_header_data,
918                                                 OPJ_UINT32 p_header_size,
919                                                 struct opj_event_mgr * p_manager
920                                         );
921 /**
922 Write the TLM marker (Mainheader)
923 @param j2k J2K handle
924 */
925 static void j2k_write_tlm(opj_j2k_t *j2k);
926
927 /**
928  * Writes the TLM marker (Tile Length Marker)
929  * 
930  * @param       p_stream                                the stream to write data to.
931  * @param       p_j2k                           J2K codec.
932  * @param       p_manager               the user event manager.
933 */
934 static opj_bool j2k_write_tlm_v2(       opj_j2k_v2_t *p_j2k,
935                                                                         struct opj_stream_private *p_stream,
936                                                                         struct opj_event_mgr * p_manager );
937
938 /**
939 Write the SOT marker (start of tile-part)
940 @param j2k J2K handle
941 */
942 static void j2k_write_sot(opj_j2k_t *j2k);
943 /**
944 Read the SOT marker (start of tile-part)
945 @param j2k J2K handle
946 */
947 static void j2k_read_sot(opj_j2k_t *j2k);
948
949 /**
950  * Writes the SOT marker (Start of tile-part)
951  *
952  * @param       p_stream                the stream to write data to.
953  * @param       p_j2k                   J2K codec.
954  * @param       p_manager               the user event manager.
955 */
956 static opj_bool j2k_write_sot_v2(       opj_j2k_v2_t *p_j2k,
957                                                                         OPJ_BYTE * p_data,
958                                                                         OPJ_UINT32 * p_data_written,
959                                                                         const struct opj_stream_private *p_stream,
960                                                                         struct opj_event_mgr * p_manager );
961
962 /**
963  * Reads a PPT marker (Packed packet headers, tile-part header)
964  *
965  * @param       p_header_data   the data contained in the PPT box.
966  * @param       p_j2k                   the jpeg2000 codec.
967  * @param       p_header_size   the size of the data contained in the PPT marker.
968  * @param       p_manager               the user event manager.
969 */
970 static opj_bool j2k_read_sot_v2 (
971                                                 opj_j2k_v2_t *p_j2k,
972                                                 OPJ_BYTE * p_header_data,
973                                                 OPJ_UINT32 p_header_size,
974                                                 struct opj_event_mgr * p_manager
975                                         );
976 /**
977 Write the SOD marker (start of data)
978 @param j2k J2K handle
979 @param tile_coder Pointer to a TCD handle
980 */
981 static void j2k_write_sod(opj_j2k_t *j2k, void *tile_coder);
982
983 /**
984  * Writes the SOD marker (Start of data)
985  *
986  * @param       p_stream                                the stream to write data to.
987  * @param       p_j2k                           J2K codec.
988  * @param       p_manager               the user event manager.
989 */
990 static opj_bool j2k_write_sod_v2(       opj_j2k_v2_t *p_j2k,
991                                                                         struct opj_tcd_v2 * p_tile_coder,
992                                                                         OPJ_BYTE * p_data,
993                                                                         OPJ_UINT32 * p_data_written,
994                                                                         OPJ_UINT32 p_total_data_size,
995                                                                         const struct opj_stream_private *p_stream,
996                                                                         struct opj_event_mgr * p_manager );
997
998 /**
999 Read the SOD marker (start of data)
1000 @param j2k J2K handle
1001 */
1002 static void j2k_read_sod(opj_j2k_t *j2k);
1003
1004 /**
1005  * Reads a SOD marker (Start Of Data)
1006  *
1007  * @param       p_header_data   the data contained in the SOD box.
1008  * @param       p_j2k                   the jpeg2000 codec.
1009  * @param       p_header_size   the size of the data contained in the SOD marker.
1010  * @param       p_manager               the user event manager.
1011 */
1012 static opj_bool j2k_read_sod_v2 (
1013                                                 opj_j2k_v2_t *p_j2k,
1014                                                 struct opj_stream_private *p_stream,
1015                                                 struct opj_event_mgr * p_manager
1016                                         );
1017
1018 /**
1019  * Updates the Tile Length Marker.
1020  */
1021 void j2k_update_tlm (opj_j2k_v2_t * p_j2k, OPJ_UINT32 p_tile_part_size )
1022 {
1023         opj_write_bytes(p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current,p_j2k->m_current_tile_number,1);                                    /* PSOT */
1024         ++p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current;
1025
1026         opj_write_bytes(p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current,p_tile_part_size,4);                                        /* PSOT */
1027         p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current += 4;
1028 }
1029
1030 /**
1031 Write the RGN marker (region-of-interest)
1032 @param j2k J2K handle
1033 @param compno Number of the component concerned by the information written
1034 @param tileno Number of the tile concerned by the information written
1035 */
1036 static void j2k_write_rgn(opj_j2k_t *j2k, int compno, int tileno);
1037
1038 /**
1039  * Writes the RGN marker (Region Of Interest)
1040  *
1041  * @param       p_tile_no               the tile to output
1042  * @param       p_comp_no               the component to output
1043  * @param       p_stream                                the stream to write data to.
1044  * @param       p_j2k                           J2K codec.
1045  * @param       p_manager               the user event manager.
1046 */
1047 static opj_bool j2k_write_rgn_v2(       opj_j2k_v2_t *p_j2k,
1048                                                                         OPJ_UINT32 p_tile_no,
1049                                                                         OPJ_UINT32 p_comp_no,
1050                                                                         struct opj_stream_private *p_stream,
1051                                                                         struct opj_event_mgr * p_manager );
1052
1053 /**
1054 Read the RGN marker (region-of-interest)
1055 @param j2k J2K handle
1056 */
1057 static void j2k_read_rgn(opj_j2k_t *j2k);
1058
1059 /**
1060  * Reads a RGN marker (Region Of Interest)
1061  *
1062  * @param       p_header_data   the data contained in the POC box.
1063  * @param       p_j2k                   the jpeg2000 codec.
1064  * @param       p_header_size   the size of the data contained in the POC marker.
1065  * @param       p_manager               the user event manager.
1066 */
1067 static opj_bool j2k_read_rgn_v2 (
1068                                                 opj_j2k_v2_t *p_j2k,
1069                                                 OPJ_BYTE * p_header_data,
1070                                                 OPJ_UINT32 p_header_size,
1071                                                 struct opj_event_mgr * p_manager
1072                                         ) ;
1073
1074 /**
1075  * Writes the EOC marker (End of Codestream)
1076  * 
1077  * @param       p_stream                the stream to write data to.
1078  * @param       p_j2k                   J2K codec.
1079  * @param       p_manager               the user event manager.
1080 */
1081 static opj_bool j2k_write_eoc_v2(       opj_j2k_v2_t *p_j2k,
1082                                                                         struct opj_stream_private *p_stream,
1083                                                                         struct opj_event_mgr * p_manager );
1084
1085 /**
1086 Write the EOC marker (end of codestream)
1087 @param j2k J2K handle
1088 */
1089 static void j2k_write_eoc(opj_j2k_t *j2k);
1090 /**
1091 Read the EOC marker (end of codestream)
1092 @param j2k J2K handle
1093 */
1094 static void j2k_read_eoc(opj_j2k_t *j2k);
1095
1096 /**
1097  * Reads a EOC marker (End Of Codestream)
1098  *
1099  * @param       p_header_data   the data contained in the SOD box.
1100  * @param       p_j2k                   the jpeg2000 codec.
1101  * @param       p_header_size   the size of the data contained in the SOD marker.
1102  * @param       p_manager               the user event manager.
1103 */
1104 #if 0
1105 static opj_bool j2k_read_eoc_v2 (
1106                                             opj_j2k_v2_t *p_j2k,
1107                                                 struct opj_stream_private *p_stream,
1108                                                 struct opj_event_mgr * p_manager
1109                                         ) ;
1110 #endif
1111
1112
1113
1114 /**
1115  * Writes the CBD-MCT-MCC-MCO markers (Multi components transform)
1116  *
1117  * @param       p_stream                        the stream to write data to.
1118  * @param       p_j2k                   J2K codec.
1119  * @param       p_manager       the user event manager.
1120 */
1121 static opj_bool j2k_write_mct_data_group(       opj_j2k_v2_t *p_j2k,
1122                                                                                         struct opj_stream_private *p_stream,
1123                                                                                         struct opj_event_mgr * p_manager );
1124
1125 /**
1126  * Inits the Info
1127  *
1128  * @param       p_stream                the stream to write data to.
1129  * @param       p_j2k                   J2K codec.
1130  * @param       p_manager               the user event manager.
1131 */
1132 static opj_bool j2k_init_info(  opj_j2k_v2_t *p_j2k,
1133                                                                 struct opj_stream_private *p_stream,
1134                                                                 struct opj_event_mgr * p_manager );
1135
1136 /**
1137 Read an unknown marker
1138 @param j2k J2K handle
1139 */
1140 static void j2k_read_unk(opj_j2k_t *j2k);
1141 /**
1142 Add main header marker information
1143 @param cstr_info Codestream information structure
1144 @param type marker type
1145 @param pos byte offset of marker segment
1146 @param len length of marker segment
1147  */
1148 static void j2k_add_mhmarker(opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len);
1149
1150 static void j2k_add_mhmarker_v2(opj_codestream_index_t *cstr_index, OPJ_UINT32 type, OPJ_OFF_T pos, OPJ_UINT32 len) ;
1151 /**
1152 Add tile header marker information
1153 @param tileno tile index number
1154 @param cstr_info Codestream information structure
1155 @param type marker type
1156 @param pos byte offset of marker segment
1157 @param len length of marker segment
1158  */
1159 static void j2k_add_tlmarker( int tileno, opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len);
1160
1161 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);
1162
1163 /**
1164  * Reads an unknown marker
1165  *
1166  * @param       p_stream                the stream object to read from.
1167  * @param       p_j2k                   the jpeg2000 codec.
1168  * @param       p_manager               the user event manager.
1169  *
1170  * @return      true                    if the marker could be deduced.
1171 */
1172 static opj_bool j2k_read_unk_v2 (       opj_j2k_v2_t *p_j2k,
1173                                                                         struct opj_stream_private *p_stream,
1174                                                                         OPJ_UINT32 *output_marker,
1175                                                                         struct opj_event_mgr * p_manager );
1176
1177 /**
1178  * Writes the MCT marker (Multiple Component Transform)
1179  *
1180  * @param       p_stream                                the stream to write data to.
1181  * @param       p_j2k                           J2K codec.
1182  * @param       p_manager               the user event manager.
1183 */
1184 static opj_bool j2k_write_mct_record(   opj_j2k_v2_t *p_j2k,
1185                                                                                 opj_mct_data_t * p_mct_record,
1186                                                                                 struct opj_stream_private *p_stream,
1187                                                                                 struct opj_event_mgr * p_manager );
1188
1189 /**
1190  * Reads a MCT marker (Multiple Component Transform)
1191  *
1192  * @param       p_header_data   the data contained in the MCT box.
1193  * @param       p_j2k                   the jpeg2000 codec.
1194  * @param       p_header_size   the size of the data contained in the MCT marker.
1195  * @param       p_manager               the user event manager.
1196 */
1197 static opj_bool j2k_read_mct (  opj_j2k_v2_t *p_j2k,
1198                                                                 OPJ_BYTE * p_header_data,
1199                                                                 OPJ_UINT32 p_header_size,
1200                                                                 struct opj_event_mgr * p_manager );
1201
1202 /**
1203  * Writes the MCC marker (Multiple Component Collection)
1204  *
1205  * @param       p_stream                the stream to write data to.
1206  * @param       p_j2k                   J2K codec.
1207  * @param       p_manager               the user event manager.
1208 */
1209 static opj_bool j2k_write_mcc_record(   opj_j2k_v2_t *p_j2k,
1210                                                                                 struct opj_simple_mcc_decorrelation_data * p_mcc_record,
1211                                                                                 struct opj_stream_private *p_stream,
1212                                                                                 struct opj_event_mgr * p_manager );
1213
1214
1215 /**
1216  * Reads a MCC marker (Multiple Component Collection)
1217  *
1218  * @param       p_header_data   the data contained in the MCC box.
1219  * @param       p_j2k                   the jpeg2000 codec.
1220  * @param       p_header_size   the size of the data contained in the MCC marker.
1221  * @param       p_manager               the user event manager.
1222 */
1223 static opj_bool j2k_read_mcc (  opj_j2k_v2_t *p_j2k,
1224                                                                 OPJ_BYTE * p_header_data,
1225                                                                 OPJ_UINT32 p_header_size,
1226                                                                 struct opj_event_mgr * p_manager );
1227
1228 /**
1229  * Writes the MCO marker (Multiple component transformation ordering)
1230  *
1231  * @param       p_stream                                the stream to write data to.
1232  * @param       p_j2k                           J2K codec.
1233  * @param       p_manager               the user event manager.
1234 */
1235 static opj_bool j2k_write_mco(  opj_j2k_v2_t *p_j2k,
1236                                                                 struct opj_stream_private *p_stream,
1237                                                                 struct opj_event_mgr * p_manager );
1238
1239 /**
1240  * Reads a MCO marker (Multiple Component Transform Ordering)
1241  *
1242  * @param       p_header_data   the data contained in the MCO box.
1243  * @param       p_j2k                   the jpeg2000 codec.
1244  * @param       p_header_size   the size of the data contained in the MCO marker.
1245  * @param       p_manager               the user event manager.
1246 */
1247 static opj_bool j2k_read_mco (  opj_j2k_v2_t *p_j2k,
1248                                                                 OPJ_BYTE * p_header_data,
1249                                                                 OPJ_UINT32 p_header_size,
1250                                                                 struct opj_event_mgr * p_manager );
1251
1252 static opj_bool j2k_add_mct(opj_tcp_v2_t * p_tcp, opj_image_t * p_image, OPJ_UINT32 p_index);
1253
1254 static void  j2k_read_int16_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
1255 static void  j2k_read_int32_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
1256 static void  j2k_read_float32_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
1257 static void  j2k_read_float64_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
1258
1259 static void  j2k_read_int16_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
1260 static void  j2k_read_int32_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
1261 static void  j2k_read_float32_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
1262 static void  j2k_read_float64_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
1263
1264 static void  j2k_write_float_to_int16 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
1265 static void  j2k_write_float_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
1266 static void  j2k_write_float_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
1267 static void  j2k_write_float_to_float64 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
1268
1269
1270 /**
1271  * Ends the encoding, i.e. frees memory.
1272  *
1273  * @param       p_stream                the stream to write data to.
1274  * @param       p_j2k                   J2K codec.
1275  * @param       p_manager               the user event manager.
1276 */
1277 static opj_bool j2k_end_encoding(       opj_j2k_v2_t *p_j2k,
1278                                                                         struct opj_stream_private *p_stream,
1279                                                                         struct opj_event_mgr * p_manager );
1280
1281 /**
1282  * Writes the CBD marker (Component bit depth definition)
1283  *
1284  * @param       p_stream                                the stream to write data to.
1285  * @param       p_j2k                           J2K codec.
1286  * @param       p_manager               the user event manager.
1287 */
1288 static opj_bool j2k_write_cbd(  opj_j2k_v2_t *p_j2k,
1289                                                                 struct opj_stream_private *p_stream,
1290                                                                 struct opj_event_mgr * p_manager );
1291
1292 /**
1293  * Reads a CBD marker (Component bit depth definition)
1294  * @param       p_header_data   the data contained in the CBD box.
1295  * @param       p_j2k                   the jpeg2000 codec.
1296  * @param       p_header_size   the size of the data contained in the CBD marker.
1297  * @param       p_manager               the user event manager.
1298 */
1299 static opj_bool j2k_read_cbd (  opj_j2k_v2_t *p_j2k,
1300                                                         OPJ_BYTE * p_header_data,
1301                                                         OPJ_UINT32 p_header_size,
1302                                                         struct opj_event_mgr * p_manager);
1303
1304 /**
1305  * Writes the image components.
1306  *
1307  * @param       p_stream                the stream to write data to.
1308  * @param       p_j2k                   J2K codec.
1309  * @param       p_manager               the user event manager.
1310 */
1311 static opj_bool j2k_write_image_components(     opj_j2k_v2_t *p_j2k,
1312                                                                                         struct opj_stream_private *p_stream,
1313                                                                                         struct opj_event_mgr * p_manager );
1314
1315 /**
1316  * Writes regions of interests.
1317  *
1318  * @param       p_stream                the stream to write data to.
1319  * @param       p_j2k                   J2K codec.
1320  * @param       p_manager               the user event manager.
1321 */
1322 static opj_bool j2k_write_regions(      opj_j2k_v2_t *p_j2k,
1323                                                                         struct opj_stream_private *p_stream,
1324                                                                         struct opj_event_mgr * p_manager );
1325
1326 /**
1327  * Writes EPC ????
1328  *
1329  * @param       p_stream                the stream to write data to.
1330  * @param       p_j2k                   J2K codec.
1331  * @param       p_manager               the user event manager.
1332 */
1333 static opj_bool j2k_write_epc(  opj_j2k_v2_t *p_j2k,
1334                                                                 struct opj_stream_private *p_stream,
1335                                                                 struct opj_event_mgr * p_manager );
1336
1337 /**
1338  * Checks the progression order changes values. Tells of the poc given as input are valid.
1339  * A nice message is outputted at errors.
1340  *
1341  * @param       p_pocs                          the progression order changes.
1342  * @param       p_nb_pocs                       the number of progression order changes.
1343  * @param       p_nb_resolutions        the number of resolutions.
1344  * @param       numcomps                        the number of components
1345  * @param       numlayers                       the number of layers.
1346  *
1347  * @return      true if the pocs are valid.
1348  */
1349 static opj_bool j2k_check_poc_val(      const opj_poc_t *p_pocs,
1350                                                                         OPJ_UINT32 p_nb_pocs,
1351                                                                         OPJ_UINT32 p_nb_resolutions,
1352                                                                         OPJ_UINT32 numcomps,
1353                                                                         OPJ_UINT32 numlayers,
1354                                                                         opj_event_mgr_t * p_manager);
1355
1356 /**
1357  * Gets the number of tile parts used for the given change of progression (if any) and the given tile.
1358  *
1359  * @param               cp                      the coding parameters.
1360  * @param               pino            the offset of the given poc (i.e. its position in the coding parameter).
1361  * @param               tileno          the given tile.
1362  *
1363  * @return              the number of tile parts.
1364  */
1365 static OPJ_UINT32 j2k_get_num_tp_v2( opj_cp_v2_t *cp, OPJ_UINT32 pino, OPJ_UINT32 tileno);
1366
1367 /**     mem allocation for TLM marker*/
1368 static int j2k_calculate_tp(opj_cp_t *cp,int img_numcomp,opj_image_t *image,opj_j2k_t *j2k );
1369
1370 /**
1371  * Calculates the total number of tile parts needed by the encoder to
1372  * encode such an image. If not enough memory is available, then the function return false.
1373  *
1374  * @param       p_nb_tiles      pointer that will hold the number of tile parts.
1375  * @param       cp                      the coding parameters for the image.
1376  * @param       image           the image to encode.
1377  * @param       p_j2k                   the p_j2k encoder.
1378  * @param       p_manager       the user event manager.
1379  *
1380  * @return true if the function was successful, false else.
1381  */
1382 static opj_bool j2k_calculate_tp_v2(opj_j2k_v2_t *p_j2k,
1383                                                                         opj_cp_v2_t *cp,
1384                                                                         OPJ_UINT32 * p_nb_tiles,
1385                                                                         opj_image_t *image,
1386                                                                         opj_event_mgr_t * p_manager);
1387
1388 static void j2k_dump_MH_info(opj_j2k_v2_t* p_j2k, FILE* out_stream);
1389
1390 static void j2k_dump_MH_index(opj_j2k_v2_t* p_j2k, FILE* out_stream);
1391
1392 static opj_codestream_index_t* j2k_create_cstr_index(void);
1393
1394 /*@}*/
1395
1396 /*@}*/
1397
1398 /* ----------------------------------------------------------------------- */
1399 typedef struct j2k_prog_order{
1400         OPJ_PROG_ORDER enum_prog;
1401         char str_prog[5];
1402 }j2k_prog_order_t;
1403
1404 j2k_prog_order_t j2k_prog_order_list[] = {
1405         {CPRL, "CPRL"},
1406         {LRCP, "LRCP"},
1407         {PCRL, "PCRL"},
1408         {RLCP, "RLCP"},
1409         {RPCL, "RPCL"},
1410         {(OPJ_PROG_ORDER)-1, ""}
1411 };
1412
1413
1414
1415 /**
1416  * FIXME DOC
1417  */
1418 const OPJ_UINT32 MCT_ELEMENT_SIZE [] =
1419 {
1420         2,
1421         4,
1422         4,
1423         8
1424 };
1425
1426 typedef void (* j2k_mct_function) (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
1427
1428 const j2k_mct_function j2k_mct_read_functions_to_float [] =
1429 {
1430         j2k_read_int16_to_float,
1431         j2k_read_int32_to_float,
1432         j2k_read_float32_to_float,
1433         j2k_read_float64_to_float
1434 };
1435
1436 const j2k_mct_function j2k_mct_read_functions_to_int32 [] =
1437 {
1438         j2k_read_int16_to_int32,
1439         j2k_read_int32_to_int32,
1440         j2k_read_float32_to_int32,
1441         j2k_read_float64_to_int32
1442 };
1443
1444 const j2k_mct_function j2k_mct_write_functions_from_float [] =
1445 {
1446         j2k_write_float_to_int16,
1447         j2k_write_float_to_int32,
1448         j2k_write_float_to_float,
1449         j2k_write_float_to_float64
1450 };
1451
1452 typedef struct opj_dec_memory_marker_handler
1453 {
1454         /** marker value */
1455         OPJ_UINT32 id;
1456         /** value of the state when the marker can appear */
1457         OPJ_UINT32 states;
1458         /** action linked to the marker */
1459         opj_bool (*handler) (
1460                                         opj_j2k_v2_t *p_j2k,
1461                                         OPJ_BYTE * p_header_data,
1462                                         OPJ_UINT32 p_header_size,
1463                                         struct opj_event_mgr * p_manager
1464                                                 );
1465 }
1466 opj_dec_memory_marker_handler_t;
1467
1468 const opj_dec_memory_marker_handler_t j2k_memory_marker_handler_tab [] =
1469 {
1470 #ifdef TODO_MS
1471   {J2K_MS_SOT, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPHSOT, j2k_read_sot},
1472   {J2K_MS_COD, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_cod},
1473   {J2K_MS_COC, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_coc},
1474   {J2K_MS_RGN, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_rgn},
1475   {J2K_MS_QCD, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_qcd},
1476   {J2K_MS_QCC, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_qcc},
1477   {J2K_MS_POC, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_poc},
1478   {J2K_MS_SIZ, J2K_DEC_STATE_MHSIZ , j2k_read_siz},
1479   {J2K_MS_TLM, J2K_DEC_STATE_MH, j2k_read_tlm},
1480   {J2K_MS_PLM, J2K_DEC_STATE_MH, j2k_read_plm},
1481   {J2K_MS_PLT, J2K_DEC_STATE_TPH, j2k_read_plt},
1482   {J2K_MS_PPM, J2K_DEC_STATE_MH, j2k_read_ppm},
1483   {J2K_MS_PPT, J2K_DEC_STATE_TPH, j2k_read_ppt},
1484   {J2K_MS_SOP, 0, 0},
1485   {J2K_MS_CRG, J2K_DEC_STATE_MH, j2k_read_crg},
1486   {J2K_MS_COM, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_com},
1487   {J2K_MS_MCT, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_mct},
1488   {J2K_MS_CBD, J2K_DEC_STATE_MH , j2k_read_cbd},
1489   {J2K_MS_MCC, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_mcc},
1490   {J2K_MS_MCO, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_mco},
1491 #endif
1492   {J2K_MS_SOT, J2K_STATE_MH | J2K_STATE_TPHSOT, j2k_read_sot_v2},
1493   {J2K_MS_COD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_cod_v2},
1494   {J2K_MS_COC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_coc_v2},
1495   {J2K_MS_RGN, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_rgn_v2},
1496   {J2K_MS_QCD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_qcd_v2},
1497   {J2K_MS_QCC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_qcc_v2},
1498   {J2K_MS_POC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_poc_v2},
1499   {J2K_MS_SIZ, J2K_STATE_MHSIZ , j2k_read_siz_v2},
1500   {J2K_MS_TLM, J2K_STATE_MH, j2k_read_tlm_v2},
1501   {J2K_MS_PLM, J2K_STATE_MH, j2k_read_plm_v2},
1502   {J2K_MS_PLT, J2K_STATE_TPH, j2k_read_plt_v2},
1503   {J2K_MS_PPM, J2K_STATE_MH, j2k_read_ppm_v3},
1504   {J2K_MS_PPT, J2K_STATE_TPH, j2k_read_ppt_v2},
1505   {J2K_MS_SOP, 0, 0},
1506   {J2K_MS_CRG, J2K_STATE_MH, j2k_read_crg_v2},
1507   {J2K_MS_COM, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_com_v2},
1508   {J2K_MS_MCT, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_mct},
1509   {J2K_MS_CBD, J2K_STATE_MH , j2k_read_cbd},
1510   {J2K_MS_MCC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_mcc},
1511   {J2K_MS_MCO, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_mco},
1512 #ifdef USE_JPWL
1513 #ifdef TODO_MS /* FIXME */
1514   {J2K_MS_EPC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_epc},
1515   {J2K_MS_EPB, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_epb},
1516   {J2K_MS_ESD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_esd},
1517   {J2K_MS_RED, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_red},
1518 #endif
1519 #endif /* USE_JPWL */
1520 #ifdef USE_JPSEC
1521   {J2K_MS_SEC, J2K_DEC_STATE_MH, j2k_read_sec},
1522   {J2K_MS_INSEC, 0, j2k_read_insec}
1523 #endif /* USE_JPSEC */
1524   {J2K_MS_UNK, J2K_STATE_MH | J2K_STATE_TPH, 0}/*j2k_read_unk_v2}*/
1525 };
1526
1527
1528
1529 void  j2k_read_int16_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
1530 {
1531         OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
1532         OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data;
1533         OPJ_UINT32 i;
1534         OPJ_UINT32 l_temp;
1535
1536         for (i=0;i<p_nb_elem;++i) {
1537                 opj_read_bytes(l_src_data,&l_temp,2);
1538
1539                 l_src_data+=sizeof(OPJ_INT16);
1540
1541                 *(l_dest_data++) = (OPJ_FLOAT32) l_temp;
1542         }
1543 }
1544
1545 void  j2k_read_int32_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
1546 {
1547         OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
1548         OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data;
1549         OPJ_UINT32 i;
1550         OPJ_UINT32 l_temp;
1551
1552         for (i=0;i<p_nb_elem;++i) {
1553                 opj_read_bytes(l_src_data,&l_temp,4);
1554
1555                 l_src_data+=sizeof(OPJ_INT32);
1556
1557                 *(l_dest_data++) = (OPJ_FLOAT32) l_temp;
1558         }
1559 }
1560
1561 void  j2k_read_float32_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
1562 {
1563         OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
1564         OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data;
1565         OPJ_UINT32 i;
1566         OPJ_FLOAT32 l_temp;
1567
1568         for (i=0;i<p_nb_elem;++i) {
1569                 opj_read_float(l_src_data,&l_temp);
1570
1571                 l_src_data+=sizeof(OPJ_FLOAT32);
1572
1573                 *(l_dest_data++) = l_temp;
1574         }
1575 }
1576
1577 void  j2k_read_float64_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
1578 {
1579         OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
1580         OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data;
1581         OPJ_UINT32 i;
1582         OPJ_FLOAT64 l_temp;
1583
1584         for (i=0;i<p_nb_elem;++i) {
1585                 opj_read_double(l_src_data,&l_temp);
1586
1587                 l_src_data+=sizeof(OPJ_FLOAT64);
1588
1589                 *(l_dest_data++) = (OPJ_FLOAT32) l_temp;
1590         }
1591 }
1592
1593 void  j2k_read_int16_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
1594 {
1595         OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
1596         OPJ_INT32 * l_dest_data = (OPJ_INT32 *) p_dest_data;
1597         OPJ_UINT32 i;
1598         OPJ_UINT32 l_temp;
1599
1600         for (i=0;i<p_nb_elem;++i) {
1601                 opj_read_bytes(l_src_data,&l_temp,2);
1602
1603                 l_src_data+=sizeof(OPJ_INT16);
1604
1605                 *(l_dest_data++) = (OPJ_INT32) l_temp;
1606         }
1607 }
1608
1609 void  j2k_read_int32_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
1610 {
1611         OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
1612         OPJ_INT32 * l_dest_data = (OPJ_INT32 *) p_dest_data;
1613         OPJ_UINT32 i;
1614         OPJ_UINT32 l_temp;
1615
1616         for (i=0;i<p_nb_elem;++i) {
1617                 opj_read_bytes(l_src_data,&l_temp,4);
1618
1619                 l_src_data+=sizeof(OPJ_INT32);
1620
1621                 *(l_dest_data++) = (OPJ_INT32) l_temp;
1622         }
1623 }
1624
1625 void  j2k_read_float32_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
1626 {
1627         OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
1628         OPJ_INT32 * l_dest_data = (OPJ_INT32 *) p_dest_data;
1629         OPJ_UINT32 i;
1630         OPJ_FLOAT32 l_temp;
1631
1632         for (i=0;i<p_nb_elem;++i) {
1633                 opj_read_float(l_src_data,&l_temp);
1634
1635                 l_src_data+=sizeof(OPJ_FLOAT32);
1636
1637                 *(l_dest_data++) = (OPJ_INT32) l_temp;
1638         }
1639 }
1640
1641 void  j2k_read_float64_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
1642 {
1643         OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
1644         OPJ_INT32 * l_dest_data = (OPJ_INT32 *) p_dest_data;
1645         OPJ_UINT32 i;
1646         OPJ_FLOAT64 l_temp;
1647
1648         for (i=0;i<p_nb_elem;++i) {
1649                 opj_read_double(l_src_data,&l_temp);
1650
1651                 l_src_data+=sizeof(OPJ_FLOAT64);
1652
1653                 *(l_dest_data++) = (OPJ_INT32) l_temp;
1654         }
1655 }
1656
1657 void  j2k_write_float_to_int16 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
1658 {
1659         OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data;
1660         OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data;
1661         OPJ_UINT32 i;
1662         OPJ_UINT32 l_temp;
1663
1664         for (i=0;i<p_nb_elem;++i) {
1665                 l_temp = (OPJ_UINT32) *(l_src_data++);
1666
1667                 opj_write_bytes(l_dest_data,l_temp,sizeof(OPJ_INT16));
1668
1669                 l_dest_data+=sizeof(OPJ_INT16);
1670         }
1671 }
1672
1673 void  j2k_write_float_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
1674 {
1675         OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data;
1676         OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data;
1677         OPJ_UINT32 i;
1678         OPJ_UINT32 l_temp;
1679
1680         for (i=0;i<p_nb_elem;++i) {
1681                 l_temp = (OPJ_UINT32) *(l_src_data++);
1682
1683                 opj_write_bytes(l_dest_data,l_temp,sizeof(OPJ_INT32));
1684
1685                 l_dest_data+=sizeof(OPJ_INT32);
1686         }
1687 }
1688
1689 void  j2k_write_float_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
1690 {
1691         OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data;
1692         OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data;
1693         OPJ_UINT32 i;
1694         OPJ_FLOAT32 l_temp;
1695
1696         for (i=0;i<p_nb_elem;++i) {
1697                 l_temp = (OPJ_FLOAT32) *(l_src_data++);
1698
1699                 opj_write_float(l_dest_data,l_temp);
1700
1701                 l_dest_data+=sizeof(OPJ_FLOAT32);
1702         }
1703 }
1704
1705 void  j2k_write_float_to_float64 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
1706 {
1707         OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data;
1708         OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data;
1709         OPJ_UINT32 i;
1710         OPJ_FLOAT64 l_temp;
1711
1712         for (i=0;i<p_nb_elem;++i) {
1713                 l_temp = (OPJ_FLOAT64) *(l_src_data++);
1714
1715                 opj_write_double(l_dest_data,l_temp);
1716
1717                 l_dest_data+=sizeof(OPJ_FLOAT64);
1718         }
1719 }
1720
1721
1722 /**
1723  * Converts an enum type progression order to string type.
1724  *
1725  * @param prg_order             the progression order to get.
1726  *
1727  * @return      the string representation of the given progression order.
1728  */
1729 char *j2k_convert_progression_order(OPJ_PROG_ORDER prg_order){
1730         j2k_prog_order_t *po;
1731         for(po = j2k_prog_order_list; po->enum_prog != -1; po++ ){
1732                 if(po->enum_prog == prg_order){
1733                         return po->str_prog;
1734                 }
1735         }
1736         return po->str_prog;
1737 }
1738
1739 /**
1740  * Checks the progression order changes values. Tells if the poc given as input are valid.
1741  *
1742  * @param       p_pocs                          the progression order changes.
1743  * @param       p_nb_pocs                       the number of progression order changes.
1744  * @param       p_nb_resolutions        the number of resolutions.
1745  * @param       numcomps                        the number of components
1746  * @param       numlayers                       the number of layers.
1747  * @param       p_manager                       the user event manager.
1748  *
1749  * @return      true if the pocs are valid.
1750  */
1751 opj_bool j2k_check_poc_val(     const opj_poc_t *p_pocs,
1752                                                         OPJ_UINT32 p_nb_pocs,
1753                                                         OPJ_UINT32 p_nb_resolutions,
1754                                                         OPJ_UINT32 p_num_comps,
1755                                                         OPJ_UINT32 p_num_layers,
1756                                                         opj_event_mgr_t * p_manager)
1757 {
1758         OPJ_UINT32* packet_array;
1759         OPJ_UINT32 index , resno, compno, layno;
1760         OPJ_UINT32 i;
1761         OPJ_UINT32 step_c = 1;
1762         OPJ_UINT32 step_r = p_num_comps * step_c;
1763         OPJ_UINT32 step_l = p_nb_resolutions * step_r;
1764         opj_bool loss = OPJ_FALSE;
1765         OPJ_UINT32 layno0 = 0;
1766
1767         packet_array = (OPJ_UINT32*) opj_calloc(step_l * p_num_layers, sizeof(OPJ_UINT32));
1768         if (packet_array == 00) {
1769                 opj_event_msg_v2(p_manager , EVT_ERROR, "Not enough memory for checking the poc values.\n");
1770                 return OPJ_FALSE;
1771         }
1772         memset(packet_array,0,step_l * p_num_layers* sizeof(OPJ_UINT32));
1773
1774         if (p_nb_pocs == 0) {
1775                 return OPJ_TRUE;
1776         }
1777
1778         index = step_r * p_pocs->resno0;
1779         // take each resolution for each poc
1780         for (resno = p_pocs->resno0 ; resno < p_pocs->resno1 ; ++resno)
1781         {
1782                 OPJ_UINT32 res_index = index + p_pocs->compno0 * step_c;
1783
1784                 // take each comp of each resolution for each poc
1785                 for (compno = p_pocs->compno0 ; compno < p_pocs->compno1 ; ++compno) {
1786                         OPJ_UINT32 comp_index = res_index + layno0 * step_l;
1787
1788                         // and finally take each layer of each res of ...
1789                         for (layno = layno0; layno < p_pocs->layno1 ; ++layno) {
1790                                 //index = step_r * resno + step_c * compno + step_l * layno;
1791                                 packet_array[comp_index] = 1;
1792                                 comp_index += step_l;
1793                         }
1794
1795                         res_index += step_c;
1796                 }
1797
1798                 index += step_r;
1799         }
1800         ++p_pocs;
1801
1802         // iterate through all the pocs
1803         for (i = 1; i < p_nb_pocs ; ++i) {
1804                 OPJ_UINT32 l_last_layno1 = (p_pocs-1)->layno1 ;
1805
1806                 layno0 = (p_pocs->layno1 > l_last_layno1)? l_last_layno1 : 0;
1807                 index = step_r * p_pocs->resno0;
1808
1809                 // take each resolution for each poc
1810                 for (resno = p_pocs->resno0 ; resno < p_pocs->resno1 ; ++resno) {
1811                         OPJ_UINT32 res_index = index + p_pocs->compno0 * step_c;
1812
1813                         // take each comp of each resolution for each poc
1814                         for (compno = p_pocs->compno0 ; compno < p_pocs->compno1 ; ++compno) {
1815                                 OPJ_UINT32 comp_index = res_index + layno0 * step_l;
1816
1817                                 // and finally take each layer of each res of ...
1818                                 for (layno = layno0; layno < p_pocs->layno1 ; ++layno) {
1819                                         //index = step_r * resno + step_c * compno + step_l * layno;
1820                                         packet_array[comp_index] = 1;
1821                                         comp_index += step_l;
1822                                 }
1823
1824                                 res_index += step_c;
1825                         }
1826
1827                         index += step_r;
1828                 }
1829
1830                 ++p_pocs;
1831         }
1832
1833         index = 0;
1834         for (layno = 0; layno < p_num_layers ; ++layno) {
1835                 for (resno = 0; resno < p_nb_resolutions; ++resno) {
1836                         for (compno = 0; compno < p_num_comps; ++compno) {
1837                                 loss |= (packet_array[index]!=1);
1838                                 //index = step_r * resno + step_c * compno + step_l * layno;
1839                                 index += step_c;
1840                         }
1841                 }
1842         }
1843
1844         if (loss) {
1845                 opj_event_msg_v2(p_manager , EVT_ERROR, "Missing packets possible loss of data\n");
1846         }
1847
1848         opj_free(packet_array);
1849
1850         return !loss;
1851 }
1852
1853 /* ----------------------------------------------------------------------- */
1854 static int j2k_get_num_tp(opj_cp_t *cp,int pino,int tileno){
1855         char *prog;
1856         int i;
1857         int tpnum=1,tpend=0;
1858         opj_tcp_t *tcp = &cp->tcps[tileno];
1859         prog = j2k_convert_progression_order(tcp->prg);
1860         
1861         if(cp->tp_on == 1){
1862                 for(i=0;i<4;i++){
1863                         if(tpend!=1){
1864                                 if( cp->tp_flag == prog[i] ){
1865                                         tpend=1;cp->tp_pos=i;
1866                                 }
1867                                 switch(prog[i]){
1868                                 case 'C':
1869                                         tpnum= tpnum * tcp->pocs[pino].compE;
1870                                         break;
1871                                 case 'R':
1872                                         tpnum= tpnum * tcp->pocs[pino].resE;
1873                                         break;
1874                                 case 'P':
1875                                         tpnum= tpnum * tcp->pocs[pino].prcE;
1876                                         break;
1877                                 case 'L':
1878                                         tpnum= tpnum * tcp->pocs[pino].layE;
1879                                         break;
1880                                 }
1881                         }
1882                 }
1883         }else{
1884                 tpnum=1;
1885         }
1886         return tpnum;
1887 }
1888
1889 /**
1890  * Gets the number of tile parts used for the given change of progression (if any) and the given tile.
1891  *
1892  * @param               cp                      the coding parameters.
1893  * @param               pino            the offset of the given poc (i.e. its position in the coding parameter).
1894  * @param               tileno          the given tile.
1895  *
1896  * @return              the number of tile parts.
1897  */
1898 OPJ_UINT32 j2k_get_num_tp_v2(opj_cp_v2_t *cp, OPJ_UINT32 pino, OPJ_UINT32 tileno)
1899 {
1900         const OPJ_CHAR *prog = 00;
1901         OPJ_UINT32 i;
1902         OPJ_UINT32 tpnum = 1;
1903         opj_tcp_v2_t *tcp = 00;
1904         opj_poc_t * l_current_poc = 00;
1905
1906         /*  preconditions */
1907         assert(tileno < (cp->tw * cp->th));
1908         assert(pino < (cp->tcps[tileno].numpocs + 1));
1909
1910         /* get the given tile coding parameter */
1911         tcp = &cp->tcps[tileno];
1912         assert(tcp != 00);
1913
1914         l_current_poc = &(tcp->pocs[pino]);
1915         assert(l_current_poc != 0);
1916
1917         /* get the progression order as a character string */
1918         prog = j2k_convert_progression_order(tcp->prg);
1919         assert(strlen(prog) > 0);
1920
1921         if (cp->m_specific_param.m_enc.m_tp_on == 1) {
1922                 for (i=0;i<4;++i) {
1923                         switch (prog[i])
1924                         {
1925                                 /* component wise */
1926                                 case 'C':
1927                                         tpnum *= l_current_poc->compE;
1928                                         break;
1929                                 /* resolution wise */
1930                                 case 'R':
1931                                         tpnum *= l_current_poc->resE;
1932                                         break;
1933                                 /* precinct wise */
1934                                 case 'P':
1935                                         tpnum *= l_current_poc->prcE;
1936                                         break;
1937                                 /* layer wise */
1938                                 case 'L':
1939                                         tpnum *= l_current_poc->layE;
1940                                         break;
1941                         }
1942                         /* whould we split here ? */
1943                         if ( cp->m_specific_param.m_enc.m_tp_flag == prog[i] ) {
1944                                 cp->m_specific_param.m_enc.m_tp_pos=i;
1945                                 break;
1946                         }
1947                 }
1948         }
1949         else {
1950                 tpnum=1;
1951         }
1952
1953         return tpnum;
1954 }
1955
1956 /**     mem allocation for TLM marker*/
1957 int j2k_calculate_tp(opj_cp_t *cp,int img_numcomp,opj_image_t *image,opj_j2k_t *j2k ){
1958         int pino,tileno,totnum_tp=0;
1959
1960         OPJ_ARG_NOT_USED(img_numcomp);
1961
1962         j2k->cur_totnum_tp = (int *) opj_malloc(cp->tw * cp->th * sizeof(int));
1963         for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
1964                 int cur_totnum_tp = 0;
1965                 opj_tcp_t *tcp = &cp->tcps[tileno];
1966                 for(pino = 0; pino <= tcp->numpocs; pino++) {
1967                         int tp_num=0;
1968                         opj_pi_iterator_t *pi = pi_initialise_encode(image, cp, tileno,FINAL_PASS);
1969                         if(!pi) { return -1;}
1970                         tp_num = j2k_get_num_tp(cp,pino,tileno);
1971                         totnum_tp = totnum_tp + tp_num;
1972                         cur_totnum_tp = cur_totnum_tp + tp_num;
1973                         pi_destroy(pi, cp, tileno);
1974                 }
1975                 j2k->cur_totnum_tp[tileno] = cur_totnum_tp;
1976                 /* INDEX >> */
1977                 if (j2k->cstr_info) {
1978                         j2k->cstr_info->tile[tileno].num_tps = cur_totnum_tp;
1979                         j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_malloc(cur_totnum_tp * sizeof(opj_tp_info_t));
1980                 }
1981                 /* << INDEX */
1982         }
1983         return totnum_tp;
1984 }
1985
1986 /**
1987  * Calculates the total number of tile parts needed by the encoder to
1988  * encode such an image. If not enough memory is available, then the function return false.
1989  *
1990  * @param       p_nb_tiles      pointer that will hold the number of tile parts.
1991  * @param       cp                      the coding parameters for the image.
1992  * @param       image           the image to encode.
1993  * @param       p_j2k                   the p_j2k encoder.
1994  * @param       p_manager       the user event manager.
1995  *
1996  * @return true if the function was successful, false else.
1997  */
1998 opj_bool j2k_calculate_tp_v2( opj_j2k_v2_t *p_j2k,
1999                                                           opj_cp_v2_t *cp,
2000                                                           OPJ_UINT32 * p_nb_tiles,
2001                                                           opj_image_t *image,
2002                                                           opj_event_mgr_t * p_manager)
2003 {
2004         OPJ_UINT32 pino,tileno;
2005         OPJ_UINT32 l_nb_tiles;
2006         opj_tcp_v2_t *tcp;
2007
2008         /* preconditions */
2009         assert(p_nb_tiles != 00);
2010         assert(cp != 00);
2011         assert(image != 00);
2012         assert(p_j2k != 00);
2013         assert(p_manager != 00);
2014
2015         l_nb_tiles = cp->tw * cp->th;
2016         * p_nb_tiles = 0;
2017         tcp = cp->tcps;
2018
2019         /* INDEX >> */
2020         /* TODO mergeV2: check this part which use cstr_info */
2021         /*if (p_j2k->cstr_info) {
2022                 opj_tile_info_t * l_info_tile_ptr = p_j2k->cstr_info->tile;
2023
2024                 for (tileno = 0; tileno < l_nb_tiles; ++tileno) {
2025                         OPJ_UINT32 cur_totnum_tp = 0;
2026
2027                         pi_update_encoding_parameters(image,cp,tileno);
2028
2029                         for (pino = 0; pino <= tcp->numpocs; ++pino)
2030                         {
2031                                 OPJ_UINT32 tp_num = j2k_get_num_tp_v2(cp,pino,tileno);
2032
2033                                 *p_nb_tiles = *p_nb_tiles + tp_num;
2034
2035                                 cur_totnum_tp += tp_num;
2036                         }
2037
2038                         tcp->m_nb_tile_parts = cur_totnum_tp;
2039
2040                         l_info_tile_ptr->tp = (opj_tp_info_t *) opj_malloc(cur_totnum_tp * sizeof(opj_tp_info_t));
2041                         if (l_info_tile_ptr->tp == 00) {
2042                                 return OPJ_FALSE;
2043                         }
2044
2045                         memset(l_info_tile_ptr->tp,0,cur_totnum_tp * sizeof(opj_tp_info_t));
2046
2047                         l_info_tile_ptr->num_tps = cur_totnum_tp;
2048
2049                         ++l_info_tile_ptr;
2050                         ++tcp;
2051                 }
2052         }
2053         else */{
2054                 for (tileno = 0; tileno < l_nb_tiles; ++tileno) {
2055                         OPJ_UINT32 cur_totnum_tp = 0;
2056
2057                         pi_update_encoding_parameters(image,cp,tileno);
2058
2059                         for (pino = 0; pino <= tcp->numpocs; ++pino) {
2060                                 OPJ_UINT32 tp_num = j2k_get_num_tp_v2(cp,pino,tileno);
2061
2062                                 *p_nb_tiles = *p_nb_tiles + tp_num;
2063
2064                                 cur_totnum_tp += tp_num;
2065                         }
2066                         tcp->m_nb_tile_parts = cur_totnum_tp;
2067
2068                         ++tcp;
2069                 }
2070         }
2071
2072         return OPJ_TRUE;
2073 }
2074
2075 static void j2k_write_soc(opj_j2k_t *j2k) {
2076         opj_cio_t *cio = j2k->cio;
2077         cio_write(cio, J2K_MS_SOC, 2);
2078
2079         if(j2k->cstr_info)
2080           j2k_add_mhmarker(j2k->cstr_info, J2K_MS_SOC, cio_tell(cio), 0);
2081
2082 /* UniPG>> */
2083 #ifdef USE_JPWL
2084
2085         /* update markers struct */
2086         j2k_add_marker(j2k->cstr_info, J2K_MS_SOC, cio_tell(cio) - 2, 2);
2087 #endif /* USE_JPWL */
2088 /* <<UniPG */
2089 }
2090
2091 /**
2092  * Writes the SOC marker (Start Of Codestream)
2093  *
2094  * @param       p_stream                        the stream to write data to.
2095  * @param       p_j2k                   J2K codec.
2096  * @param       p_manager       the user event manager.
2097 */
2098 opj_bool j2k_write_soc_v2(      opj_j2k_v2_t *p_j2k,
2099                                                         struct opj_stream_private *p_stream,
2100                                                         struct opj_event_mgr * p_manager )
2101 {
2102         /* 2 bytes will be written */
2103         OPJ_BYTE * l_start_stream = 00;
2104
2105         /* preconditions */
2106         assert(p_stream != 00);
2107         assert(p_j2k != 00);
2108         assert(p_manager != 00);
2109
2110         l_start_stream = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
2111
2112         /* write SOC identifier */
2113         opj_write_bytes(l_start_stream,J2K_MS_SOC,2);
2114
2115         if (opj_stream_write_data(p_stream,l_start_stream,2,p_manager) != 2) {
2116                 return OPJ_FALSE;
2117         }
2118
2119 /* UniPG>> */
2120 #ifdef USE_JPWL
2121         /* update markers struct */
2122 /*
2123         j2k_add_marker(p_j2k->cstr_info, J2K_MS_SOC, p_stream_tell(p_stream) - 2, 2);
2124 */
2125   assert( 0 && "TODO" );
2126 #endif /* USE_JPWL */
2127 /* <<UniPG */
2128
2129         return OPJ_TRUE;
2130 }
2131
2132 static void j2k_read_soc(opj_j2k_t *j2k) {      
2133         j2k->state = J2K_STATE_MHSIZ;
2134         /* Index */
2135         if (j2k->cstr_info) {
2136                 j2k->cstr_info->main_head_start = cio_tell(j2k->cio) - 2;
2137                 j2k->cstr_info->codestream_size = cio_numbytesleft(j2k->cio) + 2 - j2k->cstr_info->main_head_start;
2138         }
2139 }
2140
2141 /**
2142  * Reads a SOC marker (Start of Codestream)
2143  * @param       p_header_data   the data contained in the SOC box.
2144  * @param       jp2                             the jpeg2000 file codec.
2145  * @param       p_header_size   the size of the data contained in the SOC marker.
2146  * @param       p_manager               the user event manager.
2147 */
2148 static opj_bool j2k_read_soc_v2(        opj_j2k_v2_t *p_j2k,
2149                                                                         struct opj_stream_private *p_stream,
2150                                                                         struct opj_event_mgr * p_manager )
2151 {
2152         OPJ_BYTE l_data [2];
2153         OPJ_UINT32 l_marker;
2154
2155         /* preconditions */
2156         assert(p_j2k != 00);
2157         assert(p_manager != 00);
2158         assert(p_stream != 00);
2159
2160         if (opj_stream_read_data(p_stream,l_data,2,p_manager) != 2) {
2161                 return OPJ_FALSE;
2162         }
2163
2164         opj_read_bytes(l_data,&l_marker,2);
2165         if (l_marker != J2K_MS_SOC) {
2166                 return OPJ_FALSE;
2167         }
2168
2169         /* Next marker should be a SIZ marker in the main header */
2170         p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_MHSIZ;
2171
2172         /* FIXME move it in a index structure included in p_j2k*/
2173         p_j2k->cstr_index->main_head_start = opj_stream_tell(p_stream) - 2;
2174
2175         opj_event_msg_v2(p_manager, EVT_INFO, "Start to read j2k main header (%d).\n", p_j2k->cstr_index->main_head_start);
2176
2177         /* Add the marker to the codestream index*/
2178         j2k_add_mhmarker_v2(p_j2k->cstr_index, J2K_MS_SOC, p_j2k->cstr_index->main_head_start, 2);
2179
2180         return OPJ_TRUE;
2181 }
2182
2183 static void j2k_write_siz(opj_j2k_t *j2k) {
2184         OPJ_UINT32 i;
2185         int lenp, len;
2186
2187         opj_cio_t *cio = j2k->cio;
2188         opj_image_t *image = j2k->image;
2189         opj_cp_t *cp = j2k->cp;
2190
2191         cio_write(cio, J2K_MS_SIZ, 2);  /* SIZ */
2192         lenp = cio_tell(cio);
2193         cio_skip(cio, 2);
2194         cio_write(cio, cp->rsiz, 2);                    /* Rsiz (capabilities) */
2195         cio_write(cio, image->x1, 4);   /* Xsiz */
2196         cio_write(cio, image->y1, 4);   /* Ysiz */
2197         cio_write(cio, image->x0, 4);   /* X0siz */
2198         cio_write(cio, image->y0, 4);   /* Y0siz */
2199         cio_write(cio, cp->tdx, 4);             /* XTsiz */
2200         cio_write(cio, cp->tdy, 4);             /* YTsiz */
2201         cio_write(cio, cp->tx0, 4);             /* XT0siz */
2202         cio_write(cio, cp->ty0, 4);             /* YT0siz */
2203         cio_write(cio, image->numcomps, 2);     /* Csiz */
2204         for (i = 0; i < image->numcomps; i++) {
2205                 cio_write(cio, image->comps[i].prec - 1 + (image->comps[i].sgnd << 7), 1);      /* Ssiz_i */
2206                 cio_write(cio, image->comps[i].dx, 1);  /* XRsiz_i */
2207                 cio_write(cio, image->comps[i].dy, 1);  /* YRsiz_i */
2208         }
2209         len = cio_tell(cio) - lenp;
2210         cio_seek(cio, lenp);
2211         cio_write(cio, len, 2);         /* Lsiz */
2212         cio_seek(cio, lenp + len);
2213         
2214         if(j2k->cstr_info)
2215           j2k_add_mhmarker(j2k->cstr_info, J2K_MS_SIZ, lenp, len);
2216 }
2217
2218 /**
2219  * Writes the SIZ marker (image and tile size)
2220  *
2221  * @param       p_stream                        the stream to write data to.
2222  * @param       p_j2k                   J2K codec.
2223  * @param       p_manager       the user event manager.
2224 */
2225 opj_bool j2k_write_siz_v2(      opj_j2k_v2_t *p_j2k,
2226                                                         struct opj_stream_private *p_stream,
2227                                                         struct opj_event_mgr * p_manager )
2228 {
2229         OPJ_UINT32 i;
2230         OPJ_UINT32 l_size_len;
2231         OPJ_BYTE * l_current_ptr;
2232         opj_image_t * l_image = 00;
2233         opj_cp_v2_t *cp = 00;
2234         opj_image_comp_t * l_img_comp = 00;
2235
2236         /* preconditions */
2237         assert(p_stream != 00);
2238         assert(p_j2k != 00);
2239         assert(p_manager != 00);
2240
2241         l_image = p_j2k->m_private_image;
2242         cp = &(p_j2k->m_cp);
2243         l_size_len = 40 + 3 * l_image->numcomps;
2244         l_img_comp = l_image->comps;
2245
2246         if (l_size_len > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
2247
2248                 p_j2k->m_specific_param.m_encoder.m_header_tile_data
2249                         = (OPJ_BYTE*)opj_realloc(
2250                                 p_j2k->m_specific_param.m_encoder.m_header_tile_data,
2251                                 l_size_len);
2252                 if (! p_j2k->m_specific_param.m_encoder.m_header_tile_data) {
2253                         return OPJ_FALSE;
2254                 }
2255
2256                 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_size_len;
2257         }
2258
2259         l_current_ptr = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
2260
2261         /* write SOC identifier */
2262         opj_write_bytes(l_current_ptr,J2K_MS_SIZ,2);    /* SIZ */
2263         l_current_ptr+=2;
2264
2265         opj_write_bytes(l_current_ptr,l_size_len-2,2); /* L_SIZ */
2266         l_current_ptr+=2;
2267
2268         opj_write_bytes(l_current_ptr, cp->rsiz, 2);    /* Rsiz (capabilities) */
2269         l_current_ptr+=2;
2270
2271         opj_write_bytes(l_current_ptr, l_image->x1, 4); /* Xsiz */
2272         l_current_ptr+=4;
2273
2274         opj_write_bytes(l_current_ptr, l_image->y1, 4); /* Ysiz */
2275         l_current_ptr+=4;
2276
2277         opj_write_bytes(l_current_ptr, l_image->x0, 4); /* X0siz */
2278         l_current_ptr+=4;
2279
2280         opj_write_bytes(l_current_ptr, l_image->y0, 4); /* Y0siz */
2281         l_current_ptr+=4;
2282
2283         opj_write_bytes(l_current_ptr, cp->tdx, 4);             /* XTsiz */
2284         l_current_ptr+=4;
2285
2286         opj_write_bytes(l_current_ptr, cp->tdy, 4);             /* YTsiz */
2287         l_current_ptr+=4;
2288
2289         opj_write_bytes(l_current_ptr, cp->tx0, 4);             /* XT0siz */
2290         l_current_ptr+=4;
2291
2292         opj_write_bytes(l_current_ptr, cp->ty0, 4);             /* YT0siz */
2293         l_current_ptr+=4;
2294
2295         opj_write_bytes(l_current_ptr, l_image->numcomps, 2);   /* Csiz */
2296         l_current_ptr+=2;
2297
2298         for (i = 0; i < l_image->numcomps; ++i) {
2299                 /* TODO here with MCT ? */
2300                 opj_write_bytes(l_current_ptr, l_img_comp->prec - 1 + (l_img_comp->sgnd << 7), 1);      /* Ssiz_i */
2301                 ++l_current_ptr;
2302
2303                 opj_write_bytes(l_current_ptr, l_img_comp->dx, 1);      /* XRsiz_i */
2304                 ++l_current_ptr;
2305
2306                 opj_write_bytes(l_current_ptr, l_img_comp->dy, 1);      /* YRsiz_i */
2307                 ++l_current_ptr;
2308
2309                 ++l_img_comp;
2310         }
2311
2312         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) {
2313                 return OPJ_FALSE;
2314         }
2315
2316         return OPJ_TRUE;
2317 }
2318
2319 static void j2k_read_siz(opj_j2k_t *j2k) {
2320         int len;
2321         OPJ_UINT32 i;
2322         
2323         opj_cio_t *cio = j2k->cio;
2324         opj_image_t *image = j2k->image;
2325         opj_cp_t *cp = j2k->cp;
2326         
2327         len = cio_read(cio, 2);                 /* Lsiz */
2328         cio_read(cio, 2);                               /* Rsiz (capabilities) */
2329         image->x1 = cio_read(cio, 4);   /* Xsiz */
2330         image->y1 = cio_read(cio, 4);   /* Ysiz */
2331         image->x0 = cio_read(cio, 4);   /* X0siz */
2332         image->y0 = cio_read(cio, 4);   /* Y0siz */
2333         cp->tdx = cio_read(cio, 4);             /* XTsiz */
2334         cp->tdy = cio_read(cio, 4);             /* YTsiz */
2335         cp->tx0 = cio_read(cio, 4);             /* XT0siz */
2336         cp->ty0 = cio_read(cio, 4);             /* YT0siz */
2337         
2338   /* the following code triggers: */
2339   /* warning: comparison of unsigned expression < 0 is always false */
2340 #if 0
2341         if ((image->x0<0)||(image->x1<0)||(image->y0<0)||(image->y1<0)) {
2342                 opj_event_msg(j2k->cinfo, EVT_ERROR,
2343                                                                         "%s: invalid image size (x0:%d, x1:%d, y0:%d, y1:%d)\n",
2344                                                                         image->x0,image->x1,image->y0,image->y1);
2345                 return;
2346         }
2347 #endif
2348         
2349         image->numcomps = cio_read(cio, 2);     /* Csiz */
2350
2351 #ifdef USE_JPWL
2352         if (j2k->cp->correct) {
2353                 /* if JPWL is on, we check whether TX errors have damaged
2354                   too much the SIZ parameters */
2355                 if (!(image->x1 * image->y1)) {
2356                         opj_event_msg(j2k->cinfo, EVT_ERROR,
2357                                 "JPWL: bad image size (%d x %d)\n",
2358                                 image->x1, image->y1);
2359                         if (!JPWL_ASSUME || JPWL_ASSUME) {
2360                                 opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
2361                                 return;
2362                         }
2363                 }
2364     assert( len >= 38 );
2365                 if (image->numcomps != (OPJ_UINT32)((len - 38) / 3)) {
2366                         opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
2367                                 "JPWL: Csiz is %d => space in SIZ only for %d comps.!!!\n",
2368                                 image->numcomps, ((len - 38) / 3));
2369                         if (!JPWL_ASSUME) {
2370                                 opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
2371                                 return;
2372                         }
2373                         /* we try to correct */
2374                         opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust this\n");
2375                         if (image->numcomps < (OPJ_UINT32)((len - 38) / 3)) {
2376                                 len = 38 + 3 * image->numcomps;
2377                                 opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting Lsiz to %d => HYPOTHESIS!!!\n",
2378                                         len);                           
2379                         } else {
2380                                 image->numcomps = ((len - 38) / 3);
2381                                 opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting Csiz to %d => HYPOTHESIS!!!\n",
2382                                         image->numcomps);                               
2383                         }
2384                 }
2385
2386                 /* update components number in the jpwl_exp_comps filed */
2387                 cp->exp_comps = image->numcomps;
2388         }
2389 #endif /* USE_JPWL */
2390
2391         image->comps = (opj_image_comp_t*) opj_calloc(image->numcomps, sizeof(opj_image_comp_t));
2392         for (i = 0; i < image->numcomps; i++) {
2393                 int tmp, w, h;
2394                 tmp = cio_read(cio, 1);         /* Ssiz_i */
2395                 image->comps[i].prec = (tmp & 0x7f) + 1;
2396                 image->comps[i].sgnd = tmp >> 7;
2397                 image->comps[i].dx = cio_read(cio, 1);  /* XRsiz_i */
2398                 image->comps[i].dy = cio_read(cio, 1);  /* YRsiz_i */
2399                 
2400 #ifdef USE_JPWL
2401                 if (j2k->cp->correct) {
2402                 /* if JPWL is on, we check whether TX errors have damaged
2403                         too much the SIZ parameters, again */
2404                         if (!(image->comps[i].dx * image->comps[i].dy)) {
2405                                 opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
2406                                         "JPWL: bad XRsiz_%d/YRsiz_%d (%d x %d)\n",
2407                                         i, i, image->comps[i].dx, image->comps[i].dy);
2408                                 if (!JPWL_ASSUME) {
2409                                         opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
2410                                         return;
2411                                 }
2412                                 /* we try to correct */
2413                                 opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust them\n");
2414                                 if (!image->comps[i].dx) {
2415                                         image->comps[i].dx = 1;
2416                                         opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting XRsiz_%d to %d => HYPOTHESIS!!!\n",
2417                                                 i, image->comps[i].dx);
2418                                 }
2419                                 if (!image->comps[i].dy) {
2420                                         image->comps[i].dy = 1;
2421                                         opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting YRsiz_%d to %d => HYPOTHESIS!!!\n",
2422                                                 i, image->comps[i].dy);
2423                                 }
2424                         }
2425                         
2426                 }
2427 #endif /* USE_JPWL */
2428
2429                 /* TODO: unused ? */
2430                 w = int_ceildiv(image->x1 - image->x0, image->comps[i].dx);
2431                 h = int_ceildiv(image->y1 - image->y0, image->comps[i].dy);
2432
2433                 image->comps[i].resno_decoded = 0;      /* number of resolution decoded */
2434                 image->comps[i].factor = cp->reduce; /* reducing factor per component */
2435         }
2436         
2437         cp->tw = int_ceildiv(image->x1 - cp->tx0, cp->tdx);
2438         cp->th = int_ceildiv(image->y1 - cp->ty0, cp->tdy);
2439
2440 #ifdef USE_JPWL
2441         if (j2k->cp->correct) {
2442                 /* if JPWL is on, we check whether TX errors have damaged
2443                   too much the SIZ parameters */
2444                 if ((cp->tw < 1) || (cp->th < 1) || (cp->tw > cp->max_tiles) || (cp->th > cp->max_tiles)) {
2445                         opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
2446                                 "JPWL: bad number of tiles (%d x %d)\n",
2447                                 cp->tw, cp->th);
2448                         if (!JPWL_ASSUME) {
2449                                 opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
2450                                 return;
2451                         }
2452                         /* we try to correct */
2453                         opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust them\n");
2454                         if (cp->tw < 1) {
2455                                 cp->tw= 1;
2456                                 opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting %d tiles in x => HYPOTHESIS!!!\n",
2457                                         cp->tw);
2458                         }
2459                         if (cp->tw > cp->max_tiles) {
2460                                 cp->tw= 1;
2461                                 opj_event_msg(j2k->cinfo, EVT_WARNING, "- too large x, increase expectance of %d\n"
2462                                         "- setting %d tiles in x => HYPOTHESIS!!!\n",
2463                                         cp->max_tiles, cp->tw);
2464                         }
2465                         if (cp->th < 1) {
2466                                 cp->th= 1;
2467                                 opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting %d tiles in y => HYPOTHESIS!!!\n",
2468                                         cp->th);
2469                         }
2470                         if (cp->th > cp->max_tiles) {
2471                                 cp->th= 1;
2472                                 opj_event_msg(j2k->cinfo, EVT_WARNING, "- too large y, increase expectance of %d to continue\n",
2473                                         "- setting %d tiles in y => HYPOTHESIS!!!\n",
2474                                         cp->max_tiles, cp->th);
2475                         }
2476                 }
2477         }
2478 #endif /* USE_JPWL */
2479
2480         cp->tcps = (opj_tcp_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tcp_t));
2481         cp->tileno = (int*) opj_malloc(cp->tw * cp->th * sizeof(int));
2482         cp->tileno_size = 0;
2483         
2484 #ifdef USE_JPWL
2485         if (j2k->cp->correct) {
2486                 if (!cp->tcps) {
2487                         opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
2488                                 "JPWL: could not alloc tcps field of cp\n");
2489                         if (!JPWL_ASSUME || JPWL_ASSUME) {
2490                                 opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
2491                                 return;
2492                         }
2493                 }
2494         }
2495 #endif /* USE_JPWL */
2496
2497         for (i = 0; i < (OPJ_UINT32)cp->tw * cp->th; i++) {
2498                 cp->tcps[i].POC = 0;
2499                 cp->tcps[i].numpocs = 0;
2500                 cp->tcps[i].first = 1;
2501         }
2502         
2503         /* Initialization for PPM marker */
2504         cp->ppm = 0;
2505         cp->ppm_data = NULL;
2506         cp->ppm_data_first = NULL;
2507         cp->ppm_previous = 0;
2508         cp->ppm_store = 0;
2509
2510         j2k->default_tcp->tccps = (opj_tccp_t*) opj_calloc(image->numcomps, sizeof(opj_tccp_t));
2511         for (i = 0; i < (OPJ_UINT32)cp->tw * cp->th; i++) {
2512                 cp->tcps[i].tccps = (opj_tccp_t*) opj_malloc(image->numcomps * sizeof(opj_tccp_t));
2513         }       
2514         j2k->tile_data = (unsigned char**) opj_calloc(cp->tw * cp->th, sizeof(unsigned char*));
2515         j2k->tile_len = (int*) opj_calloc(cp->tw * cp->th, sizeof(int));
2516         j2k->state = J2K_STATE_MH;
2517
2518         /* Index */
2519         if (j2k->cstr_info) {
2520                 opj_codestream_info_t *cstr_info = j2k->cstr_info;
2521                 cstr_info->image_w = image->x1 - image->x0;
2522                 cstr_info->image_h = image->y1 - image->y0;
2523                 cstr_info->numcomps = image->numcomps;
2524                 cstr_info->tw = cp->tw;
2525                 cstr_info->th = cp->th;
2526                 cstr_info->tile_x = cp->tdx;    
2527                 cstr_info->tile_y = cp->tdy;    
2528                 cstr_info->tile_Ox = cp->tx0;   
2529                 cstr_info->tile_Oy = cp->ty0;                   
2530                 cstr_info->tile = (opj_tile_info_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tile_info_t));              
2531         }
2532 }
2533
2534
2535 /**
2536  * Reads a SIZ marker (image and tile size)
2537  * @param       p_header_data   the data contained in the SIZ box.
2538  * @param       jp2                             the jpeg2000 file codec.
2539  * @param       p_header_size   the size of the data contained in the SIZ marker.
2540  * @param       p_manager               the user event manager.
2541 */
2542 opj_bool j2k_read_siz_v2 (
2543                                     opj_j2k_v2_t *p_j2k,
2544                                         OPJ_BYTE * p_header_data,
2545                                         OPJ_UINT32 p_header_size,
2546                                         struct opj_event_mgr * p_manager
2547                                         )
2548 {
2549         OPJ_UINT32 l_size, i;
2550         OPJ_UINT32 l_nb_comp;
2551         OPJ_UINT32 l_nb_comp_remain;
2552         OPJ_UINT32 l_remaining_size;
2553         OPJ_UINT32 l_nb_tiles;
2554         OPJ_UINT32 l_tmp;
2555         opj_image_t *l_image = 00;
2556         opj_cp_v2_t *l_cp = 00;
2557         opj_image_comp_t * l_img_comp = 00;
2558         opj_tcp_v2_t * l_current_tile_param = 00;
2559
2560         /* preconditions */
2561         assert(p_j2k != 00);
2562         assert(p_manager != 00);
2563         assert(p_header_data != 00);
2564
2565         l_image = p_j2k->m_private_image;
2566         l_cp = &(p_j2k->m_cp);
2567
2568         /* minimum size == 39 - 3 (= minimum component parameter) */
2569         if (p_header_size < 36) {
2570                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error with SIZ marker size\n");
2571                 return OPJ_FALSE;
2572         }
2573
2574         l_remaining_size = p_header_size - 36;
2575         l_nb_comp = l_remaining_size / 3;
2576         l_nb_comp_remain = l_remaining_size % 3;
2577         if (l_nb_comp_remain != 0){
2578                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error with SIZ marker size\n");
2579                 return OPJ_FALSE;
2580         }
2581
2582         l_size = p_header_size + 2;                                                                             /* Lsiz */
2583
2584         opj_read_bytes(p_header_data,&l_tmp ,2);                                                /* Rsiz (capabilities) */
2585         p_header_data+=2;
2586         l_cp->rsiz = (OPJ_RSIZ_CAPABILITIES) l_tmp;
2587         opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_image->x1, 4);   /* Xsiz */
2588         p_header_data+=4;
2589         opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_image->y1, 4);   /* Ysiz */
2590         p_header_data+=4;
2591         opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_image->x0, 4);   /* X0siz */
2592         p_header_data+=4;
2593         opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_image->y0, 4);   /* Y0siz */
2594         p_header_data+=4;
2595         opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_cp->tdx, 4);             /* XTsiz */
2596         p_header_data+=4;
2597         opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_cp->tdy, 4);             /* YTsiz */
2598         p_header_data+=4;
2599         opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_cp->tx0, 4);             /* XT0siz */
2600         p_header_data+=4;
2601         opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_cp->ty0, 4);             /* YT0siz */
2602         p_header_data+=4;
2603         opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_tmp, 2);                 /* Csiz */
2604         p_header_data+=2;
2605         if (l_tmp < 16385)
2606                 l_image->numcomps = (OPJ_UINT16) l_tmp;
2607         else {
2608                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error with SIZ marker: number of component is illegal -> %d\n", l_tmp);
2609                 return OPJ_FALSE;
2610         }
2611
2612         if (l_image->numcomps != l_nb_comp) {
2613                 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);
2614                 return OPJ_FALSE;
2615         }
2616
2617 #ifdef USE_JPWL
2618         if (l_cp->correct) {
2619                 /* if JPWL is on, we check whether TX errors have damaged
2620                   too much the SIZ parameters */
2621                 if (!(l_image->x1 * l_image->y1)) {
2622                         opj_event_msg_v2(p_manager, EVT_ERROR,
2623                                 "JPWL: bad image size (%d x %d)\n",
2624                                 l_image->x1, l_image->y1);
2625                         if (!JPWL_ASSUME || JPWL_ASSUME) {
2626                                 opj_event_msg_v2(p_manager, EVT_ERROR, "JPWL: giving up\n");
2627                                 return OPJ_FALSE;
2628                         }
2629                 }
2630
2631         /* FIXME check previously in the function so why keep this piece of code ? Need by the norm ?
2632                 if (l_image->numcomps != ((len - 38) / 3)) {
2633                         opj_event_msg_v2(p_manager, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
2634                                 "JPWL: Csiz is %d => space in SIZ only for %d comps.!!!\n",
2635                                 l_image->numcomps, ((len - 38) / 3));
2636                         if (!JPWL_ASSUME) {
2637                                 opj_event_msg_v2(p_manager, EVT_ERROR, "JPWL: giving up\n");
2638                                 return OPJ_FALSE;
2639                         }
2640         */              /* we try to correct */
2641         /*              opj_event_msg_v2(p_manager, EVT_WARNING, "- trying to adjust this\n");
2642                         if (l_image->numcomps < ((len - 38) / 3)) {
2643                                 len = 38 + 3 * l_image->numcomps;
2644                                 opj_event_msg_v2(p_manager, EVT_WARNING, "- setting Lsiz to %d => HYPOTHESIS!!!\n",
2645                                         len);
2646                         } else {
2647                                 l_image->numcomps = ((len - 38) / 3);
2648                                 opj_event_msg_v2(p_manager, EVT_WARNING, "- setting Csiz to %d => HYPOTHESIS!!!\n",
2649                                         l_image->numcomps);
2650                         }
2651                 }
2652         */
2653
2654                 /* update components number in the jpwl_exp_comps filed */
2655                 l_cp->exp_comps = l_image->numcomps;
2656         }
2657 #endif /* USE_JPWL */
2658
2659         /* Allocate the resulting image components */
2660         l_image->comps = (opj_image_comp_t*) opj_calloc(l_image->numcomps, sizeof(opj_image_comp_t));
2661         if (l_image->comps == 00){
2662                 l_image->numcomps = 0;
2663                 opj_event_msg_v2(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
2664                 return OPJ_FALSE;
2665         }
2666
2667         memset(l_image->comps,0,l_image->numcomps * sizeof(opj_image_comp_t));
2668         l_img_comp = l_image->comps;
2669
2670         /* Read the component information */
2671         for (i = 0; i < l_image->numcomps; ++i){
2672                 OPJ_UINT32 tmp;
2673                 opj_read_bytes(p_header_data,&tmp,1);   /* Ssiz_i */
2674                 ++p_header_data;
2675                 l_img_comp->prec = (tmp & 0x7f) + 1;
2676                 l_img_comp->sgnd = tmp >> 7;
2677                 opj_read_bytes(p_header_data,&tmp,1);   /* XRsiz_i */
2678                 ++p_header_data;
2679                 l_img_comp->dx = (OPJ_INT32)tmp; /* should be between 1 and 255 */
2680                 opj_read_bytes(p_header_data,&tmp,1);   /* YRsiz_i */
2681                 ++p_header_data;
2682                 l_img_comp->dy = (OPJ_INT32)tmp; /* should be between 1 and 255 */
2683
2684 #ifdef USE_JPWL
2685                 if (l_cp->correct) {
2686                 /* if JPWL is on, we check whether TX errors have damaged
2687                         too much the SIZ parameters, again */
2688                         if (!(l_image->comps[i].dx * l_image->comps[i].dy)) {
2689                                 opj_event_msg_v2(p_manager, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
2690                                         "JPWL: bad XRsiz_%d/YRsiz_%d (%d x %d)\n",
2691                                         i, i, l_image->comps[i].dx, l_image->comps[i].dy);
2692                                 if (!JPWL_ASSUME) {
2693                                         opj_event_msg_v2(p_manager, EVT_ERROR, "JPWL: giving up\n");
2694                                         return OPJ_FALSE;
2695                                 }
2696                                 /* we try to correct */
2697                                 opj_event_msg_v2(p_manager, EVT_WARNING, "- trying to adjust them\n");
2698                                 if (!l_image->comps[i].dx) {
2699                                         l_image->comps[i].dx = 1;
2700                                         opj_event_msg_v2(p_manager, EVT_WARNING, "- setting XRsiz_%d to %d => HYPOTHESIS!!!\n",
2701                                                 i, l_image->comps[i].dx);
2702                                 }
2703                                 if (!l_image->comps[i].dy) {
2704                                         l_image->comps[i].dy = 1;
2705                                         opj_event_msg_v2(p_manager, EVT_WARNING, "- setting YRsiz_%d to %d => HYPOTHESIS!!!\n",
2706                                                 i, l_image->comps[i].dy);
2707                                 }
2708                         }
2709                 }
2710 #endif /* USE_JPWL */
2711                 l_img_comp->resno_decoded = 0;                                                          /* number of resolution decoded */
2712                 l_img_comp->factor = l_cp->m_specific_param.m_dec.m_reduce; /* reducing factor per component */
2713                 ++l_img_comp;
2714         }
2715
2716         /* Compute the number of tiles */
2717         l_cp->tw = int_ceildiv(l_image->x1 - l_cp->tx0, l_cp->tdx);
2718         l_cp->th = int_ceildiv(l_image->y1 - l_cp->ty0, l_cp->tdy);
2719         l_nb_tiles = l_cp->tw * l_cp->th;
2720
2721         /* Define the tiles which will be decoded */
2722         if (p_j2k->m_specific_param.m_decoder.m_discard_tiles) {
2723                 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;
2724                 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;
2725                 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);
2726                 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);
2727         }
2728         else {
2729                 p_j2k->m_specific_param.m_decoder.m_start_tile_x = 0;
2730                 p_j2k->m_specific_param.m_decoder.m_start_tile_y = 0;
2731                 p_j2k->m_specific_param.m_decoder.m_end_tile_x = l_cp->tw;
2732                 p_j2k->m_specific_param.m_decoder.m_end_tile_y = l_cp->th;
2733         }
2734
2735 #ifdef USE_JPWL
2736         if (l_cp->correct) {
2737                 /* if JPWL is on, we check whether TX errors have damaged
2738                   too much the SIZ parameters */
2739                 if ((l_cp->tw < 1) || (l_cp->th < 1) || (l_cp->tw > l_cp->max_tiles) || (l_cp->th > l_cp->max_tiles)) {
2740                         opj_event_msg_v2(p_manager, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
2741                                 "JPWL: bad number of tiles (%d x %d)\n",
2742                                 l_cp->tw, l_cp->th);
2743                         if (!JPWL_ASSUME) {
2744                                 opj_event_msg_v2(p_manager, EVT_ERROR, "JPWL: giving up\n");
2745                                 return OPJ_FALSE;
2746                         }
2747                         /* we try to correct */
2748                         opj_event_msg_v2(p_manager, EVT_WARNING, "- trying to adjust them\n");
2749                         if (l_cp->tw < 1) {
2750                                 l_cp->tw= 1;
2751                                 opj_event_msg_v2(p_manager, EVT_WARNING, "- setting %d tiles in x => HYPOTHESIS!!!\n",
2752                                                 l_cp->tw);
2753                         }
2754                         if (l_cp->tw > l_cp->max_tiles) {
2755                                 l_cp->tw= 1;
2756                                 opj_event_msg_v2(p_manager, EVT_WARNING, "- too large x, increase expectance of %d\n"
2757                                         "- setting %d tiles in x => HYPOTHESIS!!!\n",
2758                                         l_cp->max_tiles, l_cp->tw);
2759                         }
2760                         if (l_cp->th < 1) {
2761                                 l_cp->th= 1;
2762                                 opj_event_msg_v2(p_manager, EVT_WARNING, "- setting %d tiles in y => HYPOTHESIS!!!\n",
2763                                                 l_cp->th);
2764                         }
2765                         if (l_cp->th > l_cp->max_tiles) {
2766                                 l_cp->th= 1;
2767                                 opj_event_msg_v2(p_manager, EVT_WARNING, "- too large y, increase expectance of %d to continue\n",
2768                                         "- setting %d tiles in y => HYPOTHESIS!!!\n",
2769                                         l_cp->max_tiles, l_cp->th);
2770                         }
2771                 }
2772         }
2773 #endif /* USE_JPWL */
2774
2775         /* memory allocations */
2776         l_cp->tcps = (opj_tcp_v2_t*) opj_calloc(l_nb_tiles, sizeof(opj_tcp_v2_t));
2777         if (l_cp->tcps == 00) {
2778                 opj_event_msg_v2(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
2779                 return OPJ_FALSE;
2780         }
2781         memset(l_cp->tcps,0,l_nb_tiles*sizeof(opj_tcp_t));
2782
2783 #ifdef USE_JPWL
2784         if (l_cp->correct) {
2785                 if (!l_cp->tcps) {
2786                         opj_event_msg_v2(p_manager, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
2787                                 "JPWL: could not alloc tcps field of cp\n");
2788                         if (!JPWL_ASSUME || JPWL_ASSUME) {
2789                                 opj_event_msg_v2(p_manager, EVT_ERROR, "JPWL: giving up\n");
2790                                 return OPJ_FALSE;
2791                         }
2792                 }
2793         }
2794 #endif /* USE_JPWL */
2795
2796         p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps =
2797                         (opj_tccp_t*) opj_calloc(l_image->numcomps, sizeof(opj_tccp_t));
2798         if(p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps  == 00) {
2799                 opj_event_msg_v2(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
2800                 return OPJ_FALSE;
2801         }
2802         memset(p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps ,0,l_image->numcomps*sizeof(opj_tccp_t));
2803
2804         p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mct_records =
2805                         (opj_mct_data_t*)opj_malloc(J2K_MCT_DEFAULT_NB_RECORDS * sizeof(opj_mct_data_t));
2806
2807         if (! p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mct_records) {
2808                 opj_event_msg_v2(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
2809                 return OPJ_FALSE;
2810         }
2811         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));
2812         p_j2k->m_specific_param.m_decoder.m_default_tcp->m_nb_max_mct_records = J2K_MCT_DEFAULT_NB_RECORDS;
2813
2814         p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mcc_records =
2815                         (opj_simple_mcc_decorrelation_data_t*)
2816                         opj_malloc(J2K_MCC_DEFAULT_NB_RECORDS * sizeof(opj_simple_mcc_decorrelation_data_t));
2817
2818         if (! p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mcc_records) {
2819                 opj_event_msg_v2(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
2820                 return OPJ_FALSE;
2821         }
2822         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));
2823         p_j2k->m_specific_param.m_decoder.m_default_tcp->m_nb_max_mcc_records = J2K_MCC_DEFAULT_NB_RECORDS;
2824
2825         /* set up default dc level shift */
2826         for (i=0;i<l_image->numcomps;++i) {
2827                 if (! l_image->comps[i].sgnd) {
2828                         p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps[i].m_dc_level_shift = 1 << (l_image->comps[i].prec - 1);
2829                 }
2830         }
2831
2832         l_current_tile_param = l_cp->tcps;
2833         for     (i = 0; i < l_nb_tiles; ++i) {
2834                 l_current_tile_param->tccps = (opj_tccp_t*) opj_malloc(l_image->numcomps * sizeof(opj_tccp_t));
2835                 if (l_current_tile_param->tccps == 00) {
2836                         opj_event_msg_v2(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
2837                         return OPJ_FALSE;
2838                 }
2839                 memset(l_current_tile_param->tccps,0,l_image->numcomps * sizeof(opj_tccp_t));
2840
2841                 ++l_current_tile_param;
2842         }
2843
2844         p_j2k->m_specific_param.m_decoder.m_state =  J2K_STATE_MH; /* FIXME J2K_DEC_STATE_MH; */
2845         opj_image_comp_header_update(l_image,l_cp);
2846
2847         return OPJ_TRUE;
2848 }
2849
2850
2851
2852 static void j2k_write_com(opj_j2k_t *j2k) {
2853         unsigned int i;
2854         int lenp, len;
2855
2856         if(j2k->cp->comment) {
2857                 opj_cio_t *cio = j2k->cio;
2858                 char *comment = j2k->cp->comment;
2859
2860                 cio_write(cio, J2K_MS_COM, 2);
2861                 lenp = cio_tell(cio);
2862                 cio_skip(cio, 2);
2863                 cio_write(cio, 1, 2);           /* General use (IS 8859-15:1999 (Latin) values) */
2864                 for (i = 0; i < strlen(comment); i++) {
2865                         cio_write(cio, comment[i], 1);
2866                 }
2867                 len = cio_tell(cio) - lenp;
2868                 cio_seek(cio, lenp);
2869                 cio_write(cio, len, 2);
2870                 cio_seek(cio, lenp + len);
2871
2872                 
2873                 if(j2k->cstr_info)
2874                   j2k_add_mhmarker(j2k->cstr_info, J2K_MS_COM, lenp, len);
2875
2876         }
2877 }
2878
2879 /**
2880  * Writes the COM marker (comment)
2881  * 
2882  * @param       p_stream                        the stream to write data to.
2883  * @param       p_j2k                   J2K codec.
2884  * @param       p_manager       the user event manager.
2885 */
2886 opj_bool j2k_write_com_v2(      opj_j2k_v2_t *p_j2k,
2887                                                         struct opj_stream_private *p_stream,
2888                                                         struct opj_event_mgr * p_manager )
2889 {
2890         OPJ_UINT32 l_comment_size;
2891         OPJ_UINT32 l_total_com_size;
2892         const OPJ_CHAR *l_comment;
2893         OPJ_BYTE * l_current_ptr = 00;
2894
2895         // preconditions
2896         assert(p_j2k != 00);
2897         assert(p_stream != 00);
2898         assert(p_manager != 00);
2899         
2900         l_comment = p_j2k->m_cp.comment;
2901         l_comment_size = strlen(l_comment);
2902         l_total_com_size = l_comment_size + 6;
2903
2904         if (l_total_com_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
2905                 p_j2k->m_specific_param.m_encoder.m_header_tile_data 
2906                         = (OPJ_BYTE*)opj_realloc(       p_j2k->m_specific_param.m_encoder.m_header_tile_data,
2907                                                                                 l_total_com_size);
2908                 
2909                 if(! p_j2k->m_specific_param.m_encoder.m_header_tile_data) {
2910                         return OPJ_FALSE;
2911                 }
2912
2913                 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_total_com_size;
2914         }
2915
2916         l_current_ptr = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
2917         
2918         opj_write_bytes(l_current_ptr,J2K_MS_COM , 2);  /* COM */
2919         l_current_ptr+=2;
2920         
2921         opj_write_bytes(l_current_ptr,l_total_com_size - 2 , 2);        /* L_COM */
2922         l_current_ptr+=2;
2923         
2924         opj_write_bytes(l_current_ptr,1 , 2);   /* General use (IS 8859-15:1999 (Latin) values) */
2925         l_current_ptr+=2;
2926         
2927         memcpy( l_current_ptr,l_comment,l_comment_size);
2928         
2929         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) {
2930                 return OPJ_FALSE;
2931         }
2932
2933         return OPJ_TRUE;
2934 }
2935
2936 static void j2k_read_com(opj_j2k_t *j2k) {
2937         int len;
2938         
2939         opj_cio_t *cio = j2k->cio;
2940
2941         len = cio_read(cio, 2);
2942         cio_skip(cio, len - 2);  
2943 }
2944 /**
2945  * Reads a COM marker (comments)
2946  * @param       p_header_data   the data contained in the COM box.
2947  * @param       jp2                             the jpeg2000 file codec.
2948  * @param       p_header_size   the size of the data contained in the COM marker.
2949  * @param       p_manager               the user event manager.
2950 */
2951 opj_bool j2k_read_com_v2 (
2952                                         opj_j2k_v2_t *p_j2k,
2953                                         OPJ_BYTE * p_header_data,
2954                                         OPJ_UINT32 p_header_size,
2955                                         struct opj_event_mgr * p_manager
2956                                         )
2957 {
2958         /* preconditions */
2959         assert(p_j2k != 00);
2960         assert(p_manager != 00);
2961         assert(p_header_data != 00);
2962   (void)p_header_size;
2963
2964         return OPJ_TRUE;
2965 }
2966
2967 static void j2k_write_cox(opj_j2k_t *j2k, int compno) {
2968         OPJ_UINT32 i;
2969
2970         opj_cp_t *cp = j2k->cp;
2971         opj_tcp_t *tcp = &cp->tcps[j2k->curtileno];
2972         opj_tccp_t *tccp = &tcp->tccps[compno];
2973         opj_cio_t *cio = j2k->cio;
2974         
2975         cio_write(cio, tccp->numresolutions - 1, 1);    /* SPcox (D) */
2976         cio_write(cio, tccp->cblkw - 2, 1);                             /* SPcox (E) */
2977         cio_write(cio, tccp->cblkh - 2, 1);                             /* SPcox (F) */
2978         cio_write(cio, tccp->cblksty, 1);                               /* SPcox (G) */
2979         cio_write(cio, tccp->qmfbid, 1);                                /* SPcox (H) */
2980         
2981         if (tccp->csty & J2K_CCP_CSTY_PRT) {
2982                 for (i = 0; i < tccp->numresolutions; i++) {
2983                         cio_write(cio, tccp->prcw[i] + (tccp->prch[i] << 4), 1);        /* SPcox (I_i) */
2984                 }
2985         }
2986 }
2987
2988 static void j2k_read_cox(opj_j2k_t *j2k, int compno) {
2989         OPJ_UINT32 i;
2990
2991         opj_cp_t *cp = j2k->cp;
2992         opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp;
2993         opj_tccp_t *tccp = &tcp->tccps[compno];
2994         opj_cio_t *cio = j2k->cio;
2995
2996         tccp->numresolutions = cio_read(cio, 1) + 1;    /* SPcox (D) */
2997
2998         /* If user wants to remove more resolutions than the codestream contains, return error*/
2999         assert(cp->reduce >= 0);
3000         if ((OPJ_UINT32)cp->reduce >= tccp->numresolutions) {
3001                 opj_event_msg(j2k->cinfo, EVT_ERROR, "Error decoding component %d.\nThe number of resolutions to remove is higher than the number "
3002                                         "of resolutions of this component\nModify the cp_reduce parameter.\n\n", compno);
3003                 j2k->state |= J2K_STATE_ERR;
3004         }
3005
3006         tccp->cblkw = cio_read(cio, 1) + 2;     /* SPcox (E) */
3007         tccp->cblkh = cio_read(cio, 1) + 2;     /* SPcox (F) */
3008         tccp->cblksty = cio_read(cio, 1);       /* SPcox (G) */
3009         tccp->qmfbid = cio_read(cio, 1);        /* SPcox (H) */
3010         if (tccp->csty & J2K_CP_CSTY_PRT) {
3011                 for (i = 0; i < tccp->numresolutions; i++) {
3012                         int tmp = cio_read(cio, 1);     /* SPcox (I_i) */
3013                         tccp->prcw[i] = tmp & 0xf;
3014                         tccp->prch[i] = tmp >> 4;
3015                 }
3016         }
3017
3018         /* INDEX >> */
3019         if(j2k->cstr_info && compno == 0) {
3020                 for (i = 0; i < tccp->numresolutions; i++) {
3021                         if (tccp->csty & J2K_CP_CSTY_PRT) {
3022                                 j2k->cstr_info->tile[j2k->curtileno].pdx[i] = tccp->prcw[i];
3023                                 j2k->cstr_info->tile[j2k->curtileno].pdy[i] = tccp->prch[i];
3024                         }
3025                         else {
3026                                 j2k->cstr_info->tile[j2k->curtileno].pdx[i] = 15;
3027                                 j2k->cstr_info->tile[j2k->curtileno].pdx[i] = 15;
3028                         }
3029                 }
3030         }
3031         /* << INDEX */
3032 }
3033
3034 static void j2k_write_cod(opj_j2k_t *j2k) {
3035         opj_cp_t *cp = NULL;
3036         opj_tcp_t *tcp = NULL;
3037         int lenp, len;
3038
3039         opj_cio_t *cio = j2k->cio;
3040         
3041         cio_write(cio, J2K_MS_COD, 2);  /* COD */
3042         
3043         lenp = cio_tell(cio);
3044         cio_skip(cio, 2);
3045         
3046         cp = j2k->cp;
3047         tcp = &cp->tcps[j2k->curtileno];
3048
3049         cio_write(cio, tcp->csty, 1);           /* Scod */
3050         cio_write(cio, tcp->prg, 1);            /* SGcod (A) */
3051         cio_write(cio, tcp->numlayers, 2);      /* SGcod (B) */
3052         cio_write(cio, tcp->mct, 1);            /* SGcod (C) */
3053         
3054         j2k_write_cox(j2k, 0);
3055         len = cio_tell(cio) - lenp;
3056         cio_seek(cio, lenp);
3057         cio_write(cio, len, 2);         /* Lcod */
3058         cio_seek(cio, lenp + len);
3059
3060         if(j2k->cstr_info)
3061           j2k_add_mhmarker(j2k->cstr_info, J2K_MS_COD, lenp, len);
3062
3063 }
3064
3065 /**
3066  * Writes the COD marker (Coding style default)
3067  *
3068  * @param       p_stream                        the stream to write data to.
3069  * @param       p_j2k                   J2K codec.
3070  * @param       p_manager       the user event manager.
3071 */
3072 opj_bool j2k_write_cod_v2(      opj_j2k_v2_t *p_j2k,
3073                                                         struct opj_stream_private *p_stream,
3074                                                         struct opj_event_mgr * p_manager )
3075 {
3076         opj_cp_v2_t *l_cp = 00;
3077         opj_tcp_v2_t *l_tcp = 00;
3078         OPJ_UINT32 l_code_size,l_remaining_size;
3079         OPJ_BYTE * l_current_data = 00;
3080
3081         /* preconditions */
3082         assert(p_j2k != 00);
3083         assert(p_manager != 00);
3084         assert(p_stream != 00);
3085
3086         l_cp = &(p_j2k->m_cp);
3087         l_tcp = &l_cp->tcps[p_j2k->m_current_tile_number];
3088         l_code_size = 9 + j2k_get_SPCod_SPCoc_size(p_j2k,p_j2k->m_current_tile_number,0);
3089         l_remaining_size = l_code_size;
3090
3091         if (l_code_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
3092                 p_j2k->m_specific_param.m_encoder.m_header_tile_data
3093                         = (OPJ_BYTE*)opj_realloc(
3094                                 p_j2k->m_specific_param.m_encoder.m_header_tile_data,
3095                                 l_code_size);
3096
3097                 if (! p_j2k->m_specific_param.m_encoder.m_header_tile_data) {
3098                         return OPJ_FALSE;
3099                 }
3100
3101                 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_code_size;
3102         }
3103
3104         l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
3105
3106         opj_write_bytes(l_current_data,J2K_MS_COD,2);           /* COD */
3107         l_current_data += 2;
3108
3109         opj_write_bytes(l_current_data,l_code_size-2,2);        /* L_COD */
3110         l_current_data += 2;
3111
3112         opj_write_bytes(l_current_data,l_tcp->csty,1);          /* Scod */
3113         ++l_current_data;
3114
3115         opj_write_bytes(l_current_data,l_tcp->prg,1);           /* SGcod (A) */
3116         ++l_current_data;
3117
3118         opj_write_bytes(l_current_data,l_tcp->numlayers,2);     /* SGcod (B) */
3119         l_current_data+=2;
3120
3121         opj_write_bytes(l_current_data,l_tcp->mct,1);           /* SGcod (C) */
3122         ++l_current_data;
3123
3124         l_remaining_size -= 9;
3125
3126         if (! j2k_write_SPCod_SPCoc(p_j2k,p_j2k->m_current_tile_number,0,l_current_data,&l_remaining_size,p_manager)) {
3127                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error writting COD marker\n");
3128                 return OPJ_FALSE;
3129         }
3130
3131         if (l_remaining_size != 0) {
3132                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error writting COD marker\n");
3133                 return OPJ_FALSE;
3134         }
3135
3136         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) {
3137                 return OPJ_FALSE;
3138         }
3139
3140         return OPJ_TRUE;
3141 }
3142
3143 static void j2k_read_cod(opj_j2k_t *j2k) {
3144         int len, pos;
3145   OPJ_UINT32 i;
3146         
3147         opj_cio_t *cio = j2k->cio;
3148         opj_cp_t *cp = j2k->cp;
3149         opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp;
3150         opj_image_t *image = j2k->image;
3151         
3152         len = cio_read(cio, 2);                         /* Lcod */
3153         tcp->csty = cio_read(cio, 1);           /* Scod */
3154         tcp->prg = (OPJ_PROG_ORDER)cio_read(cio, 1);            /* SGcod (A) */
3155         tcp->numlayers = cio_read(cio, 2);      /* SGcod (B) */
3156         tcp->mct = cio_read(cio, 1);            /* SGcod (C) */
3157         
3158         pos = cio_tell(cio);
3159         for (i = 0; i < image->numcomps; i++) {
3160                 tcp->tccps[i].csty = tcp->csty & J2K_CP_CSTY_PRT;
3161                 cio_seek(cio, pos);
3162                 j2k_read_cox(j2k, i);
3163         }
3164
3165         /* Index */
3166         if (j2k->cstr_info) {
3167                 opj_codestream_info_t *cstr_info = j2k->cstr_info;
3168                 cstr_info->prog = tcp->prg;
3169                 cstr_info->numlayers = tcp->numlayers;
3170                 cstr_info->numdecompos = (int*) opj_malloc(image->numcomps * sizeof(int));
3171                 for (i = 0; i < image->numcomps; i++) {
3172                         cstr_info->numdecompos[i] = tcp->tccps[i].numresolutions - 1;
3173                 }
3174         }
3175 }
3176
3177 /**
3178  * Reads a COD marker (Coding Styke defaults)
3179  * @param       p_header_data   the data contained in the COD box.
3180  * @param       p_j2k                   the jpeg2000 codec.
3181  * @param       p_header_size   the size of the data contained in the COD marker.
3182  * @param       p_manager               the user event manager.
3183 */
3184 opj_bool j2k_read_cod_v2 (
3185                                         opj_j2k_v2_t *p_j2k,
3186                                         OPJ_BYTE * p_header_data,
3187                                         OPJ_UINT32 p_header_size,
3188                                         struct opj_event_mgr * p_manager
3189                                         )
3190 {
3191         /* loop */
3192         OPJ_UINT32 i;
3193         OPJ_UINT32 l_tmp;
3194         opj_cp_v2_t *l_cp = 00;
3195         opj_tcp_v2_t *l_tcp = 00;
3196         opj_image_t *l_image = 00;
3197
3198         /* preconditions */
3199         assert(p_header_data != 00);
3200         assert(p_j2k != 00);
3201         assert(p_manager != 00);
3202
3203         l_image = p_j2k->m_private_image;
3204         l_cp = &(p_j2k->m_cp);
3205
3206         /* If we are in the first tile-part header of the current tile */
3207         l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH) ?
3208                                 &l_cp->tcps[p_j2k->m_current_tile_number] :
3209                                 p_j2k->m_specific_param.m_decoder.m_default_tcp;
3210
3211         /* Make sure room is sufficient */
3212         if (p_header_size < 5) {
3213                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading COD marker\n");
3214                 return OPJ_FALSE;
3215         }
3216
3217         opj_read_bytes(p_header_data,&l_tcp->csty,1);           /* Scod */
3218         ++p_header_data;
3219         opj_read_bytes(p_header_data,&l_tmp,1);                         /* SGcod (A) */
3220         ++p_header_data;
3221         l_tcp->prg = (OPJ_PROG_ORDER) l_tmp;
3222         opj_read_bytes(p_header_data,&l_tcp->numlayers,2);      /* SGcod (B) */
3223         p_header_data+=2;
3224
3225         /* If user didn't set a number layer to decode take the max specify in the codestream. */
3226         if      (l_cp->m_specific_param.m_dec.m_layer) {
3227                 l_tcp->num_layers_to_decode = l_cp->m_specific_param.m_dec.m_layer;
3228         }
3229         else {
3230                 l_tcp->num_layers_to_decode = l_tcp->numlayers;
3231         }
3232
3233         opj_read_bytes(p_header_data,&l_tcp->mct,1);            /* SGcod (C) */
3234         ++p_header_data;
3235
3236         p_header_size -= 5;
3237         for     (i = 0; i < l_image->numcomps; ++i) {
3238                 l_tcp->tccps[i].csty = l_tcp->csty & J2K_CCP_CSTY_PRT;
3239         }
3240
3241         if (! j2k_read_SPCod_SPCoc(p_j2k,0,p_header_data,&p_header_size,p_manager)) {
3242                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading COD marker\n");
3243                 return OPJ_FALSE;
3244         }
3245
3246         if (p_header_size != 0) {
3247                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading COD marker\n");
3248                 return OPJ_FALSE;
3249         }
3250
3251         /* Apply the coding style to other components of the current tile or the m_default_tcp*/
3252         j2k_copy_tile_component_parameters(p_j2k);
3253
3254         /* Index */
3255 #ifdef WIP_REMOVE_MSD
3256         if (p_j2k->cstr_info) {
3257                 /*opj_codestream_info_t *l_cstr_info = p_j2k->cstr_info;*/
3258                 p_j2k->cstr_info->prog = l_tcp->prg;
3259                 p_j2k->cstr_info->numlayers = l_tcp->numlayers;
3260                 p_j2k->cstr_info->numdecompos = (OPJ_INT32*) opj_malloc(l_image->numcomps * sizeof(OPJ_UINT32));
3261                 for     (i = 0; i < l_image->numcomps; ++i) {
3262                         p_j2k->cstr_info->numdecompos[i] = l_tcp->tccps[i].numresolutions - 1;
3263                 }
3264         }
3265 #endif
3266
3267         return OPJ_TRUE;
3268 }
3269
3270 static void j2k_write_coc(opj_j2k_t *j2k, int compno) {
3271         int lenp, len;
3272
3273         opj_cp_t *cp = j2k->cp;
3274         opj_tcp_t *tcp = &cp->tcps[j2k->curtileno];
3275         opj_image_t *image = j2k->image;
3276         opj_cio_t *cio = j2k->cio;
3277         
3278         cio_write(cio, J2K_MS_COC, 2);  /* COC */
3279         lenp = cio_tell(cio);
3280         cio_skip(cio, 2);
3281         cio_write(cio, compno, image->numcomps <= 256 ? 1 : 2); /* Ccoc */
3282         cio_write(cio, tcp->tccps[compno].csty, 1);     /* Scoc */
3283         j2k_write_cox(j2k, compno);
3284         len = cio_tell(cio) - lenp;
3285         cio_seek(cio, lenp);
3286         cio_write(cio, len, 2);                 /* Lcoc */
3287         cio_seek(cio, lenp + len);
3288 }
3289
3290 /**
3291  * Writes the COC marker (Coding style component)
3292  *
3293  * @param       p_comp_no               the index of the component to output.
3294  * @param       p_stream                                the stream to write data to.
3295  * @param       p_j2k                           J2K codec.
3296  * @param       p_manager               the user event manager.
3297 */
3298 opj_bool j2k_write_coc_v2(      opj_j2k_v2_t *p_j2k,
3299                                                         OPJ_UINT32 p_comp_no,
3300                                                         struct opj_stream_private *p_stream,
3301                                                         struct opj_event_mgr * p_manager )
3302 {
3303         OPJ_UINT32 l_coc_size,l_remaining_size;
3304         OPJ_UINT32 l_comp_room;
3305
3306         /* preconditions */
3307         assert(p_j2k != 00);
3308         assert(p_manager != 00);
3309         assert(p_stream != 00);
3310
3311         l_comp_room = (p_j2k->m_private_image->numcomps <= 256) ? 1 : 2;
3312
3313         l_coc_size = 5 + l_comp_room + j2k_get_SPCod_SPCoc_size(p_j2k,p_j2k->m_current_tile_number,p_comp_no);
3314
3315         if (l_coc_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
3316                 p_j2k->m_specific_param.m_encoder.m_header_tile_data
3317                         = (OPJ_BYTE*)opj_realloc(
3318                                 p_j2k->m_specific_param.m_encoder.m_header_tile_data,
3319                                 l_coc_size);
3320                 if (! p_j2k->m_specific_param.m_encoder.m_header_tile_data) {
3321                         return OPJ_FALSE;
3322                 }
3323
3324                 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_coc_size;
3325         }
3326
3327         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);
3328
3329         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) {
3330                 return OPJ_FALSE;
3331         }
3332
3333         return OPJ_TRUE;
3334 }
3335
3336 /**
3337  * Writes the COC marker (Coding style component)
3338  *
3339  * @param       p_comp_no               the index of the component to output.
3340  * @param       p_stream                                the stream to write data to.
3341  * @param       p_j2k                           J2K codec.
3342  * @param       p_manager               the user event manager.
3343 */
3344 void j2k_write_coc_in_memory(   opj_j2k_v2_t *p_j2k,
3345                                                                 OPJ_UINT32 p_comp_no,
3346                                                                 OPJ_BYTE * p_data,
3347                                                                 OPJ_UINT32 * p_data_written,
3348                                                                 struct opj_event_mgr * p_manager )
3349 {
3350         opj_cp_v2_t *l_cp = 00;
3351         opj_tcp_v2_t *l_tcp = 00;
3352         OPJ_UINT32 l_coc_size,l_remaining_size;
3353         OPJ_BYTE * l_current_data = 00;
3354         opj_image_t *l_image = 00;
3355         OPJ_UINT32 l_comp_room;
3356
3357         /* preconditions */
3358         assert(p_j2k != 00);
3359         assert(p_manager != 00);
3360
3361         l_cp = &(p_j2k->m_cp);
3362         l_tcp = &l_cp->tcps[p_j2k->m_current_tile_number];
3363         l_image = p_j2k->m_private_image;
3364         l_comp_room = (l_image->numcomps <= 256) ? 1 : 2;
3365
3366         l_coc_size = 5 + l_comp_room + j2k_get_SPCod_SPCoc_size(p_j2k,p_j2k->m_current_tile_number,p_comp_no);
3367         l_remaining_size = l_coc_size;
3368
3369         l_current_data = p_data;
3370
3371         opj_write_bytes(l_current_data,J2K_MS_COC,2);                           /* COC */
3372         l_current_data += 2;
3373
3374         opj_write_bytes(l_current_data,l_coc_size-2,2);                         /* L_COC */
3375         l_current_data += 2;
3376
3377         opj_write_bytes(l_current_data,p_comp_no, l_comp_room);         /* Ccoc */
3378         l_current_data+=l_comp_room;
3379
3380         opj_write_bytes(l_current_data, l_tcp->tccps[p_comp_no].csty, 1);               /* Scoc */
3381         ++l_current_data;
3382
3383         l_remaining_size -= (5 + l_comp_room);
3384         j2k_write_SPCod_SPCoc(p_j2k,p_j2k->m_current_tile_number,0,l_current_data,&l_remaining_size,p_manager);
3385         * p_data_written = l_coc_size;
3386 }
3387
3388 /**
3389  * Gets the maximum size taken by a coc.
3390  *
3391  * @param       p_j2k   the jpeg2000 codec to use.
3392  */
3393 OPJ_UINT32 j2k_get_max_coc_size(opj_j2k_v2_t *p_j2k)
3394 {
3395         OPJ_UINT32 i,j;
3396         OPJ_UINT32 l_nb_comp;
3397         OPJ_UINT32 l_nb_tiles;
3398         OPJ_UINT32 l_max = 0;
3399
3400         /* preconditions */
3401
3402         l_nb_tiles = p_j2k->m_cp.tw * p_j2k->m_cp.th ;
3403         l_nb_comp = p_j2k->m_private_image->numcomps;
3404
3405         for (i=0;i<l_nb_tiles;++i) {
3406                 for (j=0;j<l_nb_comp;++j) {
3407                         l_max = uint_max(l_max,j2k_get_SPCod_SPCoc_size(p_j2k,i,j));
3408                 }
3409         }
3410
3411         return 6 + l_max;
3412 }
3413
3414 static void j2k_read_coc(opj_j2k_t *j2k) {
3415         int len, compno;
3416
3417         opj_cp_t *cp = j2k->cp;
3418         opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp;
3419         opj_image_t *image = j2k->image;
3420         opj_cio_t *cio = j2k->cio;
3421         
3422         len = cio_read(cio, 2);         /* Lcoc */
3423         compno = cio_read(cio, image->numcomps <= 256 ? 1 : 2); /* Ccoc */
3424         tcp->tccps[compno].csty = cio_read(cio, 1);     /* Scoc */
3425         j2k_read_cox(j2k, compno);
3426 }
3427
3428 /**
3429  * Reads a COC marker (Coding Style Component)
3430  * @param       p_header_data   the data contained in the COC box.
3431  * @param       p_j2k                   the jpeg2000 codec.
3432  * @param       p_header_size   the size of the data contained in the COC marker.
3433  * @param       p_manager               the user event manager.
3434 */
3435 opj_bool j2k_read_coc_v2 (
3436                                         opj_j2k_v2_t *p_j2k,
3437                                         OPJ_BYTE * p_header_data,
3438                                         OPJ_UINT32 p_header_size,
3439                                         struct opj_event_mgr * p_manager
3440                                         )
3441 {
3442         opj_cp_v2_t *l_cp = NULL;
3443         opj_tcp_v2_t *l_tcp = NULL;
3444         opj_image_t *l_image = NULL;
3445         OPJ_UINT32 l_comp_room;
3446         OPJ_UINT32 l_comp_no;
3447
3448         /* preconditions */
3449         assert(p_header_data != 00);
3450         assert(p_j2k != 00);
3451         assert(p_manager != 00);
3452
3453         l_cp = &(p_j2k->m_cp);
3454         l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH ) ? /*FIXME J2K_DEC_STATE_TPH*/
3455                                 &l_cp->tcps[p_j2k->m_current_tile_number] :
3456                                 p_j2k->m_specific_param.m_decoder.m_default_tcp;
3457         l_image = p_j2k->m_private_image;
3458
3459         l_comp_room = l_image->numcomps <= 256 ? 1 : 2;
3460
3461         /* make sure room is sufficient*/
3462         if (p_header_size < l_comp_room + 1) {
3463                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading COC marker\n");
3464                 return OPJ_FALSE;
3465         }
3466         p_header_size -= l_comp_room + 1;
3467
3468         opj_read_bytes(p_header_data,&l_comp_no,l_comp_room);                   /* Ccoc */
3469         p_header_data += l_comp_room;
3470         if (l_comp_no >= l_image->numcomps) {
3471                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading COC marker (bad number of components)\n");
3472                 return OPJ_FALSE;
3473         }
3474
3475         opj_read_bytes(p_header_data,&l_tcp->tccps[l_comp_no].csty,1);                  /* Scoc */
3476         ++p_header_data ;
3477
3478         if (! j2k_read_SPCod_SPCoc(p_j2k,l_comp_no,p_header_data,&p_header_size,p_manager)) {
3479                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading COC marker\n");
3480                 return OPJ_FALSE;
3481         }
3482
3483         if (p_header_size != 0) {
3484                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading COC marker\n");
3485                 return OPJ_FALSE;
3486         }
3487         return OPJ_TRUE;
3488 }
3489
3490 static void j2k_write_qcx(opj_j2k_t *j2k, int compno) {
3491         int bandno, numbands;
3492         int expn, mant;
3493         
3494         opj_cp_t *cp = j2k->cp;
3495         opj_tcp_t *tcp = &cp->tcps[j2k->curtileno];
3496         opj_tccp_t *tccp = &tcp->tccps[compno];
3497         opj_cio_t *cio = j2k->cio;
3498         
3499         cio_write(cio, tccp->qntsty + (tccp->numgbits << 5), 1);        /* Sqcx */
3500         numbands = tccp->qntsty == J2K_CCP_QNTSTY_SIQNT ? 1 : tccp->numresolutions * 3 - 2;
3501         
3502         for (bandno = 0; bandno < numbands; bandno++) {
3503                 expn = tccp->stepsizes[bandno].expn;
3504                 mant = tccp->stepsizes[bandno].mant;
3505                 
3506                 if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) {
3507                         cio_write(cio, expn << 3, 1);   /* SPqcx_i */
3508                 } else {
3509                         cio_write(cio, (expn << 11) + mant, 2); /* SPqcx_i */
3510                 }
3511         }
3512 }
3513
3514 static void j2k_read_qcx(opj_j2k_t *j2k, int compno, int len) {
3515         int tmp;
3516         int bandno, numbands;
3517
3518         opj_cp_t *cp = j2k->cp;
3519         opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp;
3520         opj_tccp_t *tccp = &tcp->tccps[compno];
3521         opj_cio_t *cio = j2k->cio;
3522
3523         tmp = cio_read(cio, 1);         /* Sqcx */
3524         tccp->qntsty = tmp & 0x1f;
3525         tccp->numgbits = tmp >> 5;
3526         numbands = (tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? 
3527                 1 : ((tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) ? len - 1 : (len - 1) / 2);
3528
3529 #ifdef USE_JPWL
3530         if (j2k->cp->correct) {
3531
3532                 /* if JPWL is on, we check whether there are too many subbands */
3533                 if ((numbands < 0) || (numbands >= J2K_MAXBANDS)) {
3534                         opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
3535                                 "JPWL: bad number of subbands in Sqcx (%d)\n",
3536                                 numbands);
3537                         if (!JPWL_ASSUME) {
3538                                 opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
3539                                 return;
3540                         }
3541                         /* we try to correct */
3542                         numbands = 1;
3543                         opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust them\n"
3544                                 "- setting number of bands to %d => HYPOTHESIS!!!\n",
3545                                 numbands);
3546                 };
3547
3548         };
3549
3550 #else
3551         /* We check whether there are too many subbands */
3552         if ((numbands < 0) || (numbands >= J2K_MAXBANDS)) {
3553                 opj_event_msg(j2k->cinfo, EVT_WARNING ,
3554                                         "bad number of subbands in Sqcx (%d) regarding to J2K_MAXBANDS (%d) \n"
3555                                     "- limiting number of bands to J2K_MAXBANDS and try to move to the next markers\n", numbands, J2K_MAXBANDS);
3556         }
3557
3558 #endif /* USE_JPWL */
3559
3560         for (bandno = 0; bandno < numbands; bandno++) {
3561                 int expn, mant;
3562                 if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) {
3563                         expn = cio_read(cio, 1) >> 3;   /* SPqcx_i */
3564                         mant = 0;
3565                 } else {
3566                         tmp = cio_read(cio, 2); /* SPqcx_i */
3567                         expn = tmp >> 11;
3568                         mant = tmp & 0x7ff;
3569                 }
3570                 if (bandno < J2K_MAXBANDS){
3571                         tccp->stepsizes[bandno].expn = expn;
3572                         tccp->stepsizes[bandno].mant = mant;
3573                 }
3574         }
3575         
3576         /* Add Antonin : if scalar_derived -> compute other stepsizes */
3577         if (tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) {
3578                 for (bandno = 1; bandno < J2K_MAXBANDS; bandno++) {
3579                         tccp->stepsizes[bandno].expn = 
3580                                 ((tccp->stepsizes[0].expn) - ((bandno - 1) / 3) > 0) ? 
3581                                         (tccp->stepsizes[0].expn) - ((bandno - 1) / 3) : 0;
3582                         tccp->stepsizes[bandno].mant = tccp->stepsizes[0].mant;
3583                 }
3584         }
3585         /* ddA */
3586 }
3587
3588 static void j2k_write_qcd(opj_j2k_t *j2k) {
3589         int lenp, len;
3590
3591         opj_cio_t *cio = j2k->cio;
3592         
3593         cio_write(cio, J2K_MS_QCD, 2);  /* QCD */
3594         lenp = cio_tell(cio);
3595         cio_skip(cio, 2);
3596         j2k_write_qcx(j2k, 0);
3597         len = cio_tell(cio) - lenp;
3598         cio_seek(cio, lenp);
3599         cio_write(cio, len, 2);                 /* Lqcd */
3600         cio_seek(cio, lenp + len);
3601
3602         if(j2k->cstr_info)
3603           j2k_add_mhmarker(j2k->cstr_info, J2K_MS_QCD, lenp, len);
3604 }
3605
3606 /**
3607  * Writes the QCD marker (quantization default)
3608  *
3609  * @param       p_comp_number   the index of the component to output.
3610  * @param       p_stream                                the stream to write data to.
3611  * @param       p_j2k                           J2K codec.
3612  * @param       p_manager               the user event manager.
3613 */
3614 opj_bool j2k_write_qcd_v2(      opj_j2k_v2_t *p_j2k,
3615                                                         struct opj_stream_private *p_stream,
3616                                                         struct opj_event_mgr * p_manager )
3617 {
3618         opj_cp_v2_t *l_cp = 00;
3619         opj_tcp_v2_t *l_tcp = 00;
3620         OPJ_UINT32 l_qcd_size,l_remaining_size;
3621         OPJ_BYTE * l_current_data = 00;
3622
3623         /* preconditions */
3624         assert(p_j2k != 00);
3625         assert(p_manager != 00);
3626         assert(p_stream != 00);
3627
3628         l_cp = &(p_j2k->m_cp);
3629         l_tcp = &l_cp->tcps[p_j2k->m_current_tile_number];
3630         l_qcd_size = 4 + j2k_get_SQcd_SQcc_size(p_j2k,p_j2k->m_current_tile_number,0);
3631         l_remaining_size = l_qcd_size;
3632
3633         if (l_qcd_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
3634                 p_j2k->m_specific_param.m_encoder.m_header_tile_data
3635                         = (OPJ_BYTE*)opj_realloc(
3636                                 p_j2k->m_specific_param.m_encoder.m_header_tile_data,
3637                                 l_qcd_size);
3638
3639                 if (! p_j2k->m_specific_param.m_encoder.m_header_tile_data) {
3640                         return OPJ_FALSE;
3641                 }
3642
3643                 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_qcd_size;
3644         }
3645
3646         l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
3647
3648         opj_write_bytes(l_current_data,J2K_MS_QCD,2);           /* QCD */
3649         l_current_data += 2;
3650
3651         opj_write_bytes(l_current_data,l_qcd_size-2,2);         /* L_QCD */
3652         l_current_data += 2;
3653
3654         l_remaining_size -= 4;
3655
3656         if (! j2k_write_SQcd_SQcc(p_j2k,p_j2k->m_current_tile_number,0,l_current_data,&l_remaining_size,p_manager)) {
3657                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error writting QCD marker\n");
3658                 return OPJ_FALSE;
3659         }
3660
3661         if (l_remaining_size != 0) {
3662                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error writting QCD marker\n");
3663                 return OPJ_FALSE;
3664         }
3665
3666         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) {
3667                 return OPJ_FALSE;
3668         }
3669
3670         return OPJ_TRUE;
3671 }
3672
3673
3674 static void j2k_read_qcd(opj_j2k_t *j2k) {
3675         int len, pos;
3676   OPJ_UINT32 i;
3677
3678         opj_cio_t *cio = j2k->cio;
3679         opj_image_t *image = j2k->image;
3680         
3681         len = cio_read(cio, 2);         /* Lqcd */
3682         pos = cio_tell(cio);
3683         for (i = 0; i < image->numcomps; i++) {
3684                 cio_seek(cio, pos);
3685                 j2k_read_qcx(j2k, i, len - 2);
3686         }
3687 }
3688
3689 /**
3690  * Reads a QCD marker (Quantization defaults)
3691  * @param       p_header_data   the data contained in the QCD box.
3692  * @param       p_j2k                   the jpeg2000 codec.
3693  * @param       p_header_size   the size of the data contained in the QCD marker.
3694  * @param       p_manager               the user event manager.
3695 */
3696 opj_bool j2k_read_qcd_v2 (
3697                                     opj_j2k_v2_t *p_j2k,
3698                                         OPJ_BYTE * p_header_data,
3699                                         OPJ_UINT32 p_header_size,
3700                                         struct opj_event_mgr * p_manager
3701                                         )
3702 {
3703         /* preconditions */
3704         assert(p_header_data != 00);
3705         assert(p_j2k != 00);
3706         assert(p_manager != 00);
3707
3708         if (! j2k_read_SQcd_SQcc(p_j2k,0,p_header_data,&p_header_size,p_manager)) {
3709                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading QCD marker\n");
3710                 return OPJ_FALSE;
3711         }
3712
3713         if (p_header_size != 0) {
3714                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading QCD marker\n");
3715                 return OPJ_FALSE;
3716         }
3717
3718         /* Apply the quantization parameters to other components of the current tile or the m_default_tcp */
3719         j2k_copy_tile_quantization_parameters(p_j2k);
3720
3721         return OPJ_TRUE;
3722 }
3723
3724 static void j2k_write_qcc(opj_j2k_t *j2k, int compno) {
3725         int lenp, len;
3726
3727         opj_cio_t *cio = j2k->cio;
3728         
3729         cio_write(cio, J2K_MS_QCC, 2);  /* QCC */
3730         lenp = cio_tell(cio);
3731         cio_skip(cio, 2);
3732         cio_write(cio, compno, j2k->image->numcomps <= 256 ? 1 : 2);    /* Cqcc */
3733         j2k_write_qcx(j2k, compno);
3734         len = cio_tell(cio) - lenp;
3735         cio_seek(cio, lenp);
3736         cio_write(cio, len, 2);                 /* Lqcc */
3737         cio_seek(cio, lenp + len);
3738 }
3739
3740 /**
3741  * Writes the QCC marker (quantization component)
3742  *
3743  * @param       p_comp_no       the index of the component to output.
3744  * @param       p_stream                                the stream to write data to.
3745  * @param       p_j2k                           J2K codec.
3746  * @param       p_manager               the user event manager.
3747 */
3748 opj_bool j2k_write_qcc_v2(      opj_j2k_v2_t *p_j2k,
3749                                                         OPJ_UINT32 p_comp_no,
3750                                                         struct opj_stream_private *p_stream,
3751                                                         struct opj_event_mgr * p_manager )
3752 {
3753         OPJ_UINT32 l_qcc_size,l_remaining_size;
3754
3755         /* preconditions */
3756         assert(p_j2k != 00);
3757         assert(p_manager != 00);
3758         assert(p_stream != 00);
3759
3760         l_qcc_size = 6 + j2k_get_SQcd_SQcc_size(p_j2k,p_j2k->m_current_tile_number,p_comp_no);
3761         l_remaining_size = l_qcc_size;
3762
3763         if (l_qcc_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
3764                 p_j2k->m_specific_param.m_encoder.m_header_tile_data
3765                         = (OPJ_BYTE*)opj_realloc(
3766                                 p_j2k->m_specific_param.m_encoder.m_header_tile_data,
3767                                 l_qcc_size);
3768                 if (! p_j2k->m_specific_param.m_encoder.m_header_tile_data) {
3769                         return OPJ_FALSE;
3770                 }
3771
3772                 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_qcc_size;
3773         }
3774
3775         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);
3776
3777         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) {
3778                 return OPJ_FALSE;
3779         }
3780
3781         return OPJ_TRUE;
3782 }
3783
3784 /**
3785  * Writes the QCC marker (quantization component)
3786  *
3787  * @param       p_comp_no       the index of the component to output.
3788  * @param       p_stream                                the stream to write data to.
3789  * @param       p_j2k                           J2K codec.
3790  * @param       p_manager               the user event manager.
3791 */
3792 void j2k_write_qcc_in_memory(   opj_j2k_v2_t *p_j2k,
3793                                                                 OPJ_UINT32 p_comp_no,
3794                                                                 OPJ_BYTE * p_data,
3795                                                                 OPJ_UINT32 * p_data_written,
3796                                                                 struct opj_event_mgr * p_manager )
3797 {
3798         OPJ_UINT32 l_qcc_size,l_remaining_size;
3799         OPJ_BYTE * l_current_data = 00;
3800
3801         /* preconditions */
3802         assert(p_j2k != 00);
3803         assert(p_manager != 00);
3804
3805         l_qcc_size = 6 + j2k_get_SQcd_SQcc_size(p_j2k,p_j2k->m_current_tile_number,p_comp_no);
3806         l_remaining_size = l_qcc_size;
3807
3808         l_current_data = p_data;
3809
3810         opj_write_bytes(l_current_data,J2K_MS_QCC,2);           /* QCC */
3811         l_current_data += 2;
3812
3813         if (p_j2k->m_private_image->numcomps <= 256) {
3814                 --l_qcc_size;
3815
3816                 opj_write_bytes(l_current_data,l_qcc_size-2,2);         /* L_QCC */
3817                 l_current_data += 2;
3818
3819                 opj_write_bytes(l_current_data, p_comp_no, 1);  /* Cqcc */
3820                 ++l_current_data;
3821
3822                 /* in the case only one byte is sufficient the last byte allocated is useless -> still do -6 for available */
3823                 l_remaining_size -= 6;
3824         }
3825         else {
3826                 opj_write_bytes(l_current_data,l_qcc_size-2,2);         /* L_QCC */
3827                 l_current_data += 2;
3828
3829                 opj_write_bytes(l_current_data, p_comp_no, 2);  /* Cqcc */
3830                 l_current_data+=2;
3831
3832                 l_remaining_size -= 6;
3833         }
3834
3835         j2k_write_SQcd_SQcc(p_j2k,p_j2k->m_current_tile_number,p_comp_no,l_current_data,&l_remaining_size,p_manager);
3836
3837         *p_data_written = l_qcc_size;
3838 }
3839
3840 /**
3841  * Gets the maximum size taken by a qcc.
3842  */
3843 OPJ_UINT32 j2k_get_max_qcc_size (opj_j2k_v2_t *p_j2k)
3844 {
3845         return j2k_get_max_coc_size(p_j2k);
3846 }
3847
3848 static void j2k_read_qcc(opj_j2k_t *j2k) {
3849         int len, compno;
3850         int numcomp = j2k->image->numcomps;
3851         opj_cio_t *cio = j2k->cio;
3852
3853         len = cio_read(cio, 2); /* Lqcc */
3854         compno = cio_read(cio, numcomp <= 256 ? 1 : 2); /* Cqcc */
3855
3856 #ifdef USE_JPWL
3857         if (j2k->cp->correct) {
3858
3859                 static int backup_compno = 0;
3860
3861                 /* compno is negative or larger than the number of components!!! */
3862                 if ((compno < 0) || (compno >= numcomp)) {
3863                         opj_event_msg(j2k->cinfo, EVT_ERROR,
3864                                 "JPWL: bad component number in QCC (%d out of a maximum of %d)\n",
3865                                 compno, numcomp);
3866                         if (!JPWL_ASSUME) {
3867                                 opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
3868                                 return;
3869                         }
3870                         /* we try to correct */
3871                         compno = backup_compno % numcomp;
3872                         opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust this\n"
3873                                 "- setting component number to %d\n",
3874                                 compno);
3875                 }
3876
3877                 /* keep your private count of tiles */
3878                 backup_compno++;
3879         };
3880 #endif /* USE_JPWL */
3881
3882         j2k_read_qcx(j2k, compno, len - 2 - (numcomp <= 256 ? 1 : 2));
3883 }
3884
3885 /**
3886  * Reads a QCC marker (Quantization component)
3887  * @param       p_header_data   the data contained in the QCC box.
3888  * @param       p_j2k                   the jpeg2000 codec.
3889  * @param       p_header_size   the size of the data contained in the QCC marker.
3890  * @param       p_manager               the user event manager.
3891 */
3892 opj_bool j2k_read_qcc_v2(       opj_j2k_v2_t *p_j2k,
3893                                                         OPJ_BYTE * p_header_data,
3894                                                         OPJ_UINT32 p_header_size,
3895                                                         struct opj_event_mgr * p_manager)
3896 {
3897         OPJ_UINT32 l_num_comp,l_comp_no;
3898
3899         /* preconditions */
3900         assert(p_header_data != 00);
3901         assert(p_j2k != 00);
3902         assert(p_manager != 00);
3903
3904         l_num_comp = p_j2k->m_private_image->numcomps;
3905
3906         if (l_num_comp <= 256) {
3907                 if (p_header_size < 1) {
3908                         opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading QCC marker\n");
3909                         return OPJ_FALSE;
3910                 }
3911                 opj_read_bytes(p_header_data,&l_comp_no,1);
3912                 ++p_header_data;
3913                 --p_header_size;
3914         }
3915         else {
3916                 if (p_header_size < 2) {
3917                         opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading QCC marker\n");
3918                         return OPJ_FALSE;
3919                 }
3920                 opj_read_bytes(p_header_data,&l_comp_no,2);
3921                 p_header_data+=2;
3922                 p_header_size-=2;
3923         }
3924
3925 #ifdef USE_JPWL
3926         if (p_j2k->m_cp.correct) {
3927
3928                 static OPJ_UINT32 backup_compno = 0;
3929
3930                 /* compno is negative or larger than the number of components!!! */
3931                 if (/*(l_comp_no < 0) ||*/ (l_comp_no >= l_num_comp)) {
3932                         opj_event_msg_v2(p_manager, EVT_ERROR,
3933                                 "JPWL: bad component number in QCC (%d out of a maximum of %d)\n",
3934                                 l_comp_no, l_num_comp);
3935                         if (!JPWL_ASSUME) {
3936                                 opj_event_msg_v2(p_manager, EVT_ERROR, "JPWL: giving up\n");
3937                                 return OPJ_FALSE;
3938                         }
3939                         /* we try to correct */
3940                         l_comp_no = backup_compno % l_num_comp;
3941                         opj_event_msg_v2(p_manager, EVT_WARNING, "- trying to adjust this\n"
3942                                 "- setting component number to %d\n",
3943                                 l_comp_no);
3944                 }
3945
3946                 /* keep your private count of tiles */
3947                 backup_compno++;
3948         };
3949 #endif /* USE_JPWL */
3950
3951         if (! j2k_read_SQcd_SQcc(p_j2k,l_comp_no,p_header_data,&p_header_size,p_manager)) {
3952                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading QCC marker\n");
3953                 return OPJ_FALSE;
3954         }
3955
3956         if (p_header_size != 0) {
3957                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading QCC marker\n");
3958                 return OPJ_FALSE;
3959         }
3960
3961         return OPJ_TRUE;
3962 }
3963
3964
3965 static void j2k_write_poc(opj_j2k_t *j2k) {
3966         int len, numpchgs, i;
3967
3968         int numcomps = j2k->image->numcomps;
3969         
3970         opj_cp_t *cp = j2k->cp;
3971         opj_tcp_t *tcp = &cp->tcps[j2k->curtileno];
3972         opj_tccp_t *tccp = &tcp->tccps[0];
3973         opj_cio_t *cio = j2k->cio;
3974
3975         numpchgs = 1 + tcp->numpocs;
3976         cio_write(cio, J2K_MS_POC, 2);  /* POC  */
3977         len = 2 + (5 + 2 * (numcomps <= 256 ? 1 : 2)) * numpchgs;
3978         cio_write(cio, len, 2);         /* Lpoc */
3979         for (i = 0; i < numpchgs; i++) {
3980                 opj_poc_t *poc = &tcp->pocs[i];
3981                 cio_write(cio, poc->resno0, 1); /* RSpoc_i */
3982                 cio_write(cio, poc->compno0, (numcomps <= 256 ? 1 : 2));        /* CSpoc_i */
3983                 cio_write(cio, poc->layno1, 2); /* LYEpoc_i */
3984                 poc->layno1 = int_min(poc->layno1, tcp->numlayers);
3985                 cio_write(cio, poc->resno1, 1); /* REpoc_i */
3986                 poc->resno1 = int_min(poc->resno1, tccp->numresolutions);
3987                 cio_write(cio, poc->compno1, (numcomps <= 256 ? 1 : 2));        /* CEpoc_i */
3988                 poc->compno1 = int_min(poc->compno1, numcomps);
3989                 cio_write(cio, poc->prg, 1);    /* Ppoc_i */
3990         }
3991 }
3992
3993 /**
3994  * Writes the POC marker (Progression Order Change)
3995  * 
3996  * @param       p_stream                                the stream to write data to.
3997  * @param       p_j2k                           J2K codec.
3998  * @param       p_manager               the user event manager.
3999 */
4000 opj_bool j2k_write_poc_v2(      opj_j2k_v2_t *p_j2k,
4001                                                         struct opj_stream_private *p_stream,
4002                                                         struct opj_event_mgr * p_manager )
4003 {
4004         OPJ_UINT32 l_nb_comp;
4005         OPJ_UINT32 l_nb_poc;
4006         OPJ_UINT32 l_poc_size;
4007         OPJ_UINT32 l_written_size = 0;
4008         opj_tcp_v2_t *l_tcp = 00;
4009         opj_tccp_t *l_tccp = 00;
4010         OPJ_UINT32 l_poc_room;
4011
4012         // preconditions
4013         assert(p_j2k != 00);
4014         assert(p_manager != 00);
4015         assert(p_stream != 00);
4016
4017         l_tcp = &p_j2k->m_cp.tcps[p_j2k->m_current_tile_number];
4018         l_tccp = &l_tcp->tccps[0];
4019         l_nb_comp = p_j2k->m_private_image->numcomps;
4020         l_nb_poc = 1 + l_tcp->numpocs;
4021         
4022         if (l_nb_comp <= 256) {
4023                 l_poc_room = 1;
4024         }
4025         else {
4026                 l_poc_room = 2;
4027         }
4028         l_poc_size = 4 + (5 + 2 * l_poc_room) * l_nb_poc;
4029         
4030         if (l_poc_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
4031                 p_j2k->m_specific_param.m_encoder.m_header_tile_data 
4032                         = (OPJ_BYTE*)opj_realloc(
4033                                 p_j2k->m_specific_param.m_encoder.m_header_tile_data,
4034                                 l_poc_size);
4035                 
4036                 if (! p_j2k->m_specific_param.m_encoder.m_header_tile_data) {
4037                         return OPJ_FALSE;
4038                 }
4039
4040                 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_poc_size;
4041         }
4042
4043         j2k_write_poc_in_memory(p_j2k,p_j2k->m_specific_param.m_encoder.m_header_tile_data,&l_written_size,p_manager);
4044
4045         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) {
4046                 return OPJ_FALSE;
4047         }
4048
4049         return OPJ_TRUE;
4050 }
4051
4052
4053 /**
4054  * Writes the POC marker (Progression Order Change)
4055  *
4056  * @param       p_stream                                the stream to write data to.
4057  * @param       p_j2k                           J2K codec.
4058  * @param       p_manager               the user event manager.
4059 */
4060 void j2k_write_poc_in_memory(   opj_j2k_v2_t *p_j2k,
4061                                                                 OPJ_BYTE * p_data,
4062                                                                 OPJ_UINT32 * p_data_written,
4063                                                                 struct opj_event_mgr * p_manager )
4064 {
4065         OPJ_UINT32 i;
4066         OPJ_BYTE * l_current_data = 00;
4067         OPJ_UINT32 l_nb_comp;
4068         OPJ_UINT32 l_nb_poc;
4069         OPJ_UINT32 l_poc_size;
4070         opj_image_t *l_image = 00;
4071         opj_tcp_v2_t *l_tcp = 00;
4072         opj_tccp_t *l_tccp = 00;
4073         opj_poc_t *l_current_poc = 00;
4074         OPJ_UINT32 l_poc_room;
4075
4076         /* preconditions */
4077         assert(p_j2k != 00);
4078         assert(p_manager != 00);
4079
4080         l_tcp = &p_j2k->m_cp.tcps[p_j2k->m_current_tile_number];
4081         l_tccp = &l_tcp->tccps[0];
4082         l_image = p_j2k->m_private_image;
4083         l_nb_comp = l_image->numcomps;
4084         l_nb_poc = 1 + l_tcp->numpocs;
4085
4086         if (l_nb_comp <= 256) {
4087                 l_poc_room = 1;
4088         }
4089         else {
4090                 l_poc_room = 2;
4091         }
4092
4093         l_poc_size = 4 + (5 + 2 * l_poc_room) * l_nb_poc;
4094
4095         l_current_data = p_data;
4096
4097         opj_write_bytes(l_current_data,J2K_MS_POC,2);                                   /* POC  */
4098         l_current_data += 2;
4099
4100         opj_write_bytes(l_current_data,l_poc_size-2,2);                                 /* Lpoc */
4101         l_current_data += 2;
4102
4103         l_current_poc =  l_tcp->pocs;
4104         for (i = 0; i < l_nb_poc; ++i) {
4105                 opj_write_bytes(l_current_data,l_current_poc->resno0,1);                                /* RSpoc_i */
4106                 ++l_current_data;
4107
4108                 opj_write_bytes(l_current_data,l_current_poc->compno0,l_poc_room);              /* CSpoc_i */
4109                 l_current_data+=l_poc_room;
4110
4111                 opj_write_bytes(l_current_data,l_current_poc->layno1,2);                                /* LYEpoc_i */
4112                 l_current_data+=2;
4113
4114                 opj_write_bytes(l_current_data,l_current_poc->resno1,1);                                /* REpoc_i */
4115                 ++l_current_data;
4116
4117                 opj_write_bytes(l_current_data,l_current_poc->compno1,l_poc_room);              /* CEpoc_i */
4118                 l_current_data+=l_poc_room;
4119
4120                 opj_write_bytes(l_current_data,l_current_poc->prg,1);                                   /* Ppoc_i */
4121                 ++l_current_data;
4122
4123                 /* change the value of the max layer according to the actual number of layers in the file, components and resolutions*/
4124                 l_current_poc->layno1 = int_min(l_current_poc->layno1, l_tcp->numlayers);
4125                 l_current_poc->resno1 = int_min(l_current_poc->resno1, l_tccp->numresolutions);
4126                 l_current_poc->compno1 = int_min(l_current_poc->compno1, l_nb_comp);
4127
4128                 ++l_current_poc;
4129         }
4130
4131         *p_data_written = l_poc_size;
4132 }
4133
4134 /**
4135  * Gets the maximum size taken by the writing of a POC.
4136  */
4137 OPJ_UINT32 j2k_get_max_poc_size(opj_j2k_v2_t *p_j2k)
4138 {
4139         opj_tcp_v2_t * l_tcp = 00;
4140         OPJ_UINT32 l_nb_tiles = 0;
4141         OPJ_UINT32 l_max_poc = 0;
4142         OPJ_UINT32 i;
4143
4144         l_tcp = p_j2k->m_cp.tcps;
4145         l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
4146
4147         for (i=0;i<l_nb_tiles;++i) {
4148                 l_max_poc = uint_max(l_max_poc,l_tcp->numpocs);
4149                 ++l_tcp;
4150         }
4151
4152         ++l_max_poc;
4153
4154         return 4 + 9 * l_max_poc;
4155 }
4156
4157 /**
4158  * Gets the maximum size taken by the toc headers of all the tile parts of any given tile.
4159  */
4160 OPJ_UINT32 j2k_get_max_toc_size (opj_j2k_v2_t *p_j2k)
4161 {
4162         OPJ_UINT32 i;
4163         OPJ_UINT32 l_nb_tiles;
4164         OPJ_UINT32 l_max = 0;
4165         opj_tcp_v2_t * l_tcp = 00;
4166
4167         l_tcp = p_j2k->m_cp.tcps;
4168         l_nb_tiles = p_j2k->m_cp.tw * p_j2k->m_cp.th ;
4169
4170         for (i=0;i<l_nb_tiles;++i) {
4171                 l_max = uint_max(l_max,l_tcp->m_nb_tile_parts);
4172
4173                 ++l_tcp;
4174         }
4175
4176         return 12 * l_max;
4177 }
4178
4179
4180 /**
4181  * Gets the maximum size taken by the headers of the SOT.
4182  *
4183  * @param       p_j2k   the jpeg2000 codec to use.
4184  */
4185 OPJ_UINT32 j2k_get_specific_header_sizes(opj_j2k_v2_t *p_j2k)
4186 {
4187         OPJ_UINT32 l_nb_bytes = 0;
4188         OPJ_UINT32 l_nb_comps;
4189         OPJ_UINT32 l_coc_bytes,l_qcc_bytes;
4190
4191         l_nb_comps = p_j2k->m_private_image->numcomps - 1;
4192         l_nb_bytes += j2k_get_max_toc_size(p_j2k);
4193
4194         if (p_j2k->m_cp.m_specific_param.m_enc.m_cinema == 0) {
4195                 l_coc_bytes = j2k_get_max_coc_size(p_j2k);
4196                 l_nb_bytes += l_nb_comps * l_coc_bytes;
4197
4198                 l_qcc_bytes = j2k_get_max_qcc_size(p_j2k);
4199                 l_nb_bytes += l_nb_comps * l_qcc_bytes;
4200         }
4201
4202         l_nb_bytes += j2k_get_max_poc_size(p_j2k);
4203
4204         /*** DEVELOPER CORNER, Add room for your headers ***/
4205
4206         return l_nb_bytes;
4207 }
4208
4209 static void j2k_read_poc(opj_j2k_t *j2k) {
4210         int len, numpchgs, i, old_poc;
4211
4212         int numcomps = j2k->image->numcomps;
4213         
4214         opj_cp_t *cp = j2k->cp;
4215         opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp;
4216         opj_cio_t *cio = j2k->cio;
4217         
4218         old_poc = tcp->POC ? tcp->numpocs + 1 : 0;
4219         tcp->POC = 1;
4220         len = cio_read(cio, 2);         /* Lpoc */
4221         numpchgs = (len - 2) / (5 + 2 * (numcomps <= 256 ? 1 : 2));
4222         
4223         for (i = old_poc; i < numpchgs + old_poc; i++) {
4224                 opj_poc_t *poc;
4225                 poc = &tcp->pocs[i];
4226                 poc->resno0 = cio_read(cio, 1); /* RSpoc_i */
4227                 poc->compno0 = cio_read(cio, numcomps <= 256 ? 1 : 2);  /* CSpoc_i */
4228                 poc->layno1 = cio_read(cio, 2);    /* LYEpoc_i */
4229                 poc->resno1 = cio_read(cio, 1);    /* REpoc_i */
4230                 poc->compno1 = int_min(
4231                         cio_read(cio, numcomps <= 256 ? 1 : 2), (unsigned int) numcomps);       /* CEpoc_i */
4232                 poc->prg = (OPJ_PROG_ORDER)cio_read(cio, 1);    /* Ppoc_i */
4233         }
4234         
4235         tcp->numpocs = numpchgs + old_poc - 1;
4236 }
4237
4238 /**
4239  * Reads a POC marker (Progression Order Change)
4240  *
4241  * @param       p_header_data   the data contained in the POC box.
4242  * @param       p_j2k                   the jpeg2000 codec.
4243  * @param       p_header_size   the size of the data contained in the POC marker.
4244  * @param       p_manager               the user event manager.
4245 */
4246 opj_bool j2k_read_poc_v2 (
4247                                                 opj_j2k_v2_t *p_j2k,
4248                                                 OPJ_BYTE * p_header_data,
4249                                                 OPJ_UINT32 p_header_size,
4250                                                 struct opj_event_mgr * p_manager)
4251 {
4252         OPJ_UINT32 i, l_nb_comp, l_tmp;
4253         opj_image_t * l_image = 00;
4254         OPJ_UINT32 l_old_poc_nb, l_current_poc_nb, l_current_poc_remaining;
4255         OPJ_UINT32 l_chunk_size, l_comp_room;
4256
4257         opj_cp_v2_t *l_cp = 00;
4258         opj_tcp_v2_t *l_tcp = 00;
4259         opj_poc_t *l_current_poc = 00;
4260
4261         /* preconditions */
4262         assert(p_header_data != 00);
4263         assert(p_j2k != 00);
4264         assert(p_manager != 00);
4265
4266         l_image = p_j2k->m_private_image;
4267         l_nb_comp = l_image->numcomps;
4268         if (l_nb_comp <= 256) {
4269                 l_comp_room = 1;
4270         }
4271         else {
4272                 l_comp_room = 2;
4273         }
4274         l_chunk_size = 5 + 2 * l_comp_room;
4275         l_current_poc_nb = p_header_size / l_chunk_size;
4276         l_current_poc_remaining = p_header_size % l_chunk_size;
4277
4278         if ((l_current_poc_nb <= 0) || (l_current_poc_remaining != 0)) {
4279                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading POC marker\n");
4280                 return OPJ_FALSE;
4281         }
4282
4283         l_cp = &(p_j2k->m_cp);
4284         l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH) ?
4285                                 &l_cp->tcps[p_j2k->m_current_tile_number] :
4286                                 p_j2k->m_specific_param.m_decoder.m_default_tcp;
4287         l_old_poc_nb = l_tcp->POC ? l_tcp->numpocs + 1 : 0;
4288         l_current_poc_nb += l_old_poc_nb;
4289
4290         assert(l_current_poc_nb < 32);
4291
4292         /* now poc is in use.*/
4293         l_tcp->POC = 1;
4294
4295         l_current_poc = &l_tcp->pocs[l_old_poc_nb];
4296         for     (i = l_old_poc_nb; i < l_current_poc_nb; ++i) {
4297                 opj_read_bytes(p_header_data,&(l_current_poc->resno0),1);                               /* RSpoc_i */
4298                 ++p_header_data;
4299                 opj_read_bytes(p_header_data,&(l_current_poc->compno0),l_comp_room);    /* CSpoc_i */
4300                 p_header_data+=l_comp_room;
4301                 opj_read_bytes(p_header_data,&(l_current_poc->layno1),2);                               /* LYEpoc_i */
4302                 p_header_data+=2;
4303                 opj_read_bytes(p_header_data,&(l_current_poc->resno1),1);                               /* REpoc_i */
4304                 ++p_header_data;
4305                 opj_read_bytes(p_header_data,&(l_current_poc->compno1),l_comp_room);    /* CEpoc_i */
4306                 p_header_data+=l_comp_room;
4307                 opj_read_bytes(p_header_data,&l_tmp,1);                                                                 /* Ppoc_i */
4308                 ++p_header_data;
4309                 l_current_poc->prg = (OPJ_PROG_ORDER) l_tmp;
4310                 /* make sure comp is in acceptable bounds */
4311                 l_current_poc->compno1 = uint_min(l_current_poc->compno1, l_nb_comp);
4312                 ++l_current_poc;
4313         }
4314
4315         l_tcp->numpocs = l_current_poc_nb - 1;
4316         return OPJ_TRUE;
4317 }
4318
4319 static void j2k_read_crg(opj_j2k_t *j2k) {
4320         int len, i, Xcrg_i, Ycrg_i;
4321         
4322         opj_cio_t *cio = j2k->cio;
4323         int numcomps = j2k->image->numcomps;
4324         
4325         len = cio_read(cio, 2);                 /* Lcrg */
4326         for (i = 0; i < numcomps; i++) {
4327                 Xcrg_i = cio_read(cio, 2);      /* Xcrg_i */
4328                 Ycrg_i = cio_read(cio, 2);      /* Ycrg_i */
4329         }
4330 }
4331
4332 /**
4333  * Reads a CRG marker (Component registration)
4334  *
4335  * @param       p_header_data   the data contained in the TLM box.
4336  * @param       p_j2k                   the jpeg2000 codec.
4337  * @param       p_header_size   the size of the data contained in the TLM marker.
4338  * @param       p_manager               the user event manager.
4339 */
4340 opj_bool j2k_read_crg_v2 (
4341                                                 opj_j2k_v2_t *p_j2k,
4342                                                 OPJ_BYTE * p_header_data,
4343                                                 OPJ_UINT32 p_header_size,
4344                                                 struct opj_event_mgr * p_manager
4345                                         )
4346 {
4347         OPJ_UINT32 l_nb_comp;
4348         /* preconditions */
4349         assert(p_header_data != 00);
4350         assert(p_j2k != 00);
4351         assert(p_manager != 00);
4352
4353         l_nb_comp = p_j2k->m_private_image->numcomps;
4354
4355         if (p_header_size != l_nb_comp *4) {
4356                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading CRG marker\n");
4357                 return OPJ_FALSE;
4358         }
4359         /* Do not care of this at the moment since only local variables are set here */
4360         /*
4361         for
4362                 (i = 0; i < l_nb_comp; ++i)
4363         {
4364                 opj_read_bytes(p_header_data,&l_Xcrg_i,2);                              // Xcrg_i
4365                 p_header_data+=2;
4366                 opj_read_bytes(p_header_data,&l_Ycrg_i,2);                              // Xcrg_i
4367                 p_header_data+=2;
4368         }
4369         */
4370         return OPJ_TRUE;
4371 }
4372
4373 static void j2k_read_tlm(opj_j2k_t *j2k) {
4374         int len, Ztlm, Stlm, ST, SP, tile_tlm, i;
4375         long int Ttlm_i, Ptlm_i;
4376
4377         opj_cio_t *cio = j2k->cio;
4378         
4379         len = cio_read(cio, 2);         /* Ltlm */
4380         Ztlm = cio_read(cio, 1);        /* Ztlm */
4381         Stlm = cio_read(cio, 1);        /* Stlm */
4382         ST = ((Stlm >> 4) & 0x01) + ((Stlm >> 4) & 0x02);
4383         SP = (Stlm >> 6) & 0x01;
4384         tile_tlm = (len - 4) / ((SP + 1) * 2 + ST);
4385         for (i = 0; i < tile_tlm; i++) {
4386                 Ttlm_i = cio_read(cio, ST);     /* Ttlm_i */
4387                 Ptlm_i = cio_read(cio, SP ? 4 : 2);     /* Ptlm_i */
4388         }
4389 }
4390
4391 /**
4392  * Reads a TLM marker (Tile Length Marker)
4393  *
4394  * @param       p_header_data   the data contained in the TLM box.
4395  * @param       p_j2k                   the jpeg2000 codec.
4396  * @param       p_header_size   the size of the data contained in the TLM marker.
4397  * @param       p_manager               the user event manager.
4398 */
4399 opj_bool j2k_read_tlm_v2 (
4400                                                 opj_j2k_v2_t *p_j2k,
4401                                                 OPJ_BYTE * p_header_data,
4402                                                 OPJ_UINT32 p_header_size,
4403                                                 struct opj_event_mgr * p_manager
4404                                         )
4405 {
4406         OPJ_UINT32 l_Ztlm, l_Stlm, l_ST, l_SP, l_tot_num_tp, l_tot_num_tp_remaining, l_quotient, l_Ptlm_size;
4407         /* preconditions */
4408         assert(p_header_data != 00);
4409         assert(p_j2k != 00);
4410         assert(p_manager != 00);
4411
4412         if (p_header_size < 2) {
4413                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading TLM marker\n");
4414                 return OPJ_FALSE;
4415         }
4416         p_header_size -= 2;
4417
4418         opj_read_bytes(p_header_data,&l_Ztlm,1);                                /* Ztlm */
4419         ++p_header_data;
4420         opj_read_bytes(p_header_data,&l_Stlm,1);                                /* Stlm */
4421         ++p_header_data;
4422
4423         l_ST = ((l_Stlm >> 4) & 0x3);
4424         l_SP = (l_Stlm >> 6) & 0x1;
4425
4426         l_Ptlm_size = (l_SP + 1) * 2;
4427         l_quotient = l_Ptlm_size + l_ST;
4428
4429         l_tot_num_tp = p_header_size / l_quotient;
4430         l_tot_num_tp_remaining = p_header_size % l_quotient;
4431
4432         if (l_tot_num_tp_remaining != 0) {
4433                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading TLM marker\n");
4434                 return OPJ_FALSE;
4435         }
4436         /* FIXME Do not care of this at the moment since only local variables are set here */
4437         /*
4438         for
4439                 (i = 0; i < l_tot_num_tp; ++i)
4440         {
4441                 opj_read_bytes(p_header_data,&l_Ttlm_i,l_ST);                           // Ttlm_i
4442                 p_header_data += l_ST;
4443                 opj_read_bytes(p_header_data,&l_Ptlm_i,l_Ptlm_size);            // Ptlm_i
4444                 p_header_data += l_Ptlm_size;
4445         }*/
4446         return OPJ_TRUE;
4447 }
4448
4449 static void j2k_read_plm(opj_j2k_t *j2k) {
4450         int len, i, Zplm, Nplm, add, packet_len = 0;
4451         
4452         opj_cio_t *cio = j2k->cio;
4453
4454         len = cio_read(cio, 2);         /* Lplm */
4455         Zplm = cio_read(cio, 1);        /* Zplm */
4456         len -= 3;
4457         while (len > 0) {
4458                 Nplm = cio_read(cio, 4);                /* Nplm */
4459                 len -= 4;
4460                 for (i = Nplm; i > 0; i--) {
4461                         add = cio_read(cio, 1);
4462                         len--;
4463                         packet_len = (packet_len << 7) + add;   /* Iplm_ij */
4464                         if ((add & 0x80) == 0) {
4465                                 /* New packet */
4466                                 packet_len = 0;
4467                         }
4468                         if (len <= 0)
4469                                 break;
4470                 }
4471         }
4472 }
4473
4474 /**
4475  * Reads a PLM marker (Packet length, main header marker)
4476  *
4477  * @param       p_header_data   the data contained in the TLM box.
4478  * @param       p_j2k                   the jpeg2000 codec.
4479  * @param       p_header_size   the size of the data contained in the TLM marker.
4480  * @param       p_manager               the user event manager.
4481 */
4482 opj_bool j2k_read_plm_v2 (
4483                                                 opj_j2k_v2_t *p_j2k,
4484                                                 OPJ_BYTE * p_header_data,
4485                                                 OPJ_UINT32 p_header_size,
4486                                                 struct opj_event_mgr * p_manager
4487                                         )
4488 {
4489         /* preconditions */
4490         assert(p_header_data != 00);
4491         assert(p_j2k != 00);
4492         assert(p_manager != 00);
4493
4494         if (p_header_size < 1) {
4495                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading PLM marker\n");
4496                 return OPJ_FALSE;
4497         }
4498         /* Do not care of this at the moment since only local variables are set here */
4499         /*
4500         opj_read_bytes(p_header_data,&l_Zplm,1);                                        // Zplm
4501         ++p_header_data;
4502         --p_header_size;
4503
4504         while
4505                 (p_header_size > 0)
4506         {
4507                 opj_read_bytes(p_header_data,&l_Nplm,1);                                // Nplm
4508                 ++p_header_data;
4509                 p_header_size -= (1+l_Nplm);
4510                 if
4511                         (p_header_size < 0)
4512                 {
4513                         opj_event_msg(p_manager, EVT_ERROR, "Error reading PLM marker\n");
4514                         return false;
4515                 }
4516                 for
4517                         (i = 0; i < l_Nplm; ++i)
4518                 {
4519                         opj_read_bytes(p_header_data,&l_tmp,1);                         // Iplm_ij
4520                         ++p_header_data;
4521                         // take only the last seven bytes
4522                         l_packet_len |= (l_tmp & 0x7f);
4523                         if
4524                                 (l_tmp & 0x80)
4525                         {
4526                                 l_packet_len <<= 7;
4527                         }
4528                         else
4529                         {
4530                 // store packet length and proceed to next packet
4531                                 l_packet_len = 0;
4532                         }
4533                 }
4534                 if
4535                         (l_packet_len != 0)
4536                 {
4537                         opj_event_msg(p_manager, EVT_ERROR, "Error reading PLM marker\n");
4538                         return false;
4539                 }
4540         }
4541         */
4542         return OPJ_TRUE;
4543 }
4544
4545 static void j2k_read_plt(opj_j2k_t *j2k) {
4546         int len, i, Zplt, packet_len = 0, add;
4547         
4548         opj_cio_t *cio = j2k->cio;
4549         
4550         len = cio_read(cio, 2);         /* Lplt */
4551         Zplt = cio_read(cio, 1);        /* Zplt */
4552         for (i = len - 3; i > 0; i--) {
4553                 add = cio_read(cio, 1);
4554                 packet_len = (packet_len << 7) + add;   /* Iplt_i */
4555                 if ((add & 0x80) == 0) {
4556                         /* New packet */
4557                         packet_len = 0;
4558                 }
4559         }
4560 }
4561
4562 /**
4563  * Reads a PLT marker (Packet length, tile-part header)
4564  *
4565  * @param       p_header_data   the data contained in the PLT box.
4566  * @param       p_j2k                   the jpeg2000 codec.
4567  * @param       p_header_size   the size of the data contained in the PLT marker.
4568  * @param       p_manager               the user event manager.
4569 */
4570 opj_bool j2k_read_plt_v2 (
4571                                                 opj_j2k_v2_t *p_j2k,
4572                                                 OPJ_BYTE * p_header_data,
4573                                                 OPJ_UINT32 p_header_size,
4574                                                 struct opj_event_mgr * p_manager
4575                                         )
4576 {
4577         OPJ_UINT32 l_Zplt, l_tmp, l_packet_len = 0, i;
4578
4579         /* preconditions */
4580         assert(p_header_data != 00);
4581         assert(p_j2k != 00);
4582         assert(p_manager != 00);
4583
4584         if (p_header_size < 1) {
4585                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading PLM marker\n");
4586                 return OPJ_FALSE;
4587         }
4588
4589         opj_read_bytes(p_header_data,&l_Zplt,1);                /* Zplt */
4590         ++p_header_data;
4591         --p_header_size;
4592
4593         for (i = 0; i < p_header_size; ++i) {
4594                 opj_read_bytes(p_header_data,&l_tmp,1);         /* Iplt_ij */
4595                 ++p_header_data;
4596                 /* take only the last seven bytes */
4597                 l_packet_len |= (l_tmp & 0x7f);
4598                 if (l_tmp & 0x80) {
4599                         l_packet_len <<= 7;
4600                 }
4601                 else {
4602             /* store packet length and proceed to next packet */
4603                         l_packet_len = 0;
4604                 }
4605         }
4606
4607         if (l_packet_len != 0) {
4608                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading PLM marker\n");
4609                 return OPJ_FALSE;
4610         }
4611
4612         return OPJ_TRUE;
4613 }
4614
4615 static void j2k_read_ppm(opj_j2k_t *j2k) {
4616         int len, Z_ppm, i, j;
4617         int N_ppm;
4618
4619         opj_cp_t *cp = j2k->cp;
4620         opj_cio_t *cio = j2k->cio;
4621         
4622         len = cio_read(cio, 2);
4623         cp->ppm = 1;
4624         
4625         Z_ppm = cio_read(cio, 1);       /* Z_ppm */
4626         len -= 3;
4627         while (len > 0) {
4628                 if (cp->ppm_previous == 0) {
4629                         N_ppm = cio_read(cio, 4);       /* N_ppm */
4630                         len -= 4;
4631                 } else {
4632                         N_ppm = cp->ppm_previous;
4633                 }
4634                 j = cp->ppm_store;
4635                 if (Z_ppm == 0) {       /* First PPM marker */
4636                         cp->ppm_data = (unsigned char *) opj_malloc(N_ppm * sizeof(unsigned char));
4637                         cp->ppm_data_first = cp->ppm_data;
4638                         cp->ppm_len = N_ppm;
4639                 } else {                        /* NON-first PPM marker */
4640                         cp->ppm_data = (unsigned char *) opj_realloc(cp->ppm_data, (N_ppm +     cp->ppm_store) * sizeof(unsigned char));
4641
4642 #ifdef USE_JPWL
4643                         /* this memory allocation check could be done even in non-JPWL cases */
4644                         if (cp->correct) {
4645                                 if (!cp->ppm_data) {
4646                                         opj_event_msg(j2k->cinfo, EVT_ERROR,
4647                                                 "JPWL: failed memory allocation during PPM marker parsing (pos. %x)\n",
4648                                                 cio_tell(cio));
4649                                         if (!JPWL_ASSUME || JPWL_ASSUME) {
4650                                                 opj_free(cp->ppm_data);
4651                                                 opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
4652                                                 return;
4653                                         }
4654                                 }
4655                         }
4656 #endif
4657
4658                         cp->ppm_data_first = cp->ppm_data;
4659                         cp->ppm_len = N_ppm + cp->ppm_store;
4660                 }
4661                 for (i = N_ppm; i > 0; i--) {   /* Read packet header */
4662                         cp->ppm_data[j] = cio_read(cio, 1);
4663                         j++;
4664                         len--;
4665                         if (len == 0)
4666                                 break;                  /* Case of non-finished packet header in present marker but finished in next one */
4667                 }
4668                 cp->ppm_previous = i - 1;
4669                 cp->ppm_store = j;
4670         }
4671 }
4672 /**
4673  * Reads a PPM marker (Packed packet headers, main header)
4674  *
4675  * @param       p_header_data   the data contained in the POC box.
4676  * @param       p_j2k                   the jpeg2000 codec.
4677  * @param       p_header_size   the size of the data contained in the POC marker.
4678  * @param       p_manager               the user event manager.
4679 */
4680 #if 0
4681 opj_bool j2k_read_ppm_v2 (
4682                                                 opj_j2k_v2_t *p_j2k,
4683                                                 OPJ_BYTE * p_header_data,
4684                                                 OPJ_UINT32 p_header_size,
4685                                                 struct opj_event_mgr * p_manager
4686                                         )
4687 {
4688
4689         opj_cp_v2_t *l_cp = 00;
4690         OPJ_UINT32 l_remaining_data, l_Z_ppm, l_N_ppm;
4691
4692         /* preconditions */
4693         assert(p_header_data != 00);
4694         assert(p_j2k != 00);
4695         assert(p_manager != 00);
4696
4697         if (p_header_size < 1) {
4698                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading PPM marker\n");
4699                 return OPJ_FALSE;
4700         }
4701
4702         l_cp = &(p_j2k->m_cp);
4703         l_cp->ppm = 1;
4704
4705         opj_read_bytes(p_header_data,&l_Z_ppm,1);               /* Z_ppm */
4706         ++p_header_data;
4707         --p_header_size;
4708
4709         /* First PPM marker */
4710         if (l_Z_ppm == 0) {
4711                 if (p_header_size < 4) {
4712                         opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading PPM marker\n");
4713                         return OPJ_FALSE;
4714                 }
4715
4716                 opj_read_bytes(p_header_data,&l_N_ppm,4);               /* N_ppm */
4717                 p_header_data+=4;
4718                 p_header_size-=4;
4719
4720                 /* First PPM marker: Initialization */
4721                 l_cp->ppm_len = l_N_ppm;
4722                 l_cp->ppm_data_size = 0;
4723
4724                 l_cp->ppm_buffer = (OPJ_BYTE *) opj_malloc(l_cp->ppm_len);
4725                 if (l_cp->ppm_buffer == 00) {
4726                         opj_event_msg_v2(p_manager, EVT_ERROR, "Not enough memory reading ppm marker\n");
4727                         return OPJ_FALSE;
4728                 }
4729                 memset(l_cp->ppm_buffer,0,l_cp->ppm_len);
4730
4731                 l_cp->ppm_data = l_cp->ppm_buffer;
4732         }
4733
4734         while (1) {
4735                 if (l_cp->ppm_data_size == l_cp->ppm_len) {
4736                         if (p_header_size >= 4) {
4737                                 /* read a N_ppm */
4738                                 opj_read_bytes(p_header_data,&l_N_ppm,4);               /* N_ppm */
4739                                 p_header_data+=4;
4740                                 p_header_size-=4;
4741                                 l_cp->ppm_len += l_N_ppm ;
4742
4743                                 l_cp->ppm_buffer = (OPJ_BYTE *) opj_realloc(l_cp->ppm_buffer, l_cp->ppm_len);
4744                                 if (l_cp->ppm_buffer == 00) {
4745                                         opj_event_msg_v2(p_manager, EVT_ERROR, "Not enough memory reading ppm marker\n");
4746                                         return OPJ_FALSE;
4747                                 }
4748                                 memset(l_cp->ppm_buffer+l_cp->ppm_data_size,0,l_N_ppm);
4749
4750                                 l_cp->ppm_data = l_cp->ppm_buffer;
4751                         }
4752                         else {
4753                                 return OPJ_FALSE;
4754                         }
4755                 }
4756
4757                 l_remaining_data = l_cp->ppm_len - l_cp->ppm_data_size;
4758
4759                 if (l_remaining_data <= p_header_size) {
4760                         /* we must store less information than available in the packet */
4761                         memcpy(l_cp->ppm_buffer + l_cp->ppm_data_size , p_header_data , l_remaining_data);
4762                         l_cp->ppm_data_size = l_cp->ppm_len;
4763                         p_header_size -= l_remaining_data;
4764                         p_header_data += l_remaining_data;
4765                 }
4766                 else {
4767                         memcpy(l_cp->ppm_buffer + l_cp->ppm_data_size , p_header_data , p_header_size);
4768                         l_cp->ppm_data_size += p_header_size;
4769                         p_header_data += p_header_size;
4770                         p_header_size = 0;
4771                         break;
4772                 }
4773         }
4774
4775         return OPJ_TRUE;
4776 }
4777 #endif
4778
4779
4780
4781 /**
4782  * Reads a PPM marker (Packed packet headers, main header)
4783  *
4784  * @param       p_header_data   the data contained in the POC box.
4785  * @param       p_j2k                   the jpeg2000 codec.
4786  * @param       p_header_size   the size of the data contained in the POC marker.
4787  * @param       p_manager               the user event manager.
4788 */
4789 opj_bool j2k_read_ppm_v3 (
4790                                                 opj_j2k_v2_t *p_j2k,
4791                                                 OPJ_BYTE * p_header_data,
4792                                                 OPJ_UINT32 p_header_size,
4793                                                 struct opj_event_mgr * p_manager
4794                                         )
4795 {
4796         opj_cp_v2_t *l_cp = 00;
4797         OPJ_UINT32 l_remaining_data, l_Z_ppm, l_N_ppm;
4798
4799         /* preconditions */
4800         assert(p_header_data != 00);
4801         assert(p_j2k != 00);
4802         assert(p_manager != 00);
4803
4804         /* Minimum size of PPM marker is equal to the size of Zppm element */
4805         if (p_header_size < 1) {
4806                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading PPM marker\n");
4807                 return OPJ_FALSE;
4808         }
4809
4810         l_cp = &(p_j2k->m_cp);
4811         l_cp->ppm = 1;
4812
4813         opj_read_bytes(p_header_data,&l_Z_ppm,1);               /* Z_ppm */
4814         ++p_header_data;
4815         --p_header_size;
4816
4817         /* First PPM marker */
4818         if (l_Z_ppm == 0) {
4819                 /* We need now at least the Nppm^0 element */
4820                 if (p_header_size < 4) {
4821                         opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading PPM marker\n");
4822                         return OPJ_FALSE;
4823                 }
4824
4825                 opj_read_bytes(p_header_data,&l_N_ppm,4);               /* First N_ppm */
4826                 p_header_data+=4;
4827                 p_header_size-=4;
4828
4829                 /* First PPM marker: Initialization */
4830                 l_cp->ppm_len = l_N_ppm;
4831                 l_cp->ppm_data_read = 0;
4832
4833                 l_cp->ppm_data = (OPJ_BYTE *) opj_malloc(l_cp->ppm_len);
4834                 if (l_cp->ppm_data == 00) {
4835                         opj_event_msg_v2(p_manager, EVT_ERROR, "Not enough memory reading ppm marker\n");
4836                         return OPJ_FALSE;
4837                 }
4838                 memset(l_cp->ppm_data,0,l_cp->ppm_len);
4839
4840                 l_cp->ppm_data_current = l_cp->ppm_data;
4841
4842                 /*l_cp->ppm_data = l_cp->ppm_buffer;*/
4843         }
4844         else {
4845                 if (p_header_size < 4) {
4846                         opj_event_msg_v2(p_manager, EVT_WARNING, "Empty PPM marker\n");
4847                         return OPJ_TRUE;
4848                 }
4849                 else {
4850                         /* Uncompleted Ippm series in the previous PPM marker?*/
4851                         if (l_cp->ppm_data_read < l_cp->ppm_len) {
4852                                 /* Get the place where add the remaining Ippm series*/
4853                                 l_cp->ppm_data_current = &(l_cp->ppm_data[l_cp->ppm_data_read]);
4854                                 l_N_ppm = l_cp->ppm_len - l_cp->ppm_data_read;
4855                         }
4856                         else {
4857                                 opj_read_bytes(p_header_data,&l_N_ppm,4);               /* First N_ppm */
4858                                 p_header_data+=4;
4859                                 p_header_size-=4;
4860
4861                                 /* Increase the size of ppm_data to add the new Ippm series*/
4862                                 l_cp->ppm_data = (OPJ_BYTE *) opj_realloc(l_cp->ppm_data, l_cp->ppm_len + l_N_ppm);
4863
4864                                 /* Keep the position of the place where concatenate the new series*/
4865                                 l_cp->ppm_data_current = &(l_cp->ppm_data[l_cp->ppm_len]);
4866                                 l_cp->ppm_len += l_N_ppm;
4867                         }
4868                 }
4869         }
4870
4871         l_remaining_data = p_header_size;
4872
4873         while (l_remaining_data >= l_N_ppm) {
4874                 /* read a complete Ippm series*/
4875                 memcpy(l_cp->ppm_data_current, p_header_data, l_N_ppm);
4876                 p_header_size -= l_N_ppm;
4877                 p_header_data += l_N_ppm;
4878
4879                 l_cp->ppm_data_read += l_N_ppm; /* Increase the number of data read*/
4880
4881                 if (p_header_size)
4882                 {
4883                         opj_read_bytes(p_header_data,&l_N_ppm,4);               /* N_ppm^i */
4884                         p_header_data+=4;
4885                         p_header_size-=4;
4886                 }
4887                 else {
4888                         l_remaining_data = p_header_size;
4889                         break;
4890                 }
4891
4892                 l_remaining_data = p_header_size;
4893
4894                 /* Next Ippm series is a complete series ?*/
4895                 if (l_remaining_data > l_N_ppm) {
4896                         /* Increase the size of ppm_data to add the new Ippm series*/
4897                         l_cp->ppm_data = (OPJ_BYTE *) opj_realloc(l_cp->ppm_data, l_cp->ppm_len + l_N_ppm);
4898
4899                         /* Keep the position of the place where concatenate the new series */
4900                         l_cp->ppm_data_current = &(l_cp->ppm_data[l_cp->ppm_len]);
4901                         l_cp->ppm_len += l_N_ppm;
4902                 }
4903
4904         }
4905
4906         /* Need to read an incomplete Ippm series*/
4907         if (l_remaining_data) {
4908                 l_cp->ppm_data = (OPJ_BYTE *) opj_realloc(l_cp->ppm_data, l_cp->ppm_len + l_N_ppm);
4909
4910                 /* Keep the position of the place where concatenate the new series*/
4911                 l_cp->ppm_data_current = &(l_cp->ppm_data[l_cp->ppm_len]);
4912                 l_cp->ppm_len += l_N_ppm;
4913
4914                 /* Read incomplete Ippm series*/
4915                 memcpy(l_cp->ppm_data_current, p_header_data, l_remaining_data);
4916                 p_header_size -= l_remaining_data;
4917                 p_header_data += l_remaining_data;
4918
4919                 l_cp->ppm_data_read += l_remaining_data; /* Increase the number of data read*/
4920         }
4921
4922 #ifdef CLEAN_MSD
4923
4924                 if (l_cp->ppm_data_size == l_cp->ppm_len) {
4925                         if (p_header_size >= 4) {
4926                                 /* read a N_ppm*/
4927                                 opj_read_bytes(p_header_data,&l_N_ppm,4);               /* N_ppm */
4928                                 p_header_data+=4;
4929                                 p_header_size-=4;
4930                                 l_cp->ppm_len += l_N_ppm ;
4931
4932                                 l_cp->ppm_buffer = (OPJ_BYTE *) opj_realloc(l_cp->ppm_buffer, l_cp->ppm_len);
4933                                 if (l_cp->ppm_buffer == 00) {
4934                                         opj_event_msg_v2(p_manager, EVT_ERROR, "Not enough memory reading ppm marker\n");
4935                                         return OPJ_FALSE;
4936                                 }
4937                                 memset(l_cp->ppm_buffer+l_cp->ppm_data_size,0,l_N_ppm);
4938
4939                                 l_cp->ppm_data = l_cp->ppm_buffer;
4940                         }
4941                         else {
4942                                 return OPJ_FALSE;
4943                         }
4944                 }
4945
4946                 l_remaining_data = l_cp->ppm_len - l_cp->ppm_data_size;
4947
4948                 if (l_remaining_data <= p_header_size) {
4949                         /* we must store less information than available in the packet */
4950                         memcpy(l_cp->ppm_buffer + l_cp->ppm_data_size , p_header_data , l_remaining_data);
4951                         l_cp->ppm_data_size = l_cp->ppm_len;
4952                         p_header_size -= l_remaining_data;
4953                         p_header_data += l_remaining_data;
4954                 }
4955                 else {
4956                         memcpy(l_cp->ppm_buffer + l_cp->ppm_data_size , p_header_data , p_header_size);
4957                         l_cp->ppm_data_size += p_header_size;
4958                         p_header_data += p_header_size;
4959                         p_header_size = 0;
4960                         break;
4961                 }
4962         }
4963 #endif
4964         return OPJ_TRUE;
4965 }
4966
4967 static void j2k_read_ppt(opj_j2k_t *j2k) {
4968         int len, Z_ppt, i, j = 0;
4969
4970         opj_cp_t *cp = j2k->cp;
4971         opj_tcp_t *tcp = cp->tcps + j2k->curtileno;
4972         opj_cio_t *cio = j2k->cio;
4973
4974         len = cio_read(cio, 2);
4975         Z_ppt = cio_read(cio, 1);
4976         tcp->ppt = 1;
4977         if (Z_ppt == 0) {               /* First PPT marker */
4978                 tcp->ppt_data = (unsigned char *) opj_malloc((len - 3) * sizeof(unsigned char));
4979                 tcp->ppt_data_first = tcp->ppt_data;
4980                 tcp->ppt_store = 0;
4981                 tcp->ppt_len = len - 3;
4982         } else {                        /* NON-first PPT marker */
4983                 tcp->ppt_data = (unsigned char *) opj_realloc(tcp->ppt_data, (len - 3 + tcp->ppt_store) * sizeof(unsigned char));
4984                 tcp->ppt_data_first = tcp->ppt_data;
4985                 tcp->ppt_len = len - 3 + tcp->ppt_store;
4986         }
4987         j = tcp->ppt_store;
4988         for (i = len - 3; i > 0; i--) {
4989                 tcp->ppt_data[j] = cio_read(cio, 1);
4990                 j++;
4991         }
4992         tcp->ppt_store = j;
4993 }
4994
4995 /**
4996  * Reads a PPT marker (Packed packet headers, tile-part header)
4997  *
4998  * @param       p_header_data   the data contained in the PPT box.
4999  * @param       p_j2k                   the jpeg2000 codec.
5000  * @param       p_header_size   the size of the data contained in the PPT marker.
5001  * @param       p_manager               the user event manager.
5002 */
5003 opj_bool j2k_read_ppt_v2 (      opj_j2k_v2_t *p_j2k,
5004                                                         OPJ_BYTE * p_header_data,
5005                                                         OPJ_UINT32 p_header_size,
5006                                                         struct opj_event_mgr * p_manager )
5007 {
5008         opj_cp_v2_t *l_cp = 00;
5009         opj_tcp_v2_t *l_tcp = 00;
5010         OPJ_UINT32 l_Z_ppt;
5011
5012         /* preconditions */
5013         assert(p_header_data != 00);
5014         assert(p_j2k != 00);
5015         assert(p_manager != 00);
5016
5017         /* We need to have the Z_ppt element at minimum */
5018         if (p_header_size < 1) {
5019                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading PPT marker\n");
5020                 return OPJ_FALSE;
5021         }
5022
5023         l_cp = &(p_j2k->m_cp);
5024         if (l_cp->ppm){
5025                 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");
5026                 return OPJ_FALSE;
5027         }
5028
5029         l_tcp = &(l_cp->tcps[p_j2k->m_current_tile_number]);
5030         l_tcp->ppt = 1;
5031
5032         opj_read_bytes(p_header_data,&l_Z_ppt,1);               /* Z_ppt */
5033         ++p_header_data;
5034         --p_header_size;
5035
5036         /* Allocate buffer to read the packet header */
5037         if (l_Z_ppt == 0) {
5038                 /* First PPT marker */
5039                 l_tcp->ppt_data_size = 0;
5040                 l_tcp->ppt_len = p_header_size;
5041
5042                 l_tcp->ppt_buffer = (OPJ_BYTE *) opj_calloc(l_tcp->ppt_len, sizeof(OPJ_BYTE) );
5043                 if (l_tcp->ppt_buffer == 00) {
5044                         opj_event_msg_v2(p_manager, EVT_ERROR, "Not enough memory reading PPT marker\n");
5045                         return OPJ_FALSE;
5046                 }
5047                 l_tcp->ppt_data = l_tcp->ppt_buffer;
5048
5049                 /* memset(l_tcp->ppt_buffer,0,l_tcp->ppt_len); */
5050         }
5051         else {
5052                 l_tcp->ppt_len += p_header_size;
5053
5054                 l_tcp->ppt_buffer = (OPJ_BYTE *) opj_realloc(l_tcp->ppt_buffer,l_tcp->ppt_len);
5055                 if (l_tcp->ppt_buffer == 00) {
5056                         opj_event_msg_v2(p_manager, EVT_ERROR, "Not enough memory reading PPT marker\n");
5057                         return OPJ_FALSE;
5058                 }
5059                 l_tcp->ppt_data = l_tcp->ppt_buffer;
5060
5061                 memset(l_tcp->ppt_buffer+l_tcp->ppt_data_size,0,p_header_size);
5062         }
5063
5064         /* Read packet header from buffer */
5065         memcpy(l_tcp->ppt_buffer+l_tcp->ppt_data_size,p_header_data,p_header_size);
5066
5067         l_tcp->ppt_data_size += p_header_size;
5068
5069         return OPJ_TRUE;
5070 }
5071
5072 /**
5073  * Writes the TLM marker (Tile Length Marker)
5074  * 
5075  * @param       p_stream                                the stream to write data to.
5076  * @param       p_j2k                           J2K codec.
5077  * @param       p_manager               the user event manager.
5078 */
5079 opj_bool j2k_write_tlm_v2(      opj_j2k_v2_t *p_j2k,
5080                                                         struct opj_stream_private *p_stream,
5081                                                         struct opj_event_mgr * p_manager )
5082 {
5083         OPJ_BYTE * l_current_data = 00;
5084         OPJ_UINT32 l_tlm_size;
5085
5086         // preconditions
5087         assert(p_j2k != 00);
5088         assert(p_manager != 00);
5089         assert(p_stream != 00);
5090
5091         l_tlm_size = 6 + (5*p_j2k->m_specific_param.m_encoder.m_total_tile_parts);
5092         
5093         if (l_tlm_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
5094                 p_j2k->m_specific_param.m_encoder.m_header_tile_data 
5095                         = (OPJ_BYTE*)opj_realloc(
5096                                 p_j2k->m_specific_param.m_encoder.m_header_tile_data,
5097                                 l_tlm_size);
5098                 
5099                 if (! p_j2k->m_specific_param.m_encoder.m_header_tile_data) {
5100                         return OPJ_FALSE;
5101                 }
5102
5103                 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_tlm_size;
5104         }
5105
5106         l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
5107
5108         /* change the way data is written to avoid seeking if possible */
5109         // TODO
5110         p_j2k->m_specific_param.m_encoder.m_tlm_start = opj_stream_tell(p_stream);
5111         
5112         opj_write_bytes(l_current_data,J2K_MS_TLM,2);                                   /* TLM */
5113         l_current_data += 2;
5114         
5115         opj_write_bytes(l_current_data,l_tlm_size-2,2);                                 /* Lpoc */
5116         l_current_data += 2;
5117         
5118         opj_write_bytes(l_current_data,0,1);                                                    /* Ztlm=0*/
5119         ++l_current_data;
5120         
5121         opj_write_bytes(l_current_data,0x50,1);                                                 /* Stlm ST=1(8bits-255 tiles max),SP=1(Ptlm=32bits) */
5122         ++l_current_data;
5123         
5124         /* do nothing on the 5 * l_j2k->m_specific_param.m_encoder.m_total_tile_parts remaining data */
5125         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) {
5126                 return OPJ_FALSE;
5127         }
5128
5129         return OPJ_TRUE;
5130 }
5131
5132 static void j2k_write_tlm(opj_j2k_t *j2k){
5133         int lenp;
5134         opj_cio_t *cio = j2k->cio;
5135         j2k->tlm_start = cio_tell(cio);
5136         cio_write(cio, J2K_MS_TLM, 2);/* TLM */
5137         lenp = 4 + (5*j2k->totnum_tp);
5138         cio_write(cio,lenp,2);                          /* Ltlm */
5139         cio_write(cio, 0,1);                                    /* Ztlm=0*/
5140         cio_write(cio,80,1);                                    /* Stlm ST=1(8bits-255 tiles max),SP=1(Ptlm=32bits) */
5141         cio_skip(cio,5*j2k->totnum_tp);
5142 }
5143
5144 static void j2k_write_sot(opj_j2k_t *j2k) {
5145         int lenp, len;
5146
5147         opj_cio_t *cio = j2k->cio;
5148
5149         j2k->sot_start = cio_tell(cio);
5150         cio_write(cio, J2K_MS_SOT, 2);          /* SOT */
5151         lenp = cio_tell(cio);
5152         cio_skip(cio, 2);                                       /* Lsot (further) */
5153         cio_write(cio, j2k->curtileno, 2);      /* Isot */
5154         cio_skip(cio, 4);                                       /* Psot (further in j2k_write_sod) */
5155         cio_write(cio, j2k->cur_tp_num , 1);    /* TPsot */
5156         cio_write(cio, j2k->cur_totnum_tp[j2k->curtileno], 1);          /* TNsot */
5157         len = cio_tell(cio) - lenp;
5158         cio_seek(cio, lenp);
5159         cio_write(cio, len, 2);                         /* Lsot */
5160         cio_seek(cio, lenp + len);
5161
5162         /* UniPG>> */
5163 #ifdef USE_JPWL
5164         /* update markers struct */
5165         j2k_add_marker(j2k->cstr_info, J2K_MS_SOT, j2k->sot_start, len + 2);
5166 #endif /* USE_JPWL */
5167         /* <<UniPG */
5168
5169         if( j2k->cstr_info && j2k->cur_tp_num==0){
5170           j2k_add_tlmarker( j2k->curtileno, j2k->cstr_info, J2K_MS_SOT, lenp, len);
5171         }
5172 }
5173
5174 /**
5175  * Writes the SOT marker (Start of tile-part)
5176  *
5177  * @param       p_stream                                the stream to write data to.
5178  * @param       p_j2k                           J2K codec.
5179  * @param       p_manager               the user event manager.
5180 */
5181 opj_bool j2k_write_sot_v2(      opj_j2k_v2_t *p_j2k,
5182                                                         OPJ_BYTE * p_data,
5183                                                         OPJ_UINT32 * p_data_written,
5184                                                         const struct opj_stream_private *p_stream,
5185                                                         struct opj_event_mgr * p_manager )
5186 {
5187         /* preconditions */
5188         assert(p_j2k != 00);
5189         assert(p_manager != 00);
5190         assert(p_stream != 00);
5191
5192         opj_write_bytes(p_data,J2K_MS_SOT,2);                                   /* SOT */
5193         p_data += 2;
5194
5195         opj_write_bytes(p_data,10,2);                                                   /* Lsot */
5196         p_data += 2;
5197
5198         opj_write_bytes(p_data, p_j2k->m_current_tile_number,2);                        /* Isot */
5199         p_data += 2;
5200
5201         /* Psot  */
5202         p_data += 4;
5203
5204         opj_write_bytes(p_data, p_j2k->m_specific_param.m_encoder.m_current_tile_part_number,1);                        /* TPsot */
5205         ++p_data;
5206
5207         opj_write_bytes(p_data, p_j2k->m_cp.tcps[p_j2k->m_current_tile_number].m_nb_tile_parts,1);                      /* TNsot */
5208         ++p_data;
5209
5210         /* UniPG>> */
5211 #ifdef USE_JPWL
5212         /* update markers struct */
5213 /*
5214         j2k_add_marker(p_j2k->cstr_info, J2K_MS_SOT, p_j2k->sot_start, len + 2);
5215 */
5216   assert( 0 && "TODO" );
5217 #endif /* USE_JPWL */
5218
5219         * p_data_written = 12;
5220
5221         return OPJ_TRUE;
5222 }
5223
5224
5225 static void j2k_read_sot(opj_j2k_t *j2k) {
5226         int len, tileno, totlen, partno, numparts;
5227   OPJ_UINT32 i;
5228         opj_tcp_t *tcp = NULL;
5229         char status = 0;
5230
5231         opj_cp_t *cp = j2k->cp;
5232         opj_cio_t *cio = j2k->cio;
5233
5234         len = cio_read(cio, 2);
5235         tileno = cio_read(cio, 2);
5236
5237 #ifdef USE_JPWL
5238         if (j2k->cp->correct) {
5239
5240                 static int backup_tileno = 0;
5241
5242                 /* tileno is negative or larger than the number of tiles!!! */
5243                 if ((tileno < 0) || (tileno > (cp->tw * cp->th))) {
5244                         opj_event_msg(j2k->cinfo, EVT_ERROR,
5245                                 "JPWL: bad tile number (%d out of a maximum of %d)\n",
5246                                 tileno, (cp->tw * cp->th));
5247                         if (!JPWL_ASSUME) {
5248                                 opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
5249                                 return;
5250                         }
5251                         /* we try to correct */
5252                         tileno = backup_tileno;
5253                         opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust this\n"
5254                                 "- setting tile number to %d\n",
5255                                 tileno);
5256                 }
5257
5258                 /* keep your private count of tiles */
5259                 backup_tileno++;
5260         };
5261 #endif /* USE_JPWL */
5262         
5263         if (cp->tileno_size == 0) {
5264                 cp->tileno[cp->tileno_size] = tileno;
5265                 cp->tileno_size++;
5266         } else {
5267                 i = 0;
5268                 assert(cp->tileno_size >= 0);
5269                 while (i < (OPJ_UINT32)cp->tileno_size && status == 0) {
5270                         status = cp->tileno[i] == tileno ? 1 : 0;
5271                         i++;
5272                 }
5273                 if (status == 0) {
5274                         cp->tileno[cp->tileno_size] = tileno;
5275                         cp->tileno_size++;
5276                 }
5277         }
5278         
5279         totlen = cio_read(cio, 4);
5280
5281 #ifdef USE_JPWL
5282         if (j2k->cp->correct) {
5283
5284                 /* totlen is negative or larger than the bytes left!!! */
5285                 if ((totlen < 0) || (totlen > (cio_numbytesleft(cio) + 8))) {
5286                         opj_event_msg(j2k->cinfo, EVT_ERROR,
5287                                 "JPWL: bad tile byte size (%d bytes against %d bytes left)\n",
5288                                 totlen, cio_numbytesleft(cio) + 8);
5289                         if (!JPWL_ASSUME) {
5290                                 opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
5291                                 return;
5292                         }
5293                         /* we try to correct */
5294                         totlen = 0;
5295                         opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust this\n"
5296                                 "- setting Psot to %d => assuming it is the last tile\n",
5297                                 totlen);
5298                 }
5299
5300         };
5301 #endif /* USE_JPWL */
5302
5303         if (!totlen)
5304                 totlen = cio_numbytesleft(cio) + 8;
5305         
5306         partno = cio_read(cio, 1);
5307         numparts = cio_read(cio, 1);
5308   
5309   if (partno >= numparts) {
5310     opj_event_msg(j2k->cinfo, EVT_WARNING, "SOT marker inconsistency in tile %d: tile-part index greater (%d) than number of tile-parts (%d)\n", tileno, partno, numparts);
5311     numparts = partno+1;
5312   }
5313         
5314         j2k->curtileno = tileno;
5315         j2k->cur_tp_num = partno;
5316         j2k->eot = cio_getbp(cio) - 12 + totlen;
5317         j2k->state = J2K_STATE_TPH;
5318         tcp = &cp->tcps[j2k->curtileno];
5319
5320         /* Index */
5321         if (j2k->cstr_info) {
5322                 if (tcp->first) {
5323                         if (tileno == 0) 
5324                                 j2k->cstr_info->main_head_end = cio_tell(cio) - 13;
5325                         j2k->cstr_info->tile[tileno].tileno = tileno;
5326                         j2k->cstr_info->tile[tileno].start_pos = cio_tell(cio) - 12;
5327                         j2k->cstr_info->tile[tileno].end_pos = j2k->cstr_info->tile[tileno].start_pos + totlen - 1;                             
5328     } else {
5329                         j2k->cstr_info->tile[tileno].end_pos += totlen;
5330                 }
5331     j2k->cstr_info->tile[tileno].num_tps = numparts;
5332     if (numparts)
5333       j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_realloc(j2k->cstr_info->tile[tileno].tp, numparts * sizeof(opj_tp_info_t));
5334     else
5335       j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_realloc(j2k->cstr_info->tile[tileno].tp, 10 * sizeof(opj_tp_info_t)); /* Fixme (10)*/
5336                 j2k->cstr_info->tile[tileno].tp[partno].tp_start_pos = cio_tell(cio) - 12;
5337                 j2k->cstr_info->tile[tileno].tp[partno].tp_end_pos = 
5338                         j2k->cstr_info->tile[tileno].tp[partno].tp_start_pos + totlen - 1;
5339         }
5340         
5341         if (tcp->first == 1) {          
5342                 /* Initialization PPT */
5343                 opj_tccp_t *tmp = tcp->tccps;
5344                 memcpy(tcp, j2k->default_tcp, sizeof(opj_tcp_t));
5345                 tcp->ppt = 0;
5346                 tcp->ppt_data = NULL;
5347                 tcp->ppt_data_first = NULL;
5348                 tcp->tccps = tmp;
5349
5350                 for (i = 0; i < j2k->image->numcomps; i++) {
5351                         tcp->tccps[i] = j2k->default_tcp->tccps[i];
5352                 }
5353                 cp->tcps[j2k->curtileno].first = 0;
5354         }
5355 }
5356
5357 /**
5358  * Reads a PPT marker (Packed packet headers, tile-part header)
5359  *
5360  * @param       p_header_data   the data contained in the PPT box.
5361  * @param       p_j2k                   the jpeg2000 codec.
5362  * @param       p_header_size   the size of the data contained in the PPT marker.
5363  * @param       p_manager               the user event manager.
5364 */
5365 opj_bool j2k_read_sot_v2 (
5366                                                 opj_j2k_v2_t *p_j2k,
5367                                                 OPJ_BYTE * p_header_data,
5368                                                 OPJ_UINT32 p_header_size,
5369                                                 struct opj_event_mgr * p_manager
5370                                         )
5371 {
5372
5373         opj_cp_v2_t *l_cp = 00;
5374         opj_tcp_v2_t *l_tcp = 00;
5375         OPJ_UINT32 l_tot_len, l_num_parts = 0;
5376         OPJ_UINT32 l_current_part;
5377         OPJ_UINT32 l_tile_x,l_tile_y;
5378
5379         /* preconditions */
5380         assert(p_header_data != 00);
5381         assert(p_j2k != 00);
5382         assert(p_manager != 00);
5383
5384         /* Size of this marker is fixed = 12 (we have already read marker and its size)*/
5385         if (p_header_size != 8) {
5386                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading SOT marker\n");
5387                 return OPJ_FALSE;
5388         }
5389
5390         l_cp = &(p_j2k->m_cp);
5391         opj_read_bytes(p_header_data,&(p_j2k->m_current_tile_number),2);                /* Isot */
5392         p_header_data+=2;
5393
5394         l_tcp = &l_cp->tcps[p_j2k->m_current_tile_number];
5395         l_tile_x = p_j2k->m_current_tile_number % l_cp->tw;
5396         l_tile_y = p_j2k->m_current_tile_number / l_cp->tw;
5397
5398 #ifdef USE_JPWL
5399         if (l_cp->correct) {
5400
5401                 int tileno = p_j2k->m_current_tile_number;
5402                 static int backup_tileno = 0;
5403
5404                 /* tileno is negative or larger than the number of tiles!!! */
5405                 if ((tileno < 0) || (tileno > (l_cp->tw * l_cp->th))) {
5406                         opj_event_msg_v2(p_manager, EVT_ERROR,
5407                                 "JPWL: bad tile number (%d out of a maximum of %d)\n",
5408                                 tileno, (l_cp->tw * l_cp->th));
5409                         if (!JPWL_ASSUME) {
5410                                 opj_event_msg_v2(p_manager, EVT_ERROR, "JPWL: giving up\n");
5411                                 return OPJ_FALSE;
5412                         }
5413                         /* we try to correct */
5414                         tileno = backup_tileno;
5415                         opj_event_msg_v2(p_manager, EVT_WARNING, "- trying to adjust this\n"
5416                                 "- setting tile number to %d\n",
5417                                 tileno);
5418                 }
5419
5420                 /* keep your private count of tiles */
5421                 backup_tileno++;
5422         };
5423 #endif /* USE_JPWL */
5424
5425         /* look for the tile in the list of already processed tile (in parts). */
5426         /* Optimization possible here with a more complex data structure and with the removing of tiles */
5427         /* since the time taken by this function can only grow at the time */
5428
5429         opj_read_bytes(p_header_data,&l_tot_len,4);             /* Psot */
5430         p_header_data+=4;
5431
5432         /* PSot should be equal to zero or >=14 or <= 2^32-1 */
5433         if ((l_tot_len !=0 ) && (l_tot_len < 14) )
5434         {
5435                 opj_event_msg_v2(p_manager, EVT_ERROR, "Psot value (%d) is not correct regards to the JPEG2000 norm!\n", l_tot_len);
5436                 return OPJ_FALSE;
5437         }
5438
5439
5440 #ifdef USE_JPWL
5441         if (l_cp->correct) {
5442
5443                 /* totlen is negative or larger than the bytes left!!! */
5444                 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))) { */
5445                         opj_event_msg_v2(p_manager, EVT_ERROR,
5446                                 "JPWL: bad tile byte size (%d bytes against %d bytes left)\n",
5447                                 l_tot_len, p_header_size ); /* FIXME it seems correct; for info in V1 -> p_stream_numbytesleft(p_stream) + 8); */
5448                         if (!JPWL_ASSUME) {
5449                                 opj_event_msg_v2(p_manager, EVT_ERROR, "JPWL: giving up\n");
5450                                 return OPJ_FALSE;
5451                         }
5452                         /* we try to correct */
5453                         l_tot_len = 0;
5454                         opj_event_msg_v2(p_manager, EVT_WARNING, "- trying to adjust this\n"
5455                                 "- setting Psot to %d => assuming it is the last tile\n",
5456                                 l_tot_len);
5457                 }
5458         };
5459 #endif /* USE_JPWL */
5460
5461         /* Ref A.4.2: Psot could be equal zero if it is the last tile-part of the codestream.*/
5462         if (!l_tot_len) {
5463                 opj_event_msg_v2(p_manager, EVT_INFO, "Psot value of the current tile-part is equal to zero, "
5464                                 "we assuming it is the last tile-part of the codestream.\n");
5465                 p_j2k->m_specific_param.m_decoder.m_last_tile_part = 1;
5466         }
5467
5468         opj_read_bytes(p_header_data,&l_current_part ,1);       /* TPsot */
5469         ++p_header_data;
5470
5471         opj_read_bytes(p_header_data,&l_num_parts ,1);          /* TNsot */
5472         ++p_header_data;
5473
5474         if (l_num_parts != 0) { /* Number of tile-part header is provided by this tile-part header */
5475                 /* Useful to manage the case of textGBR.jp2 file because two values of TNSot are allowed: the correct numbers of
5476                  * tile-parts for that tile and zero (A.4.2 of 15444-1 : 2002). */
5477                 if (l_tcp->m_nb_tile_parts) {
5478                         if (l_current_part >= l_tcp->m_nb_tile_parts){
5479                                 opj_event_msg_v2(p_manager, EVT_ERROR, "In SOT marker, TPSot (%d) is not valid regards to the current "
5480                                                 "number of tile-part (%d), giving up\n", l_current_part, l_tcp->m_nb_tile_parts );
5481                                 p_j2k->m_specific_param.m_decoder.m_last_tile_part = 1;
5482                                 return OPJ_FALSE;
5483                         }
5484                 }
5485                 l_tcp->m_nb_tile_parts = l_num_parts;
5486         }
5487
5488         /* If know the number of tile part header we will check if we didn't read the last*/
5489         if (l_tcp->m_nb_tile_parts) {
5490                 if (l_tcp->m_nb_tile_parts == (l_current_part + 1)) {
5491                         p_j2k->m_specific_param.m_decoder.m_can_decode = 1; /* Process the last tile-part header*/
5492                 }
5493         }
5494
5495         if (!p_j2k->m_specific_param.m_decoder.m_last_tile_part){
5496                 /* Keep the size of data to skip after this marker */
5497                 p_j2k->m_specific_param.m_decoder.m_sot_length = l_tot_len - 12; /* SOT_marker_size = 12 */
5498         }
5499         else {
5500                 /* FIXME: need to be computed from the number of bytes remaining in the codestream */
5501                 p_j2k->m_specific_param.m_decoder.m_sot_length = 0;
5502         }
5503
5504         p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_TPH;
5505
5506         /* Check if the current tile is outside the area we want decode or not corresponding to the tile index*/
5507         if (p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec == -1) {
5508                 p_j2k->m_specific_param.m_decoder.m_skip_data =
5509                                 (l_tile_x < p_j2k->m_specific_param.m_decoder.m_start_tile_x)
5510                         ||      (l_tile_x >= p_j2k->m_specific_param.m_decoder.m_end_tile_x)
5511                         ||  (l_tile_y < p_j2k->m_specific_param.m_decoder.m_start_tile_y)
5512                         ||      (l_tile_y >= p_j2k->m_specific_param.m_decoder.m_end_tile_y);
5513         }
5514   else {
5515       assert( p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec >= 0 );
5516     p_j2k->m_specific_param.m_decoder.m_skip_data =
5517       (p_j2k->m_current_tile_number != (OPJ_UINT32)p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec);
5518     }
5519
5520         /* Index */
5521         if (p_j2k->cstr_index)
5522         {
5523                 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tileno = p_j2k->m_current_tile_number;
5524                 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_tpsno = l_current_part;
5525
5526                 if (l_num_parts != 0){
5527                         p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].nb_tps = l_num_parts;
5528                         p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps = l_num_parts;
5529
5530
5531                         if (!p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index)
5532                                 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index =
5533                                         (opj_tp_index_t*)opj_calloc(l_num_parts, sizeof(opj_tp_index_t));
5534                         else
5535                                 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index =
5536                                         (opj_tp_index_t*)opj_realloc(
5537                                                         p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index,
5538                                                         l_num_parts* sizeof(opj_tp_index_t));
5539                 }
5540                 else{
5541                         /*if (!p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index)*/ {
5542
5543                                 if (!p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index) {
5544                                         p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps = 10;
5545                                         p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index =
5546                                                 (opj_tp_index_t*)opj_calloc( p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps,
5547                                                                                                          sizeof(opj_tp_index_t));
5548                                 }
5549
5550                                 if ( l_current_part >= p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps ){
5551                                         p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps += 10;
5552                                         p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index =
5553                                                 (opj_tp_index_t*)opj_realloc( p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index,
5554                                                                                                           p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps
5555                                                                                                           * sizeof(opj_tp_index_t));
5556                                 }
5557                         }
5558
5559                 }
5560
5561         }
5562
5563
5564         /* 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 */
5565         /* if (p_j2k->cstr_info) {
5566                 if (l_tcp->first) {
5567                         if (tileno == 0) {
5568                                 p_j2k->cstr_info->main_head_end = p_stream_tell(p_stream) - 13;
5569                         }
5570
5571                         p_j2k->cstr_info->tile[tileno].tileno = tileno;
5572                         p_j2k->cstr_info->tile[tileno].start_pos = p_stream_tell(p_stream) - 12;
5573                         p_j2k->cstr_info->tile[tileno].end_pos = p_j2k->cstr_info->tile[tileno].start_pos + totlen - 1;
5574                         p_j2k->cstr_info->tile[tileno].num_tps = numparts;
5575
5576                         if (numparts) {
5577                                 p_j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_malloc(numparts * sizeof(opj_tp_info_t));
5578                         }
5579                         else {
5580                                 p_j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_malloc(10 * sizeof(opj_tp_info_t)); // Fixme (10)
5581                         }
5582                 }
5583                 else {
5584                         p_j2k->cstr_info->tile[tileno].end_pos += totlen;
5585                 }
5586
5587                 p_j2k->cstr_info->tile[tileno].tp[partno].tp_start_pos = p_stream_tell(p_stream) - 12;
5588                 p_j2k->cstr_info->tile[tileno].tp[partno].tp_end_pos =
5589                 p_j2k->cstr_info->tile[tileno].tp[partno].tp_start_pos + totlen - 1;
5590         }*/
5591         return OPJ_TRUE;
5592 }
5593
5594 static void j2k_write_sod(opj_j2k_t *j2k, void *tile_coder) {
5595         int l, layno;
5596         int totlen;
5597         opj_tcp_t *tcp = NULL;
5598         opj_codestream_info_t *cstr_info = NULL;
5599         
5600         opj_tcd_t *tcd = (opj_tcd_t*)tile_coder;        /* cast is needed because of conflicts in header inclusions */
5601         opj_cp_t *cp = j2k->cp;
5602         opj_cio_t *cio = j2k->cio;
5603
5604         tcd->tp_num = j2k->tp_num ;
5605         tcd->cur_tp_num = j2k->cur_tp_num;
5606         
5607         cio_write(cio, J2K_MS_SOD, 2);
5608
5609         if( j2k->cstr_info && j2k->cur_tp_num==0){
5610           j2k_add_tlmarker( j2k->curtileno, j2k->cstr_info, J2K_MS_SOD, cio_tell(cio), 0);
5611         }
5612
5613         if (j2k->curtileno == 0) {
5614                 j2k->sod_start = cio_tell(cio) + j2k->pos_correction;
5615         }
5616
5617         /* INDEX >> */
5618         cstr_info = j2k->cstr_info;
5619         if (cstr_info) {
5620                 if (!j2k->cur_tp_num ) {
5621                         cstr_info->tile[j2k->curtileno].end_header = cio_tell(cio) + j2k->pos_correction - 1;
5622                         j2k->cstr_info->tile[j2k->curtileno].tileno = j2k->curtileno;
5623                 }
5624                 else{
5625                         if(cstr_info->tile[j2k->curtileno].packet[cstr_info->packno - 1].end_pos < cio_tell(cio))
5626                                 cstr_info->tile[j2k->curtileno].packet[cstr_info->packno].start_pos = cio_tell(cio);
5627                 }
5628                 /* UniPG>> */
5629 #ifdef USE_JPWL
5630                 /* update markers struct */
5631                 j2k_add_marker(j2k->cstr_info, J2K_MS_SOD, j2k->sod_start, 2);
5632 #endif /* USE_JPWL */
5633                 /* <<UniPG */
5634         }
5635         /* << INDEX */
5636         
5637         tcp = &cp->tcps[j2k->curtileno];
5638         for (layno = 0; layno < tcp->numlayers; layno++) {
5639                 if (tcp->rates[layno]>(j2k->sod_start / (cp->th * cp->tw))) {
5640                         tcp->rates[layno]-=(j2k->sod_start / (cp->th * cp->tw));
5641                 } else if (tcp->rates[layno]) {
5642                         tcp->rates[layno]=1;
5643                 }
5644         }
5645         if(j2k->cur_tp_num == 0){
5646                 tcd->tcd_image->tiles->packno = 0;
5647                 if(cstr_info)
5648                         cstr_info->packno = 0;
5649         }
5650         
5651         l = tcd_encode_tile(tcd, j2k->curtileno, cio_getbp(cio), cio_numbytesleft(cio) - 2, cstr_info);
5652         
5653         /* Writing Psot in SOT marker */
5654         totlen = cio_tell(cio) + l - j2k->sot_start;
5655         cio_seek(cio, j2k->sot_start + 6);
5656         cio_write(cio, totlen, 4);
5657         cio_seek(cio, j2k->sot_start + totlen);
5658         /* Writing Ttlm and Ptlm in TLM marker */
5659         if(cp->cinema){
5660                 cio_seek(cio, j2k->tlm_start + 6 + (5*j2k->cur_tp_num));
5661                 cio_write(cio, j2k->curtileno, 1);
5662                 cio_write(cio, totlen, 4);
5663         }
5664         cio_seek(cio, j2k->sot_start + totlen);
5665 }
5666
5667 /**
5668  * Writes the SOD marker (Start of data)
5669  *
5670  * @param       p_stream                                the stream to write data to.
5671  * @param       p_j2k                           J2K codec.
5672  * @param       p_manager               the user event manager.
5673 */
5674 opj_bool j2k_write_sod_v2(      opj_j2k_v2_t *p_j2k,
5675                                                         struct opj_tcd_v2 * p_tile_coder,
5676                                                         OPJ_BYTE * p_data,
5677                                                         OPJ_UINT32 * p_data_written,
5678                                                         OPJ_UINT32 p_total_data_size,
5679                                                         const struct opj_stream_private *p_stream,
5680                                                         struct opj_event_mgr * p_manager )
5681 {
5682         opj_tcp_v2_t *l_tcp = 00;
5683         opj_codestream_info_t *l_cstr_info = 00;
5684         opj_cp_v2_t *l_cp = 00;
5685
5686         OPJ_UINT32 l_size_tile;
5687         OPJ_UINT32 l_remaining_data;
5688
5689         /* preconditions */
5690         assert(p_j2k != 00);
5691         assert(p_manager != 00);
5692         assert(p_stream != 00);
5693
5694         opj_write_bytes(p_data,J2K_MS_SOD,2);                                   /* SOD */
5695         p_data += 2;
5696
5697         /* make room for the EOF marker */
5698         l_remaining_data =  p_total_data_size - 4;
5699
5700         l_cp = &(p_j2k->m_cp);
5701         l_tcp = &l_cp->tcps[p_j2k->m_current_tile_number];
5702
5703
5704         /* update tile coder */
5705         p_tile_coder->tp_num = p_j2k->m_specific_param.m_encoder.m_current_poc_tile_part_number ;
5706         p_tile_coder->cur_tp_num = p_j2k->m_specific_param.m_encoder.m_current_tile_part_number;
5707
5708         l_size_tile = l_cp->th * l_cp->tw;
5709
5710         /* INDEX >> */
5711         /* TODO mergeV2: check this part which use cstr_info */
5712         /*l_cstr_info = p_j2k->cstr_info;
5713         if (l_cstr_info) {
5714                 if (!p_j2k->m_specific_param.m_encoder.m_current_tile_part_number ) {
5715                         //TODO cstr_info->tile[p_j2k->m_current_tile_number].end_header = p_stream_tell(p_stream) + p_j2k->pos_correction - 1;
5716                         l_cstr_info->tile[p_j2k->m_current_tile_number].tileno = p_j2k->m_current_tile_number;
5717                 }
5718                 else {*/
5719                         /*
5720                         TODO
5721                         if
5722                                 (cstr_info->tile[p_j2k->m_current_tile_number].packet[cstr_info->packno - 1].end_pos < p_stream_tell(p_stream))
5723                         {
5724                                 cstr_info->tile[p_j2k->m_current_tile_number].packet[cstr_info->packno].start_pos = p_stream_tell(p_stream);
5725                         }*/
5726                 /*}*/
5727                 /* UniPG>> */
5728 #ifdef USE_JPWL
5729                 /* update markers struct */
5730                 /*j2k_add_marker(p_j2k->cstr_info, J2K_MS_SOD, p_j2k->sod_start, 2);
5731 */
5732   assert( 0 && "TODO" );
5733 #endif /* USE_JPWL */
5734                 /* <<UniPG */
5735         /*}*/
5736         /* << INDEX */
5737
5738         if (p_j2k->m_specific_param.m_encoder.m_current_tile_part_number == 0) {
5739                 p_tile_coder->tcd_image->tiles->packno = 0;
5740                 if (l_cstr_info) {
5741                         l_cstr_info->packno = 0;
5742                 }
5743         }
5744
5745         *p_data_written = 0;
5746
5747         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)) {
5748                 opj_event_msg_v2(p_manager, EVT_ERROR, "Cannot encode tile\n");
5749                 return OPJ_FALSE;
5750         }
5751
5752         *p_data_written += 2;
5753
5754         return OPJ_TRUE;
5755 }
5756
5757
5758 static void j2k_read_sod(opj_j2k_t *j2k) {
5759         int len, truncate = 0, i;
5760         unsigned char *data = NULL, *data_ptr = NULL;
5761
5762         opj_cio_t *cio = j2k->cio;
5763         int curtileno = j2k->curtileno;
5764
5765         /* Index */
5766         if (j2k->cstr_info) {
5767                 j2k->cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_end_header =
5768                         cio_tell(cio) + j2k->pos_correction - 1;
5769                 if (j2k->cur_tp_num == 0)
5770                         j2k->cstr_info->tile[j2k->curtileno].end_header = cio_tell(cio) + j2k->pos_correction - 1;
5771                 j2k->cstr_info->packno = 0;
5772         }
5773         
5774         len = int_min(j2k->eot - cio_getbp(cio), cio_numbytesleft(cio) + 1);
5775
5776         if (len == cio_numbytesleft(cio) + 1) {
5777                 truncate = 1;           /* Case of a truncate codestream */
5778         }       
5779
5780         data = j2k->tile_data[curtileno];
5781         data = (unsigned char*) opj_realloc(data, (j2k->tile_len[curtileno] + len) * sizeof(unsigned char));
5782
5783         data_ptr = data + j2k->tile_len[curtileno];
5784         for (i = 0; i < len; i++) {
5785                 data_ptr[i] = cio_read(cio, 1);
5786         }
5787
5788         j2k->tile_len[curtileno] += len;
5789         j2k->tile_data[curtileno] = data;
5790         
5791         if (!truncate) {
5792                 j2k->state = J2K_STATE_TPHSOT;
5793         } else {
5794                 j2k->state = J2K_STATE_NEOC;    /* RAJOUTE !! */
5795         }
5796         j2k->cur_tp_num++;
5797 }
5798
5799 /**
5800  * Reads a SOD marker (Start Of Data)
5801  *
5802  * @param       p_header_data   the data contained in the SOD box.
5803  * @param       p_j2k                   the jpeg2000 codec.
5804  * @param       p_header_size   the size of the data contained in the SOD marker.
5805  * @param       p_manager               the user event manager.
5806 */
5807 opj_bool j2k_read_sod_v2 (
5808                                                 opj_j2k_v2_t *p_j2k,
5809                                                 struct opj_stream_private *p_stream,
5810                                                 struct opj_event_mgr * p_manager
5811                                         )
5812 {
5813         OPJ_UINT32 l_current_read_size;
5814         opj_codestream_index_t * l_cstr_index = 00;
5815         OPJ_BYTE ** l_current_data = 00;
5816         opj_tcp_v2_t * l_tcp = 00;
5817         OPJ_UINT32 * l_tile_len = 00;
5818
5819         /* preconditions */
5820         assert(p_j2k != 00);
5821         assert(p_manager != 00);
5822         assert(p_stream != 00);
5823
5824         l_tcp = &(p_j2k->m_cp.tcps[p_j2k->m_current_tile_number]);
5825
5826         if (p_j2k->m_specific_param.m_decoder.m_last_tile_part) {
5827                 /* opj_stream_get_number_byte_left returns OPJ_OFF_T
5828                 // but we are in the last tile part,
5829                 // so its result will fit on OPJ_UINT32 unless we find
5830                 // a file with a single tile part of more than 4 GB...*/
5831                 p_j2k->m_specific_param.m_decoder.m_sot_length = (OPJ_UINT32)(opj_stream_get_number_byte_left(p_stream) - 2);
5832         }
5833         else
5834                 p_j2k->m_specific_param.m_decoder.m_sot_length -= 2;
5835
5836         l_current_data = &(l_tcp->m_data);
5837         l_tile_len = &l_tcp->m_data_size;
5838
5839         if (! *l_current_data) {
5840                 *l_current_data = (OPJ_BYTE*) opj_malloc(p_j2k->m_specific_param.m_decoder.m_sot_length);
5841         }
5842         else {
5843                 *l_current_data = (OPJ_BYTE*) opj_realloc(*l_current_data, *l_tile_len + p_j2k->m_specific_param.m_decoder.m_sot_length);
5844         }
5845
5846         if (*l_current_data == 00) {
5847                 opj_event_msg_v2(p_manager, EVT_ERROR, "Cannot decode tile\n");
5848                 return OPJ_FALSE;
5849         }
5850
5851
5852         /* Index */
5853         l_cstr_index = p_j2k->cstr_index;
5854         if (l_cstr_index) {
5855                 OPJ_OFF_T l_current_pos = opj_stream_tell(p_stream) - 2;
5856
5857                 OPJ_UINT32 l_current_tile_part = l_cstr_index->tile_index[p_j2k->m_current_tile_number].current_tpsno;
5858                 l_cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index[l_current_tile_part].end_header =
5859                                 l_current_pos;
5860                 l_cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index[l_current_tile_part].end_pos =
5861                                 l_current_pos + p_j2k->m_specific_param.m_decoder.m_sot_length + 2;
5862
5863                 j2k_add_tlmarker_v2(p_j2k->m_current_tile_number,
5864                                                         l_cstr_index,
5865                                                         J2K_MS_SOD,
5866                                                         l_current_pos,
5867                                                         p_j2k->m_specific_param.m_decoder.m_sot_length + 2);
5868
5869                 /*l_cstr_index->packno = 0;*/
5870         }
5871
5872         l_current_read_size = opj_stream_read_data(     p_stream,
5873                                                                                                 *l_current_data + *l_tile_len,
5874                                                                                                 p_j2k->m_specific_param.m_decoder.m_sot_length,
5875                                                                                                 p_manager);
5876
5877         if (l_current_read_size != p_j2k->m_specific_param.m_decoder.m_sot_length) {
5878                 p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_NEOC;
5879         }
5880         else {
5881                 p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_TPHSOT;
5882         }
5883
5884         *l_tile_len +=  l_current_read_size;
5885
5886         return OPJ_TRUE;
5887 }
5888
5889
5890 static void j2k_write_rgn(opj_j2k_t *j2k, int compno, int tileno) {
5891         opj_cp_t *cp = j2k->cp;
5892         opj_tcp_t *tcp = &cp->tcps[tileno];
5893         opj_cio_t *cio = j2k->cio;
5894         int numcomps = j2k->image->numcomps;
5895         
5896         cio_write(cio, J2K_MS_RGN, 2);                                          /* RGN  */
5897         cio_write(cio, numcomps <= 256 ? 5 : 6, 2);                     /* Lrgn */
5898         cio_write(cio, compno, numcomps <= 256 ? 1 : 2);        /* Crgn */
5899         cio_write(cio, 0, 1);                                                           /* Srgn */
5900         cio_write(cio, tcp->tccps[compno].roishift, 1);         /* SPrgn */
5901 }
5902
5903 /**
5904  * Writes the RGN marker (Region Of Interest)
5905  *
5906  * @param       p_tile_no               the tile to output
5907  * @param       p_comp_no               the component to output
5908  * @param       p_stream                                the stream to write data to.
5909  * @param       p_j2k                           J2K codec.
5910  * @param       p_manager               the user event manager.
5911 */
5912 opj_bool j2k_write_rgn_v2(      opj_j2k_v2_t *p_j2k,
5913                                                         OPJ_UINT32 p_tile_no,
5914                                                         OPJ_UINT32 p_comp_no,
5915                                                         struct opj_stream_private *p_stream,
5916                                                         struct opj_event_mgr * p_manager )
5917 {
5918         OPJ_BYTE * l_current_data = 00;
5919         OPJ_UINT32 l_nb_comp;
5920         OPJ_UINT32 l_rgn_size;
5921         opj_image_t *l_image = 00;
5922         opj_cp_v2_t *l_cp = 00;
5923         opj_tcp_v2_t *l_tcp = 00;
5924         opj_tccp_t *l_tccp = 00;
5925         OPJ_UINT32 l_comp_room;
5926
5927         /* preconditions */
5928         assert(p_j2k != 00);
5929         assert(p_manager != 00);
5930         assert(p_stream != 00);
5931
5932         l_cp = &(p_j2k->m_cp);
5933         l_tcp = &l_cp->tcps[p_tile_no];
5934         l_tccp = &l_tcp->tccps[p_comp_no];
5935
5936         l_nb_comp = l_image->numcomps;
5937
5938         if (l_nb_comp <= 256) {
5939                 l_comp_room = 1;
5940         }
5941         else {
5942                 l_comp_room = 2;
5943         }
5944
5945         l_rgn_size = 6 + l_comp_room;
5946
5947         l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
5948
5949         opj_write_bytes(l_current_data,J2K_MS_RGN,2);                                   /* RGN  */
5950         l_current_data += 2;
5951
5952         opj_write_bytes(l_current_data,l_rgn_size-2,2);                                 /* Lrgn */
5953         l_current_data += 2;
5954
5955         opj_write_bytes(l_current_data,p_comp_no,l_comp_room);                  /* Crgn */
5956         l_current_data+=l_comp_room;
5957
5958         opj_write_bytes(l_current_data, 0,1);                                                   /* Srgn */
5959         ++l_current_data;
5960
5961         opj_write_bytes(l_current_data, l_tccp->roishift,1);                    /* SPrgn */
5962         ++l_current_data;
5963
5964         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) {
5965                 return OPJ_FALSE;
5966         }
5967
5968         return OPJ_TRUE;
5969 }
5970
5971 static void j2k_read_rgn(opj_j2k_t *j2k) {
5972         int len, compno, roisty;
5973
5974         opj_cp_t *cp = j2k->cp;
5975         opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp;
5976         opj_cio_t *cio = j2k->cio;
5977         int numcomps = j2k->image->numcomps;
5978
5979         len = cio_read(cio, 2);                                                                         /* Lrgn */
5980         compno = cio_read(cio, numcomps <= 256 ? 1 : 2);                        /* Crgn */
5981         roisty = cio_read(cio, 1);                                                                      /* Srgn */
5982
5983 #ifdef USE_JPWL
5984         if (j2k->cp->correct) {
5985                 /* totlen is negative or larger than the bytes left!!! */
5986                 if (compno >= numcomps) {
5987                         opj_event_msg(j2k->cinfo, EVT_ERROR,
5988                                 "JPWL: bad component number in RGN (%d when there are only %d)\n",
5989                                 compno, numcomps);
5990                         if (!JPWL_ASSUME || JPWL_ASSUME) {
5991                                 opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n");
5992                                 return;
5993                         }
5994                 }
5995         };
5996 #endif /* USE_JPWL */
5997
5998         tcp->tccps[compno].roishift = cio_read(cio, 1);                         /* SPrgn */
5999 }
6000
6001 static void j2k_write_eoc(opj_j2k_t *j2k) {
6002         opj_cio_t *cio = j2k->cio;
6003         /* opj_event_msg(j2k->cinfo, "%.8x: EOC\n", cio_tell(cio) + j2k->pos_correction); */
6004         cio_write(cio, J2K_MS_EOC, 2);
6005
6006 /* UniPG>> */
6007 #ifdef USE_JPWL
6008         /* update markers struct */
6009         j2k_add_marker(j2k->cstr_info, J2K_MS_EOC, cio_tell(cio) - 2, 2);
6010 #endif /* USE_JPWL */
6011 /* <<UniPG */
6012 }
6013
6014 /**
6015  * Writes the EOC marker (End of Codestream)
6016  * 
6017  * @param       p_stream                the stream to write data to.
6018  * @param       p_j2k                   J2K codec.
6019  * @param       p_manager               the user event manager.
6020 */
6021 opj_bool j2k_write_eoc_v2(      opj_j2k_v2_t *p_j2k,
6022                                                         struct opj_stream_private *p_stream,
6023                                                         struct opj_event_mgr * p_manager )
6024 {
6025         /* preconditions */
6026         assert(p_j2k != 00);
6027         assert(p_manager != 00);
6028         assert(p_stream != 00);
6029         
6030         opj_write_bytes(p_j2k->m_specific_param.m_encoder.m_header_tile_data,J2K_MS_EOC,2);                                     /* EOC */
6031         
6032
6033 /* UniPG>> */
6034 #ifdef USE_JPWL
6035         /* update markers struct */
6036         j2k_add_marker(p_j2k->cstr_info, J2K_MS_EOC, p_stream_tell(p_stream) - 2, 2);
6037 #endif /* USE_JPWL */
6038
6039         if ( opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,2,p_manager) != 2) {
6040                 return OPJ_FALSE;
6041         }
6042
6043         if ( ! opj_stream_flush(p_stream,p_manager) ) {
6044                 return OPJ_FALSE;
6045         }
6046
6047         return OPJ_TRUE;
6048 }
6049
6050
6051 /**
6052  * Reads a RGN marker (Region Of Interest)
6053  *
6054  * @param       p_header_data   the data contained in the POC box.
6055  * @param       p_j2k                   the jpeg2000 codec.
6056  * @param       p_header_size   the size of the data contained in the POC marker.
6057  * @param       p_manager               the user event manager.
6058 */
6059 opj_bool j2k_read_rgn_v2 (
6060                                                 opj_j2k_v2_t *p_j2k,
6061                                                 OPJ_BYTE * p_header_data,
6062                                                 OPJ_UINT32 p_header_size,
6063                                                 struct opj_event_mgr * p_manager
6064                                         )
6065 {
6066         OPJ_UINT32 l_nb_comp;
6067         opj_image_t * l_image = 00;
6068
6069         opj_cp_v2_t *l_cp = 00;
6070         opj_tcp_v2_t *l_tcp = 00;
6071         OPJ_UINT32 l_comp_room, l_comp_no, l_roi_sty;
6072
6073         /* preconditions*/
6074         assert(p_header_data != 00);
6075         assert(p_j2k != 00);
6076         assert(p_manager != 00);
6077
6078         l_image = p_j2k->m_private_image;
6079         l_nb_comp = l_image->numcomps;
6080
6081         if (l_nb_comp <= 256) {
6082                 l_comp_room = 1; }
6083         else {
6084                 l_comp_room = 2; }
6085
6086         if (p_header_size != 2 + l_comp_room) {
6087                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading RGN marker\n");
6088                 return OPJ_FALSE;
6089         }
6090
6091         l_cp = &(p_j2k->m_cp);
6092         l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH) ?
6093                                 &l_cp->tcps[p_j2k->m_current_tile_number] :
6094                                 p_j2k->m_specific_param.m_decoder.m_default_tcp;
6095
6096         opj_read_bytes(p_header_data,&l_comp_no,l_comp_room);           /* Crgn */
6097         p_header_data+=l_comp_room;
6098         opj_read_bytes(p_header_data,&l_roi_sty,1);                                     /* Srgn */
6099         ++p_header_data;
6100
6101 #ifdef USE_JPWL
6102         if (l_cp->correct) {
6103                 /* totlen is negative or larger than the bytes left!!! */
6104                 if (l_comp_room >= l_nb_comp) {
6105                         opj_event_msg_v2(p_manager, EVT_ERROR,
6106                                 "JPWL: bad component number in RGN (%d when there are only %d)\n",
6107                                 l_comp_room, l_nb_comp);
6108                         if (!JPWL_ASSUME || JPWL_ASSUME) {
6109                                 opj_event_msg_v2(p_manager, EVT_ERROR, "JPWL: giving up\n");
6110                                 return OPJ_FALSE;
6111                         }
6112                 }
6113         };
6114 #endif /* USE_JPWL */
6115
6116         opj_read_bytes(p_header_data,(OPJ_UINT32 *) (&(l_tcp->tccps[l_comp_no].roishift)),1);   /* SPrgn */
6117         ++p_header_data;
6118
6119         return OPJ_TRUE;
6120
6121 }
6122
6123 static OPJ_FLOAT32 get_tp_stride (opj_tcp_v2_t * p_tcp)
6124 {
6125         return (OPJ_FLOAT32) ((p_tcp->m_nb_tile_parts - 1) * 14);
6126 }
6127
6128 static OPJ_FLOAT32 get_default_stride (opj_tcp_v2_t * p_tcp)
6129 {
6130   (void)p_tcp;
6131         return 0;
6132 }
6133
6134 /**
6135  * Updates the rates of the tcp.
6136  *
6137  * @param       p_stream                the stream to write data to.
6138  * @param       p_j2k                   J2K codec.
6139  * @param       p_manager               the user event manager.
6140 */
6141 opj_bool j2k_update_rates(      opj_j2k_v2_t *p_j2k,
6142                                                         struct opj_stream_private *p_stream,
6143                                                         struct opj_event_mgr * p_manager )
6144 {
6145         opj_cp_v2_t * l_cp = 00;
6146         opj_image_t * l_image = 00;
6147         opj_tcp_v2_t * l_tcp = 00;
6148         opj_image_comp_t * l_img_comp = 00;
6149
6150         OPJ_UINT32 i,j,k;
6151         OPJ_INT32 l_x0,l_y0,l_x1,l_y1;
6152         OPJ_FLOAT32 * l_rates = 0;
6153         OPJ_FLOAT32 l_sot_remove;
6154         OPJ_UINT32 l_bits_empty, l_size_pixel;
6155         OPJ_UINT32 l_tile_size = 0;
6156         OPJ_UINT32 l_last_res;
6157         OPJ_FLOAT32 (* l_tp_stride_func)(opj_tcp_v2_t *) = 00;
6158
6159         /* preconditions */
6160         assert(p_j2k != 00);
6161         assert(p_manager != 00);
6162         assert(p_stream != 00);
6163
6164
6165         l_cp = &(p_j2k->m_cp);
6166         l_image = p_j2k->m_private_image;
6167         l_tcp = l_cp->tcps;
6168
6169         l_bits_empty = 8 * l_image->comps->dx * l_image->comps->dy;
6170         l_size_pixel = l_image->numcomps * l_image->comps->prec;
6171         l_sot_remove = ((OPJ_FLOAT32) opj_stream_tell(p_stream)) / (l_cp->th * l_cp->tw);
6172
6173         if (l_cp->m_specific_param.m_enc.m_tp_on) {
6174                 l_tp_stride_func = get_tp_stride;
6175         }
6176         else {
6177                 l_tp_stride_func = get_default_stride;
6178         }
6179
6180         for (i=0;i<l_cp->th;++i) {
6181                 for (j=0;j<l_cp->tw;++j) {
6182                         OPJ_FLOAT32 l_offset = ((*l_tp_stride_func)(l_tcp)) / l_tcp->numlayers;
6183
6184                         /* 4 borders of the tile rescale on the image if necessary */
6185                         l_x0 = int_max(l_cp->tx0 + j * l_cp->tdx, l_image->x0);
6186                         l_y0 = int_max(l_cp->ty0 + i * l_cp->tdy, l_image->y0);
6187                         l_x1 = int_min(l_cp->tx0 + (j + 1) * l_cp->tdx, l_image->x1);
6188                         l_y1 = int_min(l_cp->ty0 + (i + 1) * l_cp->tdy, l_image->y1);
6189
6190                         l_rates = l_tcp->rates;
6191
6192                         /* Modification of the RATE >> */
6193                         if (*l_rates) {
6194                                 *l_rates =              (( (float) (l_size_pixel * (l_x1 - l_x0) * (l_y1 - l_y0)))
6195                                                                 /
6196                                                                 ((*l_rates) * l_bits_empty)
6197                                                                 )
6198                                                                 -
6199                                                                 l_offset;
6200                         }
6201
6202                         ++l_rates;
6203
6204                         for (k = 1; k < l_tcp->numlayers; ++k) {
6205                                 if (*l_rates) {
6206                                         *l_rates =              (( (OPJ_FLOAT32) (l_size_pixel * (l_x1 - l_x0) * (l_y1 - l_y0)))
6207                                                                         /
6208                                                                                 ((*l_rates) * l_bits_empty)
6209                                                                         )
6210                                                                         -
6211                                                                         l_offset;
6212                                 }
6213
6214                                 ++l_rates;
6215                         }
6216
6217                         ++l_tcp;
6218
6219                 }
6220         }
6221
6222         l_tcp = l_cp->tcps;
6223
6224         for (i=0;i<l_cp->th;++i) {
6225                 for     (j=0;j<l_cp->tw;++j) {
6226                         l_rates = l_tcp->rates;
6227
6228                         if (*l_rates) {
6229                                 *l_rates -= l_sot_remove;
6230
6231                                 if (*l_rates < 30) {
6232                                         *l_rates = 30;
6233                                 }
6234                         }
6235
6236                         ++l_rates;
6237
6238                         l_last_res = l_tcp->numlayers - 1;
6239
6240                         for (k = 1; k < l_last_res; ++k) {
6241
6242                                 if (*l_rates) {
6243                                         *l_rates -= l_sot_remove;
6244
6245                                         if (*l_rates < *(l_rates - 1) + 10) {
6246                                                 *l_rates  = (*(l_rates - 1)) + 20;
6247                                         }
6248                                 }
6249
6250                                 ++l_rates;
6251                         }
6252
6253                         if (*l_rates) {
6254                                 *l_rates -= (l_sot_remove + 2.f);
6255
6256                                 if (*l_rates < *(l_rates - 1) + 10) {
6257                                         *l_rates  = (*(l_rates - 1)) + 20;
6258                                 }
6259                         }
6260
6261                         ++l_tcp;
6262                 }
6263         }
6264
6265         l_img_comp = l_image->comps;
6266         l_tile_size = 0;
6267
6268         for (i=0;i<l_image->numcomps;++i) {
6269                 l_tile_size += (        uint_ceildiv(l_cp->tdx,l_img_comp->dx)
6270                                                         *
6271                                                         uint_ceildiv(l_cp->tdy,l_img_comp->dy)
6272                                                         *
6273                                                         l_img_comp->prec
6274                                                 );
6275
6276                 ++l_img_comp;
6277         }
6278
6279         l_tile_size = (OPJ_UINT32) (l_tile_size * 0.1625); /* 1.3/8 = 0.1625 */
6280
6281         l_tile_size += j2k_get_specific_header_sizes(p_j2k);
6282
6283         p_j2k->m_specific_param.m_encoder.m_encoded_tile_size = l_tile_size;
6284         p_j2k->m_specific_param.m_encoder.m_encoded_tile_data =
6285                         (OPJ_BYTE *) opj_malloc(p_j2k->m_specific_param.m_encoder.m_encoded_tile_size);
6286         if (p_j2k->m_specific_param.m_encoder.m_encoded_tile_data == 00) {
6287                 return OPJ_FALSE;
6288         }
6289
6290         if (l_cp->m_specific_param.m_enc.m_cinema) {
6291                 p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer =
6292                                 (OPJ_BYTE *) opj_malloc(5*p_j2k->m_specific_param.m_encoder.m_total_tile_parts);
6293                 if (! p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer) {
6294                         return OPJ_FALSE;
6295                 }
6296
6297                 p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current =
6298                                 p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer;
6299         }
6300
6301         return OPJ_TRUE;
6302 }
6303
6304 static void j2k_read_eoc(opj_j2k_t *j2k) {
6305         int i, tileno;
6306         opj_bool success;
6307
6308         /* if packets should be decoded */
6309         if (j2k->cp->limit_decoding != DECODE_ALL_BUT_PACKETS) {
6310                 opj_tcd_t *tcd = tcd_create(j2k->cinfo);
6311                 tcd_malloc_decode(tcd, j2k->image, j2k->cp);
6312                 for (i = 0; i < j2k->cp->tileno_size; i++) {
6313                         tcd_malloc_decode_tile(tcd, j2k->image, j2k->cp, i, j2k->cstr_info);
6314                         tileno = j2k->cp->tileno[i];
6315                         success = tcd_decode_tile(tcd, j2k->tile_data[tileno], j2k->tile_len[tileno], tileno, j2k->cstr_info);
6316                         opj_free(j2k->tile_data[tileno]);
6317                         j2k->tile_data[tileno] = NULL;
6318                         tcd_free_decode_tile(tcd, i);
6319                         if (success == OPJ_FALSE) {
6320                                 j2k->state |= J2K_STATE_ERR;
6321                                 break;
6322                         }
6323                 }
6324                 tcd_free_decode(tcd);
6325                 tcd_destroy(tcd);
6326         }
6327         /* if packets should not be decoded  */
6328         else {
6329                 for (i = 0; i < j2k->cp->tileno_size; i++) {
6330                         tileno = j2k->cp->tileno[i];
6331                         opj_free(j2k->tile_data[tileno]);
6332                         j2k->tile_data[tileno] = NULL;
6333                 }
6334         }       
6335         if (j2k->state & J2K_STATE_ERR)
6336                 j2k->state = J2K_STATE_MT + J2K_STATE_ERR;
6337         else
6338                 j2k->state = J2K_STATE_MT; 
6339 }
6340
6341 /**
6342  * Reads a EOC marker (End Of Codestream)
6343  *
6344  * @param       p_header_data   the data contained in the SOD box.
6345  * @param       p_j2k                   the jpeg2000 codec.
6346  * @param       p_header_size   the size of the data contained in the SOD marker.
6347  * @param       p_manager               the user event manager.
6348 */
6349 #if 0
6350 opj_bool j2k_read_eoc_v2 (      opj_j2k_v2_t *p_j2k,
6351                                                         struct opj_stream_private *p_stream,
6352                                                         struct opj_event_mgr * p_manager )
6353 {
6354         OPJ_UINT32 i;
6355         opj_tcd_v2_t * l_tcd = 00;
6356         OPJ_UINT32 l_nb_tiles;
6357         opj_tcp_v2_t * l_tcp = 00;
6358         opj_bool l_success;
6359
6360         /* preconditions */
6361         assert(p_j2k != 00);
6362         assert(p_manager != 00);
6363         assert(p_stream != 00);
6364
6365         l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
6366         l_tcp = p_j2k->m_cp.tcps;
6367
6368         l_tcd = tcd_create_v2(OPJ_TRUE);
6369         if (l_tcd == 00) {
6370                 opj_event_msg_v2(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n");
6371                 return OPJ_FALSE;
6372         }
6373
6374         for (i = 0; i < l_nb_tiles; ++i) {
6375                 if (l_tcp->m_data) {
6376                         if (! tcd_init_decode_tile(l_tcd, i)) {
6377                                 tcd_destroy_v2(l_tcd);
6378                                 opj_event_msg_v2(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n");
6379                                 return OPJ_FALSE;
6380                         }
6381
6382                         l_success = tcd_decode_tile_v2(l_tcd, l_tcp->m_data, l_tcp->m_data_size, i, p_j2k->cstr_index);
6383                         /* cleanup */
6384
6385                         if (! l_success) {
6386                                 p_j2k->m_specific_param.m_decoder.m_state |= J2K_STATE_ERR;
6387                                 break;
6388                         }
6389                 }
6390
6391                 j2k_tcp_destroy(l_tcp);
6392                 ++l_tcp;
6393         }
6394
6395         tcd_destroy_v2(l_tcd);
6396         return OPJ_TRUE;
6397 }
6398 #endif
6399
6400 /**
6401  * Gets the offset of the header.
6402  *
6403  * @param       p_stream                                the stream to write data to.
6404  * @param       p_j2k                           J2K codec.
6405  * @param       p_manager               the user event manager.
6406 */
6407 opj_bool j2k_get_end_header(opj_j2k_v2_t *p_j2k,
6408                                                         struct opj_stream_private *p_stream,
6409                                                         struct opj_event_mgr * p_manager )
6410 {
6411         /* preconditions */
6412         assert(p_j2k != 00);
6413         assert(p_manager != 00);
6414         assert(p_stream != 00);
6415
6416         p_j2k->cstr_index->main_head_end = opj_stream_tell(p_stream);
6417
6418         return OPJ_TRUE;
6419 }
6420
6421 /**
6422  * Writes the MCT marker (Multiple Component Transform)
6423  *
6424  * @param       p_stream                                the stream to write data to.
6425  * @param       p_j2k                           J2K codec.
6426  * @param       p_manager               the user event manager.
6427 */
6428 opj_bool j2k_write_mct_data_group(      opj_j2k_v2_t *p_j2k,
6429                                                                         struct opj_stream_private *p_stream,
6430                                                                         struct opj_event_mgr * p_manager )
6431 {
6432         OPJ_UINT32 i;
6433         opj_simple_mcc_decorrelation_data_t * l_mcc_record;
6434         opj_mct_data_t * l_mct_record;
6435         opj_tcp_v2_t * l_tcp;
6436
6437         /* preconditions */
6438         assert(p_j2k != 00);
6439         assert(p_stream != 00);
6440         assert(p_manager != 00);
6441
6442         if (! j2k_write_cbd(p_j2k,p_stream,p_manager)) {
6443                 return OPJ_FALSE;
6444         }
6445
6446         l_tcp = &(p_j2k->m_cp.tcps[p_j2k->m_current_tile_number]);
6447         l_mct_record = l_tcp->m_mct_records;
6448
6449         for (i=0;i<l_tcp->m_nb_mct_records;++i) {
6450
6451                 if (! j2k_write_mct_record(p_j2k,l_mct_record,p_stream,p_manager)) {
6452                         return OPJ_FALSE;
6453                 }
6454
6455                 ++l_mct_record;
6456         }
6457
6458         l_mcc_record = l_tcp->m_mcc_records;
6459
6460         for     (i=0;i<l_tcp->m_nb_mcc_records;++i) {
6461
6462                 if (! j2k_write_mcc_record(p_j2k,l_mcc_record,p_stream,p_manager)) {
6463                         return OPJ_FALSE;
6464                 }
6465
6466                 ++l_mcc_record;
6467         }
6468
6469         if (! j2k_write_mco(p_j2k,p_stream,p_manager)) {
6470                 return OPJ_FALSE;
6471         }
6472
6473         return OPJ_TRUE;
6474 }
6475
6476 /**
6477  * Writes the image components.
6478  *
6479  * @param       p_stream                                the stream to write data to.
6480  * @param       p_j2k                           J2K codec.
6481  * @param       p_manager               the user event manager.
6482 */
6483 opj_bool j2k_write_image_components(opj_j2k_v2_t *p_j2k,
6484                                                                         struct opj_stream_private *p_stream,
6485                                                                         struct opj_event_mgr * p_manager )
6486 {
6487         OPJ_UINT32 compno;
6488
6489         /* preconditions */
6490         assert(p_j2k != 00);
6491         assert(p_manager != 00);
6492         assert(p_stream != 00);
6493
6494         for (compno = 1; compno < p_j2k->m_private_image->numcomps; ++compno)
6495         {
6496                 if (! j2k_write_coc_v2(p_j2k,compno,p_stream, p_manager)) {
6497                         return OPJ_FALSE;
6498                 }
6499
6500                 if (! j2k_write_qcc_v2(p_j2k,compno,p_stream, p_manager)) {
6501                         return OPJ_FALSE;
6502                 }
6503         }
6504
6505         return OPJ_TRUE;
6506 }
6507
6508 /**
6509  * Writes regions of interests.
6510  *
6511  * @param       p_stream                                the stream to write data to.
6512  * @param       p_j2k                           J2K codec.
6513  * @param       p_manager               the user event manager.
6514 */
6515 opj_bool j2k_write_regions(     opj_j2k_v2_t *p_j2k,
6516                                                         struct opj_stream_private *p_stream,
6517                                                         struct opj_event_mgr * p_manager )
6518 {
6519         OPJ_UINT32 compno;
6520         const opj_tccp_t *l_tccp = 00;
6521
6522         /* preconditions */
6523         assert(p_j2k != 00);
6524         assert(p_manager != 00);
6525         assert(p_stream != 00);
6526
6527         l_tccp = p_j2k->m_cp.tcps->tccps;
6528
6529         for     (compno = 0; compno < p_j2k->m_private_image->numcomps; ++compno)  {
6530                 if (l_tccp->roishift) {
6531
6532                         if (! j2k_write_rgn_v2(p_j2k,0,compno,p_stream,p_manager)) {
6533                                 return OPJ_FALSE;
6534                         }
6535                 }
6536
6537                 ++l_tccp;
6538         }
6539
6540         return OPJ_TRUE;
6541 }
6542
6543 /**
6544  * Writes EPC ????
6545  *
6546  * @param       p_stream                the stream to write data to.
6547  * @param       p_j2k                   J2K codec.
6548  * @param       p_manager               the user event manager.
6549 */
6550 opj_bool j2k_write_epc( opj_j2k_v2_t *p_j2k,
6551                                                 struct opj_stream_private *p_stream,
6552                                                 struct opj_event_mgr * p_manager )
6553 {
6554         opj_codestream_index_t * l_cstr_index = 00;
6555
6556         /* preconditions */
6557         assert(p_j2k != 00);
6558         assert(p_manager != 00);
6559         assert(p_stream != 00);
6560
6561         l_cstr_index = p_j2k->cstr_index;
6562         if (l_cstr_index) {
6563                 l_cstr_index->codestream_size = opj_stream_tell(p_stream);
6564                 /* UniPG>> */
6565                 /* The following adjustment is done to adjust the codestream size */
6566                 /* if SOD is not at 0 in the buffer. Useful in case of JP2, where */
6567                 /* the first bunch of bytes is not in the codestream              */
6568                 l_cstr_index->codestream_size -= l_cstr_index->main_head_start;
6569                 /* <<UniPG */
6570         }
6571
6572 #ifdef USE_JPWL
6573         /* preparation of JPWL marker segments */
6574 #if 0
6575         if(cp->epc_on) {
6576
6577                 /* encode according to JPWL */
6578                 jpwl_encode(p_j2k, p_stream, image);
6579
6580         }
6581 #endif
6582   assert( 0 && "TODO" );
6583 #endif /* USE_JPWL */
6584
6585         return OPJ_TRUE;
6586 }
6587
6588 typedef struct opj_dec_mstabent {
6589         /** marker value */
6590         int id;
6591         /** value of the state when the marker can appear */
6592         int states;
6593         /** action linked to the marker */
6594         void (*handler) (opj_j2k_t *j2k);
6595 } opj_dec_mstabent_t;
6596
6597 opj_dec_mstabent_t j2k_dec_mstab[] = {
6598   {J2K_MS_SOC, J2K_STATE_MHSOC, j2k_read_soc},
6599   {J2K_MS_SOT, J2K_STATE_MH | J2K_STATE_TPHSOT, j2k_read_sot},
6600   {J2K_MS_SOD, J2K_STATE_TPH, j2k_read_sod},
6601   {J2K_MS_EOC, J2K_STATE_TPHSOT, j2k_read_eoc},
6602   {J2K_MS_SIZ, J2K_STATE_MHSIZ, j2k_read_siz},
6603   {J2K_MS_COD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_cod},
6604   {J2K_MS_COC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_coc},
6605   {J2K_MS_RGN, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_rgn},
6606   {J2K_MS_QCD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_qcd},
6607   {J2K_MS_QCC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_qcc},
6608   {J2K_MS_POC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_poc},
6609   {J2K_MS_TLM, J2K_STATE_MH, j2k_read_tlm},
6610   {J2K_MS_PLM, J2K_STATE_MH, j2k_read_plm},
6611   {J2K_MS_PLT, J2K_STATE_TPH, j2k_read_plt},
6612   {J2K_MS_PPM, J2K_STATE_MH, j2k_read_ppm},
6613   {J2K_MS_PPT, J2K_STATE_TPH, j2k_read_ppt},
6614   {J2K_MS_SOP, 0, 0},
6615   {J2K_MS_CRG, J2K_STATE_MH, j2k_read_crg},
6616   {J2K_MS_COM, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_com},
6617
6618 #ifdef USE_JPWL
6619   {J2K_MS_EPC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_epc},
6620   {J2K_MS_EPB, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_epb},
6621   {J2K_MS_ESD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_esd},
6622   {J2K_MS_RED, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_red},
6623 #endif /* USE_JPWL */
6624 #ifdef USE_JPSEC
6625   {J2K_MS_SEC, J2K_STATE_MH, j2k_read_sec},
6626   {J2K_MS_INSEC, 0, j2k_read_insec},
6627 #endif /* USE_JPSEC */
6628
6629   {0, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_unk}
6630 };
6631
6632 static void j2k_read_unk(opj_j2k_t *j2k) {
6633         opj_event_msg(j2k->cinfo, EVT_WARNING, "Unknown marker\n");
6634
6635 #ifdef USE_JPWL
6636         if (j2k->cp->correct) {
6637                 int m = 0, id, i;
6638                 int min_id = 0, min_dist = 17, cur_dist = 0, tmp_id;
6639                 cio_seek(j2k->cio, cio_tell(j2k->cio) - 2);
6640                 id = cio_read(j2k->cio, 2);
6641                 opj_event_msg(j2k->cinfo, EVT_ERROR,
6642                         "JPWL: really don't know this marker %x\n",
6643                         id);
6644                 if (!JPWL_ASSUME) {
6645                         opj_event_msg(j2k->cinfo, EVT_ERROR,
6646                                 "- possible synch loss due to uncorrectable codestream errors => giving up\n");
6647                         return;
6648                 }
6649                 /* OK, activate this at your own risk!!! */
6650                 /* we look for the marker at the minimum hamming distance from this */
6651                 while (j2k_dec_mstab[m].id) {
6652                         
6653                         /* 1's where they differ */
6654                         tmp_id = j2k_dec_mstab[m].id ^ id;
6655
6656                         /* compute the hamming distance between our id and the current */
6657                         cur_dist = 0;
6658                         for (i = 0; i < 16; i++) {
6659                                 if ((tmp_id >> i) & 0x0001) {
6660                                         cur_dist++;
6661                                 }
6662                         }
6663
6664                         /* if current distance is smaller, set the minimum */
6665                         if (cur_dist < min_dist) {
6666                                 min_dist = cur_dist;
6667                                 min_id = j2k_dec_mstab[m].id;
6668                         }
6669                         
6670                         /* jump to the next marker */
6671                         m++;
6672                 }
6673
6674                 /* do we substitute the marker? */
6675                 if (min_dist < JPWL_MAXIMUM_HAMMING) {
6676                         opj_event_msg(j2k->cinfo, EVT_ERROR,
6677                                 "- marker %x is at distance %d from the read %x\n",
6678                                 min_id, min_dist, id);
6679                         opj_event_msg(j2k->cinfo, EVT_ERROR,
6680                                 "- trying to substitute in place and crossing fingers!\n");
6681                         cio_seek(j2k->cio, cio_tell(j2k->cio) - 2);
6682                         cio_write(j2k->cio, min_id, 2);
6683
6684                         /* rewind */
6685                         cio_seek(j2k->cio, cio_tell(j2k->cio) - 2);
6686
6687                 }
6688
6689         };
6690 #endif /* USE_JPWL */
6691
6692 }
6693
6694 /**
6695  * Reads an unknown marker
6696  *
6697  * @param       p_stream                                the stream object to read from.
6698  * @param       p_j2k                   the jpeg2000 codec.
6699  * @param       p_manager               the user event manager.
6700  *
6701  * @return      true                    if the marker could be deduced.
6702 */
6703 opj_bool j2k_read_unk_v2 (      opj_j2k_v2_t *p_j2k,
6704                                                         struct opj_stream_private *p_stream,
6705                                                         OPJ_UINT32 *output_marker,
6706                                                         struct opj_event_mgr * p_manager
6707                                                         )
6708 {
6709         OPJ_UINT32 l_unknown_marker;
6710         const opj_dec_memory_marker_handler_t * l_marker_handler;
6711         OPJ_UINT32 l_size_unk = 2;
6712
6713         /* preconditions*/
6714         assert(p_j2k != 00);
6715         assert(p_manager != 00);
6716         assert(p_stream != 00);
6717
6718         opj_event_msg_v2(p_manager, EVT_WARNING, "Unknown marker\n");
6719
6720         while(1) {
6721                 /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer*/
6722                 if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
6723                         opj_event_msg_v2(p_manager, EVT_ERROR, "Stream too short\n");
6724                         return OPJ_FALSE;
6725                 }
6726
6727                 /* read 2 bytes as the new marker ID*/
6728                 opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_unknown_marker,2);
6729
6730                 if (!(l_unknown_marker < 0xff00)) {
6731
6732                         /* Get the marker handler from the marker ID*/
6733                         l_marker_handler = j2k_get_marker_handler(l_unknown_marker);
6734
6735                         if (!(p_j2k->m_specific_param.m_decoder.m_state & l_marker_handler->states)) {
6736                                 opj_event_msg_v2(p_manager, EVT_ERROR, "Marker is not compliant with its position\n");
6737                                 return OPJ_FALSE;
6738                         }
6739                         else {
6740                                 if (l_marker_handler->id != J2K_MS_UNK) {
6741                                         /* Add the marker to the codestream index*/
6742                                         if (l_marker_handler->id != J2K_MS_SOT)
6743                                                 j2k_add_mhmarker_v2(p_j2k->cstr_index, J2K_MS_UNK,
6744                                                                                         (OPJ_UINT32) opj_stream_tell(p_stream) - l_size_unk,
6745                                                                                         l_size_unk);
6746                                         break; /* next marker is known and well located */
6747                                 }
6748                                 else
6749                                         l_size_unk += 2;
6750                         }
6751                 }
6752         }
6753
6754         *output_marker = l_marker_handler->id ;
6755
6756         return OPJ_TRUE;
6757 }
6758
6759 /**
6760 Read the lookup table containing all the marker, status and action
6761 @param id Marker value
6762 */
6763 static opj_dec_mstabent_t *j2k_dec_mstab_lookup(int id) {
6764         opj_dec_mstabent_t *e;
6765         for (e = j2k_dec_mstab; e->id != 0; e++) {
6766                 if (e->id == id) {
6767                         break;
6768                 }
6769         }
6770         return e;
6771 }
6772
6773 /**
6774  * Writes the MCT marker (Multiple Component Transform)
6775  *
6776  * @param       p_stream                                the stream to write data to.
6777  * @param       p_j2k                           J2K codec.
6778  * @param       p_manager               the user event manager.
6779 */
6780 opj_bool j2k_write_mct_record(  opj_j2k_v2_t *p_j2k,
6781                                                                 opj_mct_data_t * p_mct_record,
6782                                                                 struct opj_stream_private *p_stream,
6783                                                                 struct opj_event_mgr * p_manager )
6784 {
6785         OPJ_UINT32 l_mct_size;
6786         OPJ_BYTE * l_current_data = 00;
6787         OPJ_UINT32 l_tmp;
6788
6789         /* preconditions */
6790         assert(p_j2k != 00);
6791         assert(p_manager != 00);
6792         assert(p_stream != 00);
6793
6794         l_mct_size = 10 + p_mct_record->m_data_size;
6795
6796         if (l_mct_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
6797                 p_j2k->m_specific_param.m_encoder.m_header_tile_data
6798                         = (OPJ_BYTE*)opj_realloc(
6799                                 p_j2k->m_specific_param.m_encoder.m_header_tile_data,
6800                                 l_mct_size);
6801
6802                 if (! p_j2k->m_specific_param.m_encoder.m_header_tile_data) {
6803                         return OPJ_FALSE;
6804                 }
6805
6806                 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_mct_size;
6807         }
6808
6809         l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
6810
6811         opj_write_bytes(l_current_data,J2K_MS_MCT,2);                                   /* MCT */
6812         l_current_data += 2;
6813
6814         opj_write_bytes(l_current_data,l_mct_size-2,2);                                 /* Lmct */
6815         l_current_data += 2;
6816
6817         opj_write_bytes(l_current_data,0,2);                                                    /* Zmct */
6818         l_current_data += 2;
6819
6820         /* only one marker atm */
6821         l_tmp = (p_mct_record->m_index & 0xff) | (p_mct_record->m_array_type << 8) | (p_mct_record->m_element_type << 10);
6822
6823         opj_write_bytes(l_current_data,l_tmp,2);
6824         l_current_data += 2;
6825
6826         opj_write_bytes(l_current_data,0,2);                                                    /* Ymct */
6827         l_current_data+=2;
6828
6829         memcpy(l_current_data,p_mct_record->m_data,p_mct_record->m_data_size);
6830
6831         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) {
6832                 return OPJ_FALSE;
6833         }
6834
6835         return OPJ_TRUE;
6836 }
6837
6838 /**
6839  * Reads a MCT marker (Multiple Component Transform)
6840  *
6841  * @param       p_header_data   the data contained in the MCT box.
6842  * @param       p_j2k                   the jpeg2000 codec.
6843  * @param       p_header_size   the size of the data contained in the MCT marker.
6844  * @param       p_manager               the user event manager.
6845 */
6846 opj_bool j2k_read_mct ( opj_j2k_v2_t *p_j2k,
6847                                                 OPJ_BYTE * p_header_data,
6848                                                 OPJ_UINT32 p_header_size,
6849                                                 struct opj_event_mgr * p_manager )
6850 {
6851         OPJ_UINT32 i;
6852         opj_tcp_v2_t *l_tcp = 00;
6853         OPJ_UINT32 l_tmp;
6854         OPJ_UINT32 l_indix;
6855         opj_mct_data_t * l_mct_data;
6856
6857         /* preconditions */
6858         assert(p_header_data != 00);
6859         assert(p_j2k != 00);
6860
6861         l_tcp = p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH ?
6862                         &p_j2k->m_cp.tcps[p_j2k->m_current_tile_number] :
6863                         p_j2k->m_specific_param.m_decoder.m_default_tcp;
6864
6865         if (p_header_size < 2) {
6866                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading MCT marker\n");
6867                 return OPJ_FALSE;
6868         }
6869
6870         /* first marker */
6871         opj_read_bytes(p_header_data,&l_tmp,2);                         /* Zmct */
6872         p_header_data += 2;
6873         if (l_tmp != 0) {
6874                 opj_event_msg_v2(p_manager, EVT_WARNING, "Cannot take in charge mct data within multiple MCT records\n");
6875                 return OPJ_TRUE;
6876         }
6877
6878         if(p_header_size <= 6) {
6879                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading MCT marker\n");
6880                 return OPJ_FALSE;
6881         }
6882
6883         /* Imct -> no need for other values, take the first, type is double with decorrelation x0000 1101 0000 0000*/
6884         opj_read_bytes(p_header_data,&l_tmp,2);                         /* Imct */
6885         p_header_data += 2;
6886
6887         l_indix = l_tmp & 0xff;
6888         l_mct_data = l_tcp->m_mct_records;
6889
6890         for (i=0;i<l_tcp->m_nb_mct_records;++i) {
6891                 if (l_mct_data->m_index == l_indix) {
6892                         break;
6893                 }
6894                 ++l_mct_data;
6895         }
6896
6897         /* NOT FOUND */
6898         if (i == l_tcp->m_nb_mct_records) {
6899                 if (l_tcp->m_nb_mct_records == l_tcp->m_nb_max_mct_records) {
6900                         l_tcp->m_nb_max_mct_records += J2K_MCT_DEFAULT_NB_RECORDS;
6901
6902                         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));
6903                         if(! l_tcp->m_mct_records) {
6904                                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading MCT marker\n");
6905                                 return OPJ_FALSE;
6906                         }
6907
6908                         l_mct_data = l_tcp->m_mct_records + l_tcp->m_nb_mct_records;
6909                         memset(l_mct_data ,0,(l_tcp->m_nb_max_mct_records - l_tcp->m_nb_mct_records) * sizeof(opj_mct_data_t));
6910                 }
6911
6912                 l_mct_data = l_tcp->m_mct_records + l_tcp->m_nb_mct_records;
6913         }
6914
6915         if (l_mct_data->m_data) {
6916                 opj_free(l_mct_data->m_data);
6917                 l_mct_data->m_data = 00;
6918         }
6919
6920         l_mct_data->m_index = l_indix;
6921         l_mct_data->m_array_type = (J2K_MCT_ARRAY_TYPE)((l_tmp  >> 8) & 3);
6922         l_mct_data->m_element_type = (J2K_MCT_ELEMENT_TYPE)((l_tmp  >> 10) & 3);
6923
6924         opj_read_bytes(p_header_data,&l_tmp,2);                         /* Ymct */
6925         p_header_data+=2;
6926         if (l_tmp != 0) {
6927                 opj_event_msg_v2(p_manager, EVT_WARNING, "Cannot take in charge multiple MCT markers\n");
6928                 return OPJ_TRUE;
6929         }
6930
6931         p_header_size -= 6;
6932
6933         l_mct_data->m_data = (OPJ_BYTE*)opj_malloc(p_header_size);
6934         if (! l_mct_data->m_data) {
6935                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading MCT marker\n");
6936                 return OPJ_FALSE;
6937         }
6938         memcpy(l_mct_data->m_data,p_header_data,p_header_size);
6939
6940         l_mct_data->m_data_size = p_header_size;
6941         ++l_tcp->m_nb_mct_records;
6942
6943         return OPJ_TRUE;
6944 }
6945
6946 /**
6947  * Writes the MCC marker (Multiple Component Collection)
6948  *
6949  * @param       p_stream                the stream to write data to.
6950  * @param       p_j2k                   J2K codec.
6951  * @param       p_manager               the user event manager.
6952 */
6953 opj_bool j2k_write_mcc_record(  opj_j2k_v2_t *p_j2k,
6954                                                                 struct opj_simple_mcc_decorrelation_data * p_mcc_record,
6955                                                                 struct opj_stream_private *p_stream,
6956                                                                 struct opj_event_mgr * p_manager )
6957 {
6958         OPJ_UINT32 i;
6959         OPJ_UINT32 l_mcc_size;
6960         OPJ_BYTE * l_current_data = 00;
6961         OPJ_UINT32 l_nb_bytes_for_comp;
6962         OPJ_UINT32 l_mask;
6963         OPJ_UINT32 l_tmcc;
6964
6965         /* preconditions */
6966         assert(p_j2k != 00);
6967         assert(p_manager != 00);
6968         assert(p_stream != 00);
6969
6970         if (p_mcc_record->m_nb_comps > 255 ) {
6971         l_nb_bytes_for_comp = 2;
6972                 l_mask = 0x8000;
6973         }
6974         else {
6975                 l_nb_bytes_for_comp = 1;
6976                 l_mask = 0;
6977         }
6978
6979         l_mcc_size = p_mcc_record->m_nb_comps * 2 * l_nb_bytes_for_comp + 19;
6980         if (l_mcc_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size)
6981         {
6982                 p_j2k->m_specific_param.m_encoder.m_header_tile_data
6983                         = (OPJ_BYTE*)opj_realloc(
6984                                 p_j2k->m_specific_param.m_encoder.m_header_tile_data,
6985                                 l_mcc_size);
6986                 if (! p_j2k->m_specific_param.m_encoder.m_header_tile_data) {
6987                         return OPJ_FALSE;
6988                 }
6989
6990                 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_mcc_size;
6991         }
6992
6993         l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
6994
6995         opj_write_bytes(l_current_data,J2K_MS_MCC,2);                                   /* MCC */
6996         l_current_data += 2;
6997
6998         opj_write_bytes(l_current_data,l_mcc_size-2,2);                                 /* Lmcc */
6999         l_current_data += 2;
7000
7001         /* first marker */
7002         opj_write_bytes(l_current_data,0,2);                                    /* Zmcc */
7003         l_current_data += 2;
7004
7005         opj_write_bytes(l_current_data,p_mcc_record->m_index,1);                                        /* Imcc -> no need for other values, take the first */
7006         ++l_current_data;
7007
7008         /* only one marker atm */
7009         opj_write_bytes(l_current_data,0,2);                                    /* Ymcc */
7010         l_current_data+=2;
7011
7012         opj_write_bytes(l_current_data,1,2);                                    /* Qmcc -> number of collections -> 1 */
7013         l_current_data+=2;
7014
7015         opj_write_bytes(l_current_data,0x1,1);                                  /* Xmcci type of component transformation -> array based decorrelation */
7016         ++l_current_data;
7017
7018         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 */
7019         l_current_data+=2;
7020
7021         for (i=0;i<p_mcc_record->m_nb_comps;++i) {
7022                 opj_write_bytes(l_current_data,i,l_nb_bytes_for_comp);                          /* Cmccij Component offset*/
7023                 l_current_data+=l_nb_bytes_for_comp;
7024         }
7025
7026         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 */
7027         l_current_data+=2;
7028
7029         for (i=0;i<p_mcc_record->m_nb_comps;++i)
7030         {
7031                 opj_write_bytes(l_current_data,i,l_nb_bytes_for_comp);                          /* Wmccij Component offset*/
7032                 l_current_data+=l_nb_bytes_for_comp;
7033         }
7034
7035         l_tmcc = ((!p_mcc_record->m_is_irreversible)&1)<<16;
7036
7037         if (p_mcc_record->m_decorrelation_array) {
7038                 l_tmcc |= p_mcc_record->m_decorrelation_array->m_index;
7039         }
7040
7041         if (p_mcc_record->m_offset_array) {
7042                 l_tmcc |= ((p_mcc_record->m_offset_array->m_index)<<8);
7043         }
7044
7045         opj_write_bytes(l_current_data,l_tmcc,3);       /* Tmcci : use MCT defined as number 1 and irreversible array based. */
7046         l_current_data+=3;
7047
7048         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) {
7049                 return OPJ_FALSE;
7050         }
7051
7052         return OPJ_TRUE;
7053 }
7054
7055 /**
7056  * Reads a MCC marker (Multiple Component Collection)
7057  *
7058  * @param       p_header_data   the data contained in the MCC box.
7059  * @param       p_j2k                   the jpeg2000 codec.
7060  * @param       p_header_size   the size of the data contained in the MCC marker.
7061  * @param       p_manager               the user event manager.
7062 */
7063 opj_bool j2k_read_mcc ( opj_j2k_v2_t *p_j2k,
7064                                         OPJ_BYTE * p_header_data,
7065                                         OPJ_UINT32 p_header_size,
7066                                         struct opj_event_mgr * p_manager )
7067 {
7068         OPJ_UINT32 i,j;
7069         OPJ_UINT32 l_tmp;
7070         OPJ_UINT32 l_indix;
7071         opj_tcp_v2_t * l_tcp;
7072         opj_simple_mcc_decorrelation_data_t * l_mcc_record;
7073         opj_mct_data_t * l_mct_data;
7074         OPJ_UINT32 l_nb_collections;
7075         OPJ_UINT32 l_nb_comps;
7076         OPJ_UINT32 l_nb_bytes_by_comp;
7077
7078
7079         /* preconditions */
7080         assert(p_header_data != 00);
7081         assert(p_j2k != 00);
7082         assert(p_manager != 00);
7083
7084         l_tcp = p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH ?
7085                         &p_j2k->m_cp.tcps[p_j2k->m_current_tile_number] :
7086                         p_j2k->m_specific_param.m_decoder.m_default_tcp;
7087
7088         if (p_header_size < 2) {
7089                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading MCC marker\n");
7090                 return OPJ_FALSE;
7091         }
7092
7093         /* first marker */
7094         opj_read_bytes(p_header_data,&l_tmp,2);                         /* Zmcc */
7095         p_header_data += 2;
7096         if (l_tmp != 0) {
7097                 opj_event_msg_v2(p_manager, EVT_WARNING, "Cannot take in charge multiple data spanning\n");
7098                 return OPJ_TRUE;
7099         }
7100
7101         if (p_header_size < 7) {
7102                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading MCC marker\n");
7103                 return OPJ_FALSE;
7104         }
7105
7106         opj_read_bytes(p_header_data,&l_indix,1); /* Imcc -> no need for other values, take the first */
7107         ++p_header_data;
7108
7109         l_mcc_record = l_tcp->m_mcc_records;
7110
7111         for(i=0;i<l_tcp->m_nb_mcc_records;++i) {
7112                 if (l_mcc_record->m_index == l_indix) {
7113                         break;
7114                 }
7115                 ++l_mcc_record;
7116         }
7117
7118         /** NOT FOUND */
7119         if (i == l_tcp->m_nb_mcc_records) {
7120                 if (l_tcp->m_nb_mcc_records == l_tcp->m_nb_max_mcc_records) {
7121                         l_tcp->m_nb_max_mcc_records += J2K_MCC_DEFAULT_NB_RECORDS;
7122
7123                         l_tcp->m_mcc_records = (opj_simple_mcc_decorrelation_data_t*)
7124                                         opj_realloc(l_tcp->m_mcc_records,l_tcp->m_nb_max_mcc_records * sizeof(opj_simple_mcc_decorrelation_data_t));
7125                         if (! l_tcp->m_mcc_records) {
7126                                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading MCC marker\n");
7127                                 return OPJ_FALSE;
7128                         }
7129                         l_mcc_record = l_tcp->m_mcc_records + l_tcp->m_nb_mcc_records;
7130                         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));
7131                 }
7132                 l_mcc_record = l_tcp->m_mcc_records + l_tcp->m_nb_mcc_records;
7133         }
7134         l_mcc_record->m_index = l_indix;
7135
7136         /* only one marker atm */
7137         opj_read_bytes(p_header_data,&l_tmp,2);                         /* Ymcc */
7138         p_header_data+=2;
7139         if (l_tmp != 0) {
7140                 opj_event_msg_v2(p_manager, EVT_WARNING, "Cannot take in charge multiple data spanning\n");
7141                 return OPJ_TRUE;
7142         }
7143
7144         opj_read_bytes(p_header_data,&l_nb_collections,2);                              /* Qmcc -> number of collections -> 1 */
7145         p_header_data+=2;
7146
7147         if (l_nb_collections > 1) {
7148                 opj_event_msg_v2(p_manager, EVT_WARNING, "Cannot take in charge multiple collections\n");
7149                 return OPJ_TRUE;
7150         }
7151
7152         p_header_size -= 7;
7153
7154         for (i=0;i<l_nb_collections;++i) {
7155                 if (p_header_size < 3) {
7156                         opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading MCC marker\n");
7157                         return OPJ_FALSE;
7158                 }
7159
7160                 opj_read_bytes(p_header_data,&l_tmp,1); /* Xmcci type of component transformation -> array based decorrelation */
7161                 ++p_header_data;
7162
7163                 if (l_tmp != 1) {
7164                         opj_event_msg_v2(p_manager, EVT_WARNING, "Cannot take in charge collections other than array decorrelation\n");
7165                         return OPJ_TRUE;
7166                 }
7167
7168                 opj_read_bytes(p_header_data,&l_nb_comps,2);
7169
7170                 p_header_data+=2;
7171                 p_header_size-=3;
7172
7173                 l_nb_bytes_by_comp = 1 + (l_nb_comps>>15);
7174                 l_mcc_record->m_nb_comps = l_nb_comps & 0x7fff;
7175
7176                 if (p_header_size < (l_nb_bytes_by_comp * l_mcc_record->m_nb_comps + 2)) {
7177                         opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading MCC marker\n");
7178                         return OPJ_FALSE;
7179                 }
7180
7181                 p_header_size -= (l_nb_bytes_by_comp * l_mcc_record->m_nb_comps + 2);
7182
7183                 for (j=0;j<l_mcc_record->m_nb_comps;++j) {
7184                         opj_read_bytes(p_header_data,&l_tmp,l_nb_bytes_by_comp);        /* Cmccij Component offset*/
7185                         p_header_data+=l_nb_bytes_by_comp;
7186
7187                         if (l_tmp != j) {
7188                                 opj_event_msg_v2(p_manager, EVT_WARNING, "Cannot take in charge collections with indix shuffle\n");
7189                                 return OPJ_TRUE;
7190                         }
7191                 }
7192
7193                 opj_read_bytes(p_header_data,&l_nb_comps,2);
7194                 p_header_data+=2;
7195
7196                 l_nb_bytes_by_comp = 1 + (l_nb_comps>>15);
7197                 l_nb_comps &= 0x7fff;
7198
7199                 if (l_nb_comps != l_mcc_record->m_nb_comps) {
7200                         opj_event_msg_v2(p_manager, EVT_WARNING, "Cannot take in charge collections without same number of indixes\n");
7201                         return OPJ_TRUE;
7202                 }
7203
7204                 if (p_header_size < (l_nb_bytes_by_comp * l_mcc_record->m_nb_comps + 3)) {
7205                         opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading MCC marker\n");
7206                         return OPJ_FALSE;
7207                 }
7208
7209                 p_header_size -= (l_nb_bytes_by_comp * l_mcc_record->m_nb_comps + 3);
7210
7211                 for (j=0;j<l_mcc_record->m_nb_comps;++j) {
7212                         opj_read_bytes(p_header_data,&l_tmp,l_nb_bytes_by_comp);        /* Wmccij Component offset*/
7213                         p_header_data+=l_nb_bytes_by_comp;
7214
7215                         if (l_tmp != j) {
7216                                 opj_event_msg_v2(p_manager, EVT_WARNING, "Cannot take in charge collections with indix shuffle\n");
7217                                 return OPJ_TRUE;
7218                         }
7219                 }
7220
7221                 opj_read_bytes(p_header_data,&l_tmp,3); /* Wmccij Component offset*/
7222                 p_header_data += 3;
7223
7224                 l_mcc_record->m_is_irreversible = ! ((l_tmp>>16) & 1);
7225                 l_mcc_record->m_decorrelation_array = 00;
7226                 l_mcc_record->m_offset_array = 00;
7227
7228                 l_indix = l_tmp & 0xff;
7229                 if (l_indix != 0) {
7230                         l_mct_data = l_tcp->m_mct_records;
7231                         for (j=0;j<l_tcp->m_nb_mct_records;++j) {
7232                                 if (l_mct_data->m_index == l_indix) {
7233                                         l_mcc_record->m_decorrelation_array = l_mct_data;
7234                                         break;
7235                                 }
7236                                 ++l_mct_data;
7237                         }
7238
7239                         if (l_mcc_record->m_decorrelation_array == 00) {
7240                                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading MCC marker\n");
7241                                 return OPJ_FALSE;
7242                         }
7243                 }
7244
7245                 l_indix = (l_tmp >> 8) & 0xff;
7246                 if (l_indix != 0) {
7247                         l_mct_data = l_tcp->m_mct_records;
7248                         for (j=0;j<l_tcp->m_nb_mct_records;++j) {
7249                                 if (l_mct_data->m_index == l_indix) {
7250                                         l_mcc_record->m_offset_array = l_mct_data;
7251                                         break;
7252                                 }
7253                                 ++l_mct_data;
7254                         }
7255
7256                         if (l_mcc_record->m_offset_array == 00) {
7257                                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading MCC marker\n");
7258                                 return OPJ_FALSE;
7259                         }
7260                 }
7261         }
7262
7263         if (p_header_size != 0) {
7264                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading MCC marker\n");
7265                 return OPJ_FALSE;
7266         }
7267
7268         ++l_tcp->m_nb_mcc_records;
7269
7270         return OPJ_TRUE;
7271 }
7272
7273
7274 /**
7275  * Writes the MCO marker (Multiple component transformation ordering)
7276  *
7277  * @param       p_stream                                the stream to write data to.
7278  * @param       p_j2k                           J2K codec.
7279  * @param       p_manager               the user event manager.
7280 */
7281 opj_bool j2k_write_mco( opj_j2k_v2_t *p_j2k,
7282                                                 struct opj_stream_private *p_stream,
7283                                                 struct opj_event_mgr * p_manager
7284                                   )
7285 {
7286         OPJ_BYTE * l_current_data = 00;
7287         OPJ_UINT32 l_mco_size;
7288         opj_tcp_v2_t * l_tcp = 00;
7289         opj_simple_mcc_decorrelation_data_t * l_mcc_record;
7290         OPJ_UINT32 i;
7291
7292         /* preconditions */
7293         assert(p_j2k != 00);
7294         assert(p_manager != 00);
7295         assert(p_stream != 00);
7296
7297         l_tcp =&(p_j2k->m_cp.tcps[p_j2k->m_current_tile_number]);
7298         l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
7299
7300         l_mco_size = 5 + l_tcp->m_nb_mcc_records;
7301         if (l_mco_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
7302
7303                 p_j2k->m_specific_param.m_encoder.m_header_tile_data
7304                         = (OPJ_BYTE*)opj_realloc(
7305                                 p_j2k->m_specific_param.m_encoder.m_header_tile_data,
7306                                 l_mco_size);
7307                 if (! p_j2k->m_specific_param.m_encoder.m_header_tile_data)
7308                 {
7309                         return OPJ_FALSE;
7310                 }
7311
7312                 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_mco_size;
7313         }
7314
7315         opj_write_bytes(l_current_data,J2K_MS_MCO,2);                   /* MCO */
7316         l_current_data += 2;
7317
7318         opj_write_bytes(l_current_data,l_mco_size-2,2);                                 /* Lmco */
7319         l_current_data += 2;
7320
7321         opj_write_bytes(l_current_data,l_tcp->m_nb_mcc_records,1);                                      /* Nmco : only one tranform stage*/
7322         ++l_current_data;
7323
7324         l_mcc_record = l_tcp->m_mcc_records;
7325         for     (i=0;i<l_tcp->m_nb_mcc_records;++i) {
7326                 opj_write_bytes(l_current_data,l_mcc_record->m_index,1);                                        /* Imco -> use the mcc indicated by 1*/
7327                 ++l_current_data;
7328
7329                 ++l_mcc_record;
7330         }
7331
7332         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) {
7333                 return OPJ_FALSE;
7334         }
7335
7336         return OPJ_TRUE;
7337 }
7338
7339 /**
7340  * Reads a MCO marker (Multiple Component Transform Ordering)
7341  *
7342  * @param       p_header_data   the data contained in the MCO box.
7343  * @param       p_j2k                   the jpeg2000 codec.
7344  * @param       p_header_size   the size of the data contained in the MCO marker.
7345  * @param       p_manager               the user event manager.
7346 */
7347 opj_bool j2k_read_mco ( opj_j2k_v2_t *p_j2k,
7348                                                 OPJ_BYTE * p_header_data,
7349                                                 OPJ_UINT32 p_header_size,
7350                                                 struct opj_event_mgr * p_manager )
7351 {
7352         OPJ_UINT32 l_tmp, i;
7353         OPJ_UINT32 l_nb_stages;
7354         opj_tcp_v2_t * l_tcp;
7355         opj_tccp_t * l_tccp;
7356         opj_image_t * l_image;
7357         opj_image_comp_t * l_img_comp;
7358
7359         /* preconditions */
7360         assert(p_header_data != 00);
7361         assert(p_j2k != 00);
7362         assert(p_manager != 00);
7363
7364         l_image = p_j2k->m_private_image;
7365         l_tcp = p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH ?
7366                         &p_j2k->m_cp.tcps[p_j2k->m_current_tile_number] :
7367                         p_j2k->m_specific_param.m_decoder.m_default_tcp;
7368
7369         if (p_header_size < 1) {
7370                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading MCO marker\n");
7371                 return OPJ_FALSE;
7372         }
7373
7374         opj_read_bytes(p_header_data,&l_nb_stages,1);                           /* Nmco : only one tranform stage*/
7375         ++p_header_data;
7376
7377         if (l_nb_stages > 1) {
7378                 opj_event_msg_v2(p_manager, EVT_WARNING, "Cannot take in charge multiple transformation stages.\n");
7379                 return OPJ_TRUE;
7380         }
7381
7382         if (p_header_size != l_nb_stages + 1) {
7383                 opj_event_msg_v2(p_manager, EVT_WARNING, "Error reading MCO marker\n");
7384                 return OPJ_FALSE;
7385         }
7386
7387         l_tccp = l_tcp->tccps;
7388         l_img_comp = l_image->comps;
7389
7390         for (i=0;i<l_image->numcomps;++i) {
7391                 l_tccp->m_dc_level_shift = 0;
7392                 ++l_tccp;
7393         }
7394
7395         if (l_tcp->m_mct_decoding_matrix) {
7396                 opj_free(l_tcp->m_mct_decoding_matrix);
7397                 l_tcp->m_mct_decoding_matrix = 00;
7398         }
7399
7400         for (i=0;i<l_nb_stages;++i) {
7401                 opj_read_bytes(p_header_data,&l_tmp,1);
7402                 ++p_header_data;
7403
7404                 if (! j2k_add_mct(l_tcp,p_j2k->m_private_image,l_tmp)) {
7405                         return OPJ_FALSE;
7406                 }
7407         }
7408
7409         return OPJ_TRUE;
7410 }
7411
7412 opj_bool j2k_add_mct(opj_tcp_v2_t * p_tcp, opj_image_t * p_image, OPJ_UINT32 p_index)
7413 {
7414         OPJ_UINT32 i;
7415         opj_simple_mcc_decorrelation_data_t * l_mcc_record;
7416         opj_mct_data_t * l_deco_array, * l_offset_array;
7417         OPJ_UINT32 l_data_size,l_mct_size, l_offset_size;
7418         OPJ_UINT32 l_nb_elem;
7419         OPJ_UINT32 * l_offset_data, * l_current_offset_data;
7420         opj_tccp_t * l_tccp;
7421
7422         /* preconditions */
7423         assert(p_tcp != 00);
7424
7425         l_mcc_record = p_tcp->m_mcc_records;
7426
7427         for (i=0;i<p_tcp->m_nb_mcc_records;++i) {
7428                 if (l_mcc_record->m_index == p_index) {
7429                         break;
7430                 }
7431         }
7432
7433         if (i==p_tcp->m_nb_mcc_records) {
7434                 /** element discarded **/
7435                 return OPJ_TRUE;
7436         }
7437
7438         if (l_mcc_record->m_nb_comps != p_image->numcomps) {
7439                 /** do not support number of comps != image */
7440                 return OPJ_TRUE;
7441         }
7442
7443         l_deco_array = l_mcc_record->m_decorrelation_array;
7444
7445         if (l_deco_array) {
7446                 l_data_size = MCT_ELEMENT_SIZE[l_deco_array->m_element_type] * p_image->numcomps * p_image->numcomps;
7447                 if (l_deco_array->m_data_size != l_data_size) {
7448                         return OPJ_FALSE;
7449                 }
7450
7451                 l_nb_elem = p_image->numcomps * p_image->numcomps;
7452                 l_mct_size = l_nb_elem * sizeof(OPJ_FLOAT32);
7453                 p_tcp->m_mct_decoding_matrix = (OPJ_FLOAT32*)opj_malloc(l_mct_size);
7454
7455                 if (! p_tcp->m_mct_decoding_matrix ) {
7456                         return OPJ_FALSE;
7457                 }
7458
7459                 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);
7460         }
7461
7462         l_offset_array = l_mcc_record->m_offset_array;
7463
7464         if (l_offset_array) {
7465                 l_data_size = MCT_ELEMENT_SIZE[l_offset_array->m_element_type] * p_image->numcomps;
7466                 if (l_offset_array->m_data_size != l_data_size) {
7467                         return OPJ_FALSE;
7468                 }
7469
7470                 l_nb_elem = p_image->numcomps;
7471                 l_offset_size = l_nb_elem * sizeof(OPJ_UINT32);
7472                 l_offset_data = (OPJ_UINT32*)opj_malloc(l_offset_size);
7473
7474                 if (! l_offset_data ) {
7475                         return OPJ_FALSE;
7476                 }
7477
7478                 j2k_mct_read_functions_to_int32[l_offset_array->m_element_type](l_offset_array->m_data,l_offset_data,l_nb_elem);
7479
7480                 l_tccp = p_tcp->tccps;
7481                 l_current_offset_data = l_offset_data;
7482
7483                 for (i=0;i<p_image->numcomps;++i) {
7484                         l_tccp->m_dc_level_shift = *(l_current_offset_data++);
7485                         ++l_tccp;
7486                 }
7487
7488                 opj_free(l_offset_data);
7489         }
7490
7491         return OPJ_TRUE;
7492 }
7493
7494 /**
7495  * Writes the CBD marker (Component bit depth definition)
7496  *
7497  * @param       p_stream                                the stream to write data to.
7498  * @param       p_j2k                           J2K codec.
7499  * @param       p_manager               the user event manager.
7500 */
7501 opj_bool j2k_write_cbd( opj_j2k_v2_t *p_j2k,
7502                                                 struct opj_stream_private *p_stream,
7503                                                 struct opj_event_mgr * p_manager )
7504 {
7505         OPJ_UINT32 i;
7506         OPJ_UINT32 l_cbd_size;
7507         OPJ_BYTE * l_current_data = 00;
7508         opj_image_t *l_image = 00;
7509         opj_image_comp_t * l_comp = 00;
7510
7511         /* preconditions */
7512         assert(p_j2k != 00);
7513         assert(p_manager != 00);
7514         assert(p_stream != 00);
7515
7516         l_image = p_j2k->m_private_image;
7517         l_cbd_size = 6 + p_j2k->m_private_image->numcomps;
7518
7519         if (l_cbd_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
7520                 p_j2k->m_specific_param.m_encoder.m_header_tile_data
7521                         = (OPJ_BYTE*)opj_realloc(
7522                                 p_j2k->m_specific_param.m_encoder.m_header_tile_data,
7523                                 l_cbd_size);
7524
7525                 if (! p_j2k->m_specific_param.m_encoder.m_header_tile_data) {
7526                         return OPJ_FALSE;
7527                 }
7528
7529                 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_cbd_size;
7530         }
7531
7532         l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
7533
7534         opj_write_bytes(l_current_data,J2K_MS_CBD,2);                                   /* CBD */
7535         l_current_data += 2;
7536
7537         opj_write_bytes(l_current_data,l_cbd_size-2,2);                                 /* L_CBD */
7538         l_current_data += 2;
7539
7540         opj_write_bytes(l_current_data,l_image->numcomps, 2);           /* Ncbd */
7541         l_current_data+=2;
7542
7543         l_comp = l_image->comps;
7544
7545         for (i=0;i<l_image->numcomps;++i) {
7546                 opj_write_bytes(l_current_data, (l_comp->sgnd << 7) | (l_comp->prec - 1), 1);           /* Component bit depth */
7547                 ++l_current_data;
7548
7549                 ++l_comp;
7550         }
7551
7552         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) {
7553                 return OPJ_FALSE;
7554         }
7555
7556         return OPJ_TRUE;
7557 }
7558
7559 /**
7560  * Reads a CBD marker (Component bit depth definition)
7561  * @param       p_header_data   the data contained in the CBD box.
7562  * @param       p_j2k                   the jpeg2000 codec.
7563  * @param       p_header_size   the size of the data contained in the CBD marker.
7564  * @param       p_manager               the user event manager.
7565 */
7566 opj_bool j2k_read_cbd ( opj_j2k_v2_t *p_j2k,
7567                                                 OPJ_BYTE * p_header_data,
7568                                                 OPJ_UINT32 p_header_size,
7569                                                 struct opj_event_mgr * p_manager)
7570 {
7571         OPJ_UINT32 l_nb_comp,l_num_comp;
7572         OPJ_UINT32 l_comp_def;
7573         OPJ_UINT32 i;
7574         opj_image_comp_t * l_comp = 00;
7575
7576         /* preconditions */
7577         assert(p_header_data != 00);
7578         assert(p_j2k != 00);
7579         assert(p_manager != 00);
7580
7581         l_num_comp = p_j2k->m_private_image->numcomps;
7582
7583         if (p_header_size != (p_j2k->m_private_image->numcomps + 2)) {
7584                 opj_event_msg_v2(p_manager, EVT_ERROR, "Crror reading CBD marker\n");
7585                 return OPJ_FALSE;
7586         }
7587
7588         opj_read_bytes(p_header_data,&l_nb_comp,2);                             /* Ncbd */
7589         p_header_data+=2;
7590
7591         if (l_nb_comp != l_num_comp) {
7592                 opj_event_msg_v2(p_manager, EVT_ERROR, "Crror reading CBD marker\n");
7593                 return OPJ_FALSE;
7594         }
7595
7596         l_comp = p_j2k->m_private_image->comps;
7597         for (i=0;i<l_num_comp;++i) {
7598                 opj_read_bytes(p_header_data,&l_comp_def,1);                    /* Component bit depth */
7599                 ++p_header_data;
7600         l_comp->sgnd = (l_comp_def>>7) & 1;
7601                 l_comp->prec = (l_comp_def&0x7f) + 1;
7602                 ++l_comp;
7603         }
7604
7605         return OPJ_TRUE;
7606 }
7607
7608
7609 /* ----------------------------------------------------------------------- */
7610 /* J2K / JPT decoder interface                                             */
7611 /* ----------------------------------------------------------------------- */
7612
7613 opj_j2k_t* j2k_create_decompress(opj_common_ptr cinfo) {
7614         opj_j2k_t *j2k = (opj_j2k_t*) opj_calloc(1, sizeof(opj_j2k_t));
7615         if(!j2k)
7616                 return NULL;
7617
7618         j2k->default_tcp = (opj_tcp_t*) opj_calloc(1, sizeof(opj_tcp_t));
7619         if(!j2k->default_tcp) {
7620                 opj_free(j2k);
7621                 return NULL;
7622         }
7623
7624         j2k->cinfo = cinfo;
7625         j2k->tile_data = NULL;
7626
7627         return j2k;
7628 }
7629
7630 void j2k_destroy_decompress(opj_j2k_t *j2k) {
7631         int i = 0;
7632
7633         if(j2k->tile_len != NULL) {
7634                 opj_free(j2k->tile_len);
7635         }
7636         if(j2k->tile_data != NULL) {
7637                 opj_free(j2k->tile_data);
7638         }
7639         if(j2k->default_tcp != NULL) {
7640                 opj_tcp_t *default_tcp = j2k->default_tcp;
7641                 if(default_tcp->ppt_data_first != NULL) {
7642                         opj_free(default_tcp->ppt_data_first);
7643                 }
7644                 if(j2k->default_tcp->tccps != NULL) {
7645                         opj_free(j2k->default_tcp->tccps);
7646                 }
7647                 opj_free(j2k->default_tcp);
7648         }
7649         if(j2k->cp != NULL) {
7650                 opj_cp_t *cp = j2k->cp;
7651                 if(cp->tcps != NULL) {
7652                         for(i = 0; i < cp->tw * cp->th; i++) {
7653                                 if(cp->tcps[i].ppt_data_first != NULL) {
7654                                         opj_free(cp->tcps[i].ppt_data_first);
7655                                 }
7656                                 if(cp->tcps[i].tccps != NULL) {
7657                                         opj_free(cp->tcps[i].tccps);
7658                                 }
7659                         }
7660                         opj_free(cp->tcps);
7661                 }
7662                 if(cp->ppm_data_first != NULL) {
7663                         opj_free(cp->ppm_data_first);
7664                 }
7665                 if(cp->tileno != NULL) {
7666                         opj_free(cp->tileno);  
7667                 }
7668                 if(cp->comment != NULL) {
7669                         opj_free(cp->comment);
7670                 }
7671
7672                 opj_free(cp);
7673         }
7674         opj_free(j2k);
7675 }
7676
7677 void j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters) {
7678         if(j2k && parameters) {
7679                 /* create and initialize the coding parameters structure */
7680                 opj_cp_t *cp = (opj_cp_t*) opj_calloc(1, sizeof(opj_cp_t));
7681                 cp->reduce = parameters->cp_reduce;     
7682                 cp->layer = parameters->cp_layer;
7683                 cp->limit_decoding = parameters->cp_limit_decoding;
7684
7685 #ifdef USE_JPWL
7686                 cp->correct = parameters->jpwl_correct;
7687                 cp->exp_comps = parameters->jpwl_exp_comps;
7688                 cp->max_tiles = parameters->jpwl_max_tiles;
7689 #endif /* USE_JPWL */
7690
7691
7692                 /* keep a link to cp so that we can destroy it later in j2k_destroy_decompress */
7693                 j2k->cp = cp;
7694         }
7695 }
7696
7697 void j2k_setup_decoder_v2(opj_j2k_v2_t *j2k, opj_dparameters_t *parameters)
7698 {
7699         if(j2k && parameters) {
7700                 j2k->m_cp.m_specific_param.m_dec.m_layer = parameters->cp_layer;
7701                 j2k->m_cp.m_specific_param.m_dec.m_reduce = parameters->cp_reduce;
7702
7703 #ifdef USE_JPWL
7704                 j2k->m_cp.correct = parameters->jpwl_correct;
7705                 j2k->m_cp.exp_comps = parameters->jpwl_exp_comps;
7706                 j2k->m_cp.max_tiles = parameters->jpwl_max_tiles;
7707 #endif /* USE_JPWL */
7708         }
7709 }
7710
7711 opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *cstr_info) {
7712         opj_image_t *image = NULL;
7713
7714         opj_common_ptr cinfo = j2k->cinfo;      
7715
7716         j2k->cio = cio;
7717         j2k->cstr_info = cstr_info;
7718         if (cstr_info)
7719                 memset(cstr_info, 0, sizeof(opj_codestream_info_t));
7720
7721         /* create an empty image */
7722         image = opj_image_create0();
7723         j2k->image = image;
7724
7725         j2k->state = J2K_STATE_MHSOC;
7726
7727         for (;;) {
7728                 opj_dec_mstabent_t *e;
7729                 int id = cio_read(cio, 2);
7730
7731 #ifdef USE_JPWL
7732                 /* we try to honor JPWL correction power */
7733                 if (j2k->cp->correct) {
7734
7735                         int orig_pos = cio_tell(cio);
7736                         opj_bool status;
7737
7738                         /* call the corrector */
7739                         status = jpwl_correct(j2k);
7740
7741                         /* go back to where you were */
7742                         cio_seek(cio, orig_pos - 2);
7743
7744                         /* re-read the marker */
7745                         id = cio_read(cio, 2);
7746
7747                         /* check whether it begins with ff */
7748                         if (id >> 8 != 0xff) {
7749                                 opj_event_msg(cinfo, EVT_ERROR,
7750                                         "JPWL: possible bad marker %x at %d\n",
7751                                         id, cio_tell(cio) - 2);
7752                                 if (!JPWL_ASSUME) {
7753                                         opj_image_destroy(image);
7754                                         opj_event_msg(cinfo, EVT_ERROR, "JPWL: giving up\n");
7755                                         return 0;
7756                                 }
7757                                 /* we try to correct */
7758                                 id = id | 0xff00;
7759                                 cio_seek(cio, cio_tell(cio) - 2);
7760                                 cio_write(cio, id, 2);
7761                                 opj_event_msg(cinfo, EVT_WARNING, "- trying to adjust this\n"
7762                                         "- setting marker to %x\n",
7763                                         id);
7764                         }
7765
7766                 }
7767 #endif /* USE_JPWL */
7768
7769                 if (id >> 8 != 0xff) {
7770                         opj_image_destroy(image);
7771                         opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
7772                         return 0;
7773                 }
7774                 e = j2k_dec_mstab_lookup(id);
7775                 /* Check if the marker is known*/
7776                 if (!(j2k->state & e->states)) {
7777                         opj_image_destroy(image);
7778                         opj_event_msg(cinfo, EVT_ERROR, "%.8x: unexpected marker %x\n", cio_tell(cio) - 2, id);
7779                         return 0;
7780                 }
7781                 /* Check if the decoding is limited to the main header*/
7782                 if (e->id == J2K_MS_SOT && j2k->cp->limit_decoding == LIMIT_TO_MAIN_HEADER) {
7783                         opj_event_msg(cinfo, EVT_INFO, "Main Header decoded.\n");
7784                         return image;
7785                 }               
7786
7787                 if (e->handler) {
7788                         (*e->handler)(j2k);
7789                 }
7790                 if (j2k->state & J2K_STATE_ERR) 
7791                         return NULL;    
7792
7793                 if (j2k->state == J2K_STATE_MT) {
7794                         break;
7795                 }
7796                 if (j2k->state == J2K_STATE_NEOC) {
7797                         break;
7798                 }
7799         }
7800         if (j2k->state == J2K_STATE_NEOC) {
7801                 j2k_read_eoc(j2k);
7802         }
7803
7804         if (j2k->state != J2K_STATE_MT) {
7805                 opj_event_msg(cinfo, EVT_WARNING, "Incomplete bitstream\n");
7806         }
7807         return image;
7808 }
7809
7810 /*
7811 * Read a JPT-stream and decode file
7812 *
7813 */
7814 opj_image_t* j2k_decode_jpt_stream(opj_j2k_t *j2k, opj_cio_t *cio,  opj_codestream_info_t *cstr_info) {
7815         opj_image_t *image = NULL;
7816         opj_jpt_msg_header_t header;
7817         int position;
7818         opj_common_ptr cinfo = j2k->cinfo;
7819
7820         OPJ_ARG_NOT_USED(cstr_info);
7821
7822         j2k->cio = cio;
7823
7824         /* create an empty image */
7825         image = opj_image_create0();
7826         j2k->image = image;
7827
7828         j2k->state = J2K_STATE_MHSOC;
7829         
7830         /* Initialize the header */
7831         jpt_init_msg_header(&header);
7832         /* Read the first header of the message */
7833         jpt_read_msg_header(cinfo, cio, &header);
7834         
7835         position = cio_tell(cio);
7836         if (header.Class_Id != 6) {     /* 6 : Main header data-bin message */
7837                 opj_image_destroy(image);
7838                 opj_event_msg(cinfo, EVT_ERROR, "[JPT-stream] : Expecting Main header first [class_Id %d] !\n", header.Class_Id);
7839                 return 0;
7840         }
7841         
7842         for (;;) {
7843                 opj_dec_mstabent_t *e = NULL;
7844                 int id;
7845                 
7846                 if (!cio_numbytesleft(cio)) {
7847                         j2k_read_eoc(j2k);
7848                         return image;
7849                 }
7850                 /* data-bin read -> need to read a new header */
7851                 if ((unsigned int) (cio_tell(cio) - position) == header.Msg_length) {
7852                         jpt_read_msg_header(cinfo, cio, &header);
7853                         position = cio_tell(cio);
7854                         if (header.Class_Id != 4) {     /* 4 : Tile data-bin message */
7855                                 opj_image_destroy(image);
7856                                 opj_event_msg(cinfo, EVT_ERROR, "[JPT-stream] : Expecting Tile info !\n");
7857                                 return 0;
7858                         }
7859                 }
7860                 
7861                 id = cio_read(cio, 2);
7862                 if (id >> 8 != 0xff) {
7863                         opj_image_destroy(image);
7864                         opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
7865                         return 0;
7866                 }
7867                 e = j2k_dec_mstab_lookup(id);
7868                 if (!(j2k->state & e->states)) {
7869                         opj_image_destroy(image);
7870                         opj_event_msg(cinfo, EVT_ERROR, "%.8x: unexpected marker %x\n", cio_tell(cio) - 2, id);
7871                         return 0;
7872                 }
7873                 if (e->handler) {
7874                         (*e->handler)(j2k);
7875                 }
7876                 if (j2k->state == J2K_STATE_MT) {
7877                         break;
7878                 }
7879                 if (j2k->state == J2K_STATE_NEOC) {
7880                         break;
7881                 }
7882         }
7883         if (j2k->state == J2K_STATE_NEOC) {
7884                 j2k_read_eoc(j2k);
7885         }
7886         
7887         if (j2k->state != J2K_STATE_MT) {
7888                 opj_event_msg(cinfo, EVT_WARNING, "Incomplete bitstream\n");
7889         }
7890
7891         return image;
7892 }
7893
7894 /* ----------------------------------------------------------------------- */
7895 /* J2K encoder interface                                                       */
7896 /* ----------------------------------------------------------------------- */
7897
7898 opj_j2k_t* j2k_create_compress(opj_common_ptr cinfo) {
7899         opj_j2k_t *j2k = (opj_j2k_t*) opj_calloc(1, sizeof(opj_j2k_t));
7900         if(j2k) {
7901                 j2k->cinfo = cinfo;
7902         }
7903         return j2k;
7904 }
7905
7906 opj_j2k_v2_t* j2k_create_compress_v2(void)
7907 {
7908         opj_j2k_v2_t *l_j2k = (opj_j2k_v2_t*) opj_malloc(sizeof(opj_j2k_v2_t));
7909         if (!l_j2k) {
7910                 return NULL;
7911         }
7912
7913         memset(l_j2k,0,sizeof(opj_j2k_v2_t));
7914
7915         l_j2k->m_is_decoder = 0;
7916         l_j2k->m_cp.m_is_decoder = 0;
7917
7918         l_j2k->m_specific_param.m_encoder.m_header_tile_data = (OPJ_BYTE *) opj_malloc(J2K_DEFAULT_HEADER_SIZE);
7919         if (! l_j2k->m_specific_param.m_encoder.m_header_tile_data) {
7920                 j2k_destroy(l_j2k);
7921                 return NULL;
7922         }
7923
7924         l_j2k->m_specific_param.m_encoder.m_header_tile_data_size = J2K_DEFAULT_HEADER_SIZE;
7925
7926         /* validation list creation*/
7927         l_j2k->m_validation_list = opj_procedure_list_create();
7928         if (! l_j2k->m_validation_list) {
7929                 j2k_destroy(l_j2k);
7930                 return NULL;
7931         }
7932
7933         /* execution list creation*/
7934         l_j2k->m_procedure_list = opj_procedure_list_create();
7935         if (! l_j2k->m_procedure_list) {
7936                 j2k_destroy(l_j2k);
7937                 return NULL;
7938         }
7939
7940         return l_j2k;
7941 }
7942
7943 void j2k_destroy_compress(opj_j2k_t *j2k) {
7944         int tileno;
7945
7946         if(!j2k) return;
7947         if(j2k->cp != NULL) {
7948                 opj_cp_t *cp = j2k->cp;
7949
7950                 if(cp->comment) {
7951                         opj_free(cp->comment);
7952                 }
7953                 if(cp->matrice) {
7954                         opj_free(cp->matrice);
7955                 }
7956                 for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
7957                         opj_free(cp->tcps[tileno].tccps);
7958                 }
7959                 opj_free(cp->tcps);
7960                 opj_free(cp);
7961         }
7962
7963         opj_free(j2k);
7964 }
7965
7966 void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_t *image) {
7967         OPJ_UINT32 i,j;
7968   int tileno, numpocs_tile;
7969         opj_cp_t *cp = NULL;
7970
7971         if(!j2k || !parameters || ! image) {
7972                 return;
7973         }
7974
7975         /* create and initialize the coding parameters structure */
7976         cp = (opj_cp_t*) opj_calloc(1, sizeof(opj_cp_t));
7977
7978         /* keep a link to cp so that we can destroy it later in j2k_destroy_compress */
7979         j2k->cp = cp;
7980
7981         /* set default values for cp */
7982         cp->tw = 1;
7983         cp->th = 1;
7984
7985         /* 
7986         copy user encoding parameters 
7987         */
7988         cp->cinema = parameters->cp_cinema;
7989         cp->max_comp_size =     parameters->max_comp_size;
7990         cp->rsiz   = parameters->cp_rsiz;
7991         cp->disto_alloc = parameters->cp_disto_alloc;
7992         cp->fixed_alloc = parameters->cp_fixed_alloc;
7993         cp->fixed_quality = parameters->cp_fixed_quality;
7994
7995         /* mod fixed_quality */
7996         if(parameters->cp_matrice) {
7997                 size_t array_size = parameters->tcp_numlayers * parameters->numresolution * 3 * sizeof(int);
7998                 cp->matrice = (int *) opj_malloc(array_size);
7999                 memcpy(cp->matrice, parameters->cp_matrice, array_size);
8000         }
8001
8002         /* tiles */
8003         cp->tdx = parameters->cp_tdx;
8004         cp->tdy = parameters->cp_tdy;
8005
8006         /* tile offset */
8007         cp->tx0 = parameters->cp_tx0;
8008         cp->ty0 = parameters->cp_ty0;
8009
8010         /* comment string */
8011         if(parameters->cp_comment) {
8012                 cp->comment = (char*)opj_malloc(strlen(parameters->cp_comment) + 1);
8013                 if(cp->comment) {
8014                         strcpy(cp->comment, parameters->cp_comment);
8015                 }
8016         }
8017
8018         /*
8019         calculate other encoding parameters
8020         */
8021
8022         if (parameters->tile_size_on) {
8023                 cp->tw = int_ceildiv(image->x1 - cp->tx0, cp->tdx);
8024                 cp->th = int_ceildiv(image->y1 - cp->ty0, cp->tdy);
8025         } else {
8026                 cp->tdx = image->x1 - cp->tx0;
8027                 cp->tdy = image->y1 - cp->ty0;
8028         }
8029
8030         if(parameters->tp_on){
8031                 cp->tp_flag = parameters->tp_flag;
8032                 cp->tp_on = 1;
8033         }
8034         
8035         cp->img_size = 0;
8036         for(i=0;i<image->numcomps ;i++){
8037         cp->img_size += (image->comps[i].w *image->comps[i].h * image->comps[i].prec);
8038         }
8039
8040
8041 #ifdef USE_JPWL
8042         /*
8043         calculate JPWL encoding parameters
8044         */
8045
8046         if (parameters->jpwl_epc_on) {
8047                 OPJ_UINT32 i;
8048
8049                 /* set JPWL on */
8050                 cp->epc_on = OPJ_TRUE;
8051                 cp->info_on = OPJ_FALSE; /* no informative technique */
8052
8053                 /* set EPB on */
8054                 if ((parameters->jpwl_hprot_MH > 0) || (parameters->jpwl_hprot_TPH[0] > 0)) {
8055                         cp->epb_on = OPJ_TRUE;
8056                         
8057                         cp->hprot_MH = parameters->jpwl_hprot_MH;
8058                         for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) {
8059                                 cp->hprot_TPH_tileno[i] = parameters->jpwl_hprot_TPH_tileno[i];
8060                                 cp->hprot_TPH[i] = parameters->jpwl_hprot_TPH[i];
8061                         }
8062                         /* if tile specs are not specified, copy MH specs */
8063                         if (cp->hprot_TPH[0] == -1) {
8064                                 cp->hprot_TPH_tileno[0] = 0;
8065                                 cp->hprot_TPH[0] = parameters->jpwl_hprot_MH;
8066                         }
8067                         for (i = 0; i < JPWL_MAX_NO_PACKSPECS; i++) {
8068                                 cp->pprot_tileno[i] = parameters->jpwl_pprot_tileno[i];
8069                                 cp->pprot_packno[i] = parameters->jpwl_pprot_packno[i];
8070                                 cp->pprot[i] = parameters->jpwl_pprot[i];
8071                         }
8072                 }
8073
8074                 /* set ESD writing */
8075                 if ((parameters->jpwl_sens_size == 1) || (parameters->jpwl_sens_size == 2)) {
8076                         cp->esd_on = OPJ_TRUE;
8077
8078                         cp->sens_size = parameters->jpwl_sens_size;
8079                         cp->sens_addr = parameters->jpwl_sens_addr;
8080                         cp->sens_range = parameters->jpwl_sens_range;
8081
8082                         cp->sens_MH = parameters->jpwl_sens_MH;
8083                         for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) {
8084                                 cp->sens_TPH_tileno[i] = parameters->jpwl_sens_TPH_tileno[i];
8085                                 cp->sens_TPH[i] = parameters->jpwl_sens_TPH[i];
8086                         }
8087                 }
8088
8089                 /* always set RED writing to false: we are at the encoder */
8090                 cp->red_on = OPJ_FALSE;
8091
8092         } else {
8093                 cp->epc_on = OPJ_FALSE;
8094         }
8095 #endif /* USE_JPWL */
8096
8097
8098         /* initialize the mutiple tiles */
8099         /* ---------------------------- */
8100         cp->tcps = (opj_tcp_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tcp_t));
8101
8102         for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
8103                 opj_tcp_t *tcp = &cp->tcps[tileno];
8104                 tcp->numlayers = parameters->tcp_numlayers;
8105                 assert ( tcp->numlayers >= 0 );
8106                 for (j = 0; j < (OPJ_UINT32)tcp->numlayers; j++) {
8107                         if(cp->cinema){
8108                                 if (cp->fixed_quality) {
8109                                         tcp->distoratio[j] = parameters->tcp_distoratio[j];
8110                                 }
8111                                 tcp->rates[j] = parameters->tcp_rates[j];
8112                         }else{
8113                                 if (cp->fixed_quality) {        /* add fixed_quality */
8114                                         tcp->distoratio[j] = parameters->tcp_distoratio[j];
8115                                 } else {
8116                                         tcp->rates[j] = parameters->tcp_rates[j];
8117                                 }
8118                         }
8119                 }
8120                 tcp->csty = parameters->csty;
8121                 tcp->prg = parameters->prog_order;
8122                 tcp->mct = parameters->tcp_mct; 
8123
8124                 numpocs_tile = 0;
8125                 tcp->POC = 0;
8126                 if (parameters->numpocs) {
8127                         /* initialisation of POC */
8128                         tcp->POC = 1;
8129       assert( parameters->numpocs >= 0 );
8130                         for (i = 0; i < (OPJ_UINT32)parameters->numpocs; i++) {
8131                                 if((tileno == parameters->POC[i].tile - 1) || (parameters->POC[i].tile == -1)) {
8132                                         opj_poc_t *tcp_poc = &tcp->pocs[numpocs_tile];
8133                                         tcp_poc->resno0         = parameters->POC[numpocs_tile].resno0;
8134                                         tcp_poc->compno0        = parameters->POC[numpocs_tile].compno0;
8135                                         tcp_poc->layno1         = parameters->POC[numpocs_tile].layno1;
8136                                         tcp_poc->resno1         = parameters->POC[numpocs_tile].resno1;
8137                                         tcp_poc->compno1        = parameters->POC[numpocs_tile].compno1;
8138                                         tcp_poc->prg1           = parameters->POC[numpocs_tile].prg1;
8139                                         tcp_poc->tile           = parameters->POC[numpocs_tile].tile;
8140                                         numpocs_tile++;
8141                                 }
8142                         }
8143                         tcp->numpocs = numpocs_tile -1 ;
8144                 }else{ 
8145                         tcp->numpocs = 0;
8146                 }
8147
8148                 tcp->tccps = (opj_tccp_t*) opj_calloc(image->numcomps, sizeof(opj_tccp_t));
8149
8150                 for (i = 0; i < image->numcomps; i++) {
8151                         opj_tccp_t *tccp = &tcp->tccps[i];
8152                         tccp->csty = parameters->csty & 0x01;   /* 0 => one precinct || 1 => custom precinct  */
8153                         tccp->numresolutions = parameters->numresolution;
8154                         tccp->cblkw = int_floorlog2(parameters->cblockw_init);
8155                         tccp->cblkh = int_floorlog2(parameters->cblockh_init);
8156                         tccp->cblksty = parameters->mode;
8157                         tccp->qmfbid = parameters->irreversible ? 0 : 1;
8158                         tccp->qntsty = parameters->irreversible ? J2K_CCP_QNTSTY_SEQNT : J2K_CCP_QNTSTY_NOQNT;
8159                         tccp->numgbits = 2;
8160                         assert(parameters->roi_compno >= 0);
8161                         if (i == (OPJ_UINT32)parameters->roi_compno) {
8162                                 tccp->roishift = parameters->roi_shift;
8163                         } else {
8164                                 tccp->roishift = 0;
8165                         }
8166
8167                         if(parameters->cp_cinema)
8168                         {
8169                                 /*Precinct size for lowest frequency subband=128*/
8170                                 tccp->prcw[0] = 7;
8171                                 tccp->prch[0] = 7;
8172                                 /*Precinct size at all other resolutions = 256*/
8173                                 for (j = 1; j < tccp->numresolutions; j++) {
8174                                         tccp->prcw[j] = 8;
8175                                         tccp->prch[j] = 8;
8176                                 }
8177                         }else{
8178                                 if (parameters->csty & J2K_CCP_CSTY_PRT) {
8179                                         int p = 0;
8180                                         assert(tccp->numresolutions > 0);
8181                                         for (j = (OPJ_UINT32)(tccp->numresolutions - 1); (int)j >= 0; j--) {
8182                                                 if (p < parameters->res_spec) {
8183                                                         
8184                                                         if (parameters->prcw_init[p] < 1) {
8185                                                                 tccp->prcw[j] = 1;
8186                                                         } else {
8187                                                                 tccp->prcw[j] = int_floorlog2(parameters->prcw_init[p]);
8188                                                         }
8189                                                         
8190                                                         if (parameters->prch_init[p] < 1) {
8191                                                                 tccp->prch[j] = 1;
8192                                                         }else {
8193                                                                 tccp->prch[j] = int_floorlog2(parameters->prch_init[p]);
8194                                                         }
8195
8196                                                 } else {
8197                                                         int res_spec = parameters->res_spec;
8198                                                         int size_prcw = parameters->prcw_init[res_spec - 1] >> (p - (res_spec - 1));
8199                                                         int size_prch = parameters->prch_init[res_spec - 1] >> (p - (res_spec - 1));
8200                                                         
8201                                                         if (size_prcw < 1) {
8202                                                                 tccp->prcw[j] = 1;
8203                                                         } else {
8204                                                                 tccp->prcw[j] = int_floorlog2(size_prcw);
8205                                                         }
8206                                                         
8207                                                         if (size_prch < 1) {
8208                                                                 tccp->prch[j] = 1;
8209                                                         } else {
8210                                                                 tccp->prch[j] = int_floorlog2(size_prch);
8211                                                         }
8212                                                 }
8213                                                 p++;
8214                                                 /*printf("\nsize precinct for level %d : %d,%d\n", j,tccp->prcw[j], tccp->prch[j]); */
8215                                         }       /*end for*/
8216                                 } else {
8217                                         for (j = 0; j < tccp->numresolutions; j++) {
8218                                                 tccp->prcw[j] = 15;
8219                                                 tccp->prch[j] = 15;
8220                                         }
8221                                 }
8222                         }
8223
8224                         dwt_calc_explicit_stepsizes(tccp, image->comps[i].prec);
8225                 }
8226         }
8227 }
8228
8229 void j2k_setup_encoder_v2(      opj_j2k_v2_t *p_j2k,
8230                                                         opj_cparameters_t *parameters,
8231                                                         opj_image_t *image,
8232                                                         struct opj_event_mgr * p_manager)
8233 {
8234         OPJ_UINT32 i, j, tileno, numpocs_tile;
8235         opj_cp_v2_t *cp = 00;
8236         opj_bool l_res;
8237
8238         if(!p_j2k || !parameters || ! image) {
8239                 return;
8240         }
8241
8242         /* keep a link to cp so that we can destroy it later in j2k_destroy_compress */
8243         cp = &(p_j2k->m_cp);
8244
8245         /* set default values for cp */
8246         cp->tw = 1;
8247         cp->th = 1;
8248
8249         /*
8250         copy user encoding parameters
8251         */
8252         cp->m_specific_param.m_enc.m_cinema = parameters->cp_cinema;
8253         cp->m_specific_param.m_enc.m_max_comp_size =    parameters->max_comp_size;
8254         cp->rsiz   = parameters->cp_rsiz;
8255         cp->m_specific_param.m_enc.m_disto_alloc = parameters->cp_disto_alloc;
8256         cp->m_specific_param.m_enc.m_fixed_alloc = parameters->cp_fixed_alloc;
8257         cp->m_specific_param.m_enc.m_fixed_quality = parameters->cp_fixed_quality;
8258
8259         /* mod fixed_quality */
8260         if (parameters->cp_matrice) {
8261                 size_t array_size = parameters->tcp_numlayers * parameters->numresolution * 3 * sizeof(OPJ_INT32);
8262                 cp->m_specific_param.m_enc.m_matrice = (OPJ_INT32 *) opj_malloc(array_size);
8263                 memcpy(cp->m_specific_param.m_enc.m_matrice, parameters->cp_matrice, array_size);
8264         }
8265
8266         /* tiles */
8267         cp->tdx = parameters->cp_tdx;
8268         cp->tdy = parameters->cp_tdy;
8269
8270         /* tile offset */
8271         cp->tx0 = parameters->cp_tx0;
8272         cp->ty0 = parameters->cp_ty0;
8273
8274         /* comment string */
8275         if(parameters->cp_comment) {
8276                 cp->comment = (char*)opj_malloc(strlen(parameters->cp_comment) + 1);
8277                 if(cp->comment) {
8278                         strcpy(cp->comment, parameters->cp_comment);
8279                 }
8280         }
8281
8282         /*
8283         calculate other encoding parameters
8284         */
8285
8286         if (parameters->tile_size_on) {
8287                 cp->tw = int_ceildiv(image->x1 - cp->tx0, cp->tdx);
8288                 cp->th = int_ceildiv(image->y1 - cp->ty0, cp->tdy);
8289         } else {
8290                 cp->tdx = image->x1 - cp->tx0;
8291                 cp->tdy = image->y1 - cp->ty0;
8292         }
8293
8294         if (parameters->tp_on) {
8295                 cp->m_specific_param.m_enc.m_tp_flag = parameters->tp_flag;
8296                 cp->m_specific_param.m_enc.m_tp_on = 1;
8297         }
8298
8299 #ifdef USE_JPWL
8300         /*
8301         calculate JPWL encoding parameters
8302         */
8303
8304         if (parameters->jpwl_epc_on) {
8305                 OPJ_INT32 i;
8306
8307                 /* set JPWL on */
8308                 cp->epc_on = OPJ_TRUE;
8309                 cp->info_on = OPJ_FALSE; /* no informative technique */
8310
8311                 /* set EPB on */
8312                 if ((parameters->jpwl_hprot_MH > 0) || (parameters->jpwl_hprot_TPH[0] > 0)) {
8313                         cp->epb_on = OPJ_TRUE;
8314
8315                         cp->hprot_MH = parameters->jpwl_hprot_MH;
8316                         for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) {
8317                                 cp->hprot_TPH_tileno[i] = parameters->jpwl_hprot_TPH_tileno[i];
8318                                 cp->hprot_TPH[i] = parameters->jpwl_hprot_TPH[i];
8319                         }
8320                         /* if tile specs are not specified, copy MH specs */
8321                         if (cp->hprot_TPH[0] == -1) {
8322                                 cp->hprot_TPH_tileno[0] = 0;
8323                                 cp->hprot_TPH[0] = parameters->jpwl_hprot_MH;
8324                         }
8325                         for (i = 0; i < JPWL_MAX_NO_PACKSPECS; i++) {
8326                                 cp->pprot_tileno[i] = parameters->jpwl_pprot_tileno[i];
8327                                 cp->pprot_packno[i] = parameters->jpwl_pprot_packno[i];
8328                                 cp->pprot[i] = parameters->jpwl_pprot[i];
8329                         }
8330                 }
8331
8332                 /* set ESD writing */
8333                 if ((parameters->jpwl_sens_size == 1) || (parameters->jpwl_sens_size == 2)) {
8334                         cp->esd_on = OPJ_TRUE;
8335
8336                         cp->sens_size = parameters->jpwl_sens_size;
8337                         cp->sens_addr = parameters->jpwl_sens_addr;
8338                         cp->sens_range = parameters->jpwl_sens_range;
8339
8340                         cp->sens_MH = parameters->jpwl_sens_MH;
8341                         for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) {
8342                                 cp->sens_TPH_tileno[i] = parameters->jpwl_sens_TPH_tileno[i];
8343                                 cp->sens_TPH[i] = parameters->jpwl_sens_TPH[i];
8344                         }
8345                 }
8346
8347                 /* always set RED writing to false: we are at the encoder */
8348                 cp->red_on = OPJ_FALSE;
8349
8350         } else {
8351                 cp->epc_on = OPJ_FALSE;
8352         }
8353 #endif /* USE_JPWL */
8354
8355
8356         /* initialize the mutiple tiles */
8357         /* ---------------------------- */
8358         cp->tcps = (opj_tcp_v2_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tcp_v2_t));
8359         if (parameters->numpocs) {
8360                 /* initialisation of POC */
8361                 l_res = j2k_check_poc_val(parameters->POC,parameters->numpocs, parameters->numresolution, image->numcomps, parameters->tcp_numlayers, p_manager);
8362                 // TODO
8363         }
8364
8365         for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
8366                 opj_tcp_v2_t *tcp = &cp->tcps[tileno];
8367                 tcp->numlayers = parameters->tcp_numlayers;
8368
8369                 for (j = 0; j < tcp->numlayers; j++) {
8370                         if(cp->m_specific_param.m_enc.m_cinema){
8371                                 if (cp->m_specific_param.m_enc.m_fixed_quality) {
8372                                         tcp->distoratio[j] = parameters->tcp_distoratio[j];
8373                                 }
8374                                 tcp->rates[j] = parameters->tcp_rates[j];
8375                         }else{
8376                                 if (cp->m_specific_param.m_enc.m_fixed_quality) {       /* add fixed_quality */
8377                                         tcp->distoratio[j] = parameters->tcp_distoratio[j];
8378                                 } else {
8379                                         tcp->rates[j] = parameters->tcp_rates[j];
8380                                 }
8381                         }
8382                 }
8383
8384                 tcp->csty = parameters->csty;
8385                 tcp->prg = parameters->prog_order;
8386                 tcp->mct = parameters->tcp_mct;
8387
8388                 numpocs_tile = 0;
8389                 tcp->POC = 0;
8390
8391                 if (parameters->numpocs) {
8392                         /* initialisation of POC */
8393                         tcp->POC = 1;
8394                         // TODO
8395                         for (i = 0; i < (unsigned int) parameters->numpocs; i++) {
8396                                 if((tileno == parameters->POC[i].tile - 1) || (parameters->POC[i].tile == -1)) {
8397                                         opj_poc_t *tcp_poc = &tcp->pocs[numpocs_tile];
8398
8399                                         tcp_poc->resno0         = parameters->POC[numpocs_tile].resno0;
8400                                         tcp_poc->compno0        = parameters->POC[numpocs_tile].compno0;
8401                                         tcp_poc->layno1         = parameters->POC[numpocs_tile].layno1;
8402                                         tcp_poc->resno1         = parameters->POC[numpocs_tile].resno1;
8403                                         tcp_poc->compno1        = parameters->POC[numpocs_tile].compno1;
8404                                         tcp_poc->prg1           = parameters->POC[numpocs_tile].prg1;
8405                                         tcp_poc->tile           = parameters->POC[numpocs_tile].tile;
8406
8407                                         numpocs_tile++;
8408                                 }
8409                         }
8410
8411                         tcp->numpocs = numpocs_tile -1 ;
8412                 }else{
8413                         tcp->numpocs = 0;
8414                 }
8415
8416                 tcp->tccps = (opj_tccp_t*) opj_calloc(image->numcomps, sizeof(opj_tccp_t));
8417
8418                 if (parameters->mct_data) {
8419
8420                         opj_event_msg_v2(p_manager, EVT_ERROR, "MCT not supported for now\n");
8421                         return;
8422
8423                         /* TODO MSD : merge v2 add invert.c or used a external lib ?
8424                         OPJ_UINT32 lMctSize = image->numcomps * image->numcomps * sizeof(OPJ_FLOAT32);
8425                         OPJ_FLOAT32 * lTmpBuf = (OPJ_FLOAT32*)opj_malloc(lMctSize);
8426                         OPJ_INT32 * l_dc_shift = (OPJ_INT32 *) ((OPJ_BYTE *) parameters->mct_data + lMctSize);
8427
8428                         tcp->mct = 2;
8429                         tcp->m_mct_coding_matrix = (OPJ_FLOAT32*)opj_malloc(lMctSize);
8430                         memcpy(tcp->m_mct_coding_matrix,parameters->mct_data,lMctSize);
8431                         memcpy(lTmpBuf,parameters->mct_data,lMctSize);
8432
8433                         tcp->m_mct_decoding_matrix = (OPJ_FLOAT32*)opj_malloc(lMctSize);
8434                         assert(opj_matrix_inversion_f(lTmpBuf,(tcp->m_mct_decoding_matrix),image->numcomps));
8435
8436                         tcp->mct_norms = (OPJ_FLOAT64*)
8437                                         opj_malloc(image->numcomps * sizeof(OPJ_FLOAT64));
8438
8439                         opj_calculate_norms(tcp->mct_norms,image->numcomps,tcp->m_mct_decoding_matrix);
8440                         opj_free(lTmpBuf);
8441
8442                         for (i = 0; i < image->numcomps; i++) {
8443                                 opj_tccp_t *tccp = &tcp->tccps[i];
8444                                 tccp->m_dc_level_shift = l_dc_shift[i];
8445                         }
8446
8447                         j2k_setup_mct_encoding(tcp,image);
8448                         */
8449                 }
8450                 else {
8451                         for (i = 0; i < image->numcomps; i++) {
8452                                 opj_tccp_t *tccp = &tcp->tccps[i];
8453                                 opj_image_comp_t * l_comp = &(image->comps[i]);
8454
8455                                 if (! l_comp->sgnd) {
8456                                         tccp->m_dc_level_shift = 1 << (l_comp->prec - 1);
8457                                 }
8458                         }
8459                 }
8460
8461                 for (i = 0; i < image->numcomps; i++) {
8462                         opj_tccp_t *tccp = &tcp->tccps[i];
8463
8464                         tccp->csty = parameters->csty & 0x01;   /* 0 => one precinct || 1 => custom precinct  */
8465                         tccp->numresolutions = parameters->numresolution;
8466                         tccp->cblkw = int_floorlog2(parameters->cblockw_init);
8467                         tccp->cblkh = int_floorlog2(parameters->cblockh_init);
8468                         tccp->cblksty = parameters->mode;
8469                         tccp->qmfbid = parameters->irreversible ? 0 : 1;
8470                         tccp->qntsty = parameters->irreversible ? J2K_CCP_QNTSTY_SEQNT : J2K_CCP_QNTSTY_NOQNT;
8471                         tccp->numgbits = 2;
8472
8473                         if (i == parameters->roi_compno) {
8474                                 tccp->roishift = parameters->roi_shift;
8475                         } else {
8476                                 tccp->roishift = 0;
8477                         }
8478
8479                         if(parameters->cp_cinema) {
8480                                 //Precinct size for lowest frequency subband=128
8481                                 tccp->prcw[0] = 7;
8482                                 tccp->prch[0] = 7;
8483                                 //Precinct size at all other resolutions = 256
8484                                 for (j = 1; j < tccp->numresolutions; j++) {
8485                                         tccp->prcw[j] = 8;
8486                                         tccp->prch[j] = 8;
8487                                 }
8488                         }else{
8489                                 if (parameters->csty & J2K_CCP_CSTY_PRT) {
8490                                         OPJ_INT32 p = 0, it_res;
8491                                         for (it_res = tccp->numresolutions - 1; it_res >= 0; it_res--) {
8492                                                 if (p < parameters->res_spec) {
8493
8494                                                         if (parameters->prcw_init[p] < 1) {
8495                                                                 tccp->prcw[it_res] = 1;
8496                                                         } else {
8497                                                                 tccp->prcw[it_res] = int_floorlog2(parameters->prcw_init[p]);
8498                                                         }
8499
8500                                                         if (parameters->prch_init[p] < 1) {
8501                                                                 tccp->prch[it_res] = 1;
8502                                                         }else {
8503                                                                 tccp->prch[it_res] = int_floorlog2(parameters->prch_init[p]);
8504                                                         }
8505
8506                                                 } else {
8507                                                         int res_spec = parameters->res_spec;
8508                                                         int size_prcw = parameters->prcw_init[res_spec - 1] >> (p - (res_spec - 1));
8509                                                         int size_prch = parameters->prch_init[res_spec - 1] >> (p - (res_spec - 1));
8510
8511                                                         if (size_prcw < 1) {
8512                                                                 tccp->prcw[it_res] = 1;
8513                                                         } else {
8514                                                                 tccp->prcw[it_res] = int_floorlog2(size_prcw);
8515                                                         }
8516
8517                                                         if (size_prch < 1) {
8518                                                                 tccp->prch[it_res] = 1;
8519                                                         } else {
8520                                                                 tccp->prch[it_res] = int_floorlog2(size_prch);
8521                                                         }
8522                                                 }
8523                                                 p++;
8524                                                 /*printf("\nsize precinct for level %d : %d,%d\n", it_res,tccp->prcw[it_res], tccp->prch[it_res]); */
8525                                         }       //end for
8526                                 } else {
8527                                         for (j = 0; j < tccp->numresolutions; j++) {
8528                                                 tccp->prcw[j] = 15;
8529                                                 tccp->prch[j] = 15;
8530                                         }
8531                                 }
8532                         }
8533
8534                         dwt_calc_explicit_stepsizes(tccp, image->comps[i].prec);
8535                 }
8536         }
8537
8538         if (parameters->mct_data) {
8539                 opj_free(parameters->mct_data);
8540                 parameters->mct_data = 00;
8541         }
8542 }
8543
8544
8545 opj_bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) {
8546         int tileno;
8547   OPJ_UINT32 compno;
8548         opj_cp_t *cp = NULL;
8549
8550         opj_tcd_t *tcd = NULL;  /* TCD component */
8551
8552         j2k->cio = cio; 
8553         j2k->image = image;
8554
8555         cp = j2k->cp;
8556
8557         /* INDEX >> */
8558         j2k->cstr_info = cstr_info;
8559         if (cstr_info) {
8560                 OPJ_UINT32 compno;
8561                 cstr_info->tile = (opj_tile_info_t *) opj_malloc(cp->tw * cp->th * sizeof(opj_tile_info_t));
8562                 cstr_info->image_w = image->x1 - image->x0;
8563                 cstr_info->image_h = image->y1 - image->y0;
8564                 cstr_info->prog = (&cp->tcps[0])->prg;
8565                 cstr_info->tw = cp->tw;
8566                 cstr_info->th = cp->th;
8567                 cstr_info->tile_x = cp->tdx;    /* new version parser */
8568                 cstr_info->tile_y = cp->tdy;    /* new version parser */
8569                 cstr_info->tile_Ox = cp->tx0;   /* new version parser */
8570                 cstr_info->tile_Oy = cp->ty0;   /* new version parser */
8571                 cstr_info->numcomps = image->numcomps;
8572                 cstr_info->numlayers = (&cp->tcps[0])->numlayers;
8573                 cstr_info->numdecompos = (int*) opj_malloc(image->numcomps * sizeof(int));
8574                 for (compno=0; compno < image->numcomps; compno++) {
8575                         cstr_info->numdecompos[compno] = (&cp->tcps[0])->tccps->numresolutions - 1;
8576                 }
8577                 cstr_info->D_max = 0.0;         /* ADD Marcela */
8578                 cstr_info->main_head_start = cio_tell(cio); /* position of SOC */
8579                 cstr_info->maxmarknum = 100;
8580                 cstr_info->marker = (opj_marker_info_t *) opj_malloc(cstr_info->maxmarknum * sizeof(opj_marker_info_t));
8581                 cstr_info->marknum = 0;
8582         }
8583         /* << INDEX */
8584
8585         j2k_write_soc(j2k);
8586         j2k_write_siz(j2k);
8587         j2k_write_cod(j2k);
8588         j2k_write_qcd(j2k);
8589
8590         if(cp->cinema){
8591                 for (compno = 1; compno < image->numcomps; compno++) {
8592                         j2k_write_coc(j2k, compno);
8593                         j2k_write_qcc(j2k, compno);
8594                 }
8595         }
8596
8597         for (compno = 0; compno < image->numcomps; compno++) {
8598                 opj_tcp_t *tcp = &cp->tcps[0];
8599                 if (tcp->tccps[compno].roishift)
8600                         j2k_write_rgn(j2k, compno, 0);
8601         }
8602         if (cp->comment != NULL) {
8603                 j2k_write_com(j2k);
8604         }
8605
8606         j2k->totnum_tp = j2k_calculate_tp(cp,image->numcomps,image,j2k);
8607         /* TLM Marker*/
8608         if(cp->cinema){
8609                 j2k_write_tlm(j2k);
8610                 if (cp->cinema == CINEMA4K_24) {
8611                         j2k_write_poc(j2k);
8612                 }
8613         }
8614
8615         /* uncomment only for testing JPSEC marker writing */
8616         /* j2k_write_sec(j2k); */
8617
8618         /* INDEX >> */
8619         if(cstr_info) {
8620                 cstr_info->main_head_end = cio_tell(cio) - 1;
8621         }
8622         /* << INDEX */
8623         /**** Main Header ENDS here ***/
8624
8625         /* create the tile encoder */
8626         tcd = tcd_create(j2k->cinfo);
8627
8628         /* encode each tile */
8629         for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
8630                 int pino;
8631                 int tilepartno=0;
8632                 /* UniPG>> */
8633                 int acc_pack_num = 0;
8634                 /* <<UniPG */
8635
8636
8637                 opj_tcp_t *tcp = &cp->tcps[tileno];
8638                 opj_event_msg(j2k->cinfo, EVT_INFO, "tile number %d / %d\n", tileno + 1, cp->tw * cp->th);
8639
8640                 j2k->curtileno = tileno;
8641                 j2k->cur_tp_num = 0;
8642                 tcd->cur_totnum_tp = j2k->cur_totnum_tp[j2k->curtileno];
8643                 /* initialisation before tile encoding  */
8644                 if (tileno == 0) {
8645                         tcd_malloc_encode(tcd, image, cp, j2k->curtileno);
8646                 } else {
8647                         tcd_init_encode(tcd, image, cp, j2k->curtileno);
8648                 }
8649
8650                 /* INDEX >> */
8651                 if(cstr_info) {
8652                         cstr_info->tile[j2k->curtileno].start_pos = cio_tell(cio) + j2k->pos_correction;
8653                         cstr_info->tile[j2k->curtileno].maxmarknum = 10;
8654                         cstr_info->tile[j2k->curtileno].marker = (opj_marker_info_t *) opj_malloc(cstr_info->tile[j2k->curtileno].maxmarknum * sizeof(opj_marker_info_t));
8655                         cstr_info->tile[j2k->curtileno].marknum = 0;
8656                 }
8657                 /* << INDEX */
8658
8659                 for(pino = 0; pino <= tcp->numpocs; pino++) {
8660                         int tot_num_tp;
8661                         tcd->cur_pino=pino;
8662
8663                         /*Get number of tile parts*/
8664                         tot_num_tp = j2k_get_num_tp(cp,pino,tileno);
8665                         tcd->tp_pos = cp->tp_pos;
8666
8667                         for(tilepartno = 0; tilepartno < tot_num_tp ; tilepartno++){
8668                                 j2k->tp_num = tilepartno;
8669                                 /* INDEX >> */
8670                                 if(cstr_info)
8671                                         cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_start_pos =
8672                                         cio_tell(cio) + j2k->pos_correction;
8673                                 /* << INDEX */
8674                                 j2k_write_sot(j2k);
8675
8676                                 if(j2k->cur_tp_num == 0 && cp->cinema == 0){
8677                                         for (compno = 1; compno < image->numcomps; compno++) {
8678                                                 j2k_write_coc(j2k, compno);
8679                                                 j2k_write_qcc(j2k, compno);
8680                                         }
8681                                         if (cp->tcps[tileno].numpocs) {
8682                                                 j2k_write_poc(j2k);
8683                                         }
8684                                 }
8685
8686                                 /* INDEX >> */
8687                                 if(cstr_info)
8688                                         cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_end_header =
8689                                         cio_tell(cio) + j2k->pos_correction + 1;
8690                                 /* << INDEX */
8691
8692                                 j2k_write_sod(j2k, tcd);
8693
8694                                 /* INDEX >> */
8695                                 if(cstr_info) {
8696                                         cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_end_pos =
8697                                                 cio_tell(cio) + j2k->pos_correction - 1;
8698                                         cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_start_pack =
8699                                                 acc_pack_num;
8700                                         cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_numpacks =
8701                                                 cstr_info->packno - acc_pack_num;
8702                                         acc_pack_num = cstr_info->packno;
8703                                 }
8704                                 /* << INDEX */
8705
8706                                 j2k->cur_tp_num++;
8707                         }                       
8708                 }
8709                 if(cstr_info) {
8710                         cstr_info->tile[j2k->curtileno].end_pos = cio_tell(cio) + j2k->pos_correction - 1;
8711                 }
8712
8713
8714                 /*
8715                 if (tile->PPT) { // BAD PPT !!! 
8716                 FILE *PPT_file;
8717                 int i;
8718                 PPT_file=fopen("PPT","rb");
8719                 fprintf(stderr,"%c%c%c%c",255,97,tile->len_ppt/256,tile->len_ppt%256);
8720                 for (i=0;i<tile->len_ppt;i++) {
8721                 unsigned char elmt;
8722                 fread(&elmt, 1, 1, PPT_file);
8723                 fwrite(&elmt,1,1,f);
8724                 }
8725                 fclose(PPT_file);
8726                 unlink("PPT");
8727                 }
8728                 */
8729
8730         }
8731
8732         /* destroy the tile encoder */
8733         tcd_free_encode(tcd);
8734         tcd_destroy(tcd);
8735
8736         opj_free(j2k->cur_totnum_tp);
8737
8738         j2k_write_eoc(j2k);
8739
8740         if(cstr_info) {
8741                 cstr_info->codestream_size = cio_tell(cio) + j2k->pos_correction;
8742                 /* UniPG>> */
8743                 /* The following adjustment is done to adjust the codestream size */
8744                 /* if SOD is not at 0 in the buffer. Useful in case of JP2, where */
8745                 /* the first bunch of bytes is not in the codestream              */
8746                 cstr_info->codestream_size -= cstr_info->main_head_start;
8747                 /* <<UniPG */
8748         }
8749
8750 #ifdef USE_JPWL
8751         /*
8752         preparation of JPWL marker segments
8753         */
8754         if(cp->epc_on) {
8755
8756                 /* encode according to JPWL */
8757                 jpwl_encode(j2k, cio, image);
8758
8759         }
8760 #endif /* USE_JPWL */
8761
8762         return OPJ_TRUE;
8763 }
8764
8765 static void j2k_add_mhmarker(opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len)
8766 {
8767         assert(cstr_info != 00);
8768
8769         /* expand the list? */
8770         if ((cstr_info->marknum + 1) > cstr_info->maxmarknum) {
8771                 cstr_info->maxmarknum = 100 + (int) ((float) cstr_info->maxmarknum * 1.0F);
8772                 cstr_info->marker = (opj_marker_info_t*)opj_realloc(cstr_info->marker, cstr_info->maxmarknum);
8773         }
8774
8775         /* add the marker */
8776         cstr_info->marker[cstr_info->marknum].type = type;
8777         cstr_info->marker[cstr_info->marknum].pos = pos;
8778         cstr_info->marker[cstr_info->marknum].len = len;
8779         cstr_info->marknum++;
8780
8781 }
8782
8783 static void j2k_add_mhmarker_v2(opj_codestream_index_t *cstr_index, OPJ_UINT32 type, OPJ_OFF_T pos, OPJ_UINT32 len)
8784 {
8785         assert(cstr_index != 00);
8786
8787         /* expand the list? */
8788         if ((cstr_index->marknum + 1) > cstr_index->maxmarknum) {
8789                 cstr_index->maxmarknum = 100 + (int) ((float) cstr_index->maxmarknum * 1.0F);
8790                 cstr_index->marker = (opj_marker_info_t*)opj_realloc(cstr_index->marker, cstr_index->maxmarknum *sizeof(opj_marker_info_t));
8791         }
8792
8793         /* add the marker */
8794         cstr_index->marker[cstr_index->marknum].type = (OPJ_UINT16)type;
8795         cstr_index->marker[cstr_index->marknum].pos = (OPJ_INT32)pos;
8796         cstr_index->marker[cstr_index->marknum].len = (OPJ_INT32)len;
8797         cstr_index->marknum++;
8798
8799 }
8800
8801 static void j2k_add_tlmarker( int tileno, opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len)
8802 {
8803         opj_marker_info_t *marker;
8804
8805         assert(cstr_info != 00);
8806
8807         /* expand the list? */
8808         if ((cstr_info->tile[tileno].marknum + 1) > cstr_info->tile[tileno].maxmarknum) {
8809                 cstr_info->tile[tileno].maxmarknum = 100 + (int) ((float) cstr_info->tile[tileno].maxmarknum * 1.0F);
8810                 cstr_info->tile[tileno].marker = (opj_marker_info_t*)opj_realloc(cstr_info->tile[tileno].marker, cstr_info->maxmarknum);
8811         }
8812
8813         marker = &(cstr_info->tile[tileno].marker[cstr_info->tile[tileno].marknum]);
8814
8815         /* add the marker */
8816         marker->type = type;
8817         marker->pos = pos;
8818         marker->len = len;
8819         cstr_info->tile[tileno].marknum++;
8820 }
8821
8822 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)
8823 {
8824         assert(cstr_index != 00);
8825         assert(cstr_index->tile_index != 00);
8826
8827         /* expand the list? */
8828         if ((cstr_index->tile_index[tileno].marknum + 1) > cstr_index->tile_index[tileno].maxmarknum) {
8829                 cstr_index->tile_index[tileno].maxmarknum = 100 + (int) ((float) cstr_index->tile_index[tileno].maxmarknum * 1.0F);
8830                 cstr_index->tile_index[tileno].marker =
8831                                 (opj_marker_info_t*)opj_realloc(cstr_index->tile_index[tileno].marker,
8832                                                                                                 cstr_index->tile_index[tileno].maxmarknum *sizeof(opj_marker_info_t));
8833         }
8834
8835         /* add the marker */
8836         cstr_index->tile_index[tileno].marker[cstr_index->tile_index[tileno].marknum].type = (OPJ_UINT16)type;
8837         cstr_index->tile_index[tileno].marker[cstr_index->tile_index[tileno].marknum].pos = (OPJ_INT32)pos;
8838         cstr_index->tile_index[tileno].marker[cstr_index->tile_index[tileno].marknum].len = (OPJ_INT32)len;
8839         cstr_index->tile_index[tileno].marknum++;
8840
8841         if (type == J2K_MS_SOT) {
8842                 OPJ_UINT32 l_current_tile_part = cstr_index->tile_index[tileno].current_tpsno;
8843
8844                 if (cstr_index->tile_index[tileno].tp_index)
8845                         cstr_index->tile_index[tileno].tp_index[l_current_tile_part].start_pos = pos;
8846
8847         }
8848 }
8849
8850
8851 /*
8852  * -----------------------------------------------------------------------
8853  * -----------------------------------------------------------------------
8854  * -----------------------------------------------------------------------
8855  */
8856
8857 /**
8858  * Ends the decompression procedures and possibiliy add data to be read after the
8859  * codestream.
8860  */
8861 opj_bool j2k_end_decompress(
8862                                                 opj_j2k_v2_t *p_j2k,
8863                                                 opj_stream_private_t *p_stream,
8864                                                 opj_event_mgr_t * p_manager)
8865 {
8866   (void)p_j2k;
8867   (void)p_stream;
8868   (void)p_manager;
8869         return OPJ_TRUE;
8870 }
8871
8872 /**
8873  * Reads a jpeg2000 codestream header structure.
8874
8875  *
8876  * @param p_stream the stream to read data from.
8877  * @param p_j2k the jpeg2000 codec.
8878  * @param p_manager the user event manager.
8879  *
8880  * @return true if the box is valid.
8881  */
8882 opj_bool j2k_read_header(       struct opj_stream_private *p_stream,
8883                                                         opj_j2k_v2_t* p_j2k,
8884                                                         opj_image_t** p_image,
8885                                                         struct opj_event_mgr* p_manager )
8886 {
8887         /* preconditions */
8888         assert(p_j2k != 00);
8889         assert(p_stream != 00);
8890         assert(p_manager != 00);
8891
8892         /* create an empty image header */
8893         p_j2k->m_private_image = opj_image_create0();
8894         if (! p_j2k->m_private_image) {
8895                 return OPJ_FALSE;
8896         }
8897
8898         /* customization of the validation */
8899         j2k_setup_decoding_validation(p_j2k);
8900
8901         /* validation of the parameters codec */
8902         if (! j2k_exec(p_j2k, p_j2k->m_validation_list, p_stream,p_manager)) {
8903                 opj_image_destroy(p_j2k->m_private_image);
8904                 p_j2k->m_private_image = NULL;
8905                 return OPJ_FALSE;
8906         }
8907
8908         /* customization of the encoding */
8909         j2k_setup_header_reading(p_j2k);
8910
8911         /* read header */
8912         if (! j2k_exec (p_j2k,p_j2k->m_procedure_list,p_stream,p_manager)) {
8913                 opj_image_destroy(p_j2k->m_private_image);
8914                 p_j2k->m_private_image = NULL;
8915                 return OPJ_FALSE;
8916         }
8917
8918         *p_image = opj_image_create0();
8919         if (! (*p_image)) {
8920                 return OPJ_FALSE;
8921         }
8922
8923         /* Copy codestream image information to the output image */
8924         opj_copy_image_header(p_j2k->m_private_image, *p_image);
8925
8926
8927         return OPJ_TRUE;
8928 }
8929
8930 /**
8931  * Sets up the procedures to do on reading header. Developpers wanting to extend the library can add their own reading procedures.
8932  */
8933 void j2k_setup_header_reading (opj_j2k_v2_t *p_j2k)
8934 {
8935         /* preconditions*/
8936         assert(p_j2k != 00);
8937
8938         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_read_header_procedure);
8939
8940         /* DEVELOPER CORNER, add your custom procedures */
8941         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_copy_default_tcp_and_create_tcd);
8942
8943 }
8944
8945 /**
8946  * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
8947  * are valid. Developpers wanting to extend the library can add their own validation procedures.
8948  */
8949 void j2k_setup_decoding_validation (opj_j2k_v2_t *p_j2k)
8950 {
8951         /* preconditions*/
8952         assert(p_j2k != 00);
8953
8954         opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)j2k_build_decoder);
8955         opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)j2k_decoding_validation);
8956         /* DEVELOPER CORNER, add your custom validation procedure */
8957
8958 }
8959
8960
8961 /**
8962  * The mct encoding validation procedure.
8963  *
8964  * @param       p_j2k                   the jpeg2000 codec to validate.
8965  * @param       p_stream                                the input stream to validate.
8966  * @param       p_manager               the user event manager.
8967  *
8968  * @return true if the parameters are correct.
8969  */
8970 opj_bool j2k_mct_validation (   opj_j2k_v2_t * p_j2k,
8971                                                                 opj_stream_private_t *p_stream,
8972                                                                 opj_event_mgr_t * p_manager )
8973 {
8974         opj_bool l_is_valid = OPJ_TRUE;
8975         OPJ_UINT32 i,j;
8976
8977         /* preconditions */
8978         assert(p_j2k != 00);
8979         assert(p_stream != 00);
8980         assert(p_manager != 00);
8981
8982         if ((p_j2k->m_cp.rsiz & 0x8200) == 0x8200) {
8983                 OPJ_UINT32 l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
8984                 opj_tcp_v2_t * l_tcp = p_j2k->m_cp.tcps;
8985
8986                 for (i=0;i<l_nb_tiles;++i) {
8987                         if (l_tcp->mct == 2) {
8988                                 opj_tccp_t * l_tccp = l_tcp->tccps;
8989                                 l_is_valid &= (l_tcp->m_mct_coding_matrix != 00);
8990
8991                                 for (j=0;j<p_j2k->m_private_image->numcomps;++j) {
8992                                         l_is_valid &= ! (l_tccp->qmfbid & 1);
8993                                         ++l_tccp;
8994                                 }
8995                         }
8996                         ++l_tcp;
8997                 }
8998         }
8999
9000         return l_is_valid;
9001 }
9002
9003 opj_bool j2k_setup_mct_encoding(opj_tcp_v2_t * p_tcp, opj_image_t * p_image)
9004 {
9005         OPJ_UINT32 i;
9006         OPJ_UINT32 l_indix = 1;
9007         opj_mct_data_t * l_mct_deco_data = 00,* l_mct_offset_data = 00;
9008         opj_simple_mcc_decorrelation_data_t * l_mcc_data;
9009         OPJ_UINT32 l_mct_size,l_nb_elem;
9010         OPJ_FLOAT32 * l_data, * l_current_data;
9011         opj_tccp_t * l_tccp;
9012
9013         // preconditions
9014         assert(p_tcp != 00);
9015
9016         if (p_tcp->mct != 2) {
9017                 return OPJ_TRUE;
9018         }
9019
9020         if (p_tcp->m_mct_decoding_matrix) {
9021                 if (p_tcp->m_nb_mct_records == p_tcp->m_nb_max_mct_records) {
9022                         p_tcp->m_nb_max_mct_records += J2K_MCT_DEFAULT_NB_RECORDS;
9023
9024                         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));
9025                         if (! p_tcp->m_mct_records) {
9026                                 return OPJ_FALSE;
9027                         }
9028                         l_mct_deco_data = p_tcp->m_mct_records + p_tcp->m_nb_mct_records;
9029
9030                         memset(l_mct_deco_data ,0,(p_tcp->m_nb_max_mct_records - p_tcp->m_nb_mct_records) * sizeof(opj_mct_data_t));
9031                 }
9032                 l_mct_deco_data = p_tcp->m_mct_records + p_tcp->m_nb_mct_records;
9033
9034                 if (l_mct_deco_data->m_data) {
9035                         opj_free(l_mct_deco_data->m_data);
9036                         l_mct_deco_data->m_data = 00;
9037                 }
9038
9039                 l_mct_deco_data->m_index = l_indix++;
9040                 l_mct_deco_data->m_array_type = MCT_TYPE_DECORRELATION;
9041                 l_mct_deco_data->m_element_type = MCT_TYPE_FLOAT;
9042                 l_nb_elem = p_image->numcomps * p_image->numcomps;
9043                 l_mct_size = l_nb_elem * MCT_ELEMENT_SIZE[l_mct_deco_data->m_element_type];
9044                 l_mct_deco_data->m_data = (OPJ_BYTE*)opj_malloc(l_mct_size );
9045
9046                 if (! l_mct_deco_data->m_data) {
9047                         return OPJ_FALSE;
9048                 }
9049
9050                 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);
9051
9052                 l_mct_deco_data->m_data_size = l_mct_size;
9053                 ++p_tcp->m_nb_mct_records;
9054         }
9055
9056         if (p_tcp->m_nb_mct_records == p_tcp->m_nb_max_mct_records) {
9057                 p_tcp->m_nb_max_mct_records += J2K_MCT_DEFAULT_NB_RECORDS;
9058                 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));
9059
9060                 if (! p_tcp->m_mct_records) {
9061                         return OPJ_FALSE;
9062                 }
9063
9064                 l_mct_offset_data = p_tcp->m_mct_records + p_tcp->m_nb_mct_records;
9065                 memset(l_mct_offset_data ,0,(p_tcp->m_nb_max_mct_records - p_tcp->m_nb_mct_records) * sizeof(opj_mct_data_t));
9066
9067                 if (l_mct_deco_data) {
9068                         l_mct_deco_data = l_mct_offset_data - 1;
9069                 }
9070         }
9071
9072         l_mct_offset_data = p_tcp->m_mct_records + p_tcp->m_nb_mct_records;
9073
9074         if (l_mct_offset_data->m_data) {
9075                 opj_free(l_mct_offset_data->m_data);
9076                 l_mct_offset_data->m_data = 00;
9077         }
9078
9079         l_mct_offset_data->m_index = l_indix++;
9080         l_mct_offset_data->m_array_type = MCT_TYPE_OFFSET;
9081         l_mct_offset_data->m_element_type = MCT_TYPE_FLOAT;
9082         l_nb_elem = p_image->numcomps;
9083         l_mct_size = l_nb_elem * MCT_ELEMENT_SIZE[l_mct_offset_data->m_element_type];
9084         l_mct_offset_data->m_data = (OPJ_BYTE*)opj_malloc(l_mct_size );
9085
9086         if (! l_mct_offset_data->m_data) {
9087                 return OPJ_FALSE;
9088         }
9089
9090         l_data = (OPJ_FLOAT32*)opj_malloc(l_nb_elem * sizeof(OPJ_FLOAT32));
9091         if (! l_data) {
9092                 opj_free(l_mct_offset_data->m_data);
9093                 l_mct_offset_data->m_data = 00;
9094                 return OPJ_FALSE;
9095         }
9096
9097         l_tccp = p_tcp->tccps;
9098         l_current_data = l_data;
9099
9100         for (i=0;i<l_nb_elem;++i) {
9101                 *(l_current_data++) = (OPJ_FLOAT32) (l_tccp->m_dc_level_shift);
9102                 ++l_tccp;
9103         }
9104
9105         j2k_mct_write_functions_from_float[l_mct_offset_data->m_element_type](l_data,l_mct_offset_data->m_data,l_nb_elem);
9106
9107         opj_free(l_data);
9108
9109         l_mct_offset_data->m_data_size = l_mct_size;
9110
9111         ++p_tcp->m_nb_mct_records;
9112
9113         if (p_tcp->m_nb_mcc_records == p_tcp->m_nb_max_mcc_records) {
9114                 p_tcp->m_nb_max_mcc_records += J2K_MCT_DEFAULT_NB_RECORDS;
9115                 p_tcp->m_mcc_records = (opj_simple_mcc_decorrelation_data_t*)
9116                 opj_realloc(p_tcp->m_mcc_records,p_tcp->m_nb_max_mcc_records * sizeof(opj_simple_mcc_decorrelation_data_t));
9117
9118                 if (! p_tcp->m_mcc_records) {
9119                         return OPJ_FALSE;
9120                 }
9121                 l_mcc_data = p_tcp->m_mcc_records + p_tcp->m_nb_mcc_records;
9122                 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));
9123
9124         }
9125
9126         l_mcc_data = p_tcp->m_mcc_records + p_tcp->m_nb_mcc_records;
9127         l_mcc_data->m_decorrelation_array = l_mct_deco_data;
9128         l_mcc_data->m_is_irreversible = 1;
9129         l_mcc_data->m_nb_comps = p_image->numcomps;
9130         l_mcc_data->m_index = l_indix++;
9131         l_mcc_data->m_offset_array = l_mct_offset_data;
9132         ++p_tcp->m_nb_mcc_records;
9133
9134         return OPJ_TRUE;
9135 }
9136
9137 /**
9138  * Builds the cp decoder parameters to use to decode tile.
9139  */
9140 opj_bool j2k_build_decoder (opj_j2k_v2_t * p_j2k,
9141                                                         opj_stream_private_t *p_stream,
9142                                                         opj_event_mgr_t * p_manager )
9143 {
9144         /* add here initialization of cp
9145            copy paste of setup_decoder */
9146   (void)p_j2k;
9147   (void)p_stream;
9148   (void)p_manager;
9149         return OPJ_TRUE;
9150 }
9151
9152 /**
9153  * Builds the cp encoder parameters to use to encode tile.
9154  */
9155 opj_bool j2k_build_encoder (opj_j2k_v2_t * p_j2k,
9156                                                         opj_stream_private_t *p_stream,
9157                                                         opj_event_mgr_t * p_manager )
9158 {
9159         /* add here initialization of cp
9160            copy paste of setup_encoder */
9161   (void)p_j2k;
9162   (void)p_stream;
9163   (void)p_manager;
9164         return OPJ_TRUE;
9165 }
9166
9167 /**
9168  * The default encoding validation procedure without any extension.
9169  *
9170  * @param       p_j2k                   the jpeg2000 codec to validate.
9171  * @param       p_stream                                the input stream to validate.
9172  * @param       p_manager               the user event manager.
9173  *
9174  * @return true if the parameters are correct.
9175  */
9176 opj_bool j2k_encoding_validation (      opj_j2k_v2_t * p_j2k,
9177                                                                         opj_stream_private_t *p_stream,
9178                                                                         opj_event_mgr_t * p_manager )
9179 {
9180         opj_bool l_is_valid = OPJ_TRUE;
9181
9182         /* preconditions */
9183         assert(p_j2k != 00);
9184         assert(p_stream != 00);
9185         assert(p_manager != 00);
9186
9187         /* STATE checking */
9188         /* make sure the state is at 0 */
9189         l_is_valid &= (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_NONE);
9190
9191         /* POINTER validation */
9192         /* make sure a p_j2k codec is present */
9193         l_is_valid &= (p_j2k->m_procedure_list != 00);
9194         /* make sure a validation list is present */
9195         l_is_valid &= (p_j2k->m_validation_list != 00);
9196
9197         if ((p_j2k->m_cp.tdx) < (OPJ_UINT32) (1 << p_j2k->m_cp.tcps->tccps->numresolutions)) {
9198                 opj_event_msg_v2(p_manager, EVT_ERROR, "Number of resolutions is too high in comparison to the size of tiles\n");
9199                 return OPJ_FALSE;
9200         }
9201
9202         if ((p_j2k->m_cp.tdy) < (OPJ_UINT32) (1 << p_j2k->m_cp.tcps->tccps->numresolutions)) {
9203                 opj_event_msg_v2(p_manager, EVT_ERROR, "Number of resolutions is too high in comparison to the size of tiles\n");
9204                 return OPJ_FALSE;
9205         }
9206
9207         /* PARAMETER VALIDATION */
9208         return l_is_valid;
9209 }
9210
9211 /**
9212  * The default decoding validation procedure without any extension.
9213  *
9214  * @param       p_j2k                   the jpeg2000 codec to validate.
9215  * @param       p_stream                                the input stream to validate.
9216  * @param       p_manager               the user event manager.
9217  *
9218  * @return true if the parameters are correct.
9219  */
9220 opj_bool j2k_decoding_validation (
9221                                                                 opj_j2k_v2_t *p_j2k,
9222                                                                 opj_stream_private_t *p_stream,
9223                                                                 opj_event_mgr_t * p_manager
9224                                                           )
9225 {
9226         opj_bool l_is_valid = OPJ_TRUE;
9227
9228         /* preconditions*/
9229         assert(p_j2k != 00);
9230         assert(p_stream != 00);
9231         assert(p_manager != 00);
9232
9233
9234         /* STATE checking */
9235         /* make sure the state is at 0 */
9236 #ifdef TODO_MSD
9237         l_is_valid &= (p_j2k->m_specific_param.m_decoder.m_state == J2K_DEC_STATE_NONE);
9238 #endif
9239         l_is_valid &= (p_j2k->m_specific_param.m_decoder.m_state == 0x0000);
9240
9241         /* POINTER validation */
9242         /* make sure a p_j2k codec is present */
9243         /* make sure a procedure list is present */
9244         l_is_valid &= (p_j2k->m_procedure_list != 00);
9245         /* make sure a validation list is present */
9246         l_is_valid &= (p_j2k->m_validation_list != 00);
9247
9248         /* PARAMETER VALIDATION */
9249         return l_is_valid;
9250 }
9251
9252 opj_bool j2k_read_header_procedure(     opj_j2k_v2_t *p_j2k,
9253                                                                         struct opj_stream_private *p_stream,
9254                                                                         struct opj_event_mgr * p_manager)
9255 {
9256         OPJ_UINT32 l_current_marker;
9257         OPJ_UINT32 l_marker_size;
9258         const opj_dec_memory_marker_handler_t * l_marker_handler = 00;
9259
9260         /* preconditions */
9261         assert(p_stream != 00);
9262         assert(p_j2k != 00);
9263         assert(p_manager != 00);
9264
9265         /*  We enter in the main header */
9266         p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_MHSOC;
9267
9268         /* Try to read the SOC marker, the codestream must begin with SOC marker */
9269         if (! j2k_read_soc_v2(p_j2k,p_stream,p_manager)) {
9270                 opj_event_msg_v2(p_manager, EVT_ERROR, "Expected a SOC marker \n");
9271                 return OPJ_FALSE;
9272         }
9273
9274         /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer */
9275         if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
9276                 opj_event_msg_v2(p_manager, EVT_ERROR, "Stream too short\n");
9277                 return OPJ_FALSE;
9278         }
9279
9280         /* Read 2 bytes as the new marker ID */
9281         opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_current_marker,2);
9282
9283         /* Try to read until the SOT is detected */
9284         while (l_current_marker != J2K_MS_SOT) {
9285
9286                 /* Check if the current marker ID is valid */
9287                 if (l_current_marker < 0xff00) {
9288                         opj_event_msg_v2(p_manager, EVT_ERROR, "We expected read a marker ID (0xff--) instead of %.8x\n", l_current_marker);
9289                         return OPJ_FALSE;
9290                 }
9291
9292                 /* Get the marker handler from the marker ID */
9293                 l_marker_handler = j2k_get_marker_handler(l_current_marker);
9294
9295                 /* Manage case where marker is unknown */
9296                 if (l_marker_handler->id == J2K_MS_UNK) {
9297                         if (! j2k_read_unk_v2(p_j2k, p_stream, &l_current_marker, p_manager)){
9298                                 opj_event_msg_v2(p_manager, EVT_ERROR, "Unknow marker have been detected and generated error.\n");
9299                                 return OPJ_FALSE;
9300                         }
9301
9302                         if (l_current_marker == J2K_MS_SOT)
9303                                 break; /* SOT marker is detected main header is completely read */
9304                         else    /* Get the marker handler from the marker ID */
9305                                 l_marker_handler = j2k_get_marker_handler(l_current_marker);
9306                 }
9307
9308                 /* Check if the marker is known and if it is the right place to find it */
9309                 if (! (p_j2k->m_specific_param.m_decoder.m_state & l_marker_handler->states) ) {
9310                         opj_event_msg_v2(p_manager, EVT_ERROR, "Marker is not compliant with its position\n");
9311                         return OPJ_FALSE;
9312                 }
9313
9314                 /* Try to read 2 bytes (the marker size) from stream and copy them into the buffer */
9315                 if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
9316                         opj_event_msg_v2(p_manager, EVT_ERROR, "Stream too short\n");
9317                         return OPJ_FALSE;
9318                 }
9319
9320                 /* read 2 bytes as the marker size */
9321                 opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_marker_size,2);
9322                 l_marker_size -= 2; /* Subtract the size of the marker ID already read */
9323
9324                 /* Check if the marker size is compatible with the header data size */
9325                 if (l_marker_size > p_j2k->m_specific_param.m_decoder.m_header_data_size) {
9326                         p_j2k->m_specific_param.m_decoder.m_header_data = (OPJ_BYTE*)
9327                                         opj_realloc(p_j2k->m_specific_param.m_decoder.m_header_data,l_marker_size);
9328                         if (p_j2k->m_specific_param.m_decoder.m_header_data == 00) {
9329                                 return OPJ_FALSE;
9330                         }
9331                         p_j2k->m_specific_param.m_decoder.m_header_data_size = l_marker_size;
9332                 }
9333
9334                 /* Try to read the rest of the marker segment from stream and copy them into the buffer */
9335                 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) {
9336                         opj_event_msg_v2(p_manager, EVT_ERROR, "Stream too short\n");
9337                         return OPJ_FALSE;
9338                 }
9339
9340                 /* Read the marker segment with the correct marker handler */
9341                 if (! (*(l_marker_handler->handler))(p_j2k,p_j2k->m_specific_param.m_decoder.m_header_data,l_marker_size,p_manager)) {
9342                         opj_event_msg_v2(p_manager, EVT_ERROR, "Marker handler function failed to read the marker segment\n");
9343                         return OPJ_FALSE;
9344                 }
9345
9346                 /* Add the marker to the codestream index*/
9347                 j2k_add_mhmarker_v2(p_j2k->cstr_index,
9348                                                         l_marker_handler->id,
9349                                                         (OPJ_UINT32) opj_stream_tell(p_stream) - l_marker_size - 4,
9350                                                         l_marker_size + 4 );
9351
9352                 /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer */
9353                 if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
9354                         opj_event_msg_v2(p_manager, EVT_ERROR, "Stream too short\n");
9355                         return OPJ_FALSE;
9356                 }
9357
9358                 /* read 2 bytes as the new marker ID */
9359                 opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_current_marker,2);
9360         }
9361
9362         opj_event_msg_v2(p_manager, EVT_INFO, "Main header has been correctly decoded.\n");
9363
9364         /* Position of the last element if the main header */
9365         p_j2k->cstr_index->main_head_end = (OPJ_UINT32) opj_stream_tell(p_stream) - 2;
9366
9367         /* Next step: read a tile-part header */
9368         p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_TPHSOT;
9369
9370         return OPJ_TRUE;
9371 }
9372
9373 /**
9374  * Excutes the given procedures on the given codec.
9375  *
9376  * @param       p_procedure_list        the list of procedures to execute
9377  * @param       p_j2k                                   the jpeg2000 codec to execute the procedures on.
9378  * @param       p_stream                                        the stream to execute the procedures on.
9379  * @param       p_manager                       the user manager.
9380  *
9381  * @return      true                            if all the procedures were successfully executed.
9382  */
9383 opj_bool j2k_exec (     opj_j2k_v2_t * p_j2k,
9384                                         opj_procedure_list_t * p_procedure_list,
9385                                         opj_stream_private_t *p_stream,
9386                                         opj_event_mgr_t * p_manager )
9387 {
9388         opj_bool (** l_procedure) (opj_j2k_v2_t * ,opj_stream_private_t *,opj_event_mgr_t *) = 00;
9389         opj_bool l_result = OPJ_TRUE;
9390         OPJ_UINT32 l_nb_proc, i;
9391
9392         /* preconditions*/
9393         assert(p_procedure_list != 00);
9394         assert(p_j2k != 00);
9395         assert(p_stream != 00);
9396         assert(p_manager != 00);
9397
9398
9399         l_nb_proc = opj_procedure_list_get_nb_procedures(p_procedure_list);
9400         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);
9401
9402         for     (i=0;i<l_nb_proc;++i) {
9403                 l_result = l_result && ((*l_procedure) (p_j2k,p_stream,p_manager));
9404                 ++l_procedure;
9405         }
9406
9407         /* and clear the procedure list at the end.*/
9408         opj_procedure_list_clear(p_procedure_list);
9409         return l_result;
9410 }
9411
9412 /* FIXME DOC*/
9413 opj_bool j2k_copy_default_tcp_and_create_tcd
9414                                                 (
9415                                                 opj_j2k_v2_t * p_j2k,
9416                                                 opj_stream_private_t *p_stream,
9417                                                 opj_event_mgr_t * p_manager
9418                                                 )
9419 {
9420         opj_tcp_v2_t * l_tcp = 00;
9421         opj_tcp_v2_t * l_default_tcp = 00;
9422         OPJ_UINT32 l_nb_tiles;
9423         OPJ_UINT32 i,j;
9424         opj_tccp_t *l_current_tccp = 00;
9425         OPJ_UINT32 l_tccp_size;
9426         OPJ_UINT32 l_mct_size;
9427         opj_image_t * l_image;
9428         OPJ_UINT32 l_mcc_records_size,l_mct_records_size;
9429         opj_mct_data_t * l_src_mct_rec, *l_dest_mct_rec;
9430         opj_simple_mcc_decorrelation_data_t * l_src_mcc_rec, *l_dest_mcc_rec;
9431         OPJ_UINT32 l_offset;
9432
9433         /* preconditions */
9434         assert(p_j2k != 00);
9435         assert(p_stream != 00);
9436         assert(p_manager != 00);
9437
9438         l_image = p_j2k->m_private_image;
9439         l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
9440         l_tcp = p_j2k->m_cp.tcps;
9441         l_tccp_size = l_image->numcomps * sizeof(opj_tccp_t);
9442         l_default_tcp = p_j2k->m_specific_param.m_decoder.m_default_tcp;
9443         l_mct_size = l_image->numcomps * l_image->numcomps * sizeof(OPJ_FLOAT32);
9444
9445         /* For each tile */
9446         for (i=0; i<l_nb_tiles; ++i) {
9447                 /* keep the tile-compo coding parameters pointer of the current tile coding parameters*/
9448                 l_current_tccp = l_tcp->tccps;
9449                 /*Copy default coding parameters into the current tile coding parameters*/
9450                 memcpy(l_tcp, l_default_tcp, sizeof(opj_tcp_v2_t));
9451                 /* Initialize some values of the current tile coding parameters*/
9452                 l_tcp->ppt = 0;
9453                 l_tcp->ppt_data = 00;
9454                 /* Reconnect the tile-compo coding parameters pointer to the current tile coding parameters*/
9455                 l_tcp->tccps = l_current_tccp;
9456
9457                 /* Get the mct_decoding_matrix of the dflt_tile_cp and copy them into the current tile cp*/
9458                 if (l_default_tcp->m_mct_decoding_matrix) {
9459                         l_tcp->m_mct_decoding_matrix = (OPJ_FLOAT32*)opj_malloc(l_mct_size);
9460                         if (! l_tcp->m_mct_decoding_matrix ) {
9461                                 return OPJ_FALSE;
9462                         }
9463                         memcpy(l_tcp->m_mct_decoding_matrix,l_default_tcp->m_mct_decoding_matrix,l_mct_size);
9464                 }
9465
9466                 /* Get the mct_record of the dflt_tile_cp and copy them into the current tile cp*/
9467                 l_mct_records_size = l_default_tcp->m_nb_max_mct_records * sizeof(opj_mct_data_t);
9468                 l_tcp->m_mct_records = (opj_mct_data_t*)opj_malloc(l_mct_records_size);
9469                 if (! l_tcp->m_mct_records) {
9470                         return OPJ_FALSE;
9471                 }
9472                 memcpy(l_tcp->m_mct_records, l_default_tcp->m_mct_records,l_mct_records_size);
9473
9474                 /* Copy the mct record data from dflt_tile_cp to the current tile*/
9475                 l_src_mct_rec = l_default_tcp->m_mct_records;
9476                 l_dest_mct_rec = l_tcp->m_mct_records;
9477
9478                 for (j=0;j<l_default_tcp->m_nb_mct_records;++j) {
9479
9480                         if (l_src_mct_rec->m_data) {
9481
9482                                 l_dest_mct_rec->m_data = (OPJ_BYTE*) opj_malloc(l_src_mct_rec->m_data_size);
9483                                 if(! l_dest_mct_rec->m_data) {
9484                                         return OPJ_FALSE;
9485                                 }
9486                                 memcpy(l_dest_mct_rec->m_data,l_src_mct_rec->m_data,l_src_mct_rec->m_data_size);
9487                         }
9488
9489                         ++l_src_mct_rec;
9490                         ++l_dest_mct_rec;
9491                 }
9492
9493                 /* Get the mcc_record of the dflt_tile_cp and copy them into the current tile cp*/
9494                 l_mcc_records_size = l_default_tcp->m_nb_max_mcc_records * sizeof(opj_simple_mcc_decorrelation_data_t);
9495                 l_tcp->m_mcc_records = (opj_simple_mcc_decorrelation_data_t*) opj_malloc(l_mcc_records_size);
9496                 if (! l_tcp->m_mcc_records) {
9497                         return OPJ_FALSE;
9498                 }
9499                 memcpy(l_tcp->m_mcc_records,l_default_tcp->m_mcc_records,l_mcc_records_size);
9500
9501                 /* Copy the mcc record data from dflt_tile_cp to the current tile*/
9502                 l_src_mcc_rec = l_default_tcp->m_mcc_records;
9503                 l_dest_mcc_rec = l_tcp->m_mcc_records;
9504
9505                 for (j=0;j<l_default_tcp->m_nb_max_mcc_records;++j) {
9506
9507                         if (l_src_mcc_rec->m_decorrelation_array) {
9508                                 l_offset = l_src_mcc_rec->m_decorrelation_array - l_default_tcp->m_mct_records;
9509                                 l_dest_mcc_rec->m_decorrelation_array = l_tcp->m_mct_records + l_offset;
9510                         }
9511
9512                         if (l_src_mcc_rec->m_offset_array) {
9513                                 l_offset = l_src_mcc_rec->m_offset_array - l_default_tcp->m_mct_records;
9514                                 l_dest_mcc_rec->m_offset_array = l_tcp->m_mct_records + l_offset;
9515                         }
9516
9517                         ++l_src_mcc_rec;
9518                         ++l_dest_mcc_rec;
9519                 }
9520
9521                 /* Copy all the dflt_tile_compo_cp to the current tile cp */
9522                 memcpy(l_current_tccp,l_default_tcp->tccps,l_tccp_size);
9523
9524                 /* Move to next tile cp*/
9525                 ++l_tcp;
9526         }
9527
9528         /* Create the current tile decoder*/
9529         p_j2k->m_tcd = (opj_tcd_v2_t*)tcd_create_v2(OPJ_TRUE); /* FIXME why a cast ? */
9530         if (! p_j2k->m_tcd ) {
9531                 return OPJ_FALSE;
9532         }
9533
9534         if ( !tcd_init_v2(p_j2k->m_tcd, l_image, &(p_j2k->m_cp)) ) {
9535                 tcd_destroy_v2(p_j2k->m_tcd);
9536                 p_j2k->m_tcd = 00;
9537                 opj_event_msg_v2(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n");
9538                 return OPJ_FALSE;
9539         }
9540
9541         return OPJ_TRUE;
9542 }
9543
9544 /**
9545  * Reads the lookup table containing all the marker, status and action, and returns the handler associated
9546  * with the marker value.
9547  * @param       p_id            Marker value to look up
9548  *
9549  * @return      the handler associated with the id.
9550 */
9551 const opj_dec_memory_marker_handler_t * j2k_get_marker_handler (OPJ_UINT32 p_id)
9552 {
9553         const opj_dec_memory_marker_handler_t *e;
9554         for (e = j2k_memory_marker_handler_tab; e->id != 0; ++e) {
9555                 if (e->id == p_id) {
9556                         break; /* we find a handler corresponding to the marker ID*/
9557                 }
9558         }
9559         return e;
9560 }
9561
9562
9563 /**
9564  * Destroys a jpeg2000 codec.
9565  *
9566  * @param       p_j2k   the jpeg20000 structure to destroy.
9567  */
9568 void j2k_destroy (opj_j2k_v2_t *p_j2k)
9569 {
9570         if (p_j2k == 00) {
9571                 return;
9572         }
9573
9574         if (p_j2k->m_is_decoder) {
9575
9576                 if (p_j2k->m_specific_param.m_decoder.m_default_tcp != 00) {
9577                         j2k_tcp_destroy(p_j2k->m_specific_param.m_decoder.m_default_tcp);
9578                         opj_free(p_j2k->m_specific_param.m_decoder.m_default_tcp);
9579                         p_j2k->m_specific_param.m_decoder.m_default_tcp = 00;
9580                 }
9581
9582                 if (p_j2k->m_specific_param.m_decoder.m_header_data != 00) {
9583                         opj_free(p_j2k->m_specific_param.m_decoder.m_header_data);
9584                         p_j2k->m_specific_param.m_decoder.m_header_data = 00;
9585                         p_j2k->m_specific_param.m_decoder.m_header_data_size = 0;
9586                 }
9587         }
9588         else {
9589
9590                 if (p_j2k->m_specific_param.m_encoder.m_encoded_tile_data) {
9591                         opj_free(p_j2k->m_specific_param.m_encoder.m_encoded_tile_data);
9592                         p_j2k->m_specific_param.m_encoder.m_encoded_tile_data = 00;
9593                 }
9594
9595                 if (p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer) {
9596                         opj_free(p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer);
9597                         p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer = 00;
9598                         p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current = 00;
9599                 }
9600
9601                 if (p_j2k->m_specific_param.m_encoder.m_header_tile_data) {
9602                         opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
9603                         p_j2k->m_specific_param.m_encoder.m_header_tile_data = 00;
9604                         p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
9605                 }
9606         }
9607
9608         tcd_destroy_v2(p_j2k->m_tcd);
9609
9610         j2k_cp_destroy(&(p_j2k->m_cp));
9611         memset(&(p_j2k->m_cp),0,sizeof(opj_cp_v2_t));
9612
9613         opj_procedure_list_destroy(p_j2k->m_procedure_list);
9614         p_j2k->m_procedure_list = 00;
9615
9616         opj_procedure_list_destroy(p_j2k->m_validation_list);
9617         p_j2k->m_procedure_list = 00;
9618
9619         j2k_destroy_cstr_index(p_j2k->cstr_index);
9620         p_j2k->cstr_index = NULL;
9621
9622         opj_image_destroy(p_j2k->m_private_image);
9623         p_j2k->m_private_image = NULL;
9624
9625         opj_image_destroy(p_j2k->m_output_image);
9626         p_j2k->m_output_image = NULL;
9627
9628         opj_free(p_j2k);
9629 }
9630
9631 void j2k_destroy_cstr_index (opj_codestream_index_t *p_cstr_ind)
9632 {
9633         if (p_cstr_ind) {
9634
9635                 if (p_cstr_ind->marker) {
9636                         opj_free(p_cstr_ind->marker);
9637                         p_cstr_ind->marker = NULL;
9638                 }
9639
9640                 if (p_cstr_ind->tile_index) {
9641                         OPJ_UINT32 it_tile = 0;
9642
9643                         for (it_tile=0; it_tile < p_cstr_ind->nb_of_tiles; it_tile++) {
9644
9645                                 if(p_cstr_ind->tile_index[it_tile].packet_index) {
9646                                         opj_free(p_cstr_ind->tile_index[it_tile].packet_index);
9647                                         p_cstr_ind->tile_index[it_tile].packet_index = NULL;
9648                                 }
9649
9650                                 if(p_cstr_ind->tile_index[it_tile].tp_index){
9651                                         opj_free(p_cstr_ind->tile_index[it_tile].tp_index);
9652                                         p_cstr_ind->tile_index[it_tile].tp_index = NULL;
9653                                 }
9654
9655                                 if(p_cstr_ind->tile_index[it_tile].marker){
9656                                         opj_free(p_cstr_ind->tile_index[it_tile].marker);
9657                                         p_cstr_ind->tile_index[it_tile].marker = NULL;
9658
9659                                 }
9660                         }
9661
9662                         opj_free( p_cstr_ind->tile_index);
9663                         p_cstr_ind->tile_index = NULL;
9664                 }
9665
9666                 opj_free(p_cstr_ind);
9667         }
9668 }
9669
9670
9671
9672 /**
9673  * Destroys a tile coding parameter structure.
9674  *
9675  * @param       p_tcp           the tile coding parameter to destroy.
9676  */
9677 void j2k_tcp_destroy (opj_tcp_v2_t *p_tcp)
9678 {
9679         if (p_tcp == 00) {
9680                 return;
9681         }
9682
9683         if (p_tcp->ppt_buffer != 00) {
9684                 opj_free(p_tcp->ppt_buffer);
9685                 p_tcp->ppt_buffer = 00;
9686         }
9687
9688         if (p_tcp->tccps != 00) {
9689                 opj_free(p_tcp->tccps);
9690                 p_tcp->tccps = 00;
9691         }
9692
9693         if (p_tcp->m_mct_coding_matrix != 00) {
9694                 opj_free(p_tcp->m_mct_coding_matrix);
9695                 p_tcp->m_mct_coding_matrix = 00;
9696         }
9697
9698         if (p_tcp->m_mct_decoding_matrix != 00) {
9699                 opj_free(p_tcp->m_mct_decoding_matrix);
9700                 p_tcp->m_mct_decoding_matrix = 00;
9701         }
9702
9703         if (p_tcp->m_mcc_records) {
9704                 opj_free(p_tcp->m_mcc_records);
9705                 p_tcp->m_mcc_records = 00;
9706                 p_tcp->m_nb_max_mcc_records = 0;
9707                 p_tcp->m_nb_mcc_records = 0;
9708         }
9709
9710         if (p_tcp->m_mct_records) {
9711                 opj_mct_data_t * l_mct_data = p_tcp->m_mct_records;
9712                 OPJ_UINT32 i;
9713
9714                 for (i=0;i<p_tcp->m_nb_mct_records;++i) {
9715                         if (l_mct_data->m_data) {
9716                                 opj_free(l_mct_data->m_data);
9717                                 l_mct_data->m_data = 00;
9718                         }
9719
9720                         ++l_mct_data;
9721                 }
9722
9723                 opj_free(p_tcp->m_mct_records);
9724                 p_tcp->m_mct_records = 00;
9725         }
9726
9727         if (p_tcp->mct_norms != 00) {
9728                 opj_free(p_tcp->mct_norms);
9729                 p_tcp->mct_norms = 00;
9730         }
9731
9732         j2k_tcp_data_destroy(p_tcp);
9733
9734 }
9735
9736 /**
9737  * Destroys the data inside a tile coding parameter structure.
9738  *
9739  * @param       p_tcp           the tile coding parameter which contain data to destroy.
9740  */
9741 void j2k_tcp_data_destroy (opj_tcp_v2_t *p_tcp)
9742 {
9743         if (p_tcp->m_data) {
9744                 opj_free(p_tcp->m_data);
9745                 p_tcp->m_data = NULL;
9746                 p_tcp->m_data_size = 0;
9747         }
9748 }
9749
9750 /**
9751  * Destroys a coding parameter structure.
9752  *
9753  * @param       p_cp            the coding parameter to destroy.
9754  */
9755 void j2k_cp_destroy (opj_cp_v2_t *p_cp)
9756 {
9757         OPJ_UINT32 l_nb_tiles;
9758         opj_tcp_v2_t * l_current_tile = 00;
9759         OPJ_UINT32 i;
9760
9761         if
9762                 (p_cp == 00)
9763         {
9764                 return;
9765         }
9766         if
9767                 (p_cp->tcps != 00)
9768         {
9769                 l_current_tile = p_cp->tcps;
9770                 l_nb_tiles = p_cp->th * p_cp->tw;
9771
9772                 for
9773                         (i = 0; i < l_nb_tiles; ++i)
9774                 {
9775                         j2k_tcp_destroy(l_current_tile);
9776                         ++l_current_tile;
9777                 }
9778                 opj_free(p_cp->tcps);
9779                 p_cp->tcps = 00;
9780         }
9781         if
9782                 (p_cp->ppm_buffer != 00)
9783         {
9784                 opj_free(p_cp->ppm_buffer);
9785                 p_cp->ppm_buffer = 00;
9786         }
9787         if
9788                 (p_cp->comment != 00)
9789         {
9790                 opj_free(p_cp->comment);
9791                 p_cp->comment = 00;
9792         }
9793         if
9794                 (! p_cp->m_is_decoder)
9795         {
9796                 if
9797                         (p_cp->m_specific_param.m_enc.m_matrice)
9798                 {
9799                         opj_free(p_cp->m_specific_param.m_enc.m_matrice);
9800                         p_cp->m_specific_param.m_enc.m_matrice = 00;
9801                 }
9802         }
9803 }
9804
9805
9806
9807 /**
9808  * Reads a tile header.
9809  * @param       p_j2k           the jpeg2000 codec.
9810  * @param       p_stream                        the stream to write data to.
9811  * @param       p_manager       the user event manager.
9812  */
9813 opj_bool j2k_read_tile_header(  opj_j2k_v2_t * p_j2k,
9814                                                                 OPJ_UINT32 * p_tile_index,
9815                                                                 OPJ_UINT32 * p_data_size,
9816                                                                 OPJ_INT32 * p_tile_x0, OPJ_INT32 * p_tile_y0,
9817                                                                 OPJ_INT32 * p_tile_x1, OPJ_INT32 * p_tile_y1,
9818                                                                 OPJ_UINT32 * p_nb_comps,
9819                                                                 opj_bool * p_go_on,
9820                                                                 opj_stream_private_t *p_stream,
9821                                                                 opj_event_mgr_t * p_manager )
9822 {
9823         OPJ_UINT32 l_current_marker = J2K_MS_SOT;
9824         OPJ_UINT32 l_marker_size;
9825         const opj_dec_memory_marker_handler_t * l_marker_handler = 00;
9826         opj_tcp_v2_t * l_tcp = NULL;
9827         OPJ_UINT32 l_nb_tiles;
9828
9829         /* preconditions */
9830         assert(p_stream != 00);
9831         assert(p_j2k != 00);
9832         assert(p_manager != 00);
9833
9834         /* Reach the End Of Codestream ?*/
9835         if (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_EOC){
9836                 l_current_marker = J2K_MS_EOC;
9837         }
9838         /* We need to encounter a SOT marker (a new tile-part header) */
9839         else if (p_j2k->m_specific_param.m_decoder.m_state != J2K_STATE_TPHSOT){
9840                 return OPJ_FALSE;
9841         }
9842
9843         /* Read into the codestream until reach the EOC or ! can_decode ??? FIXME */
9844         while ( (!p_j2k->m_specific_param.m_decoder.m_can_decode) && (l_current_marker != J2K_MS_EOC) ) {
9845
9846                 /* Try to read until the Start Of Data is detected */
9847                 while (l_current_marker != J2K_MS_SOD) {
9848
9849                         /* Try to read 2 bytes (the marker size) from stream and copy them into the buffer */
9850                         if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
9851                                 opj_event_msg_v2(p_manager, EVT_ERROR, "Stream too short\n");
9852                                 return OPJ_FALSE;
9853                         }
9854
9855                         /* Read 2 bytes from the buffer as the marker size */
9856                         opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_marker_size,2);
9857
9858                         /* Why this condition? FIXME */
9859                         if (p_j2k->m_specific_param.m_decoder.m_state & J2K_STATE_TPH){
9860                                 p_j2k->m_specific_param.m_decoder.m_sot_length -= (l_marker_size + 2);
9861                         }
9862                         l_marker_size -= 2; /* Subtract the size of the marker ID already read */
9863
9864                         /* Get the marker handler from the marker ID */
9865                         l_marker_handler = j2k_get_marker_handler(l_current_marker);
9866
9867                         /* Check if the marker is known and if it is the right place to find it */
9868                         if (! (p_j2k->m_specific_param.m_decoder.m_state & l_marker_handler->states) ) {
9869                                 opj_event_msg_v2(p_manager, EVT_ERROR, "Marker is not compliant with its position\n");
9870                                 return OPJ_FALSE;
9871                         }
9872 /* FIXME manage case of unknown marker as in the main header ? */
9873
9874                         /* Check if the marker size is compatible with the header data size */
9875                         if (l_marker_size > p_j2k->m_specific_param.m_decoder.m_header_data_size) {
9876                                 p_j2k->m_specific_param.m_decoder.m_header_data = (OPJ_BYTE*)
9877                                         opj_realloc(p_j2k->m_specific_param.m_decoder.m_header_data,l_marker_size);
9878                                 if (p_j2k->m_specific_param.m_decoder.m_header_data == 00) {
9879                                         return OPJ_FALSE;
9880                                 }
9881                                 p_j2k->m_specific_param.m_decoder.m_header_data_size = l_marker_size;
9882                         }
9883
9884                         /* Try to read the rest of the marker segment from stream and copy them into the buffer */
9885                         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) {
9886                                 opj_event_msg_v2(p_manager, EVT_ERROR, "Stream too short\n");
9887                                 return OPJ_FALSE;
9888                         }
9889
9890                         /* Read the marker segment with the correct marker handler */
9891                         if (! (*(l_marker_handler->handler))(p_j2k,p_j2k->m_specific_param.m_decoder.m_header_data,l_marker_size,p_manager)) {
9892                                 opj_event_msg_v2(p_manager, EVT_ERROR, "Fail to read the current marker segment (%#x)\n", l_current_marker);
9893                                 return OPJ_FALSE;
9894                         }
9895
9896                         /* Add the marker to the codestream index*/
9897                         j2k_add_tlmarker_v2(p_j2k->m_current_tile_number,
9898                                                                 p_j2k->cstr_index,
9899                                                                 l_marker_handler->id,
9900                                                                 (OPJ_UINT32) opj_stream_tell(p_stream) - l_marker_size - 4,
9901                                                                 l_marker_size + 4 );
9902
9903                         /* Keep the position of the last SOT marker read */
9904                         if ( l_marker_handler->id == J2K_MS_SOT ) {
9905                                 OPJ_UINT32 sot_pos = (OPJ_UINT32) opj_stream_tell(p_stream) - l_marker_size - 4 ;
9906                                 if (sot_pos > p_j2k->m_specific_param.m_decoder.m_last_sot_read_pos)
9907                                 {
9908                                         p_j2k->m_specific_param.m_decoder.m_last_sot_read_pos = sot_pos;
9909                                 }
9910                         }
9911
9912
9913                         if (p_j2k->m_specific_param.m_decoder.m_skip_data) {
9914                                 /* Skip the rest of the tile part header*/
9915                                 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) {
9916                                         opj_event_msg_v2(p_manager, EVT_ERROR, "Stream too short\n");
9917                                         return OPJ_FALSE;
9918                                 }
9919                                 l_current_marker = J2K_MS_SOD; /* Normally we reached a SOD */
9920                         }
9921                         else {
9922                                 /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer*/
9923                                 if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
9924                                         opj_event_msg_v2(p_manager, EVT_ERROR, "Stream too short\n");
9925                                         return OPJ_FALSE;
9926                                 }
9927                                 /* Read 2 bytes from the buffer as the new marker ID */
9928                                 opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_current_marker,2);
9929                         }
9930                 }
9931
9932                 /* If we didn't skip data before, we need to read the SOD marker*/
9933                 if (! p_j2k->m_specific_param.m_decoder.m_skip_data) {
9934                         /* Try to read the SOD marker and skip data ? FIXME */
9935                         if (! j2k_read_sod_v2(p_j2k, p_stream, p_manager)) {
9936                                 return OPJ_FALSE;
9937                         }
9938
9939
9940
9941                         if (! p_j2k->m_specific_param.m_decoder.m_can_decode){
9942                                 /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer */
9943                                 if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
9944                                         opj_event_msg_v2(p_manager, EVT_ERROR, "Stream too short\n");
9945                                         return OPJ_FALSE;
9946                                 }
9947
9948                                 /* Read 2 bytes from buffer as the new marker ID */
9949                                 opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_current_marker,2);
9950                         }
9951                 }
9952                 else {
9953                         /* Indicate we will try to read a new tile-part header*/
9954                         p_j2k->m_specific_param.m_decoder.m_skip_data = 0;
9955                         p_j2k->m_specific_param.m_decoder.m_can_decode = 0;
9956                         p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_TPHSOT;
9957
9958                         /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer */
9959                         if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
9960                                 opj_event_msg_v2(p_manager, EVT_ERROR, "Stream too short\n");
9961                                 return OPJ_FALSE;
9962                         }
9963
9964                         /* Read 2 bytes from buffer as the new marker ID */
9965                         opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_current_marker,2);
9966                 }
9967         }
9968
9969         /* Current marker is the EOC marker ?*/
9970         if (l_current_marker == J2K_MS_EOC) {
9971                 if (p_j2k->m_specific_param.m_decoder.m_state != J2K_STATE_EOC ){
9972                         p_j2k->m_current_tile_number = 0;
9973                         p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_EOC;
9974                 }
9975         }
9976
9977         /* FIXME DOC ???*/
9978         if ( ! p_j2k->m_specific_param.m_decoder.m_can_decode) {
9979                 l_tcp = p_j2k->m_cp.tcps + p_j2k->m_current_tile_number;
9980                 l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
9981
9982                 while( (p_j2k->m_current_tile_number < l_nb_tiles) && (l_tcp->m_data == 00) ) {
9983                         ++p_j2k->m_current_tile_number;
9984                         ++l_tcp;
9985                 }
9986
9987                 if (p_j2k->m_current_tile_number == l_nb_tiles) {
9988                         *p_go_on = OPJ_FALSE;
9989                         return OPJ_TRUE;
9990                 }
9991         }
9992
9993         /*FIXME ???*/
9994         if (! tcd_init_decode_tile(p_j2k->m_tcd, p_j2k->m_current_tile_number)) {
9995                 opj_event_msg_v2(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n");
9996                 return OPJ_FALSE;
9997         }
9998
9999         opj_event_msg_v2(p_manager, EVT_INFO, "Header of tile %d / %d has been read.\n",
10000                         p_j2k->m_current_tile_number, (p_j2k->m_cp.th * p_j2k->m_cp.tw) - 1);
10001
10002         *p_tile_index = p_j2k->m_current_tile_number;
10003         *p_go_on = OPJ_TRUE;
10004         *p_data_size = tcd_get_decoded_tile_size(p_j2k->m_tcd);
10005         *p_tile_x0 = p_j2k->m_tcd->tcd_image->tiles->x0;
10006         *p_tile_y0 = p_j2k->m_tcd->tcd_image->tiles->y0;
10007         *p_tile_x1 = p_j2k->m_tcd->tcd_image->tiles->x1;
10008         *p_tile_y1 = p_j2k->m_tcd->tcd_image->tiles->y1;
10009         *p_nb_comps = p_j2k->m_tcd->tcd_image->tiles->numcomps;
10010
10011          p_j2k->m_specific_param.m_decoder.m_state |= 0x0080;/* FIXME J2K_DEC_STATE_DATA;*/
10012
10013         return OPJ_TRUE;
10014 }
10015
10016
10017 opj_bool j2k_decode_tile (      opj_j2k_v2_t * p_j2k,
10018                                                         OPJ_UINT32 p_tile_index,
10019                                                         OPJ_BYTE * p_data,
10020                                                         OPJ_UINT32 p_data_size,
10021                                                         opj_stream_private_t *p_stream,
10022                                                         opj_event_mgr_t * p_manager )
10023 {
10024         OPJ_UINT32 l_current_marker;
10025         OPJ_BYTE l_data [2];
10026         opj_tcp_v2_t * l_tcp;
10027
10028         /* preconditions */
10029         assert(p_stream != 00);
10030         assert(p_j2k != 00);
10031         assert(p_manager != 00);
10032
10033         if ( !(p_j2k->m_specific_param.m_decoder.m_state & 0x0080/*FIXME J2K_DEC_STATE_DATA*/)
10034                 || (p_tile_index != p_j2k->m_current_tile_number) ) {
10035                 return OPJ_FALSE;
10036         }
10037
10038         l_tcp = &(p_j2k->m_cp.tcps[p_tile_index]);
10039         if (! l_tcp->m_data) {
10040                 j2k_tcp_destroy(l_tcp);
10041                 return OPJ_FALSE;
10042         }
10043
10044         if (! tcd_decode_tile_v2(       p_j2k->m_tcd,
10045                                                                 l_tcp->m_data,
10046                                                                 l_tcp->m_data_size,
10047                                                                 p_tile_index,
10048                                                                 p_j2k->cstr_index) ) {
10049                 j2k_tcp_destroy(l_tcp);
10050                 p_j2k->m_specific_param.m_decoder.m_state |= 0x8000;/*FIXME J2K_DEC_STATE_ERR;*/
10051                 return OPJ_FALSE;
10052         }
10053
10054         if (! tcd_update_tile_data(p_j2k->m_tcd,p_data,p_data_size)) {
10055                 return OPJ_FALSE;
10056         }
10057
10058         /* To avoid to destroy the tcp which can be useful when we try to decode a tile decoded before (cf j2k_random_tile_access)
10059          * we destroy just the data which will be re-read in read_tile_header*/
10060         /*j2k_tcp_destroy(l_tcp);
10061         p_j2k->m_tcd->tcp = 0;*/
10062         j2k_tcp_data_destroy(l_tcp);
10063
10064         p_j2k->m_specific_param.m_decoder.m_can_decode = 0;
10065         p_j2k->m_specific_param.m_decoder.m_state &= (~ (0x0080));/* FIXME J2K_DEC_STATE_DATA);*/
10066
10067         if (p_j2k->m_specific_param.m_decoder.m_state != 0x0100){ /*FIXME J2K_DEC_STATE_EOC)*/
10068                 if (opj_stream_read_data(p_stream,l_data,2,p_manager) != 2) {
10069                         opj_event_msg_v2(p_manager, EVT_ERROR, "Stream too short\n");
10070                         return OPJ_FALSE;
10071                 }
10072
10073                 opj_read_bytes(l_data,&l_current_marker,2);
10074
10075                 if (l_current_marker == J2K_MS_EOC) {
10076                         p_j2k->m_current_tile_number = 0;
10077                         p_j2k->m_specific_param.m_decoder.m_state =  0x0100;/*FIXME J2K_DEC_STATE_EOC;*/
10078                 }
10079                 else if (l_current_marker != J2K_MS_SOT)
10080                 {
10081                         opj_event_msg_v2(p_manager, EVT_ERROR, "Stream too short, expected SOT\n");
10082                         return OPJ_FALSE;
10083                 }
10084         }
10085
10086         return OPJ_TRUE;
10087 }
10088
10089
10090 opj_bool j2k_update_image_data (opj_tcd_v2_t * p_tcd, OPJ_BYTE * p_data, opj_image_t* p_output_image)
10091 {
10092         OPJ_UINT32 i,j,k = 0;
10093         OPJ_UINT32 l_width_src,l_height_src;
10094         OPJ_UINT32 l_width_dest,l_height_dest;
10095         OPJ_INT32 l_offset_x0_src, l_offset_y0_src, l_offset_x1_src, l_offset_y1_src;
10096         OPJ_INT32 l_start_offset_src, l_line_offset_src, l_end_offset_src ;
10097         OPJ_UINT32 l_start_x_dest , l_start_y_dest;
10098         OPJ_UINT32 l_x0_dest, l_y0_dest, l_x1_dest, l_y1_dest;
10099         OPJ_INT32 l_start_offset_dest, l_line_offset_dest;
10100
10101         opj_image_comp_t * l_img_comp_src = 00;
10102         opj_image_comp_t * l_img_comp_dest = 00;
10103
10104         opj_tcd_tilecomp_v2_t * l_tilec = 00;
10105         opj_image_t * l_image_src = 00;
10106         OPJ_UINT32 l_size_comp, l_remaining;
10107         OPJ_INT32 * l_dest_ptr;
10108         opj_tcd_resolution_v2_t* l_res= 00;
10109
10110         l_tilec = p_tcd->tcd_image->tiles->comps;
10111         l_image_src = p_tcd->image;
10112         l_img_comp_src = l_image_src->comps;
10113
10114         l_img_comp_dest = p_output_image->comps;
10115
10116         for (i=0; i<l_image_src->numcomps; i++) {
10117
10118                 /* Allocate output component buffer if necessary */
10119                 if (!l_img_comp_dest->data) {
10120
10121                         l_img_comp_dest->data = (OPJ_INT32*) opj_calloc(l_img_comp_dest->w * l_img_comp_dest->h, sizeof(OPJ_INT32));
10122                         if (! l_img_comp_dest->data) {
10123                                 return OPJ_FALSE;
10124                         }
10125                 }
10126
10127                 /* Copy info from decoded comp image to output image */
10128                 l_img_comp_dest->resno_decoded = l_img_comp_src->resno_decoded;
10129
10130                 /*-----*/
10131                 /* Compute the precision of the output buffer */
10132                 l_size_comp = l_img_comp_src->prec >> 3; /*(/ 8)*/
10133                 l_remaining = l_img_comp_src->prec & 7;  /* (%8) */
10134                 l_res = l_tilec->resolutions + l_img_comp_src->resno_decoded;
10135
10136                 if (l_remaining) {
10137                         ++l_size_comp;
10138                 }
10139
10140                 if (l_size_comp == 3) {
10141                         l_size_comp = 4;
10142                 }
10143                 /*-----*/
10144
10145                 /* Current tile component size*/
10146                 /*if (i == 0) {
10147                 fprintf(stdout, "SRC: l_res_x0=%d, l_res_x1=%d, l_res_y0=%d, l_res_y1=%d\n",
10148                                 l_res->x0, l_res->x1, l_res->y0, l_res->y1);
10149                 }*/
10150
10151                 l_width_src = (l_res->x1 - l_res->x0);
10152                 l_height_src = (l_res->y1 - l_res->y0);
10153
10154                 /* Border of the current output component*/
10155                 l_x0_dest = int_ceildivpow2(l_img_comp_dest->x0, l_img_comp_dest->factor);
10156                 l_y0_dest = int_ceildivpow2(l_img_comp_dest->y0, l_img_comp_dest->factor);
10157                 l_x1_dest = l_x0_dest + l_img_comp_dest->w;
10158                 l_y1_dest = l_y0_dest + l_img_comp_dest->h;
10159
10160                 /*if (i == 0) {
10161                 fprintf(stdout, "DEST: l_x0_dest=%d, l_x1_dest=%d, l_y0_dest=%d, l_y1_dest=%d (%d)\n",
10162                                 l_x0_dest, l_x1_dest, l_y0_dest, l_y1_dest, l_img_comp_dest->factor );
10163                 }*/
10164
10165                 /*-----*/
10166                 /* Compute the area (l_offset_x0_src, l_offset_y0_src, l_offset_x1_src, l_offset_y1_src)
10167                  * of the input buffer (decoded tile component) which will be move
10168                  * in the output buffer. Compute the area of the output buffer (l_start_x_dest,
10169                  * l_start_y_dest, l_width_dest, l_height_dest)  which will be modified
10170                  * by this input area.
10171                  * */
10172                 assert( l_res->x0 >= 0);
10173                 assert( l_res->x1 >= 0);
10174                 if ( l_x0_dest < (OPJ_UINT32)l_res->x0 ) {
10175                         l_start_x_dest = l_res->x0 - l_x0_dest;
10176                         l_offset_x0_src = 0;
10177
10178                         if ( l_x1_dest >= (OPJ_UINT32)l_res->x1 ) {
10179                                 l_width_dest = l_width_src;
10180                                 l_offset_x1_src = 0;
10181                         }
10182                         else {
10183                                 l_width_dest = l_x1_dest - l_res->x0 ;
10184                                 l_offset_x1_src = l_width_src - l_width_dest;
10185                         }
10186                 }
10187                 else {
10188                         l_start_x_dest = 0 ;
10189                         l_offset_x0_src = l_x0_dest - l_res->x0;
10190
10191                         if ( l_x1_dest >= (OPJ_UINT32)l_res->x1 ) {
10192                                 l_width_dest = l_width_src - l_offset_x0_src;
10193                                 l_offset_x1_src = 0;
10194                         }
10195                         else {
10196                                 l_width_dest = l_img_comp_dest->w ;
10197                                 l_offset_x1_src = l_res->x1 - l_x1_dest;
10198                         }
10199                 }
10200
10201                 if ( l_y0_dest < (OPJ_UINT32)l_res->y0 ) {
10202                         l_start_y_dest = l_res->y0 - l_y0_dest;
10203                         l_offset_y0_src = 0;
10204
10205                         if ( l_y1_dest >= (OPJ_UINT32)l_res->y1 ) {
10206                                 l_height_dest = l_height_src;
10207                                 l_offset_y1_src = 0;
10208                         }
10209                         else {
10210                                 l_height_dest = l_y1_dest - l_res->y0 ;
10211                                 l_offset_y1_src =  l_height_src - l_height_dest;
10212                         }
10213                 }
10214                 else {
10215                         l_start_y_dest = 0 ;
10216                         l_offset_y0_src = l_y0_dest - l_res->y0;
10217
10218                         if ( l_y1_dest >= (OPJ_UINT32)l_res->y1 ) {
10219                                 l_height_dest = l_height_src - l_offset_y0_src;
10220                                 l_offset_y1_src = 0;
10221                         }
10222                         else {
10223                                 l_height_dest = l_img_comp_dest->h ;
10224                                 l_offset_y1_src = l_res->y1 - l_y1_dest;
10225                         }
10226                 }
10227
10228                 if( (l_offset_x0_src < 0 ) || (l_offset_y0_src < 0 ) || (l_offset_x1_src < 0 ) || (l_offset_y1_src < 0 ) ){
10229                         return OPJ_FALSE;
10230                 }
10231                 /*-----*/
10232
10233                 /* Compute the input buffer offset */
10234                 l_start_offset_src = l_offset_x0_src + l_offset_y0_src * l_width_src;
10235                 l_line_offset_src = l_offset_x1_src + l_offset_x0_src;
10236                 l_end_offset_src = l_offset_y1_src * l_width_src - l_offset_x0_src;
10237
10238                 /* Compute the output buffer offset */
10239                 l_start_offset_dest = l_start_x_dest + l_start_y_dest * l_img_comp_dest->w;
10240                 l_line_offset_dest = l_img_comp_dest->w - l_width_dest;
10241
10242                 /* Move the output buffer to the first place where we will write*/
10243                 l_dest_ptr = l_img_comp_dest->data + l_start_offset_dest;
10244
10245                 /*if (i == 0) {
10246                         fprintf(stdout, "COMPO[%d]:\n",i);
10247                         fprintf(stdout, "SRC: l_start_x_src=%d, l_start_y_src=%d, l_width_src=%d, l_height_src=%d\n"
10248                                         "\t tile offset:%d, %d, %d, %d\n"
10249                                         "\t buffer offset: %d; %d, %d\n",
10250                                         l_res->x0, l_res->y0, l_width_src, l_height_src,
10251                                         l_offset_x0_src, l_offset_y0_src, l_offset_x1_src, l_offset_y1_src,
10252                                         l_start_offset_src, l_line_offset_src, l_end_offset_src);
10253
10254                         fprintf(stdout, "DEST: l_start_x_dest=%d, l_start_y_dest=%d, l_width_dest=%d, l_height_dest=%d\n"
10255                                         "\t start offset: %d, line offset= %d\n",
10256                                         l_start_x_dest, l_start_y_dest, l_width_dest, l_height_dest, l_start_offset_dest, l_line_offset_dest);
10257                 }*/
10258
10259
10260                 switch (l_size_comp) {
10261                         case 1:
10262                                 {
10263                                         OPJ_CHAR * l_src_ptr = (OPJ_CHAR*) p_data;
10264                                         l_src_ptr += l_start_offset_src; /* Move to the first place where we will read*/
10265
10266                                         if (l_img_comp_src->sgnd) {
10267                                                 for (j = 0 ; j < l_height_dest ; ++j) {
10268                                                         for ( k = 0 ; k < l_width_dest ; ++k) {
10269                                                                 *(l_dest_ptr++) = (OPJ_INT32) (*(l_src_ptr++)); /* Copy only the data needed for the output image */
10270                                                         }
10271
10272                                                         l_dest_ptr+= l_line_offset_dest; /* Move to the next place where we will write */
10273                                                         l_src_ptr += l_line_offset_src ; /* Move to the next place where we will read */
10274                                                 }
10275                                         }
10276                                         else {
10277                                                 for ( j = 0 ; j < l_height_dest ; ++j ) {
10278                                                         for ( k = 0 ; k < l_width_dest ; ++k) {
10279                                                                 *(l_dest_ptr++) = (OPJ_INT32) ((*(l_src_ptr++))&0xff);
10280                                                         }
10281
10282                                                         l_dest_ptr+= l_line_offset_dest;
10283                                                         l_src_ptr += l_line_offset_src;
10284                                                 }
10285                                         }
10286
10287                                         l_src_ptr += l_end_offset_src; /* Move to the end of this component-part of the input buffer */
10288                                         p_data = (OPJ_BYTE*) l_src_ptr; /* Keep the current position for the next component-part */
10289                                 }
10290                                 break;
10291                         case 2:
10292                                 {
10293                                         OPJ_INT16 * l_src_ptr = (OPJ_INT16 *) p_data;
10294                                         l_src_ptr += l_start_offset_src;
10295
10296                                         if (l_img_comp_src->sgnd) {
10297                                                 for (j=0;j<l_height_dest;++j) {
10298                                                         for (k=0;k<l_width_dest;++k) {
10299                                                                 *(l_dest_ptr++) = *(l_src_ptr++);
10300                                                         }
10301
10302                                                         l_dest_ptr+= l_line_offset_dest;
10303                                                         l_src_ptr += l_line_offset_src ;
10304                                                 }
10305                                         }
10306                                         else {
10307                                                 for (j=0;j<l_height_dest;++j) {
10308                                                         for (k=0;k<l_width_dest;++k) {
10309                                                                 *(l_dest_ptr++) = (*(l_src_ptr++))&0xffff;
10310                                                         }
10311
10312                                                         l_dest_ptr+= l_line_offset_dest;
10313                                                         l_src_ptr += l_line_offset_src ;
10314                                                 }
10315                                         }
10316
10317                                         l_src_ptr += l_end_offset_src;
10318                                         p_data = (OPJ_BYTE*) l_src_ptr;
10319                                 }
10320                                 break;
10321                         case 4:
10322                                 {
10323                                         OPJ_INT32 * l_src_ptr = (OPJ_INT32 *) p_data;
10324                                         l_src_ptr += l_start_offset_src;
10325
10326                                         for (j=0;j<l_height_dest;++j) {
10327                                                 for (k=0;k<l_width_dest;++k) {
10328                                                         *(l_dest_ptr++) = (*(l_src_ptr++));
10329                                                 }
10330
10331                                                 l_dest_ptr+= l_line_offset_dest;
10332                                                 l_src_ptr += l_line_offset_src ;
10333                                         }
10334
10335                                         l_src_ptr += l_end_offset_src;
10336                                         p_data = (OPJ_BYTE*) l_src_ptr;
10337                                 }
10338                                 break;
10339                 }
10340
10341                 ++l_img_comp_dest;
10342                 ++l_img_comp_src;
10343                 ++l_tilec;
10344         }
10345
10346         return OPJ_TRUE;
10347 }
10348
10349 /**
10350  * Sets the given area to be decoded. This function should be called right after opj_read_header and before any tile header reading.
10351  *
10352  * @param       p_j2k                   the jpeg2000 codec.
10353  * @param       p_start_x               the left position of the rectangle to decode (in image coordinates).
10354  * @param       p_end_x                 the right position of the rectangle to decode (in image coordinates).
10355  * @param       p_start_y               the up position of the rectangle to decode (in image coordinates).
10356  * @param       p_end_y                 the bottom position of the rectangle to decode (in image coordinates).
10357  * @param       p_manager               the user event manager
10358  *
10359  * @return      true                    if the area could be set.
10360  */
10361 opj_bool j2k_set_decode_area(   opj_j2k_v2_t *p_j2k,
10362                                                                 opj_image_t* p_image,
10363                                                                 OPJ_INT32 p_start_x, OPJ_INT32 p_start_y,
10364                                                                 OPJ_INT32 p_end_x, OPJ_INT32 p_end_y,
10365                                                                 struct opj_event_mgr * p_manager )
10366 {
10367         opj_cp_v2_t * l_cp = &(p_j2k->m_cp);
10368         opj_image_t * l_image = p_j2k->m_private_image;
10369
10370         OPJ_UINT32 it_comp;
10371         OPJ_INT32 l_comp_x1, l_comp_y1;
10372         opj_image_comp_t* l_img_comp = NULL;
10373
10374         /* Check if we are read the main header */
10375         if (p_j2k->m_specific_param.m_decoder.m_state != J2K_STATE_TPHSOT) { /* FIXME J2K_DEC_STATE_TPHSOT)*/
10376                 opj_event_msg_v2(p_manager, EVT_ERROR, "Need to decode the main header before begin to decode the remaining codestream");
10377                 return OPJ_FALSE;
10378         }
10379
10380         if ( !p_start_x && !p_start_y && !p_end_x && !p_end_y){
10381                 opj_event_msg_v2(p_manager, EVT_INFO, "No decoded area parameters, set the decoded area to the whole image\n");
10382
10383                 p_j2k->m_specific_param.m_decoder.m_start_tile_x = 0;
10384                 p_j2k->m_specific_param.m_decoder.m_start_tile_y = 0;
10385                 p_j2k->m_specific_param.m_decoder.m_end_tile_x = l_cp->tw;
10386                 p_j2k->m_specific_param.m_decoder.m_end_tile_y = l_cp->th;
10387
10388                 return OPJ_TRUE;
10389         }
10390
10391         /* ----- */
10392         /* Check if the positions provided by the user are correct */
10393
10394         /* Left */
10395         assert(p_start_x >= 0 );
10396         assert(p_start_y >= 0 );
10397
10398         if ((OPJ_UINT32)p_start_x > l_image->x1 ) {
10399                 opj_event_msg_v2(p_manager, EVT_ERROR,
10400                         "Left position of the decoded area (region_x0=%d) is outside the image area (Xsiz=%d).\n",
10401                         p_start_x, l_image->x1);
10402                 return OPJ_FALSE;
10403         }
10404         else if ((OPJ_UINT32)p_start_x < l_image->x0){
10405                 opj_event_msg_v2(p_manager, EVT_WARNING,
10406                                 "Left position of the decoded area (region_x0=%d) is outside the image area (XOsiz=%d).\n",
10407                                 p_start_x, l_image->x0);
10408                 p_j2k->m_specific_param.m_decoder.m_start_tile_x = 0;
10409                 p_image->x0 = l_image->x0;
10410         }
10411         else {
10412                 p_j2k->m_specific_param.m_decoder.m_start_tile_x = (p_start_x - l_cp->tx0) / l_cp->tdx;
10413                 p_image->x0 = p_start_x;
10414         }
10415
10416         /* Up */
10417         if ((OPJ_UINT32)p_start_y > l_image->y1){
10418                 opj_event_msg_v2(p_manager, EVT_ERROR,
10419                                 "Up position of the decoded area (region_y0=%d) is outside the image area (Ysiz=%d).\n",
10420                                 p_start_y, l_image->y1);
10421                 return OPJ_FALSE;
10422         }
10423         else if ((OPJ_UINT32)p_start_y < l_image->y0){
10424                 opj_event_msg_v2(p_manager, EVT_WARNING,
10425                                 "Up position of the decoded area (region_y0=%d) is outside the image area (YOsiz=%d).\n",
10426                                 p_start_y, l_image->y0);
10427                 p_j2k->m_specific_param.m_decoder.m_start_tile_y = 0;
10428                 p_image->y0 = l_image->y0;
10429         }
10430         else {
10431                 p_j2k->m_specific_param.m_decoder.m_start_tile_y = (p_start_y - l_cp->ty0) / l_cp->tdy;
10432                 p_image->y0 = p_start_y;
10433         }
10434
10435         /* Right */
10436         assert((OPJ_UINT32)p_end_x > 0);
10437         assert((OPJ_UINT32)p_end_y > 0);
10438         if ((OPJ_UINT32)p_end_x < l_image->x0) {
10439                 opj_event_msg_v2(p_manager, EVT_ERROR,
10440                         "Right position of the decoded area (region_x1=%d) is outside the image area (XOsiz=%d).\n",
10441                         p_end_x, l_image->x0);
10442                 return OPJ_FALSE;
10443         }
10444         else if ((OPJ_UINT32)p_end_x > l_image->x1) {
10445                 opj_event_msg_v2(p_manager, EVT_WARNING,
10446                         "Right position of the decoded area (region_x1=%d) is outside the image area (Xsiz=%d).\n",
10447                         p_end_x, l_image->x1);
10448                 p_j2k->m_specific_param.m_decoder.m_end_tile_x = l_cp->tw;
10449                 p_image->x1 = l_image->x1;
10450         }
10451         else {
10452                 p_j2k->m_specific_param.m_decoder.m_end_tile_x = int_ceildiv((p_end_x - l_cp->tx0), l_cp->tdx);
10453                 p_image->x1 = p_end_x;
10454         }
10455
10456         /* Bottom */
10457         if ((OPJ_UINT32)p_end_y < l_image->y0) {
10458                 opj_event_msg_v2(p_manager, EVT_ERROR,
10459                         "Bottom position of the decoded area (region_y1=%d) is outside the image area (YOsiz=%d).\n",
10460                         p_end_y, l_image->y0);
10461                 return OPJ_FALSE;
10462         }
10463         if ((OPJ_UINT32)p_end_y > l_image->y1){
10464                 opj_event_msg_v2(p_manager, EVT_WARNING,
10465                         "Bottom position of the decoded area (region_y1=%d) is outside the image area (Ysiz=%d).\n",
10466                         p_end_y, l_image->y1);
10467                 p_j2k->m_specific_param.m_decoder.m_end_tile_y = l_cp->th;
10468                 p_image->y1 = l_image->y1;
10469         }
10470         else{
10471                 p_j2k->m_specific_param.m_decoder.m_end_tile_y = int_ceildiv((p_end_y - l_cp->ty0), l_cp->tdy);
10472                 p_image->y1 = p_end_y;
10473         }
10474         /* ----- */
10475
10476         p_j2k->m_specific_param.m_decoder.m_discard_tiles = 1;
10477
10478         l_img_comp = p_image->comps;
10479         for (it_comp=0; it_comp < p_image->numcomps; ++it_comp)
10480         {
10481                 OPJ_INT32 l_h,l_w;
10482
10483                 l_img_comp->x0 = int_ceildiv(p_image->x0, l_img_comp->dx);
10484                 l_img_comp->y0 = int_ceildiv(p_image->y0, l_img_comp->dy);
10485                 l_comp_x1 = int_ceildiv(p_image->x1, l_img_comp->dx);
10486                 l_comp_y1 = int_ceildiv(p_image->y1, l_img_comp->dy);
10487
10488                 l_w = int_ceildivpow2(l_comp_x1, l_img_comp->factor)
10489                                 - int_ceildivpow2(l_img_comp->x0, l_img_comp->factor);
10490                 if (l_w < 0){
10491                         opj_event_msg_v2(p_manager, EVT_ERROR,
10492                                 "Size x of the decoded component image is incorrect (comp[%d].w=%d).\n",
10493                                 it_comp, l_w);
10494                         return OPJ_FALSE;
10495                 }
10496                 l_img_comp->w = l_w;
10497
10498                 l_h = int_ceildivpow2(l_comp_y1, l_img_comp->factor)
10499                                 - int_ceildivpow2(l_img_comp->y0, l_img_comp->factor);
10500                 if (l_h < 0){
10501                         opj_event_msg_v2(p_manager, EVT_ERROR,
10502                                 "Size y of the decoded component image is incorrect (comp[%d].h=%d).\n",
10503                                 it_comp, l_h);
10504                         return OPJ_FALSE;
10505                 }
10506                 l_img_comp->h = l_h;
10507
10508                 l_img_comp++;
10509         }
10510
10511         opj_event_msg_v2( p_manager, EVT_INFO,"Setting decoding area to %d,%d,%d,%d\n",
10512                         p_image->x0, p_image->y0, p_image->x1, p_image->y1);
10513
10514
10515         return OPJ_TRUE;
10516 }
10517
10518
10519 /* ----------------------------------------------------------------------- */
10520 /* J2K / JPT decoder interface                                             */
10521 /* ----------------------------------------------------------------------- */
10522 /**
10523  * Creates a J2K decompression structure.
10524  *
10525  * @return a handle to a J2K decompressor if successful, NULL otherwise.
10526 */
10527 opj_j2k_v2_t* j2k_create_decompress_v2(void)
10528 {
10529         opj_j2k_v2_t *l_j2k = (opj_j2k_v2_t*) opj_malloc(sizeof(opj_j2k_v2_t));
10530         if (!l_j2k) {
10531                 return 00;
10532         }
10533         memset(l_j2k,0,sizeof(opj_j2k_v2_t));
10534
10535         l_j2k->m_is_decoder = 1;
10536         l_j2k->m_cp.m_is_decoder = 1;
10537
10538         l_j2k->m_specific_param.m_decoder.m_default_tcp = (opj_tcp_v2_t*) opj_malloc(sizeof(opj_tcp_v2_t));
10539         if (!l_j2k->m_specific_param.m_decoder.m_default_tcp) {
10540                 j2k_destroy(l_j2k);
10541                 return 00;
10542         }
10543         memset(l_j2k->m_specific_param.m_decoder.m_default_tcp,0,sizeof(opj_tcp_v2_t));
10544
10545         l_j2k->m_specific_param.m_decoder.m_header_data = (OPJ_BYTE *) opj_malloc(J2K_DEFAULT_HEADER_SIZE);
10546         if (! l_j2k->m_specific_param.m_decoder.m_header_data) {
10547                 j2k_destroy(l_j2k);
10548                 return 00;
10549         }
10550
10551         l_j2k->m_specific_param.m_decoder.m_header_data_size = J2K_DEFAULT_HEADER_SIZE;
10552
10553         l_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec = -1 ;
10554
10555         l_j2k->m_specific_param.m_decoder.m_last_sot_read_pos = 0 ;
10556
10557         /* codestream index creation */
10558         l_j2k->cstr_index = j2k_create_cstr_index();
10559
10560                         /*(opj_codestream_index_t*) opj_malloc(sizeof(opj_codestream_index_t));
10561         if (!l_j2k->cstr_index){
10562                 j2k_destroy(l_j2k);
10563                 return NULL;
10564         }
10565
10566         l_j2k->cstr_index->marker = (opj_marker_info_t*) opj_malloc(100 * sizeof(opj_marker_info_t));
10567 */
10568
10569         /* validation list creation */
10570         l_j2k->m_validation_list = opj_procedure_list_create();
10571         if (! l_j2k->m_validation_list) {
10572                 j2k_destroy(l_j2k);
10573                 return 00;
10574         }
10575
10576         /* execution list creation */
10577         l_j2k->m_procedure_list = opj_procedure_list_create();
10578         if (! l_j2k->m_procedure_list) {
10579                 j2k_destroy(l_j2k);
10580                 return 00;
10581         }
10582
10583         return l_j2k;
10584 }
10585
10586
10587 opj_codestream_index_t* j2k_create_cstr_index(void)
10588 {
10589         opj_codestream_index_t* cstr_index = (opj_codestream_index_t*)
10590                         opj_calloc(1,sizeof(opj_codestream_index_t));
10591         if (!cstr_index)
10592                 return NULL;
10593
10594         cstr_index->maxmarknum = 100;
10595         cstr_index->marknum = 0;
10596         cstr_index->marker = (opj_marker_info_t*)
10597                         opj_calloc(cstr_index->maxmarknum, sizeof(opj_marker_info_t));
10598         if (!cstr_index-> marker)
10599                 return NULL;
10600
10601         cstr_index->tile_index = NULL;
10602
10603         return cstr_index;
10604 }
10605
10606
10607 /**
10608  * Gets the size taken by writing a SPCod or SPCoc for the given tile and component.
10609  *
10610  * @param       p_tile_no               the tile index.
10611  * @param       p_comp_no               the component being outputted.
10612  * @param       p_j2k                   the J2K codec.
10613  *
10614  * @return      the number of bytes taken by the SPCod element.
10615  */
10616 OPJ_UINT32 j2k_get_SPCod_SPCoc_size (   opj_j2k_v2_t *p_j2k,
10617                                                                                 OPJ_UINT32 p_tile_no,
10618                                                                                 OPJ_UINT32 p_comp_no )
10619 {
10620         opj_cp_v2_t *l_cp = 00;
10621         opj_tcp_v2_t *l_tcp = 00;
10622         opj_tccp_t *l_tccp = 00;
10623
10624         /* preconditions */
10625         assert(p_j2k != 00);
10626
10627         l_cp = &(p_j2k->m_cp);
10628         l_tcp = &l_cp->tcps[p_tile_no];
10629         l_tccp = &l_tcp->tccps[p_comp_no];
10630
10631         /* preconditions again */
10632         assert(p_tile_no < (l_cp->tw * l_cp->th));
10633         assert(p_comp_no < p_j2k->m_private_image->numcomps);
10634
10635         if (l_tccp->csty & J2K_CCP_CSTY_PRT) {
10636                 return 5 + l_tccp->numresolutions;
10637         }
10638         else {
10639                 return 5;
10640         }
10641 }
10642
10643 /**
10644  * Writes a SPCod or SPCoc element, i.e. the coding style of a given component of a tile.
10645  *
10646  * @param       p_comp_no       the component number to output.
10647  * @param       p_stream                        the stream to write data to.
10648  * @param       p_j2k                   J2K codec.
10649  * @param       p_manager       the user event manager.
10650  *
10651 */
10652 opj_bool j2k_write_SPCod_SPCoc( opj_j2k_v2_t *p_j2k,
10653                                                                 OPJ_UINT32 p_tile_no,
10654                                                                 OPJ_UINT32 p_comp_no,
10655                                                                 OPJ_BYTE * p_data,
10656                                                                 OPJ_UINT32 * p_header_size,
10657                                                                 struct opj_event_mgr * p_manager )
10658 {
10659         OPJ_UINT32 i;
10660         opj_cp_v2_t *l_cp = 00;
10661         opj_tcp_v2_t *l_tcp = 00;
10662         opj_tccp_t *l_tccp = 00;
10663
10664         /* preconditions */
10665         assert(p_j2k != 00);
10666         assert(p_header_size != 00);
10667         assert(p_manager != 00);
10668         assert(p_data != 00);
10669
10670         l_cp = &(p_j2k->m_cp);
10671         l_tcp = &l_cp->tcps[p_tile_no];
10672         l_tccp = &l_tcp->tccps[p_comp_no];
10673
10674         /* preconditions again */
10675         assert(p_tile_no < (l_cp->tw * l_cp->th));
10676         assert(p_comp_no <(p_j2k->m_private_image->numcomps));
10677
10678         if (*p_header_size < 5) {
10679                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error writing SPCod SPCoc element\n");
10680                 return OPJ_FALSE;
10681         }
10682
10683         opj_write_bytes(p_data,l_tccp->numresolutions - 1, 1);  /* SPcoc (D) */
10684         ++p_data;
10685
10686         opj_write_bytes(p_data,l_tccp->cblkw - 2, 1);                   /* SPcoc (E) */
10687         ++p_data;
10688
10689         opj_write_bytes(p_data,l_tccp->cblkh - 2, 1);                   /* SPcoc (F) */
10690         ++p_data;
10691
10692         opj_write_bytes(p_data,l_tccp->cblksty, 1);                             /* SPcoc (G) */
10693         ++p_data;
10694
10695         opj_write_bytes(p_data,l_tccp->qmfbid, 1);                              /* SPcoc (H) */
10696         ++p_data;
10697
10698         *p_header_size = *p_header_size - 5;
10699
10700         if (l_tccp->csty & J2K_CCP_CSTY_PRT) {
10701
10702                 if (*p_header_size < l_tccp->numresolutions) {
10703                         opj_event_msg_v2(p_manager, EVT_ERROR, "Error writting SPCod SPCoc element\n");
10704                         return OPJ_FALSE;
10705                 }
10706
10707                 for (i = 0; i < l_tccp->numresolutions; ++i) {
10708                         opj_write_bytes(p_data,l_tccp->prcw[i] + (l_tccp->prch[i] << 4), 1);    /* SPcoc (I_i) */
10709                         ++p_data;
10710                 }
10711
10712                 *p_header_size = *p_header_size - l_tccp->numresolutions;
10713         }
10714
10715         return OPJ_TRUE;
10716 }
10717
10718 /**
10719  * Reads a SPCod or SPCoc element, i.e. the coding style of a given component of a tile.
10720  * @param       p_header_data   the data contained in the COM box.
10721  * @param       p_j2k                   the jpeg2000 codec.
10722  * @param       p_header_size   the size of the data contained in the COM marker.
10723  * @param       p_manager               the user event manager.
10724 */
10725 opj_bool j2k_read_SPCod_SPCoc(
10726                                                     opj_j2k_v2_t *p_j2k,
10727                                                         OPJ_UINT32 compno,
10728                                                         OPJ_BYTE * p_header_data,
10729                                                         OPJ_UINT32 * p_header_size,
10730                                                         struct opj_event_mgr * p_manager
10731                                                         )
10732 {
10733         OPJ_UINT32 i, l_tmp;
10734         opj_cp_v2_t *l_cp = NULL;
10735         opj_tcp_v2_t *l_tcp = NULL;
10736         opj_tccp_t *l_tccp = NULL;
10737         OPJ_BYTE * l_current_ptr = NULL;
10738
10739         /* preconditions */
10740         assert(p_j2k != 00);
10741         assert(p_manager != 00);
10742         assert(p_header_data != 00);
10743
10744         l_cp = &(p_j2k->m_cp);
10745         l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH) ?
10746                                 &l_cp->tcps[p_j2k->m_current_tile_number] :
10747                                 p_j2k->m_specific_param.m_decoder.m_default_tcp;
10748
10749         /* precondition again */
10750         assert(compno < p_j2k->m_private_image->numcomps);
10751
10752         l_tccp = &l_tcp->tccps[compno];
10753         l_current_ptr = p_header_data;
10754
10755         /* make sure room is sufficient */
10756         if (*p_header_size < 5) {
10757                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading SPCod SPCoc element\n");
10758                 return OPJ_FALSE;
10759         }
10760
10761         opj_read_bytes(l_current_ptr, &l_tccp->numresolutions ,1);              /* SPcox (D) */
10762         ++l_tccp->numresolutions;                                                                               /* tccp->numresolutions = read() + 1 */
10763         ++l_current_ptr;
10764
10765         /* If user wants to remove more resolutions than the codestream contains, return error */
10766         if (l_cp->m_specific_param.m_dec.m_reduce >= l_tccp->numresolutions) {
10767                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error decoding component %d.\nThe number of resolutions to remove is higher than the number "
10768                                         "of resolutions of this component\nModify the cp_reduce parameter.\n\n", compno);
10769                 p_j2k->m_specific_param.m_decoder.m_state |= 0x8000;/* FIXME J2K_DEC_STATE_ERR;*/
10770                 return OPJ_FALSE;
10771         }
10772
10773         opj_read_bytes(l_current_ptr,&l_tccp->cblkw ,1);                /* SPcoc (E) */
10774         ++l_current_ptr;
10775         l_tccp->cblkw += 2;
10776
10777         opj_read_bytes(l_current_ptr,&l_tccp->cblkh ,1);                /* SPcoc (F) */
10778         ++l_current_ptr;
10779         l_tccp->cblkh += 2;
10780
10781         opj_read_bytes(l_current_ptr,&l_tccp->cblksty ,1);              /* SPcoc (G) */
10782         ++l_current_ptr;
10783
10784         opj_read_bytes(l_current_ptr,&l_tccp->qmfbid ,1);               /* SPcoc (H) */
10785         ++l_current_ptr;
10786
10787         *p_header_size = *p_header_size - 5;
10788
10789         /* use custom precinct size ? */
10790         if (l_tccp->csty & J2K_CCP_CSTY_PRT) {
10791                 if (*p_header_size < l_tccp->numresolutions) {
10792                         opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading SPCod SPCoc element\n");
10793                         return OPJ_FALSE;
10794                 }
10795
10796                 for     (i = 0; i < l_tccp->numresolutions; ++i) {
10797                         opj_read_bytes(l_current_ptr,&l_tmp ,1);                /* SPcoc (I_i) */
10798                         ++l_current_ptr;
10799                         l_tccp->prcw[i] = l_tmp & 0xf;
10800                         l_tccp->prch[i] = l_tmp >> 4;
10801                 }
10802
10803                 *p_header_size = *p_header_size - l_tccp->numresolutions;
10804         }
10805         else {
10806                 /* set default size for the precinct width and height */
10807                 for     (i = 0; i < l_tccp->numresolutions; ++i) {
10808                         l_tccp->prcw[i] = 15;
10809                         l_tccp->prch[i] = 15;
10810                 }
10811         }
10812
10813 #ifdef WIP_REMOVE_MSD
10814         /* INDEX >> */
10815         if (p_j2k->cstr_info && compno == 0) {
10816                 OPJ_UINT32 l_data_size = l_tccp->numresolutions * sizeof(OPJ_UINT32);
10817
10818                 p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].tccp_info[compno].cblkh = l_tccp->cblkh;
10819                 p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].tccp_info[compno].cblkw = l_tccp->cblkw;
10820                 p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].tccp_info[compno].numresolutions = l_tccp->numresolutions;
10821                 p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].tccp_info[compno].cblksty = l_tccp->cblksty;
10822                 p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].tccp_info[compno].qmfbid = l_tccp->qmfbid;
10823
10824
10825                 memcpy(p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].pdx,l_tccp->prcw, l_data_size);
10826                 memcpy(p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].pdy,l_tccp->prch, l_data_size);
10827         }
10828         /* << INDEX */
10829 #endif
10830
10831         return OPJ_TRUE;
10832 }
10833
10834 /**
10835  * Copies the tile component parameters of all the component from the first tile component.
10836  *
10837  * @param               p_j2k           the J2k codec.
10838  */
10839 void j2k_copy_tile_component_parameters( opj_j2k_v2_t *p_j2k )
10840 {
10841         /* loop */
10842         OPJ_UINT32 i;
10843         opj_cp_v2_t *l_cp = NULL;
10844         opj_tcp_v2_t *l_tcp = NULL;
10845         opj_tccp_t *l_ref_tccp = NULL, *l_copied_tccp = NULL;
10846         OPJ_UINT32 l_prc_size;
10847
10848         /* preconditions */
10849         assert(p_j2k != 00);
10850
10851         l_cp = &(p_j2k->m_cp);
10852         l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH) ? /* FIXME J2K_DEC_STATE_TPH*/
10853                                 &l_cp->tcps[p_j2k->m_current_tile_number] :
10854                                 p_j2k->m_specific_param.m_decoder.m_default_tcp;
10855
10856         l_ref_tccp = &l_tcp->tccps[0];
10857         l_copied_tccp = l_ref_tccp + 1;
10858         l_prc_size = l_ref_tccp->numresolutions * sizeof(OPJ_UINT32);
10859
10860         for     (i=1; i<p_j2k->m_private_image->numcomps; ++i) {
10861                 l_copied_tccp->numresolutions = l_ref_tccp->numresolutions;
10862                 l_copied_tccp->cblkw = l_ref_tccp->cblkw;
10863                 l_copied_tccp->cblkh = l_ref_tccp->cblkh;
10864                 l_copied_tccp->cblksty = l_ref_tccp->cblksty;
10865                 l_copied_tccp->qmfbid = l_ref_tccp->qmfbid;
10866                 memcpy(l_copied_tccp->prcw,l_ref_tccp->prcw,l_prc_size);
10867                 memcpy(l_copied_tccp->prch,l_ref_tccp->prch,l_prc_size);
10868                 ++l_copied_tccp;
10869         }
10870 }
10871
10872 /**
10873  * Gets the size taken by writing SQcd or SQcc element, i.e. the quantization values of a band in the QCD or QCC.
10874  *
10875  * @param       p_tile_no               the tile index.
10876  * @param       p_comp_no               the component being outputted.
10877  * @param       p_j2k                   the J2K codec.
10878  *
10879  * @return      the number of bytes taken by the SPCod element.
10880  */
10881 OPJ_UINT32 j2k_get_SQcd_SQcc_size (     opj_j2k_v2_t *p_j2k,
10882                                                                         OPJ_UINT32 p_tile_no,
10883                                                                         OPJ_UINT32 p_comp_no )
10884 {
10885         OPJ_UINT32 l_num_bands;
10886
10887         opj_cp_v2_t *l_cp = 00;
10888         opj_tcp_v2_t *l_tcp = 00;
10889         opj_tccp_t *l_tccp = 00;
10890
10891         /* preconditions */
10892         assert(p_j2k != 00);
10893
10894         l_cp = &(p_j2k->m_cp);
10895         l_tcp = &l_cp->tcps[p_tile_no];
10896         l_tccp = &l_tcp->tccps[p_comp_no];
10897
10898         /* preconditions again */
10899         assert(p_tile_no < l_cp->tw * l_cp->th);
10900         assert(p_comp_no < p_j2k->m_private_image->numcomps);
10901
10902         l_num_bands = (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? 1 : (l_tccp->numresolutions * 3 - 2);
10903
10904         if (l_tccp->qntsty == J2K_CCP_QNTSTY_NOQNT)  {
10905                 return 1 + l_num_bands;
10906         }
10907         else {
10908                 return 1 + 2*l_num_bands;
10909         }
10910 }
10911
10912 /**
10913  * Writes a SQcd or SQcc element, i.e. the quantization values of a band.
10914  *
10915  * @param       p_tile_no               the tile to output.
10916  * @param       p_comp_no               the component number to output.
10917  * @param       p_data                  the data buffer.
10918  * @param       p_header_size   pointer to the size of the data buffer, it is changed by the function.
10919  * @param       p_j2k                           J2K codec.
10920  * @param       p_manager               the user event manager.
10921  *
10922 */
10923 opj_bool j2k_write_SQcd_SQcc(   opj_j2k_v2_t *p_j2k,
10924                                                                 OPJ_UINT32 p_tile_no,
10925                                                                 OPJ_UINT32 p_comp_no,
10926                                                                 OPJ_BYTE * p_data,
10927                                                                 OPJ_UINT32 * p_header_size,
10928                                                                 struct opj_event_mgr * p_manager )
10929 {
10930         OPJ_UINT32 l_header_size;
10931         OPJ_UINT32 l_band_no, l_num_bands;
10932         OPJ_UINT32 l_expn,l_mant;
10933
10934         opj_cp_v2_t *l_cp = 00;
10935         opj_tcp_v2_t *l_tcp = 00;
10936         opj_tccp_t *l_tccp = 00;
10937
10938         /* preconditions */
10939         assert(p_j2k != 00);
10940         assert(p_header_size != 00);
10941         assert(p_manager != 00);
10942         assert(p_data != 00);
10943
10944         l_cp = &(p_j2k->m_cp);
10945         l_tcp = &l_cp->tcps[p_tile_no];
10946         l_tccp = &l_tcp->tccps[p_comp_no];
10947
10948         /* preconditions again */
10949         assert(p_tile_no < l_cp->tw * l_cp->th);
10950         assert(p_comp_no <p_j2k->m_private_image->numcomps);
10951
10952         l_num_bands = (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? 1 : (l_tccp->numresolutions * 3 - 2);
10953
10954         if (l_tccp->qntsty == J2K_CCP_QNTSTY_NOQNT)  {
10955                 l_header_size = 1 + l_num_bands;
10956
10957                 if (*p_header_size < l_header_size) {
10958                         opj_event_msg_v2(p_manager, EVT_ERROR, "Error writing SQcd SQcc element\n");
10959                         return OPJ_FALSE;
10960                 }
10961
10962                 opj_write_bytes(p_data,l_tccp->qntsty + (l_tccp->numgbits << 5), 1);    /* Sqcx */
10963                 ++p_data;
10964
10965                 for (l_band_no = 0; l_band_no < l_num_bands; ++l_band_no) {
10966                         l_expn = l_tccp->stepsizes[l_band_no].expn;
10967                         opj_write_bytes(p_data, l_expn << 3, 1);        /* SPqcx_i */
10968                         ++p_data;
10969                 }
10970         }
10971         else {
10972                 l_header_size = 1 + 2*l_num_bands;
10973
10974                 if (*p_header_size < l_header_size) {
10975                         opj_event_msg_v2(p_manager, EVT_ERROR, "Error writing SQcd SQcc element\n");
10976                         return OPJ_FALSE;
10977                 }
10978
10979                 opj_write_bytes(p_data,l_tccp->qntsty + (l_tccp->numgbits << 5), 1);    /* Sqcx */
10980                 ++p_data;
10981
10982                 for (l_band_no = 0; l_band_no < l_num_bands; ++l_band_no) {
10983                         l_expn = l_tccp->stepsizes[l_band_no].expn;
10984                         l_mant = l_tccp->stepsizes[l_band_no].mant;
10985
10986                         opj_write_bytes(p_data, (l_expn << 11) + l_mant, 2);    /* SPqcx_i */
10987                         p_data += 2;
10988                 }
10989         }
10990
10991         *p_header_size = *p_header_size - l_header_size;
10992
10993         return OPJ_TRUE;
10994 }
10995
10996 /**
10997  * Reads a SQcd or SQcc element, i.e. the quantization values of a band.
10998  *
10999  * @param       p_comp_no               the component being targeted.
11000  * @param       p_header_data   the data contained in the COM box.
11001  * @param       p_j2k                   the jpeg2000 codec.
11002  * @param       p_header_size   the size of the data contained in the COM marker.
11003  * @param       p_manager               the user event manager.
11004 */
11005 opj_bool j2k_read_SQcd_SQcc(
11006                                                         opj_j2k_v2_t *p_j2k,
11007                                                         OPJ_UINT32 p_comp_no,
11008                                                         OPJ_BYTE* p_header_data,
11009                                                         OPJ_UINT32 * p_header_size,
11010                                                         struct opj_event_mgr * p_manager
11011                                                         )
11012 {
11013         /* loop*/
11014         OPJ_UINT32 l_band_no;
11015         opj_cp_v2_t *l_cp = 00;
11016         opj_tcp_v2_t *l_tcp = 00;
11017         opj_tccp_t *l_tccp = 00;
11018         OPJ_BYTE * l_current_ptr = 00;
11019         OPJ_UINT32 l_tmp, l_num_band;
11020
11021         /* preconditions*/
11022         assert(p_j2k != 00);
11023         assert(p_manager != 00);
11024         assert(p_header_data != 00);
11025
11026         l_cp = &(p_j2k->m_cp);
11027         /* come from tile part header or main header ?*/
11028         l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH) ? /*FIXME J2K_DEC_STATE_TPH*/
11029                                 &l_cp->tcps[p_j2k->m_current_tile_number] :
11030                                 p_j2k->m_specific_param.m_decoder.m_default_tcp;
11031
11032         /* precondition again*/
11033         assert(p_comp_no <  p_j2k->m_private_image->numcomps);
11034
11035         l_tccp = &l_tcp->tccps[p_comp_no];
11036         l_current_ptr = p_header_data;
11037
11038         if (*p_header_size < 1) {
11039                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading SQcd or SQcc element\n");
11040                 return OPJ_FALSE;
11041         }
11042         *p_header_size -= 1;
11043
11044         opj_read_bytes(l_current_ptr, &l_tmp ,1);                       /* Sqcx */
11045         ++l_current_ptr;
11046
11047         l_tccp->qntsty = l_tmp & 0x1f;
11048         l_tccp->numgbits = l_tmp >> 5;
11049         if (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) {
11050         l_num_band = 1;
11051         }
11052         else {
11053                 l_num_band = (l_tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) ?
11054                         (*p_header_size) :
11055                         (*p_header_size) / 2;
11056
11057                 if( l_num_band > J2K_MAXBANDS ) {
11058                         opj_event_msg_v2(p_manager, EVT_WARNING, "While reading CCP_QNTSTY element inside QCD or QCC marker segment, "
11059                                 "number of subbands (%d) is greater to J2K_MAXBANDS (%d). So we limit the number of elements stored to "
11060                                 "J2K_MAXBANDS (%d) and skip the rest. \n", l_num_band, J2K_MAXBANDS, J2K_MAXBANDS);
11061                         /*return OPJ_FALSE;*/
11062                 }
11063         }
11064
11065 #ifdef USE_JPWL
11066         if (l_cp->correct) {
11067
11068                 /* if JPWL is on, we check whether there are too many subbands */
11069                 if (/*(l_num_band < 0) ||*/ (l_num_band >= J2K_MAXBANDS)) {
11070                         opj_event_msg_v2(p_manager, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
11071                                 "JPWL: bad number of subbands in Sqcx (%d)\n",
11072                                 l_num_band);
11073                         if (!JPWL_ASSUME) {
11074                                 opj_event_msg_v2(p_manager, EVT_ERROR, "JPWL: giving up\n");
11075                                 return OPJ_FALSE;
11076                         }
11077                         /* we try to correct */
11078                         l_num_band = 1;
11079                         opj_event_msg_v2(p_manager, EVT_WARNING, "- trying to adjust them\n"
11080                                 "- setting number of bands to %d => HYPOTHESIS!!!\n",
11081                                 l_num_band);
11082                 };
11083
11084         };
11085 #endif /* USE_JPWL */
11086
11087         if (l_tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) {
11088                 for     (l_band_no = 0; l_band_no < l_num_band; l_band_no++) {
11089                         opj_read_bytes(l_current_ptr, &l_tmp ,1);                       /* SPqcx_i */
11090                         ++l_current_ptr;
11091                         if (l_band_no < J2K_MAXBANDS){
11092                                 l_tccp->stepsizes[l_band_no].expn = l_tmp>>3;
11093                                 l_tccp->stepsizes[l_band_no].mant = 0;
11094                         }
11095                 }
11096                 *p_header_size = *p_header_size - l_num_band;
11097         }
11098         else {
11099                 for     (l_band_no = 0; l_band_no < l_num_band; l_band_no++) {
11100                         opj_read_bytes(l_current_ptr, &l_tmp ,2);                       /* SPqcx_i */
11101                         l_current_ptr+=2;
11102                         if (l_band_no < J2K_MAXBANDS){
11103                                 l_tccp->stepsizes[l_band_no].expn = l_tmp >> 11;
11104                                 l_tccp->stepsizes[l_band_no].mant = l_tmp & 0x7ff;
11105                         }
11106                 }
11107                 *p_header_size = *p_header_size - 2*l_num_band;
11108         }
11109
11110         /* Add Antonin : if scalar_derived -> compute other stepsizes */
11111         if (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) {
11112                 for (l_band_no = 1; l_band_no < J2K_MAXBANDS; l_band_no++) {
11113                         l_tccp->stepsizes[l_band_no].expn =
11114                                 ((l_tccp->stepsizes[0].expn) - ((l_band_no - 1) / 3) > 0) ?
11115                                         (l_tccp->stepsizes[0].expn) - ((l_band_no - 1) / 3) : 0;
11116                         l_tccp->stepsizes[l_band_no].mant = l_tccp->stepsizes[0].mant;
11117                 }
11118         }
11119
11120         return OPJ_TRUE;
11121 }
11122
11123 /**
11124  * Copies the tile component parameters of all the component from the first tile component.
11125  *
11126  * @param               p_j2k           the J2k codec.
11127  */
11128 void j2k_copy_tile_quantization_parameters( opj_j2k_v2_t *p_j2k )
11129 {
11130         OPJ_UINT32 i;
11131         opj_cp_v2_t *l_cp = NULL;
11132         opj_tcp_v2_t *l_tcp = NULL;
11133         opj_tccp_t *l_ref_tccp = NULL;
11134         opj_tccp_t *l_copied_tccp = NULL;
11135         OPJ_UINT32 l_size;
11136
11137         /* preconditions */
11138         assert(p_j2k != 00);
11139
11140         l_cp = &(p_j2k->m_cp);
11141         l_tcp = p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH ?
11142                         &l_cp->tcps[p_j2k->m_current_tile_number] :
11143                         p_j2k->m_specific_param.m_decoder.m_default_tcp;
11144
11145         l_ref_tccp = &l_tcp->tccps[0];
11146         l_copied_tccp = l_ref_tccp + 1;
11147         l_size = J2K_MAXBANDS * sizeof(opj_stepsize_t);
11148
11149         for     (i=1;i<p_j2k->m_private_image->numcomps;++i) {
11150                 l_copied_tccp->qntsty = l_ref_tccp->qntsty;
11151                 l_copied_tccp->numgbits = l_ref_tccp->numgbits;
11152                 memcpy(l_copied_tccp->stepsizes,l_ref_tccp->stepsizes,l_size);
11153                 ++l_copied_tccp;
11154         }
11155 }
11156
11157 /**
11158  * Dump some elements from the J2K decompression structure .
11159  *
11160  *@param p_j2k                          the jpeg2000 codec.
11161  *@param flag                           flag to describe what elments are dump.
11162  *@param out_stream                     output stream where dump the elements.
11163  *
11164 */
11165 void j2k_dump (opj_j2k_v2_t* p_j2k, OPJ_INT32 flag, FILE* out_stream)
11166 {
11167         /* Check if the flag is compatible with j2k file*/
11168         if ( (flag & OPJ_JP2_INFO) || (flag & OPJ_JP2_IND)){
11169                 fprintf(out_stream, "Wrong flag\n");
11170                 return;
11171         }
11172
11173         /* Dump the image_header */
11174         if (flag & OPJ_IMG_INFO){
11175                 if (p_j2k->m_private_image)
11176                         j2k_dump_image_header(p_j2k->m_private_image, 0, out_stream);
11177         }
11178
11179         /* Dump the codestream info from main header */
11180         if (flag & OPJ_J2K_MH_INFO){
11181                 j2k_dump_MH_info(p_j2k, out_stream);
11182         }
11183
11184
11185         /* Dump the codestream info of the current tile */
11186         if (flag & OPJ_J2K_TH_INFO){
11187
11188         }
11189
11190         /* Dump the codestream index from main header */
11191         if (flag & OPJ_J2K_MH_IND){
11192                 j2k_dump_MH_index(p_j2k, out_stream);
11193         }
11194
11195         /* Dump the codestream index of the current tile */
11196         if (flag & OPJ_J2K_TH_IND){
11197
11198         }
11199
11200 }
11201
11202 /**
11203  * Dump index elements of the codestream extract from the main header.
11204  *
11205  *@param p_j2k                          the jpeg2000 codec.
11206  *@param out_stream                     output stream where dump the elements.
11207  *
11208 */
11209 void j2k_dump_MH_index(opj_j2k_v2_t* p_j2k, FILE* out_stream)
11210 {
11211         opj_codestream_index_t* cstr_index = p_j2k->cstr_index;
11212         OPJ_UINT32 it_marker, it_tile, it_tile_part;
11213
11214         fprintf(out_stream, "Codestream index from main header: {\n");
11215
11216         fprintf(out_stream, "\t Main header start position=%" PRIi64 "\n"
11217                                     "\t Main header end position=%" PRIi64 "\n",
11218                         cstr_index->main_head_start, cstr_index->main_head_end);
11219
11220         fprintf(out_stream, "\t Marker list: {\n");
11221
11222         if (cstr_index->marker){
11223                 for (it_marker=0; it_marker < cstr_index->marknum ; it_marker++){
11224                         fprintf(out_stream, "\t\t type=%#x, pos=%" PRIi64 ", len=%d\n",
11225                                         cstr_index->marker[it_marker].type,
11226                                         cstr_index->marker[it_marker].pos,
11227                                         cstr_index->marker[it_marker].len );
11228                 }
11229         }
11230
11231         fprintf(out_stream, "\t }\n");
11232
11233
11234         if (cstr_index->tile_index){
11235                 fprintf(out_stream, "\t Tile index: {\n");
11236
11237                 for (it_tile=0; it_tile < cstr_index->nb_of_tiles ; it_tile++){
11238                         OPJ_UINT32 nb_of_tile_part = cstr_index->tile_index[it_tile].nb_tps;
11239
11240                         fprintf(out_stream, "\t\t nb of tile-part in tile [%d]=%d\n", it_tile, nb_of_tile_part);
11241
11242                         if (cstr_index->tile_index[it_tile].tp_index){
11243                                 for (it_tile_part =0; it_tile_part < nb_of_tile_part; it_tile_part++){
11244                                         fprintf(out_stream, "\t\t\t tile-part[%d]: star_pos=%" PRIi64 ", end_header=%" PRIi64 ", end_pos=%" PRIi64 ".\n",
11245                                                         it_tile_part,
11246                                                         cstr_index->tile_index[it_tile].tp_index[it_tile_part].start_pos,
11247                                                         cstr_index->tile_index[it_tile].tp_index[it_tile_part].end_header,
11248                                                         cstr_index->tile_index[it_tile].tp_index[it_tile_part].end_pos);
11249                                 }
11250                         }
11251
11252                         if (cstr_index->tile_index[it_tile].marker){
11253                                 for (it_marker=0; it_marker < cstr_index->tile_index[it_tile].marknum ; it_marker++){
11254                                         fprintf(out_stream, "\t\t type=%#x, pos=%" PRIi64 ", len=%d\n",
11255                                                         cstr_index->tile_index[it_tile].marker[it_marker].type,
11256                                                         cstr_index->tile_index[it_tile].marker[it_marker].pos,
11257                                                         cstr_index->tile_index[it_tile].marker[it_marker].len );
11258                                 }
11259                         }
11260                 }
11261                 fprintf(out_stream,"\t }\n");
11262         }
11263
11264         fprintf(out_stream,"}\n");
11265
11266 }
11267
11268 /**
11269  * Dump info elements of the codestream extract from the main header.
11270  *
11271  *@param p_j2k                          the jpeg2000 codec.
11272  *@param out_stream                     output stream where dump the elements.
11273  *
11274 */
11275 void j2k_dump_MH_info(opj_j2k_v2_t* p_j2k, FILE* out_stream)
11276 {
11277         opj_tcp_v2_t * l_default_tile=NULL;
11278
11279         fprintf(out_stream, "Codestream info from main header: {\n");
11280
11281         fprintf(out_stream, "\t tx0=%d, ty0=%d\n", p_j2k->m_cp.tx0, p_j2k->m_cp.ty0);
11282         fprintf(out_stream, "\t tdx=%d, tdy=%d\n", p_j2k->m_cp.tdx, p_j2k->m_cp.tdy);
11283         fprintf(out_stream, "\t tw=%d, th=%d\n", p_j2k->m_cp.tw, p_j2k->m_cp.th);
11284
11285         l_default_tile = p_j2k->m_specific_param.m_decoder.m_default_tcp;
11286         if (l_default_tile)
11287         {
11288                 OPJ_INT32 compno;
11289                 OPJ_INT32 numcomps = p_j2k->m_private_image->numcomps;
11290
11291                 fprintf(out_stream, "\t default tile {\n");
11292                 fprintf(out_stream, "\t\t csty=%#x\n", l_default_tile->csty);
11293                 fprintf(out_stream, "\t\t prg=%#x\n", l_default_tile->prg);
11294                 fprintf(out_stream, "\t\t numlayers=%d\n", l_default_tile->numlayers);
11295                 fprintf(out_stream, "\t\t mct=%x\n", l_default_tile->mct);
11296
11297                 for (compno = 0; compno < numcomps; compno++) {
11298                         opj_tccp_t *l_tccp = &(l_default_tile->tccps[compno]);
11299                         OPJ_UINT32 resno;
11300       OPJ_INT32 bandno, numbands;
11301
11302                         /* coding style*/
11303                         fprintf(out_stream, "\t\t comp %d {\n", compno);
11304                         fprintf(out_stream, "\t\t\t csty=%#x\n", l_tccp->csty);
11305                         fprintf(out_stream, "\t\t\t numresolutions=%d\n", l_tccp->numresolutions);
11306                         fprintf(out_stream, "\t\t\t cblkw=2^%d\n", l_tccp->cblkw);
11307                         fprintf(out_stream, "\t\t\t cblkh=2^%d\n", l_tccp->cblkh);
11308                         fprintf(out_stream, "\t\t\t cblksty=%#x\n", l_tccp->cblksty);
11309                         fprintf(out_stream, "\t\t\t qmfbid=%d\n", l_tccp->qmfbid);
11310
11311                         fprintf(out_stream, "\t\t\t preccintsize (w,h)=");
11312                         for (resno = 0; resno < l_tccp->numresolutions; resno++) {
11313                                 fprintf(out_stream, "(%d,%d) ", l_tccp->prcw[resno], l_tccp->prch[resno]);
11314                         }
11315                         fprintf(out_stream, "\n");
11316
11317                         /* quantization style*/
11318                         fprintf(out_stream, "\t\t\t qntsty=%d\n", l_tccp->qntsty);
11319                         fprintf(out_stream, "\t\t\t numgbits=%d\n", l_tccp->numgbits);
11320                         fprintf(out_stream, "\t\t\t stepsizes (m,e)=");
11321                         numbands = (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? 1 : l_tccp->numresolutions * 3 - 2;
11322                         for (bandno = 0; bandno < numbands; bandno++) {
11323                                 fprintf(out_stream, "(%d,%d) ", l_tccp->stepsizes[bandno].mant,
11324                                         l_tccp->stepsizes[bandno].expn);
11325                         }
11326                         fprintf(out_stream, "\n");
11327
11328                         /* RGN value*/
11329                         fprintf(out_stream, "\t\t\t roishift=%d\n", l_tccp->roishift);
11330
11331                         fprintf(out_stream, "\t\t }\n");
11332                 } /*end of component of default tile*/
11333                 fprintf(out_stream, "\t }\n"); /*end of default tile*/
11334
11335         }
11336
11337         fprintf(out_stream, "}\n");
11338
11339 }
11340
11341 /**
11342  * Dump an image header structure.
11343  *
11344  *@param img_header                     the image header to dump.
11345  *@param dev_dump_flag          flag to describe if we are in the case of this function is use outside j2k_dump function
11346  *@param out_stream                     output stream where dump the elements.
11347  */
11348 void j2k_dump_image_header(opj_image_t* img_header, opj_bool dev_dump_flag, FILE* out_stream)
11349 {
11350         char tab[2];
11351
11352         if (dev_dump_flag){
11353                 fprintf(stdout, "[DEV] Dump an image_header struct {\n");
11354                 tab[0] = '\0';
11355         }
11356         else {
11357                 fprintf(out_stream, "Image info {\n");
11358                 tab[0] = '\t';tab[1] = '\0';
11359         }
11360
11361         fprintf(out_stream, "%s x0=%d, y0=%d\n", tab, img_header->x0, img_header->y0);
11362         fprintf(out_stream,     "%s x1=%d, y1=%d\n", tab, img_header->x1, img_header->y1);
11363         fprintf(out_stream, "%s numcomps=%d\n", tab, img_header->numcomps);
11364
11365         if (img_header->comps){
11366                 OPJ_UINT32 compno;
11367                 for (compno = 0; compno < img_header->numcomps; compno++) {
11368                         fprintf(out_stream, "%s\t component %d {\n", tab, compno);
11369                         j2k_dump_image_comp_header(&(img_header->comps[compno]), dev_dump_flag, out_stream);
11370                         fprintf(out_stream,"%s}\n",tab);
11371                 }
11372         }
11373
11374         fprintf(out_stream, "}\n");
11375 }
11376
11377 /**
11378  * Dump a component image header structure.
11379  *
11380  *@param comp_header            the component image header to dump.
11381  *@param dev_dump_flag          flag to describe if we are in the case of this function is use outside j2k_dump function
11382  *@param out_stream                     output stream where dump the elements.
11383  */
11384 void j2k_dump_image_comp_header(opj_image_comp_t* comp_header, opj_bool dev_dump_flag, FILE* out_stream)
11385 {
11386         char tab[3];
11387
11388         if (dev_dump_flag){
11389                 fprintf(stdout, "[DEV] Dump an image_comp_header struct {\n");
11390                 tab[0] = '\0';
11391         }       else {
11392                 tab[0] = '\t';tab[1] = '\t';tab[2] = '\0';
11393         }
11394
11395         fprintf(out_stream, "%s dx=%d, dy=%d\n", tab, comp_header->dx, comp_header->dy);
11396         fprintf(out_stream, "%s prec=%d\n", tab, comp_header->prec);
11397         fprintf(out_stream, "%s sgnd=%d\n", tab, comp_header->sgnd);
11398
11399         if (dev_dump_flag)
11400                 fprintf(out_stream, "}\n");
11401 }
11402
11403
11404 /**
11405  * Get the codestream info from a JPEG2000 codec.
11406  *
11407  *@param        p_j2k                           the component image header to dump.
11408  *
11409  *@return       the codestream information extract from the jpg2000 codec
11410  */
11411 opj_codestream_info_v2_t* j2k_get_cstr_info(opj_j2k_v2_t* p_j2k)
11412 {
11413         OPJ_UINT16 compno;
11414         OPJ_UINT16 numcomps = p_j2k->m_private_image->numcomps;
11415         opj_tcp_v2_t *l_default_tile;
11416         opj_codestream_info_v2_t* cstr_info = (opj_codestream_info_v2_t*) opj_calloc(1,sizeof(opj_codestream_info_v2_t));
11417
11418         cstr_info->nbcomps = p_j2k->m_private_image->numcomps;
11419
11420         cstr_info->tx0 = p_j2k->m_cp.tx0;
11421         cstr_info->ty0 = p_j2k->m_cp.ty0;
11422         cstr_info->tdx = p_j2k->m_cp.tdx;
11423         cstr_info->tdy = p_j2k->m_cp.tdy;
11424         cstr_info->tw = p_j2k->m_cp.tw;
11425         cstr_info->th = p_j2k->m_cp.th;
11426
11427         cstr_info->tile_info = NULL; /* Not fill from the main header*/
11428
11429         l_default_tile = p_j2k->m_specific_param.m_decoder.m_default_tcp;
11430
11431         cstr_info->m_default_tile_info.csty = l_default_tile->csty;
11432         cstr_info->m_default_tile_info.prg = l_default_tile->prg;
11433         cstr_info->m_default_tile_info.numlayers = l_default_tile->numlayers;
11434         cstr_info->m_default_tile_info.mct = l_default_tile->mct;
11435
11436         cstr_info->m_default_tile_info.tccp_info = (opj_tccp_info_t*) opj_calloc(cstr_info->nbcomps, sizeof(opj_tccp_info_t));
11437
11438         for (compno = 0; compno < numcomps; compno++) {
11439                 opj_tccp_t *l_tccp = &(l_default_tile->tccps[compno]);
11440                 opj_tccp_info_t *l_tccp_info = &(cstr_info->m_default_tile_info.tccp_info[compno]);
11441                 OPJ_INT32 bandno, numbands;
11442
11443                 /* coding style*/
11444                 l_tccp_info->csty = l_tccp->csty;
11445                 l_tccp_info->numresolutions = l_tccp->numresolutions;
11446                 l_tccp_info->cblkw = l_tccp->cblkw;
11447                 l_tccp_info->cblkh = l_tccp->cblkh;
11448                 l_tccp_info->cblksty = l_tccp->cblksty;
11449                 l_tccp_info->qmfbid = l_tccp->qmfbid;
11450                 if (l_tccp->numresolutions < J2K_MAXRLVLS)
11451                 {
11452                         memcpy(l_tccp_info->prch, l_tccp->prch, l_tccp->numresolutions);
11453                         memcpy(l_tccp_info->prcw, l_tccp->prcw, l_tccp->numresolutions);
11454                 }
11455
11456                 /* quantization style*/
11457                 l_tccp_info->qntsty = l_tccp->qntsty;
11458                 l_tccp_info->numgbits = l_tccp->numgbits;
11459
11460                 numbands = (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? 1 : l_tccp->numresolutions * 3 - 2;
11461                 if (numbands < J2K_MAXBANDS) {
11462                         for (bandno = 0; bandno < numbands; bandno++) {
11463                                 l_tccp_info->stepsizes_mant[bandno] = l_tccp->stepsizes[bandno].mant;
11464                                 l_tccp_info->stepsizes_expn[bandno] = l_tccp->stepsizes[bandno].expn;
11465                         }
11466                 }
11467
11468                 /* RGN value*/
11469                 l_tccp_info->roishift = l_tccp->roishift;
11470         }
11471
11472
11473         return cstr_info;
11474 }
11475
11476 /**
11477  * Get the codestream index from a JPEG2000 codec.
11478  *
11479  *@param        p_j2k                           the component image header to dump.
11480  *
11481  *@return       the codestream index extract from the jpg2000 codec
11482  */
11483 opj_codestream_index_t* j2k_get_cstr_index(opj_j2k_v2_t* p_j2k)
11484 {
11485         opj_codestream_index_t* l_cstr_index = (opj_codestream_index_t*)
11486                         opj_calloc(1,sizeof(opj_codestream_index_t));
11487         if (!l_cstr_index)
11488                 return NULL;
11489
11490         l_cstr_index->main_head_start = p_j2k->cstr_index->main_head_start;
11491         l_cstr_index->main_head_end = p_j2k->cstr_index->main_head_end;
11492         l_cstr_index->codestream_size = p_j2k->cstr_index->codestream_size;
11493
11494         l_cstr_index->marknum = p_j2k->cstr_index->marknum;
11495         l_cstr_index->marker = (opj_marker_info_t*)opj_malloc(l_cstr_index->marknum*sizeof(opj_marker_info_t));
11496         if (!l_cstr_index->marker){
11497                 opj_free( l_cstr_index);
11498                 return NULL;
11499         }
11500
11501         if (p_j2k->cstr_index->marker)
11502                 memcpy(l_cstr_index->marker, p_j2k->cstr_index->marker, l_cstr_index->marknum * sizeof(opj_marker_info_t) );
11503         else{
11504                 opj_free(l_cstr_index->marker);
11505                 l_cstr_index->marker = NULL;
11506         }
11507
11508         l_cstr_index->nb_of_tiles = p_j2k->cstr_index->nb_of_tiles;
11509         l_cstr_index->tile_index = (opj_tile_index_t*)opj_calloc(l_cstr_index->nb_of_tiles, sizeof(opj_tile_index_t) );
11510         if (!l_cstr_index->tile_index){
11511                 opj_free( l_cstr_index->marker);
11512                 opj_free( l_cstr_index);
11513                 return NULL;
11514         }
11515
11516         if (!p_j2k->cstr_index->tile_index){
11517                 opj_free(l_cstr_index->tile_index);
11518                 l_cstr_index->tile_index = NULL;
11519         }
11520         else {
11521                 OPJ_UINT32 it_tile = 0;
11522                 for (it_tile = 0; it_tile < l_cstr_index->nb_of_tiles; it_tile++ ){
11523
11524                         /* Tile Marker*/
11525                         l_cstr_index->tile_index[it_tile].marknum = p_j2k->cstr_index->tile_index[it_tile].marknum;
11526
11527                         l_cstr_index->tile_index[it_tile].marker =
11528                                 (opj_marker_info_t*)opj_malloc(l_cstr_index->tile_index[it_tile].marknum*sizeof(opj_marker_info_t));
11529
11530                         if (!l_cstr_index->tile_index[it_tile].marker) {
11531                                 OPJ_UINT32 it_tile_free;
11532
11533                                 for (it_tile_free=0; it_tile_free < it_tile; it_tile_free++){
11534                                         opj_free(l_cstr_index->tile_index[it_tile_free].marker);
11535                                 }
11536
11537                                 opj_free( l_cstr_index->tile_index);
11538                                 opj_free( l_cstr_index->marker);
11539                                 opj_free( l_cstr_index);
11540                                 return NULL;
11541                         }
11542
11543                         if (p_j2k->cstr_index->tile_index[it_tile].marker)
11544                                 memcpy( l_cstr_index->tile_index[it_tile].marker,
11545                                                 p_j2k->cstr_index->tile_index[it_tile].marker,
11546                                                 l_cstr_index->tile_index[it_tile].marknum * sizeof(opj_marker_info_t) );
11547                         else{
11548                                 opj_free(l_cstr_index->tile_index[it_tile].marker);
11549                                 l_cstr_index->tile_index[it_tile].marker = NULL;
11550                         }
11551
11552                         /* Tile part index*/
11553                         l_cstr_index->tile_index[it_tile].nb_tps = p_j2k->cstr_index->tile_index[it_tile].nb_tps;
11554
11555                         l_cstr_index->tile_index[it_tile].tp_index =
11556                                 (opj_tp_index_t*)opj_malloc(l_cstr_index->tile_index[it_tile].nb_tps*sizeof(opj_tp_index_t));
11557
11558                         if(!l_cstr_index->tile_index[it_tile].tp_index){
11559                                 OPJ_UINT32 it_tile_free;
11560
11561                                 for (it_tile_free=0; it_tile_free < it_tile; it_tile_free++){
11562                                         opj_free(l_cstr_index->tile_index[it_tile_free].marker);
11563                                         opj_free(l_cstr_index->tile_index[it_tile_free].tp_index);
11564                                 }
11565
11566                                 opj_free( l_cstr_index->tile_index);
11567                                 opj_free( l_cstr_index->marker);
11568                                 opj_free( l_cstr_index);
11569                                 return NULL;
11570                         }
11571
11572                         if (p_j2k->cstr_index->tile_index[it_tile].tp_index){
11573                                 memcpy( l_cstr_index->tile_index[it_tile].tp_index,
11574                                                 p_j2k->cstr_index->tile_index[it_tile].tp_index,
11575                                                 l_cstr_index->tile_index[it_tile].nb_tps * sizeof(opj_tp_index_t) );
11576                         }
11577                         else{
11578                                 opj_free(l_cstr_index->tile_index[it_tile].tp_index);
11579                                 l_cstr_index->tile_index[it_tile].tp_index = NULL;
11580                         }
11581
11582                         /* Packet index (NOT USED)*/
11583                         l_cstr_index->tile_index[it_tile].nb_packet = 0;
11584                         l_cstr_index->tile_index[it_tile].packet_index = NULL;
11585
11586                 }
11587         }
11588
11589         return l_cstr_index;
11590 }
11591
11592 static opj_bool j2k_allocate_tile_element_cstr_index(opj_j2k_v2_t *p_j2k)
11593 {
11594         OPJ_UINT32 it_tile=0;
11595
11596         p_j2k->cstr_index->nb_of_tiles = p_j2k->m_cp.tw * p_j2k->m_cp.th;
11597         p_j2k->cstr_index->tile_index = (opj_tile_index_t*)opj_calloc(p_j2k->cstr_index->nb_of_tiles, sizeof(opj_tile_index_t));
11598         if (!p_j2k->cstr_index->tile_index)
11599                 return OPJ_FALSE;
11600
11601         for (it_tile=0; it_tile < p_j2k->cstr_index->nb_of_tiles; it_tile++){
11602                 p_j2k->cstr_index->tile_index[it_tile].maxmarknum = 100;
11603                 p_j2k->cstr_index->tile_index[it_tile].marknum = 0;
11604                 p_j2k->cstr_index->tile_index[it_tile].marker = (opj_marker_info_t*)
11605                                 opj_calloc(p_j2k->cstr_index->tile_index[it_tile].maxmarknum, sizeof(opj_marker_info_t));
11606                 if (!p_j2k->cstr_index->tile_index[it_tile].marker)
11607                         return OPJ_FALSE;
11608         }
11609
11610         return OPJ_TRUE;
11611 }
11612
11613 /**
11614  * Reads the tiles.
11615  */
11616 opj_bool j2k_decode_tiles (     opj_j2k_v2_t *p_j2k,
11617                                                         opj_stream_private_t *p_stream,
11618                                                         opj_event_mgr_t * p_manager)
11619 {
11620         opj_bool l_go_on = OPJ_TRUE;
11621         OPJ_UINT32 l_current_tile_no;
11622         OPJ_UINT32 l_data_size,l_max_data_size;
11623         OPJ_INT32 l_tile_x0,l_tile_y0,l_tile_x1,l_tile_y1;
11624         OPJ_UINT32 l_nb_comps;
11625         OPJ_BYTE * l_current_data;
11626
11627         l_current_data = (OPJ_BYTE*)opj_malloc(1000);
11628         if (! l_current_data) {
11629                 return OPJ_FALSE;
11630         }
11631         l_max_data_size = 1000;
11632
11633         /*Allocate and initialize some elements of codestrem index*/
11634         if (!j2k_allocate_tile_element_cstr_index(p_j2k)){
11635                 opj_free(l_current_data);
11636                 return OPJ_FALSE;
11637         }
11638
11639         while (OPJ_TRUE) {
11640                 if (! j2k_read_tile_header(     p_j2k,
11641                                                                         &l_current_tile_no,
11642                                                                         &l_data_size,
11643                                                                         &l_tile_x0, &l_tile_y0,
11644                                                                         &l_tile_x1, &l_tile_y1,
11645                                                                         &l_nb_comps,
11646                                                                         &l_go_on,
11647                                                                         p_stream,
11648                                                                         p_manager)) {
11649                         opj_free(l_current_data);
11650                         return OPJ_FALSE;
11651                 }
11652
11653                 if (! l_go_on) {
11654                         break;
11655                 }
11656
11657                 if (l_data_size > l_max_data_size) {
11658                         l_current_data = (OPJ_BYTE*)opj_realloc(l_current_data,l_data_size);
11659                         if (! l_current_data) {
11660                                 opj_free(l_current_data);
11661                                 return OPJ_FALSE;
11662                         }
11663
11664                         l_max_data_size = l_data_size;
11665                 }
11666
11667                 if (! j2k_decode_tile(p_j2k,l_current_tile_no,l_current_data,l_data_size,p_stream,p_manager)) {
11668                         opj_free(l_current_data);
11669                         return OPJ_FALSE;
11670                 }
11671                 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);
11672
11673                 if (! j2k_update_image_data(p_j2k->m_tcd,l_current_data, p_j2k->m_output_image)) {
11674                         opj_free(l_current_data);
11675                         return OPJ_FALSE;
11676                 }
11677                 opj_event_msg_v2(p_manager, EVT_INFO, "Image data has been updated with tile %d.\n\n", l_current_tile_no + 1);
11678
11679         }
11680
11681         opj_free(l_current_data);
11682
11683         return OPJ_TRUE;
11684 }
11685
11686 /**
11687  * Sets up the procedures to do on decoding data. Developpers wanting to extend the library can add their own reading procedures.
11688  */
11689 static void j2k_setup_decoding (opj_j2k_v2_t *p_j2k)
11690 {
11691         /* preconditions*/
11692         assert(p_j2k != 00);
11693
11694         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_decode_tiles);
11695         /* DEVELOPER CORNER, add your custom procedures */
11696
11697 }
11698
11699 /*
11700  * Read and decode one tile.
11701  */
11702 static opj_bool j2k_decode_one_tile (   opj_j2k_v2_t *p_j2k,
11703                                                                 opj_stream_private_t *p_stream,
11704                                                                 opj_event_mgr_t * p_manager)
11705 {
11706         opj_bool l_go_on = OPJ_TRUE;
11707         OPJ_UINT32 l_current_tile_no;
11708         OPJ_UINT32 l_tile_no_to_dec;
11709         OPJ_UINT32 l_data_size,l_max_data_size;
11710         OPJ_INT32 l_tile_x0,l_tile_y0,l_tile_x1,l_tile_y1;
11711         OPJ_UINT32 l_nb_comps;
11712         OPJ_BYTE * l_current_data;
11713
11714         l_current_data = (OPJ_BYTE*)opj_malloc(1000);
11715         if (! l_current_data) {
11716                 return OPJ_FALSE;
11717         }
11718         l_max_data_size = 1000;
11719
11720         /*Allocate and initialize some elements of codestrem index if not already done*/
11721         if( !p_j2k->cstr_index->tile_index)
11722         {
11723                 if (!j2k_allocate_tile_element_cstr_index(p_j2k)){
11724                         opj_free(l_current_data);
11725                         return OPJ_FALSE;
11726                 }
11727         }
11728         /* Move into the codestream to the first SOT used to decode the desired tile */
11729         l_tile_no_to_dec = p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec;
11730         if (p_j2k->cstr_index->tile_index)
11731                 if(p_j2k->cstr_index->tile_index->tp_index)
11732                 {
11733                         if ( ! p_j2k->cstr_index->tile_index[l_tile_no_to_dec].nb_tps) {
11734                                 /* the index for this tile has not been built,
11735                                  *  so move to the last SOT read */
11736                                 if ( opj_stream_read_seek(p_stream, p_j2k->m_specific_param.m_decoder.m_last_sot_read_pos+2, p_manager) ){
11737                                         opj_event_msg_v2(p_manager, EVT_ERROR, "Problem with seek function\n");
11738                                         return OPJ_FALSE;
11739                                 }
11740                         }
11741                         else{
11742                                 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)) {
11743                                         opj_event_msg_v2(p_manager, EVT_ERROR, "Problem with seek function\n");
11744                                         return OPJ_FALSE;
11745                                 }
11746                         }
11747                         /* Special case if we have previously read the EOC marker (if the previous tile getted is the last ) */
11748                         if(p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_EOC)
11749                                 p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_TPHSOT;
11750                 }
11751
11752         while (OPJ_TRUE) {
11753                 if (! j2k_read_tile_header(     p_j2k,
11754                                                                         &l_current_tile_no,
11755                                                                         &l_data_size,
11756                                                                         &l_tile_x0, &l_tile_y0,
11757                                                                         &l_tile_x1, &l_tile_y1,
11758                                                                         &l_nb_comps,
11759                                                                         &l_go_on,
11760                                                                         p_stream,
11761                                                                         p_manager)) {
11762                         opj_free(l_current_data);
11763                         return OPJ_FALSE;
11764                 }
11765
11766
11767                 if (! l_go_on) {
11768                         break;
11769                 }
11770
11771                 if (l_data_size > l_max_data_size) {
11772                         l_current_data = (OPJ_BYTE*)opj_realloc(l_current_data,l_data_size);
11773                         if (! l_current_data) {
11774                                 opj_free(l_current_data);
11775                                 return OPJ_FALSE;
11776                         }
11777
11778                         l_max_data_size = l_data_size;
11779                 }
11780
11781
11782
11783                 if (! j2k_decode_tile(p_j2k,l_current_tile_no,l_current_data,l_data_size,p_stream,p_manager)) {
11784                         opj_free(l_current_data);
11785                         return OPJ_FALSE;
11786                 }
11787                 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);
11788
11789                 if (! j2k_update_image_data(p_j2k->m_tcd,l_current_data, p_j2k->m_output_image)) {
11790                         opj_free(l_current_data);
11791                         return OPJ_FALSE;
11792                 }
11793                 opj_event_msg_v2(p_manager, EVT_INFO, "Image data has been updated with tile %d.\n\n", l_current_tile_no);
11794
11795                 if(l_current_tile_no == l_tile_no_to_dec)
11796                 {
11797                         /* move into the codestream to the the first SOT (FIXME or not move?)*/
11798                         if (!(opj_stream_read_seek(p_stream, p_j2k->cstr_index->main_head_end + 2, p_manager) ) ) {
11799                                 opj_event_msg_v2(p_manager, EVT_ERROR, "Problem with seek function\n");
11800                                 return OPJ_FALSE;
11801                         }
11802                         break;
11803                 }
11804                 else {
11805                         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);
11806                 }
11807
11808         }
11809
11810         opj_free(l_current_data);
11811
11812         return OPJ_TRUE;
11813 }
11814
11815
11816 /**
11817  * Sets up the procedures to do on decoding one tile. Developpers wanting to extend the library can add their own reading procedures.
11818  */
11819 static void j2k_setup_decoding_tile (opj_j2k_v2_t *p_j2k)
11820 {
11821         /* preconditions*/
11822         assert(p_j2k != 00);
11823
11824         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_decode_one_tile);
11825         /* DEVELOPER CORNER, add your custom procedures */
11826
11827 }
11828
11829
11830 /**
11831  * Decodes the tiles of the stream.
11832  */
11833 opj_bool j2k_decode_v2( opj_j2k_v2_t * p_j2k,
11834                                                 opj_stream_private_t * p_stream,
11835                                                 opj_image_t * p_image,
11836                                                 opj_event_mgr_t * p_manager)
11837 {
11838         OPJ_UINT32 compno;
11839
11840         if (!p_image)
11841                 return OPJ_FALSE;
11842
11843         p_j2k->m_output_image = opj_image_create0();
11844         if (! (p_j2k->m_output_image)) {
11845                 return OPJ_FALSE;
11846         }
11847         opj_copy_image_header(p_image, p_j2k->m_output_image);
11848
11849         /* customization of the decoding */
11850         j2k_setup_decoding(p_j2k);
11851
11852         /* Decode the codestream */
11853         if (! j2k_exec (p_j2k,p_j2k->m_procedure_list,p_stream,p_manager)) {
11854                 opj_image_destroy(p_j2k->m_private_image);
11855                 p_j2k->m_private_image = NULL;
11856                 return OPJ_FALSE;
11857         }
11858
11859         /* Move data and copy one information from codec to output image*/
11860         for (compno = 0; compno < p_image->numcomps; compno++) {
11861                 p_image->comps[compno].resno_decoded = p_j2k->m_output_image->comps[compno].resno_decoded;
11862                 p_image->comps[compno].data = p_j2k->m_output_image->comps[compno].data;
11863                 p_j2k->m_output_image->comps[compno].data = NULL;
11864         }
11865
11866         return OPJ_TRUE;
11867 }
11868
11869
11870 /**
11871  * Get the decoded tile.
11872  *
11873  * @param       p_j2k                   the jpeg2000 codestream codec.
11874  * @param       p_stream                input_stream
11875  * @param       p_image                 output image.   .
11876  * @param       p_manager               the user event manager
11877  * @param       tile_index              index of the tile we want decode
11878  *
11879  * @return      true                    if succeed.
11880  */
11881 opj_bool j2k_get_tile(  opj_j2k_v2_t *p_j2k,
11882                                                 opj_stream_private_t *p_stream,
11883                                                 opj_image_t* p_image,
11884                                                 struct opj_event_mgr * p_manager,
11885                                                 OPJ_UINT32 tile_index )
11886 {
11887         OPJ_UINT32 compno;
11888         OPJ_UINT32 l_tile_x, l_tile_y;
11889         opj_image_comp_t* l_img_comp;
11890
11891         if (!p_image) {
11892                 opj_event_msg_v2(p_manager, EVT_ERROR, "We need an image previously created.\n");
11893                 return OPJ_FALSE;
11894         }
11895
11896         if ( /*(tile_index < 0) &&*/ (tile_index >= p_j2k->m_cp.tw * p_j2k->m_cp.th) ){
11897                 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);
11898                 return OPJ_FALSE;
11899         }
11900
11901         /* Compute the dimension of the desired tile*/
11902         l_tile_x = tile_index % p_j2k->m_cp.tw;
11903         l_tile_y = tile_index / p_j2k->m_cp.tw;
11904
11905         p_image->x0 = l_tile_x * p_j2k->m_cp.tdx + p_j2k->m_cp.tx0;
11906         if (p_image->x0 < p_j2k->m_private_image->x0)
11907                 p_image->x0 = p_j2k->m_private_image->x0;
11908         p_image->x1 = (l_tile_x + 1) * p_j2k->m_cp.tdx + p_j2k->m_cp.tx0;
11909         if (p_image->x1 > p_j2k->m_private_image->x1)
11910                 p_image->x1 = p_j2k->m_private_image->x1;
11911
11912         p_image->y0 = l_tile_y * p_j2k->m_cp.tdy + p_j2k->m_cp.ty0;
11913         if (p_image->y0 < p_j2k->m_private_image->y0)
11914                 p_image->y0 = p_j2k->m_private_image->y0;
11915         p_image->y1 = (l_tile_y + 1) * p_j2k->m_cp.tdy + p_j2k->m_cp.ty0;
11916         if (p_image->y1 > p_j2k->m_private_image->y1)
11917                 p_image->y1 = p_j2k->m_private_image->y1;
11918
11919         l_img_comp = p_image->comps;
11920         for (compno=0; compno < p_image->numcomps; ++compno)
11921         {
11922                 OPJ_INT32 l_comp_x1, l_comp_y1;
11923
11924                 l_img_comp->factor = p_j2k->m_private_image->comps[compno].factor;
11925
11926                 l_img_comp->x0 = int_ceildiv(p_image->x0, l_img_comp->dx);
11927                 l_img_comp->y0 = int_ceildiv(p_image->y0, l_img_comp->dy);
11928                 l_comp_x1 = int_ceildiv(p_image->x1, l_img_comp->dx);
11929                 l_comp_y1 = int_ceildiv(p_image->y1, l_img_comp->dy);
11930
11931                 l_img_comp->w = int_ceildivpow2(l_comp_x1, l_img_comp->factor) - int_ceildivpow2(l_img_comp->x0, l_img_comp->factor);
11932                 l_img_comp->h = int_ceildivpow2(l_comp_y1, l_img_comp->factor) - int_ceildivpow2(l_img_comp->y0, l_img_comp->factor);
11933
11934                 l_img_comp++;
11935         }
11936
11937         /* Destroy the previous output image*/
11938         if (p_j2k->m_output_image)
11939                 opj_image_destroy(p_j2k->m_output_image);
11940
11941         /* Create the ouput image from the information previously computed*/
11942         p_j2k->m_output_image = opj_image_create0();
11943         if (! (p_j2k->m_output_image)) {
11944                 return OPJ_FALSE;
11945         }
11946         opj_copy_image_header(p_image, p_j2k->m_output_image);
11947
11948         p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec = tile_index;
11949
11950         /* customization of the decoding */
11951         j2k_setup_decoding_tile(p_j2k);
11952
11953         /* Decode the codestream */
11954         if (! j2k_exec (p_j2k,p_j2k->m_procedure_list,p_stream,p_manager)) {
11955                 opj_image_destroy(p_j2k->m_private_image);
11956                 p_j2k->m_private_image = NULL;
11957                 return OPJ_FALSE;
11958         }
11959
11960         /* Move data and copy one information from codec to output image*/
11961         for (compno = 0; compno < p_image->numcomps; compno++) {
11962                 p_image->comps[compno].resno_decoded = p_j2k->m_output_image->comps[compno].resno_decoded;
11963
11964                 if (p_image->comps[compno].data)
11965                         opj_free(p_image->comps[compno].data);
11966
11967                 p_image->comps[compno].data = p_j2k->m_output_image->comps[compno].data;
11968
11969                 p_j2k->m_output_image->comps[compno].data = NULL;
11970         }
11971
11972         return OPJ_TRUE;
11973 }
11974
11975 opj_bool j2k_set_decoded_resolution_factor(opj_j2k_v2_t *p_j2k, OPJ_UINT32 res_factor, opj_event_mgr_t * p_manager)
11976 {
11977         OPJ_UINT32 it_comp;
11978
11979         p_j2k->m_cp.m_specific_param.m_dec.m_reduce = res_factor;
11980
11981         if (p_j2k->m_private_image) {
11982                 if (p_j2k->m_private_image->comps) {
11983                         if (p_j2k->m_specific_param.m_decoder.m_default_tcp) {
11984                                 if (p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps) {
11985                                         for (it_comp = 0 ; it_comp < p_j2k->m_private_image->numcomps; it_comp++) {
11986                                                 OPJ_UINT32 max_res = p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps[it_comp].numresolutions;
11987                                                 if ( res_factor >= max_res){
11988                                                         opj_event_msg_v2(p_manager, EVT_ERROR, "Resolution factor is greater than the maximum resolution in the component.\n");
11989                                                         return OPJ_FALSE;
11990                                                 }
11991                                                 p_j2k->m_private_image->comps[it_comp].factor = res_factor;
11992                                         }
11993                                         return OPJ_TRUE;
11994                                 }
11995                         }
11996                 }
11997         }
11998
11999         return OPJ_FALSE;
12000 }
12001
12002
12003 /**
12004  * Encodes all the tiles in a row.
12005  */
12006 opj_bool j2k_encode_v2( opj_j2k_v2_t * p_j2k,
12007                                                 opj_stream_private_t *p_stream,
12008                                                 opj_event_mgr_t * p_manager )
12009 {
12010         OPJ_UINT32 i;
12011         OPJ_UINT32 l_nb_tiles;
12012         OPJ_UINT32 l_max_tile_size, l_current_tile_size;
12013         OPJ_BYTE * l_current_data;
12014
12015         /* preconditions */
12016         assert(p_j2k != 00);
12017         assert(p_stream != 00);
12018         assert(p_manager != 00);
12019
12020         l_current_data = (OPJ_BYTE*)opj_malloc(1000);
12021         if (! l_current_data) {
12022                 return OPJ_FALSE;
12023         }
12024         l_max_tile_size = 1000;
12025
12026         l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
12027         for (i=0;i<l_nb_tiles;++i) {
12028                 if (! j2k_pre_write_tile(p_j2k,i,p_stream,p_manager)) {
12029                         opj_free(l_current_data);
12030                         return OPJ_FALSE;
12031                 }
12032
12033                 l_current_tile_size = tcd_get_encoded_tile_size(p_j2k->m_tcd);
12034                 if (l_current_tile_size > l_max_tile_size) {
12035                         l_current_data = (OPJ_BYTE*)opj_realloc(l_current_data,l_current_tile_size);
12036                         if (! l_current_data) {
12037                                 return OPJ_FALSE;
12038                         }
12039                         l_max_tile_size = l_current_tile_size;
12040                 }
12041
12042                 j2k_get_tile_data(p_j2k->m_tcd,l_current_data);
12043
12044                 if (! j2k_post_write_tile (p_j2k,l_current_data,l_current_tile_size,p_stream,p_manager)) {
12045                         return OPJ_FALSE;
12046                 }
12047         }
12048
12049         opj_free(l_current_data);
12050         return OPJ_TRUE;
12051 }
12052
12053 /**
12054  * Ends the compression procedures and possibility add data to be read after the
12055  * codestream.
12056  */
12057 opj_bool j2k_end_compress(      opj_j2k_v2_t *p_j2k,
12058                                                         opj_stream_private_t *p_stream,
12059                                                         struct opj_event_mgr * p_manager)
12060 {
12061         /* customization of the encoding */
12062         j2k_setup_end_compress(p_j2k);
12063
12064         if (! j2k_exec (p_j2k, p_j2k->m_procedure_list, p_stream, p_manager))
12065         {
12066                 return OPJ_FALSE;
12067         }
12068
12069         return OPJ_TRUE;
12070 }
12071
12072
12073 /**
12074  * Starts a compression scheme, i.e. validates the codec parameters, writes the header.
12075  *
12076  * @param       p_j2k           the jpeg2000 codec.
12077  * @param       p_stream        the stream object.
12078  * @param       p_manager       the user event manager.
12079  *
12080  * @return true if the codec is valid.
12081  */
12082 opj_bool j2k_start_compress(opj_j2k_v2_t *p_j2k,
12083                                                         opj_stream_private_t *p_stream,
12084                                                         opj_image_t * p_image,
12085                                                         opj_event_mgr_t * p_manager)
12086 {
12087         /* preconditions */
12088         assert(p_j2k != 00);
12089         assert(p_stream != 00);
12090         assert(p_manager != 00);
12091
12092         p_j2k->m_private_image = opj_image_create0();
12093         opj_copy_image_header(p_image, p_j2k->m_private_image);
12094
12095         // TODO_MSD: Find a better way
12096         if (p_image->comps) {
12097                 OPJ_UINT32 it_comp;
12098                 for (it_comp = 0 ; it_comp < p_image->numcomps; it_comp++) {
12099                         if (p_image->comps[it_comp].data) {
12100                                 p_j2k->m_private_image->comps[it_comp].data =p_image->comps[it_comp].data;
12101                                 p_image->comps[it_comp].data = NULL;
12102
12103                         }
12104                 }
12105         }
12106
12107         /* customization of the validation */
12108         j2k_setup_encoding_validation (p_j2k);
12109
12110         /* validation of the parameters codec */
12111         if (! j2k_exec(p_j2k,p_j2k->m_validation_list,p_stream,p_manager)) {
12112                 return OPJ_FALSE;
12113         }
12114
12115         /* customization of the encoding */
12116         j2k_setup_header_writting(p_j2k);
12117
12118         /* write header */
12119         if (! j2k_exec (p_j2k,p_j2k->m_procedure_list,p_stream,p_manager)) {
12120                 return OPJ_FALSE;
12121         }
12122
12123         return OPJ_TRUE;
12124 }
12125
12126 /*
12127  *
12128  */
12129 opj_bool j2k_pre_write_tile (   opj_j2k_v2_t * p_j2k,
12130                                                                 OPJ_UINT32 p_tile_index,
12131                                                                 opj_stream_private_t *p_stream,
12132                                                                 opj_event_mgr_t * p_manager )
12133 {
12134   (void)p_stream;
12135         if (p_tile_index != p_j2k->m_current_tile_number) {
12136                 opj_event_msg_v2(p_manager, EVT_ERROR, "The given tile index does not match." );
12137                 return OPJ_FALSE;
12138         }
12139
12140         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);
12141
12142         p_j2k->m_specific_param.m_encoder.m_current_tile_part_number = 0;
12143         p_j2k->m_tcd->cur_totnum_tp = p_j2k->m_cp.tcps[p_tile_index].m_nb_tile_parts;
12144         p_j2k->m_specific_param.m_encoder.m_current_poc_tile_part_number = 0;
12145
12146         /* initialisation before tile encoding  */
12147         if (! tcd_init_encode_tile(p_j2k->m_tcd, p_j2k->m_current_tile_number)) {
12148                 return OPJ_FALSE;
12149         }
12150
12151         return OPJ_TRUE;
12152 }
12153
12154 /*
12155  *
12156  */
12157 void j2k_get_tile_data (opj_tcd_v2_t * p_tcd, OPJ_BYTE * p_data)
12158 {
12159         OPJ_UINT32 i,j,k = 0;
12160         OPJ_UINT32 l_width,l_height,l_stride, l_offset_x,l_offset_y, l_image_width;
12161         opj_image_comp_t * l_img_comp = 00;
12162         opj_tcd_tilecomp_v2_t * l_tilec = 00;
12163         opj_image_t * l_image = 00;
12164         OPJ_UINT32 l_size_comp, l_remaining;
12165         OPJ_INT32 * l_src_ptr;
12166         l_tilec = p_tcd->tcd_image->tiles->comps;
12167         l_image = p_tcd->image;
12168         l_img_comp = l_image->comps;
12169
12170         for (i=0;i<p_tcd->image->numcomps;++i) {
12171                 l_size_comp = l_img_comp->prec >> 3; /* (/8) */
12172                 l_remaining = l_img_comp->prec & 7;  /* (%8) */
12173                 if (l_remaining) {
12174                         ++l_size_comp;
12175                 }
12176
12177                 if (l_size_comp == 3) {
12178                         l_size_comp = 4;
12179                 }
12180
12181                 l_width = (l_tilec->x1 - l_tilec->x0);
12182                 l_height = (l_tilec->y1 - l_tilec->y0);
12183                 l_offset_x = int_ceildiv(l_image->x0, l_img_comp->dx);
12184                 l_offset_y = int_ceildiv(l_image->y0, l_img_comp->dy);
12185                 l_image_width = int_ceildiv(l_image->x1 - l_image->x0, l_img_comp->dx);
12186                 l_stride = l_image_width - l_width;
12187                 l_src_ptr = l_img_comp->data + (l_tilec->x0 - l_offset_x) + (l_tilec->y0 - l_offset_y) * l_image_width;
12188
12189                 switch (l_size_comp) {
12190                         case 1:
12191                                 {
12192                                         OPJ_CHAR * l_dest_ptr = (OPJ_CHAR*) p_data;
12193                                         if (l_img_comp->sgnd) {
12194                                                 for     (j=0;j<l_height;++j) {
12195                                                         for (k=0;k<l_width;++k) {
12196                                                                 *(l_dest_ptr) = (OPJ_CHAR) (*l_src_ptr);
12197                                                                 ++l_dest_ptr;
12198                                                                 ++l_src_ptr;
12199                                                         }
12200                                                         l_src_ptr += l_stride;
12201                                                 }
12202                                         }
12203                                         else {
12204                                                 for (j=0;j<l_height;++j) {
12205                                                         for (k=0;k<l_width;++k) {
12206                                                                 *(l_dest_ptr) = (*l_src_ptr)&0xff;
12207                                                                 ++l_dest_ptr;
12208                                                                 ++l_src_ptr;
12209                                                         }
12210                                                         l_src_ptr += l_stride;
12211                                                 }
12212                                         }
12213
12214                                         p_data = (OPJ_BYTE*) l_dest_ptr;
12215                                 }
12216                                 break;
12217                         case 2:
12218                                 {
12219                                         OPJ_INT16 * l_dest_ptr = (OPJ_INT16 *) p_data;
12220                                         if (l_img_comp->sgnd) {
12221                                                 for (j=0;j<l_height;++j) {
12222                                                         for (k=0;k<l_width;++k) {
12223                                                                 *(l_dest_ptr++) = (OPJ_INT16) (*(l_src_ptr++));
12224                                                         }
12225                                                         l_src_ptr += l_stride;
12226                                                 }
12227                                         }
12228                                         else {
12229                                                 for (j=0;j<l_height;++j) {
12230                                                         for (k=0;k<l_width;++k) {
12231                                                                 *(l_dest_ptr++) = (*(l_src_ptr++))&0xffff;
12232                                                         }
12233                                                         l_src_ptr += l_stride;
12234                                                 }
12235                                         }
12236
12237                                         p_data = (OPJ_BYTE*) l_dest_ptr;
12238                                 }
12239                                 break;
12240                         case 4:
12241                                 {
12242                                         OPJ_INT32 * l_dest_ptr = (OPJ_INT32 *) p_data;
12243                                         for (j=0;j<l_height;++j) {
12244                                                 for (k=0;k<l_width;++k) {
12245                                                         *(l_dest_ptr++) = *(l_src_ptr++);
12246                                                 }
12247                                                 l_src_ptr += l_stride;
12248                                         }
12249
12250                                         p_data = (OPJ_BYTE*) l_dest_ptr;
12251                                 }
12252                                 break;
12253                 }
12254
12255                 ++l_img_comp;
12256                 ++l_tilec;
12257         }
12258 }
12259
12260
12261 /**
12262  * Write a tile.
12263  * @param       p_j2k           the jpeg2000 codec.
12264  * @param       p_stream        the stream to write data to.
12265  * @param       p_manager       the user event manager.
12266  */
12267 opj_bool j2k_post_write_tile (  opj_j2k_v2_t * p_j2k,
12268                                                                 OPJ_BYTE * p_data,
12269                                                                 OPJ_UINT32 p_data_size,
12270                                                                 opj_stream_private_t *p_stream,
12271                                                                 opj_event_mgr_t * p_manager )
12272 {
12273         opj_tcd_v2_t * l_tcd = 00;
12274         opj_cp_v2_t * l_cp = 00;
12275         opj_tcp_v2_t * l_tcp = 00;
12276         OPJ_UINT32 l_nb_bytes_written;
12277         OPJ_BYTE * l_current_data = 00;
12278         OPJ_UINT32 l_tile_size = 0;
12279         OPJ_UINT32 l_available_data;
12280
12281         /* preconditions */
12282         assert(p_j2k->m_specific_param.m_encoder.m_encoded_tile_data);
12283
12284         l_tcd = p_j2k->m_tcd;
12285         l_cp = &(p_j2k->m_cp);
12286         l_tcp = l_cp->tcps + p_j2k->m_current_tile_number;
12287
12288         l_tile_size = p_j2k->m_specific_param.m_encoder.m_encoded_tile_size;
12289         l_available_data = l_tile_size;
12290         l_current_data = p_j2k->m_specific_param.m_encoder.m_encoded_tile_data;
12291
12292         if (! tcd_copy_tile_data(l_tcd,p_data,p_data_size)) {
12293                 opj_event_msg_v2(p_manager, EVT_ERROR, "Size mismatch between tile data and sent data." );
12294                 return OPJ_FALSE;
12295         }
12296
12297         l_nb_bytes_written = 0;
12298         if (! j2k_write_first_tile_part(p_j2k,l_current_data,&l_nb_bytes_written,l_available_data,p_stream,p_manager)) {
12299                 return OPJ_FALSE;
12300         }
12301         l_current_data += l_nb_bytes_written;
12302         l_available_data -= l_nb_bytes_written;
12303
12304         l_nb_bytes_written = 0;
12305         if (! j2k_write_all_tile_parts(p_j2k,l_current_data,&l_nb_bytes_written,l_available_data,p_stream,p_manager)) {
12306                 return OPJ_FALSE;
12307         }
12308
12309         l_available_data -= l_nb_bytes_written;
12310         l_nb_bytes_written = l_tile_size - l_available_data;
12311
12312         if ( opj_stream_write_data(     p_stream,
12313                                                                 p_j2k->m_specific_param.m_encoder.m_encoded_tile_data,
12314                                                                 l_nb_bytes_written,p_manager) != l_nb_bytes_written) {
12315                 return OPJ_FALSE;
12316         }
12317
12318         ++p_j2k->m_current_tile_number;
12319
12320         return OPJ_TRUE;
12321 }
12322
12323
12324 /**
12325  * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
12326  * are valid. Developers wanting to extend the library can add their own validation procedures.
12327  */
12328 void j2k_setup_end_compress (opj_j2k_v2_t *p_j2k)
12329 {
12330         /* preconditions */
12331         assert(p_j2k != 00);
12332
12333         /* DEVELOPER CORNER, insert your custom procedures */
12334         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_write_eoc_v2 );
12335
12336         if (p_j2k->m_cp.m_specific_param.m_enc.m_cinema) {
12337                 opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_write_updated_tlm);
12338         }
12339
12340         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_write_epc );
12341         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_end_encoding );
12342         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_destroy_header_memory);
12343 }
12344
12345 /**
12346  * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
12347  * are valid. Developers wanting to extend the library can add their own validation procedures.
12348  */
12349 void j2k_setup_encoding_validation (opj_j2k_v2_t *p_j2k)
12350 {
12351         /* preconditions */
12352         assert(p_j2k != 00);
12353
12354         opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)j2k_build_encoder);
12355         opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)j2k_encoding_validation);
12356
12357         /* DEVELOPER CORNER, add your custom validation procedure */
12358         opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)j2k_mct_validation);
12359 }
12360
12361
12362 /**
12363  * Sets up the procedures to do on writing header.
12364  * Developers wanting to extend the library can add their own writing procedures.
12365  */
12366 void j2k_setup_header_writting (opj_j2k_v2_t *p_j2k)
12367 {
12368         /* preconditions */
12369         assert(p_j2k != 00);
12370
12371         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_init_info );
12372         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_write_soc_v2 );
12373         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_write_siz_v2 );
12374         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_write_cod_v2 );
12375         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_write_qcd_v2 );
12376
12377
12378         if (p_j2k->m_cp.m_specific_param.m_enc.m_cinema) {
12379                 opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_write_image_components );
12380                 opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_write_tlm_v2 );
12381
12382                 if (p_j2k->m_cp.m_specific_param.m_enc.m_cinema == CINEMA4K_24) {
12383                         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_write_poc_v2 );
12384                 }
12385         }
12386
12387         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_write_regions);
12388
12389         if (p_j2k->m_cp.comment != 00)  {
12390                 opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_write_com_v2);
12391         }
12392
12393         /* DEVELOPER CORNER, insert your custom procedures */
12394         if (p_j2k->m_cp.rsiz & MCT) {
12395                 opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_write_mct_data_group );
12396         }
12397         /* End of Developer Corner */
12398
12399         if (p_j2k->cstr_index) {
12400                 opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_get_end_header );
12401         }
12402
12403         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_create_tcd);
12404         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_update_rates);
12405 }
12406
12407
12408 opj_bool j2k_write_first_tile_part (opj_j2k_v2_t *p_j2k,
12409                                                                         OPJ_BYTE * p_data,
12410                                                                         OPJ_UINT32 * p_data_written,
12411                                                                         OPJ_UINT32 p_total_data_size,
12412                                                                         opj_stream_private_t *p_stream,
12413                                                                         struct opj_event_mgr * p_manager )
12414 {
12415         OPJ_UINT32 compno;
12416         OPJ_UINT32 l_nb_bytes_written = 0;
12417         OPJ_UINT32 l_current_nb_bytes_written;
12418         OPJ_BYTE * l_begin_data = 00;
12419
12420         opj_tcp_v2_t *l_tcp = 00;
12421         opj_tcd_v2_t * l_tcd = 00;
12422         opj_cp_v2_t * l_cp = 00;
12423
12424         l_tcd = p_j2k->m_tcd;
12425         l_cp = &(p_j2k->m_cp);
12426         l_tcp = l_cp->tcps + p_j2k->m_current_tile_number;
12427
12428         l_tcd->cur_pino = 0;
12429
12430         /*Get number of tile parts*/
12431         p_j2k->m_specific_param.m_encoder.m_current_poc_tile_part_number = 0;
12432
12433         /* INDEX >> */
12434         /* << INDEX */
12435
12436         l_current_nb_bytes_written = 0;
12437         l_begin_data = p_data;
12438         if (! j2k_write_sot_v2(p_j2k,p_data,&l_current_nb_bytes_written,p_stream,p_manager))
12439         {
12440                 return OPJ_FALSE;
12441         }
12442
12443         l_nb_bytes_written += l_current_nb_bytes_written;
12444         p_data += l_current_nb_bytes_written;
12445         p_total_data_size -= l_current_nb_bytes_written;
12446
12447         if (l_cp->m_specific_param.m_enc.m_cinema == 0) {
12448                 for (compno = 1; compno < p_j2k->m_private_image->numcomps; compno++) {
12449                         l_current_nb_bytes_written = 0;
12450                         j2k_write_coc_in_memory(p_j2k,compno,p_data,&l_current_nb_bytes_written,p_manager);
12451                         l_nb_bytes_written += l_current_nb_bytes_written;
12452                         p_data += l_current_nb_bytes_written;
12453                         p_total_data_size -= l_current_nb_bytes_written;
12454
12455                         l_current_nb_bytes_written = 0;
12456                         j2k_write_qcc_in_memory(p_j2k,compno,p_data,&l_current_nb_bytes_written,p_manager);
12457                         l_nb_bytes_written += l_current_nb_bytes_written;
12458                         p_data += l_current_nb_bytes_written;
12459                         p_total_data_size -= l_current_nb_bytes_written;
12460                 }
12461
12462                 if (l_cp->tcps[p_j2k->m_current_tile_number].numpocs) {
12463                         l_current_nb_bytes_written = 0;
12464                         j2k_write_poc_in_memory(p_j2k,p_data,&l_current_nb_bytes_written,p_manager);
12465                         l_nb_bytes_written += l_current_nb_bytes_written;
12466                         p_data += l_current_nb_bytes_written;
12467                         p_total_data_size -= l_current_nb_bytes_written;
12468                 }
12469         }
12470
12471         l_current_nb_bytes_written = 0;
12472         if (! j2k_write_sod_v2(p_j2k,l_tcd,p_data,&l_current_nb_bytes_written,p_total_data_size,p_stream,p_manager)) {
12473                 return OPJ_FALSE;
12474         }
12475
12476         l_nb_bytes_written += l_current_nb_bytes_written;
12477         * p_data_written = l_nb_bytes_written;
12478
12479         /* Writing Psot in SOT marker */
12480         opj_write_bytes(l_begin_data + 6,l_nb_bytes_written,4);                                 /* PSOT */
12481
12482         if (l_cp->m_specific_param.m_enc.m_cinema){
12483                 j2k_update_tlm(p_j2k,l_nb_bytes_written);
12484         }
12485
12486         return OPJ_TRUE;
12487 }
12488
12489 opj_bool j2k_write_all_tile_parts(      opj_j2k_v2_t *p_j2k,
12490                                                                         OPJ_BYTE * p_data,
12491                                                                         OPJ_UINT32 * p_data_written,
12492                                                                         OPJ_UINT32 p_total_data_size,
12493                                                                         opj_stream_private_t *p_stream,
12494                                                                         struct opj_event_mgr * p_manager
12495                                                                 )
12496 {
12497         OPJ_UINT32 tilepartno=0;
12498         OPJ_UINT32 l_nb_bytes_written = 0;
12499         OPJ_UINT32 l_current_nb_bytes_written;
12500         OPJ_UINT32 l_part_tile_size;
12501         OPJ_UINT32 tot_num_tp;
12502         OPJ_UINT32 pino;
12503
12504         OPJ_BYTE * l_begin_data;
12505         opj_tcp_v2_t *l_tcp = 00;
12506         opj_tcd_v2_t * l_tcd = 00;
12507         opj_cp_v2_t * l_cp = 00;
12508
12509
12510         l_tcd = p_j2k->m_tcd;
12511         l_cp = &(p_j2k->m_cp);
12512         l_tcp = l_cp->tcps + p_j2k->m_current_tile_number;
12513
12514         /*Get number of tile parts*/
12515         tot_num_tp = j2k_get_num_tp_v2(l_cp,0,p_j2k->m_current_tile_number);
12516
12517         for (tilepartno = 1; tilepartno < tot_num_tp ; ++tilepartno) {
12518                 p_j2k->m_specific_param.m_encoder.m_current_poc_tile_part_number = tilepartno;
12519                 l_current_nb_bytes_written = 0;
12520                 l_part_tile_size = 0;
12521                 l_begin_data = p_data;
12522
12523                 if (! j2k_write_sot_v2(p_j2k,p_data,&l_current_nb_bytes_written,p_stream,p_manager)) {
12524                         return OPJ_FALSE;
12525                 }
12526
12527                 l_nb_bytes_written += l_current_nb_bytes_written;
12528                 p_data += l_current_nb_bytes_written;
12529                 p_total_data_size -= l_current_nb_bytes_written;
12530                 l_part_tile_size += l_nb_bytes_written;
12531
12532                 l_current_nb_bytes_written = 0;
12533                 if (! j2k_write_sod_v2(p_j2k,l_tcd,p_data,&l_current_nb_bytes_written,p_total_data_size,p_stream,p_manager)) {
12534                         return OPJ_FALSE;
12535                 }
12536
12537                 p_data += l_current_nb_bytes_written;
12538                 l_nb_bytes_written += l_current_nb_bytes_written;
12539                 p_total_data_size -= l_current_nb_bytes_written;
12540                 l_part_tile_size += l_nb_bytes_written;
12541
12542                 /* Writing Psot in SOT marker */
12543                 opj_write_bytes(l_begin_data + 6,l_part_tile_size,4);                                   /* PSOT */
12544
12545                 if (l_cp->m_specific_param.m_enc.m_cinema) {
12546                         j2k_update_tlm(p_j2k,l_part_tile_size);
12547                 }
12548
12549                 ++p_j2k->m_specific_param.m_encoder.m_current_tile_part_number;
12550         }
12551
12552         for (pino = 1; pino <= l_tcp->numpocs; ++pino) {
12553                 l_tcd->cur_pino = pino;
12554
12555                 /*Get number of tile parts*/
12556                 tot_num_tp = j2k_get_num_tp_v2(l_cp,pino,p_j2k->m_current_tile_number);
12557                 for (tilepartno = 0; tilepartno < tot_num_tp ; ++tilepartno) {
12558                         p_j2k->m_specific_param.m_encoder.m_current_poc_tile_part_number = tilepartno;
12559                         l_current_nb_bytes_written = 0;
12560                         l_part_tile_size = 0;
12561                         l_begin_data = p_data;
12562
12563                         if (! j2k_write_sot_v2(p_j2k,p_data,&l_current_nb_bytes_written,p_stream,p_manager)) {
12564                                 return OPJ_FALSE;
12565                         }
12566
12567                         l_nb_bytes_written += l_current_nb_bytes_written;
12568                         p_data += l_current_nb_bytes_written;
12569                         p_total_data_size -= l_current_nb_bytes_written;
12570                         l_part_tile_size += l_current_nb_bytes_written;
12571
12572                         l_current_nb_bytes_written = 0;
12573
12574                         if (! j2k_write_sod_v2(p_j2k,l_tcd,p_data,&l_current_nb_bytes_written,p_total_data_size,p_stream,p_manager)) {
12575                                 return OPJ_FALSE;
12576                         }
12577
12578                         l_nb_bytes_written += l_current_nb_bytes_written;
12579                         p_data += l_current_nb_bytes_written;
12580                         p_total_data_size -= l_current_nb_bytes_written;
12581                         l_part_tile_size += l_current_nb_bytes_written;
12582
12583                         /* Writing Psot in SOT marker */
12584                         opj_write_bytes(l_begin_data + 6,l_part_tile_size,4);                                   /* PSOT */
12585
12586                         if (l_cp->m_specific_param.m_enc.m_cinema) {
12587                                 j2k_update_tlm(p_j2k,l_part_tile_size);
12588                         }
12589
12590                         ++p_j2k->m_specific_param.m_encoder.m_current_tile_part_number;
12591                 }
12592         }
12593
12594         *p_data_written = l_nb_bytes_written;
12595
12596         return OPJ_TRUE;
12597 }
12598
12599 /**
12600  * Writes the updated tlm.
12601  *
12602  * @param       p_stream                the stream to write data to.
12603  * @param       p_j2k                   J2K codec.
12604  * @param       p_manager               the user event manager.
12605 */
12606 opj_bool j2k_write_updated_tlm( opj_j2k_v2_t *p_j2k,
12607                                                                 struct opj_stream_private *p_stream,
12608                                                                 struct opj_event_mgr * p_manager )
12609 {
12610         OPJ_UINT32 l_tlm_size;
12611         OPJ_SIZE_T l_tlm_position, l_current_position;
12612
12613         /* preconditions */
12614         assert(p_j2k != 00);
12615         assert(p_manager != 00);
12616         assert(p_stream != 00);
12617
12618         l_tlm_size = 5 * p_j2k->m_specific_param.m_encoder.m_total_tile_parts;
12619         l_tlm_position = 6 + p_j2k->m_specific_param.m_encoder.m_tlm_start;
12620         l_current_position = opj_stream_tell(p_stream);
12621
12622         if (! opj_stream_seek(p_stream,l_tlm_position,p_manager)) {
12623                 return OPJ_FALSE;
12624         }
12625
12626         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) {
12627                 return OPJ_FALSE;
12628         }
12629
12630         if (! opj_stream_seek(p_stream,l_current_position,p_manager)) {
12631                 return OPJ_FALSE;
12632         }
12633
12634         return OPJ_TRUE;
12635 }
12636
12637
12638 /**
12639  * Ends the encoding, i.e. frees memory.
12640  *
12641  * @param       p_stream                                the stream to write data to.
12642  * @param       p_j2k                           J2K codec.
12643  * @param       p_manager               the user event manager.
12644 */
12645 opj_bool j2k_end_encoding(      opj_j2k_v2_t *p_j2k,
12646                                                         struct opj_stream_private *p_stream,
12647                                                         struct opj_event_mgr * p_manager )
12648 {
12649         /* preconditions */
12650         assert(p_j2k != 00);
12651         assert(p_manager != 00);
12652         assert(p_stream != 00);
12653
12654         tcd_destroy_v2(p_j2k->m_tcd);
12655         p_j2k->m_tcd = 00;
12656
12657         if (p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer) {
12658                 opj_free(p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer);
12659                 p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer = 0;
12660                 p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current = 0;
12661         }
12662
12663         if (p_j2k->m_specific_param.m_encoder.m_encoded_tile_data) {
12664                 opj_free(p_j2k->m_specific_param.m_encoder.m_encoded_tile_data);
12665                 p_j2k->m_specific_param.m_encoder.m_encoded_tile_data = 0;
12666         }
12667
12668         p_j2k->m_specific_param.m_encoder.m_encoded_tile_size = 0;
12669
12670         return OPJ_TRUE;
12671 }
12672
12673 /**
12674  * Destroys the memory associated with the decoding of headers.
12675  */
12676 opj_bool j2k_destroy_header_memory (opj_j2k_v2_t * p_j2k,
12677                                                                         opj_stream_private_t *p_stream,
12678                                                                         opj_event_mgr_t * p_manager )
12679 {
12680         /* preconditions */
12681         assert(p_j2k != 00);
12682         assert(p_stream != 00);
12683         assert(p_manager != 00);
12684
12685         if (p_j2k->m_specific_param.m_encoder.m_header_tile_data) {
12686                 opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
12687                 p_j2k->m_specific_param.m_encoder.m_header_tile_data = 0;
12688         }
12689
12690         p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
12691
12692         return OPJ_TRUE;
12693 }
12694
12695
12696 /**
12697  * Inits the Info
12698  *
12699  * @param       p_stream                                the stream to write data to.
12700  * @param       p_j2k                           J2K codec.
12701  * @param       p_manager               the user event manager.
12702 */
12703 opj_bool j2k_init_info( opj_j2k_v2_t *p_j2k,
12704                                                 struct opj_stream_private *p_stream,
12705                                                 struct opj_event_mgr * p_manager )
12706 {
12707         opj_codestream_info_t * l_cstr_info = 00;
12708
12709         /* preconditions */
12710         assert(p_j2k != 00);
12711         assert(p_manager != 00);
12712         assert(p_stream != 00);
12713   (void)l_cstr_info;
12714
12715         /* TODO mergeV2: check this part which use cstr_info */
12716         /*l_cstr_info = p_j2k->cstr_info;
12717
12718         if (l_cstr_info)  {
12719                 OPJ_UINT32 compno;
12720                 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));
12721
12722                 l_cstr_info->image_w = p_j2k->m_image->x1 - p_j2k->m_image->x0;
12723                 l_cstr_info->image_h = p_j2k->m_image->y1 - p_j2k->m_image->y0;
12724
12725                 l_cstr_info->prog = (&p_j2k->m_cp.tcps[0])->prg;
12726
12727                 l_cstr_info->tw = p_j2k->m_cp.tw;
12728                 l_cstr_info->th = p_j2k->m_cp.th;
12729
12730                 l_cstr_info->tile_x = p_j2k->m_cp.tdx;*/        /* new version parser */
12731                 /*l_cstr_info->tile_y = p_j2k->m_cp.tdy;*/      /* new version parser */
12732                 /*l_cstr_info->tile_Ox = p_j2k->m_cp.tx0;*/     /* new version parser */
12733                 /*l_cstr_info->tile_Oy = p_j2k->m_cp.ty0;*/     /* new version parser */
12734
12735                 /*l_cstr_info->numcomps = p_j2k->m_image->numcomps;
12736
12737                 l_cstr_info->numlayers = (&p_j2k->m_cp.tcps[0])->numlayers;
12738
12739                 l_cstr_info->numdecompos = (OPJ_INT32*) opj_malloc(p_j2k->m_image->numcomps * sizeof(OPJ_INT32));
12740
12741                 for (compno=0; compno < p_j2k->m_image->numcomps; compno++) {
12742                         l_cstr_info->numdecompos[compno] = (&p_j2k->m_cp.tcps[0])->tccps->numresolutions - 1;
12743                 }
12744
12745                 l_cstr_info->D_max = 0.0;       */      /* ADD Marcela */
12746
12747                 /*l_cstr_info->main_head_start = opj_stream_tell(p_stream);*/ /* position of SOC */
12748
12749                 /*l_cstr_info->maxmarknum = 100;
12750                 l_cstr_info->marker = (opj_marker_info_t *) opj_malloc(l_cstr_info->maxmarknum * sizeof(opj_marker_info_t));
12751                 l_cstr_info->marknum = 0;
12752         }*/
12753
12754         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);
12755 }
12756
12757 /**
12758  * Creates a tile-coder decoder.
12759  *
12760  * @param       p_stream                the stream to write data to.
12761  * @param       p_j2k                   J2K codec.
12762  * @param       p_manager               the user event manager.
12763 */
12764 opj_bool j2k_create_tcd(opj_j2k_v2_t *p_j2k,
12765                                                 struct opj_stream_private *p_stream,
12766                                                 struct opj_event_mgr * p_manager )
12767 {
12768         /* preconditions */
12769         assert(p_j2k != 00);
12770         assert(p_manager != 00);
12771         assert(p_stream != 00);
12772
12773         p_j2k->m_tcd = tcd_create_v2(OPJ_FALSE);
12774
12775         if (! p_j2k->m_tcd) {
12776                 opj_event_msg_v2(p_manager, EVT_ERROR, "Not enough memory to create Tile Coder\n");
12777                 return OPJ_FALSE;
12778         }
12779
12780         if (! tcd_init_v2(p_j2k->m_tcd,p_j2k->m_private_image,&p_j2k->m_cp)) {
12781                 tcd_destroy_v2(p_j2k->m_tcd);
12782                 p_j2k->m_tcd = 00;
12783                 return OPJ_FALSE;
12784         }
12785
12786         return OPJ_TRUE;
12787 }
12788
12789
12790 /**
12791  * Writes a tile.
12792  * @param       p_j2k           the jpeg2000 codec.
12793  * @param       p_stream                        the stream to write data to.
12794  * @param       p_manager       the user event manager.
12795  */
12796 opj_bool j2k_write_tile (opj_j2k_v2_t * p_j2k,
12797                                                  OPJ_UINT32 p_tile_index,
12798                                                  OPJ_BYTE * p_data,
12799                                                  OPJ_UINT32 p_data_size,
12800                                                  opj_stream_private_t *p_stream,
12801                                                  opj_event_mgr_t * p_manager )
12802 {
12803         if (! j2k_pre_write_tile(p_j2k,p_tile_index,p_stream,p_manager)) {
12804                 opj_event_msg_v2(p_manager, EVT_ERROR, "Error while j2k_pre_write_tile with tile index = %d\n", p_tile_index);
12805                 return OPJ_FALSE;
12806         }
12807         else {
12808                 if (! j2k_post_write_tile(p_j2k,p_data,p_data_size,p_stream,p_manager)) {
12809                         opj_event_msg_v2(p_manager, EVT_ERROR, "Error while j2k_post_write_tile with tile index = %d\n", p_tile_index);
12810                         return OPJ_FALSE;
12811                 }
12812         }
12813
12814         return OPJ_TRUE;
12815 }