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