Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/openjpeg/src/lib/openjp2/j2k.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 /* | |
| 2 * The copyright in this software is being made available under the 2-clauses | |
| 3 * BSD License, included below. This software may be subject to other third | |
| 4 * party and contributor rights, including patent rights, and no such rights | |
| 5 * are granted under this license. | |
| 6 * | |
| 7 * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium | |
| 8 * Copyright (c) 2002-2014, Professor Benoit Macq | |
| 9 * Copyright (c) 2001-2003, David Janssens | |
| 10 * Copyright (c) 2002-2003, Yannick Verschueren | |
| 11 * Copyright (c) 2003-2007, Francois-Olivier Devaux | |
| 12 * Copyright (c) 2003-2014, Antonin Descampe | |
| 13 * Copyright (c) 2005, Herve Drolon, FreeImage Team | |
| 14 * Copyright (c) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes@c-s.fr> | |
| 15 * Copyright (c) 2006-2007, Parvatha Elangovan | |
| 16 * Copyright (c) 2010-2011, Kaori Hagihara | |
| 17 * Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France | |
| 18 * Copyright (c) 2012, CS Systemes d'Information, France | |
| 19 * Copyright (c) 2017, IntoPIX SA <support@intopix.com> | |
| 20 * All rights reserved. | |
| 21 * | |
| 22 * Redistribution and use in source and binary forms, with or without | |
| 23 * modification, are permitted provided that the following conditions | |
| 24 * are met: | |
| 25 * 1. Redistributions of source code must retain the above copyright | |
| 26 * notice, this list of conditions and the following disclaimer. | |
| 27 * 2. Redistributions in binary form must reproduce the above copyright | |
| 28 * notice, this list of conditions and the following disclaimer in the | |
| 29 * documentation and/or other materials provided with the distribution. | |
| 30 * | |
| 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' | |
| 32 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 33 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
| 34 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |
| 35 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
| 36 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
| 37 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
| 38 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
| 39 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
| 40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 41 * POSSIBILITY OF SUCH DAMAGE. | |
| 42 */ | |
| 43 | |
| 44 #include "opj_includes.h" | |
| 45 | |
| 46 /** @defgroup J2K J2K - JPEG-2000 codestream reader/writer */ | |
| 47 /*@{*/ | |
| 48 | |
| 49 /** @name Local static functions */ | |
| 50 /*@{*/ | |
| 51 | |
| 52 /** | |
| 53 * Sets up the procedures to do on reading header. Developers wanting to extend the library can add their own reading procedures. | |
| 54 */ | |
| 55 static OPJ_BOOL opj_j2k_setup_header_reading(opj_j2k_t *p_j2k, | |
| 56 opj_event_mgr_t * p_manager); | |
| 57 | |
| 58 /** | |
| 59 * The read header procedure. | |
| 60 */ | |
| 61 static OPJ_BOOL opj_j2k_read_header_procedure(opj_j2k_t *p_j2k, | |
| 62 opj_stream_private_t *p_stream, | |
| 63 opj_event_mgr_t * p_manager); | |
| 64 | |
| 65 /** | |
| 66 * The default encoding validation procedure without any extension. | |
| 67 * | |
| 68 * @param p_j2k the jpeg2000 codec to validate. | |
| 69 * @param p_stream the input stream to validate. | |
| 70 * @param p_manager the user event manager. | |
| 71 * | |
| 72 * @return true if the parameters are correct. | |
| 73 */ | |
| 74 static OPJ_BOOL opj_j2k_encoding_validation(opj_j2k_t * p_j2k, | |
| 75 opj_stream_private_t *p_stream, | |
| 76 opj_event_mgr_t * p_manager); | |
| 77 | |
| 78 /** | |
| 79 * The default decoding validation procedure without any extension. | |
| 80 * | |
| 81 * @param p_j2k the jpeg2000 codec to validate. | |
| 82 * @param p_stream the input stream to validate. | |
| 83 * @param p_manager the user event manager. | |
| 84 * | |
| 85 * @return true if the parameters are correct. | |
| 86 */ | |
| 87 static OPJ_BOOL opj_j2k_decoding_validation(opj_j2k_t * p_j2k, | |
| 88 opj_stream_private_t *p_stream, | |
| 89 opj_event_mgr_t * p_manager); | |
| 90 | |
| 91 /** | |
| 92 * Sets up the validation ,i.e. adds the procedures to launch to make sure the codec parameters | |
| 93 * are valid. Developers wanting to extend the library can add their own validation procedures. | |
| 94 */ | |
| 95 static OPJ_BOOL opj_j2k_setup_encoding_validation(opj_j2k_t *p_j2k, | |
| 96 opj_event_mgr_t * p_manager); | |
| 97 | |
| 98 /** | |
| 99 * Sets up the validation ,i.e. adds the procedures to launch to make sure the codec parameters | |
| 100 * are valid. Developers wanting to extend the library can add their own validation procedures. | |
| 101 */ | |
| 102 static OPJ_BOOL opj_j2k_setup_decoding_validation(opj_j2k_t *p_j2k, | |
| 103 opj_event_mgr_t * p_manager); | |
| 104 | |
| 105 /** | |
| 106 * Sets up the validation ,i.e. adds the procedures to launch to make sure the codec parameters | |
| 107 * are valid. Developers wanting to extend the library can add their own validation procedures. | |
| 108 */ | |
| 109 static OPJ_BOOL opj_j2k_setup_end_compress(opj_j2k_t *p_j2k, | |
| 110 opj_event_mgr_t * p_manager); | |
| 111 | |
| 112 /** | |
| 113 * The mct encoding validation procedure. | |
| 114 * | |
| 115 * @param p_j2k the jpeg2000 codec to validate. | |
| 116 * @param p_stream the input stream to validate. | |
| 117 * @param p_manager the user event manager. | |
| 118 * | |
| 119 * @return true if the parameters are correct. | |
| 120 */ | |
| 121 static OPJ_BOOL opj_j2k_mct_validation(opj_j2k_t * p_j2k, | |
| 122 opj_stream_private_t *p_stream, | |
| 123 opj_event_mgr_t * p_manager); | |
| 124 | |
| 125 /** | |
| 126 * Builds the tcd decoder to use to decode tile. | |
| 127 */ | |
| 128 static OPJ_BOOL opj_j2k_build_decoder(opj_j2k_t * p_j2k, | |
| 129 opj_stream_private_t *p_stream, | |
| 130 opj_event_mgr_t * p_manager); | |
| 131 /** | |
| 132 * Builds the tcd encoder to use to encode tile. | |
| 133 */ | |
| 134 static OPJ_BOOL opj_j2k_build_encoder(opj_j2k_t * p_j2k, | |
| 135 opj_stream_private_t *p_stream, | |
| 136 opj_event_mgr_t * p_manager); | |
| 137 | |
| 138 /** | |
| 139 * Creates a tile-coder encoder. | |
| 140 * | |
| 141 * @param p_stream the stream to write data to. | |
| 142 * @param p_j2k J2K codec. | |
| 143 * @param p_manager the user event manager. | |
| 144 */ | |
| 145 static OPJ_BOOL opj_j2k_create_tcd(opj_j2k_t *p_j2k, | |
| 146 opj_stream_private_t *p_stream, | |
| 147 opj_event_mgr_t * p_manager); | |
| 148 | |
| 149 /** | |
| 150 * Executes the given procedures on the given codec. | |
| 151 * | |
| 152 * @param p_procedure_list the list of procedures to execute | |
| 153 * @param p_j2k the jpeg2000 codec to execute the procedures on. | |
| 154 * @param p_stream the stream to execute the procedures on. | |
| 155 * @param p_manager the user manager. | |
| 156 * | |
| 157 * @return true if all the procedures were successfully executed. | |
| 158 */ | |
| 159 static OPJ_BOOL opj_j2k_exec(opj_j2k_t * p_j2k, | |
| 160 opj_procedure_list_t * p_procedure_list, | |
| 161 opj_stream_private_t *p_stream, | |
| 162 opj_event_mgr_t * p_manager); | |
| 163 | |
| 164 /** | |
| 165 * Updates the rates of the tcp. | |
| 166 * | |
| 167 * @param p_stream the stream to write data to. | |
| 168 * @param p_j2k J2K codec. | |
| 169 * @param p_manager the user event manager. | |
| 170 */ | |
| 171 static OPJ_BOOL opj_j2k_update_rates(opj_j2k_t *p_j2k, | |
| 172 opj_stream_private_t *p_stream, | |
| 173 opj_event_mgr_t * p_manager); | |
| 174 | |
| 175 /** | |
| 176 * Copies the decoding tile parameters onto all the tile parameters. | |
| 177 * Creates also the tile decoder. | |
| 178 */ | |
| 179 static OPJ_BOOL opj_j2k_copy_default_tcp_and_create_tcd(opj_j2k_t * p_j2k, | |
| 180 opj_stream_private_t *p_stream, | |
| 181 opj_event_mgr_t * p_manager); | |
| 182 | |
| 183 /** | |
| 184 * Destroys the memory associated with the decoding of headers. | |
| 185 */ | |
| 186 static OPJ_BOOL opj_j2k_destroy_header_memory(opj_j2k_t * p_j2k, | |
| 187 opj_stream_private_t *p_stream, | |
| 188 opj_event_mgr_t * p_manager); | |
| 189 | |
| 190 /** | |
| 191 * Reads the lookup table containing all the marker, status and action, and returns the handler associated | |
| 192 * with the marker value. | |
| 193 * @param p_id Marker value to look up | |
| 194 * | |
| 195 * @return the handler associated with the id. | |
| 196 */ | |
| 197 static const struct opj_dec_memory_marker_handler * opj_j2k_get_marker_handler( | |
| 198 OPJ_UINT32 p_id); | |
| 199 | |
| 200 /** | |
| 201 * Destroys a tile coding parameter structure. | |
| 202 * | |
| 203 * @param p_tcp the tile coding parameter to destroy. | |
| 204 */ | |
| 205 static void opj_j2k_tcp_destroy(opj_tcp_t *p_tcp); | |
| 206 | |
| 207 /** | |
| 208 * Destroys the data inside a tile coding parameter structure. | |
| 209 * | |
| 210 * @param p_tcp the tile coding parameter which contain data to destroy. | |
| 211 */ | |
| 212 static void opj_j2k_tcp_data_destroy(opj_tcp_t *p_tcp); | |
| 213 | |
| 214 /** | |
| 215 * Destroys a coding parameter structure. | |
| 216 * | |
| 217 * @param p_cp the coding parameter to destroy. | |
| 218 */ | |
| 219 static void opj_j2k_cp_destroy(opj_cp_t *p_cp); | |
| 220 | |
| 221 /** | |
| 222 * Compare 2 a SPCod/ SPCoc elements, i.e. the coding style of a given component of a tile. | |
| 223 * | |
| 224 * @param p_j2k J2K codec. | |
| 225 * @param p_tile_no Tile number | |
| 226 * @param p_first_comp_no The 1st component number to compare. | |
| 227 * @param p_second_comp_no The 1st component number to compare. | |
| 228 * | |
| 229 * @return OPJ_TRUE if SPCdod are equals. | |
| 230 */ | |
| 231 static OPJ_BOOL opj_j2k_compare_SPCod_SPCoc(opj_j2k_t *p_j2k, | |
| 232 OPJ_UINT32 p_tile_no, OPJ_UINT32 p_first_comp_no, OPJ_UINT32 p_second_comp_no); | |
| 233 | |
| 234 /** | |
| 235 * Writes a SPCod or SPCoc element, i.e. the coding style of a given component of a tile. | |
| 236 * | |
| 237 * @param p_j2k J2K codec. | |
| 238 * @param p_tile_no FIXME DOC | |
| 239 * @param p_comp_no the component number to output. | |
| 240 * @param p_data FIXME DOC | |
| 241 * @param p_header_size FIXME DOC | |
| 242 * @param p_manager the user event manager. | |
| 243 * | |
| 244 * @return FIXME DOC | |
| 245 */ | |
| 246 static OPJ_BOOL opj_j2k_write_SPCod_SPCoc(opj_j2k_t *p_j2k, | |
| 247 OPJ_UINT32 p_tile_no, | |
| 248 OPJ_UINT32 p_comp_no, | |
| 249 OPJ_BYTE * p_data, | |
| 250 OPJ_UINT32 * p_header_size, | |
| 251 opj_event_mgr_t * p_manager); | |
| 252 | |
| 253 /** | |
| 254 * Gets the size taken by writing a SPCod or SPCoc for the given tile and component. | |
| 255 * | |
| 256 * @param p_j2k the J2K codec. | |
| 257 * @param p_tile_no the tile index. | |
| 258 * @param p_comp_no the component being outputted. | |
| 259 * | |
| 260 * @return the number of bytes taken by the SPCod element. | |
| 261 */ | |
| 262 static OPJ_UINT32 opj_j2k_get_SPCod_SPCoc_size(opj_j2k_t *p_j2k, | |
| 263 OPJ_UINT32 p_tile_no, | |
| 264 OPJ_UINT32 p_comp_no); | |
| 265 | |
| 266 /** | |
| 267 * Reads a SPCod or SPCoc element, i.e. the coding style of a given component of a tile. | |
| 268 * @param p_j2k the jpeg2000 codec. | |
| 269 * @param compno FIXME DOC | |
| 270 * @param p_header_data the data contained in the COM box. | |
| 271 * @param p_header_size the size of the data contained in the COM marker. | |
| 272 * @param p_manager the user event manager. | |
| 273 */ | |
| 274 static OPJ_BOOL opj_j2k_read_SPCod_SPCoc(opj_j2k_t *p_j2k, | |
| 275 OPJ_UINT32 compno, | |
| 276 OPJ_BYTE * p_header_data, | |
| 277 OPJ_UINT32 * p_header_size, | |
| 278 opj_event_mgr_t * p_manager); | |
| 279 | |
| 280 /** | |
| 281 * Gets the size taken by writing SQcd or SQcc element, i.e. the quantization values of a band in the QCD or QCC. | |
| 282 * | |
| 283 * @param p_tile_no the tile index. | |
| 284 * @param p_comp_no the component being outputted. | |
| 285 * @param p_j2k the J2K codec. | |
| 286 * | |
| 287 * @return the number of bytes taken by the SPCod element. | |
| 288 */ | |
| 289 static OPJ_UINT32 opj_j2k_get_SQcd_SQcc_size(opj_j2k_t *p_j2k, | |
| 290 OPJ_UINT32 p_tile_no, | |
| 291 OPJ_UINT32 p_comp_no); | |
| 292 | |
| 293 /** | |
| 294 * Compares 2 SQcd or SQcc element, i.e. the quantization values of a band in the QCD or QCC. | |
| 295 * | |
| 296 * @param p_j2k J2K codec. | |
| 297 * @param p_tile_no the tile to output. | |
| 298 * @param p_first_comp_no the first component number to compare. | |
| 299 * @param p_second_comp_no the second component number to compare. | |
| 300 * | |
| 301 * @return OPJ_TRUE if equals. | |
| 302 */ | |
| 303 static OPJ_BOOL opj_j2k_compare_SQcd_SQcc(opj_j2k_t *p_j2k, | |
| 304 OPJ_UINT32 p_tile_no, OPJ_UINT32 p_first_comp_no, OPJ_UINT32 p_second_comp_no); | |
| 305 | |
| 306 | |
| 307 /** | |
| 308 * Writes a SQcd or SQcc element, i.e. the quantization values of a band in the QCD or QCC. | |
| 309 * | |
| 310 * @param p_tile_no the tile to output. | |
| 311 * @param p_comp_no the component number to output. | |
| 312 * @param p_data the data buffer. | |
| 313 * @param p_header_size pointer to the size of the data buffer, it is changed by the function. | |
| 314 * @param p_j2k J2K codec. | |
| 315 * @param p_manager the user event manager. | |
| 316 * | |
| 317 */ | |
| 318 static OPJ_BOOL opj_j2k_write_SQcd_SQcc(opj_j2k_t *p_j2k, | |
| 319 OPJ_UINT32 p_tile_no, | |
| 320 OPJ_UINT32 p_comp_no, | |
| 321 OPJ_BYTE * p_data, | |
| 322 OPJ_UINT32 * p_header_size, | |
| 323 opj_event_mgr_t * p_manager); | |
| 324 | |
| 325 /** | |
| 326 * Updates the Tile Length Marker. | |
| 327 */ | |
| 328 static void opj_j2k_update_tlm(opj_j2k_t * p_j2k, OPJ_UINT32 p_tile_part_size); | |
| 329 | |
| 330 /** | |
| 331 * Reads a SQcd or SQcc element, i.e. the quantization values of a band in the QCD or QCC. | |
| 332 * | |
| 333 * @param p_j2k J2K codec. | |
| 334 * @param compno the component number to output. | |
| 335 * @param p_header_data the data buffer. | |
| 336 * @param p_header_size pointer to the size of the data buffer, it is changed by the function. | |
| 337 * @param p_manager the user event manager. | |
| 338 * | |
| 339 */ | |
| 340 static OPJ_BOOL opj_j2k_read_SQcd_SQcc(opj_j2k_t *p_j2k, | |
| 341 OPJ_UINT32 compno, | |
| 342 OPJ_BYTE * p_header_data, | |
| 343 OPJ_UINT32 * p_header_size, | |
| 344 opj_event_mgr_t * p_manager); | |
| 345 | |
| 346 /** | |
| 347 * Copies the tile component parameters of all the component from the first tile component. | |
| 348 * | |
| 349 * @param p_j2k the J2k codec. | |
| 350 */ | |
| 351 static void opj_j2k_copy_tile_component_parameters(opj_j2k_t *p_j2k); | |
| 352 | |
| 353 /** | |
| 354 * Copies the tile quantization parameters of all the component from the first tile component. | |
| 355 * | |
| 356 * @param p_j2k the J2k codec. | |
| 357 */ | |
| 358 static void opj_j2k_copy_tile_quantization_parameters(opj_j2k_t *p_j2k); | |
| 359 | |
| 360 /** | |
| 361 * Reads the tiles. | |
| 362 */ | |
| 363 static OPJ_BOOL opj_j2k_decode_tiles(opj_j2k_t *p_j2k, | |
| 364 opj_stream_private_t *p_stream, | |
| 365 opj_event_mgr_t * p_manager); | |
| 366 | |
| 367 static OPJ_BOOL opj_j2k_pre_write_tile(opj_j2k_t * p_j2k, | |
| 368 OPJ_UINT32 p_tile_index, | |
| 369 opj_stream_private_t *p_stream, | |
| 370 opj_event_mgr_t * p_manager); | |
| 371 | |
| 372 static OPJ_BOOL opj_j2k_update_image_data(opj_tcd_t * p_tcd, | |
| 373 opj_image_t* p_output_image); | |
| 374 | |
| 375 static void opj_get_tile_dimensions(opj_image_t * l_image, | |
| 376 opj_tcd_tilecomp_t * l_tilec, | |
| 377 opj_image_comp_t * l_img_comp, | |
| 378 OPJ_UINT32* l_size_comp, | |
| 379 OPJ_UINT32* l_width, | |
| 380 OPJ_UINT32* l_height, | |
| 381 OPJ_UINT32* l_offset_x, | |
| 382 OPJ_UINT32* l_offset_y, | |
| 383 OPJ_UINT32* l_image_width, | |
| 384 OPJ_UINT32* l_stride, | |
| 385 OPJ_UINT32* l_tile_offset); | |
| 386 | |
| 387 static void opj_j2k_get_tile_data(opj_tcd_t * p_tcd, OPJ_BYTE * p_data); | |
| 388 | |
| 389 static OPJ_BOOL opj_j2k_post_write_tile(opj_j2k_t * p_j2k, | |
| 390 opj_stream_private_t *p_stream, | |
| 391 opj_event_mgr_t * p_manager); | |
| 392 | |
| 393 /** | |
| 394 * Sets up the procedures to do on writing header. | |
| 395 * Developers wanting to extend the library can add their own writing procedures. | |
| 396 */ | |
| 397 static OPJ_BOOL opj_j2k_setup_header_writing(opj_j2k_t *p_j2k, | |
| 398 opj_event_mgr_t * p_manager); | |
| 399 | |
| 400 static OPJ_BOOL opj_j2k_write_first_tile_part(opj_j2k_t *p_j2k, | |
| 401 OPJ_BYTE * p_data, | |
| 402 OPJ_UINT32 * p_data_written, | |
| 403 OPJ_UINT32 total_data_size, | |
| 404 opj_stream_private_t *p_stream, | |
| 405 struct opj_event_mgr * p_manager); | |
| 406 | |
| 407 static OPJ_BOOL opj_j2k_write_all_tile_parts(opj_j2k_t *p_j2k, | |
| 408 OPJ_BYTE * p_data, | |
| 409 OPJ_UINT32 * p_data_written, | |
| 410 OPJ_UINT32 total_data_size, | |
| 411 opj_stream_private_t *p_stream, | |
| 412 struct opj_event_mgr * p_manager); | |
| 413 | |
| 414 /** | |
| 415 * Gets the offset of the header. | |
| 416 * | |
| 417 * @param p_stream the stream to write data to. | |
| 418 * @param p_j2k J2K codec. | |
| 419 * @param p_manager the user event manager. | |
| 420 */ | |
| 421 static OPJ_BOOL opj_j2k_get_end_header(opj_j2k_t *p_j2k, | |
| 422 opj_stream_private_t *p_stream, | |
| 423 opj_event_mgr_t * p_manager); | |
| 424 | |
| 425 static OPJ_BOOL opj_j2k_allocate_tile_element_cstr_index(opj_j2k_t *p_j2k); | |
| 426 | |
| 427 /* | |
| 428 * ----------------------------------------------------------------------- | |
| 429 * ----------------------------------------------------------------------- | |
| 430 * ----------------------------------------------------------------------- | |
| 431 */ | |
| 432 | |
| 433 /** | |
| 434 * Writes the SOC marker (Start Of Codestream) | |
| 435 * | |
| 436 * @param p_stream the stream to write data to. | |
| 437 * @param p_j2k J2K codec. | |
| 438 * @param p_manager the user event manager. | |
| 439 */ | |
| 440 static OPJ_BOOL opj_j2k_write_soc(opj_j2k_t *p_j2k, | |
| 441 opj_stream_private_t *p_stream, | |
| 442 opj_event_mgr_t * p_manager); | |
| 443 | |
| 444 /** | |
| 445 * Reads a SOC marker (Start of Codestream) | |
| 446 * @param p_j2k the jpeg2000 file codec. | |
| 447 * @param p_stream XXX needs data | |
| 448 * @param p_manager the user event manager. | |
| 449 */ | |
| 450 static OPJ_BOOL opj_j2k_read_soc(opj_j2k_t *p_j2k, | |
| 451 opj_stream_private_t *p_stream, | |
| 452 opj_event_mgr_t * p_manager); | |
| 453 | |
| 454 /** | |
| 455 * Writes the SIZ marker (image and tile size) | |
| 456 * | |
| 457 * @param p_j2k J2K codec. | |
| 458 * @param p_stream the stream to write data to. | |
| 459 * @param p_manager the user event manager. | |
| 460 */ | |
| 461 static OPJ_BOOL opj_j2k_write_siz(opj_j2k_t *p_j2k, | |
| 462 opj_stream_private_t *p_stream, | |
| 463 opj_event_mgr_t * p_manager); | |
| 464 | |
| 465 /** | |
| 466 * Reads a SIZ marker (image and tile size) | |
| 467 * @param p_j2k the jpeg2000 file codec. | |
| 468 * @param p_header_data the data contained in the SIZ box. | |
| 469 * @param p_header_size the size of the data contained in the SIZ marker. | |
| 470 * @param p_manager the user event manager. | |
| 471 */ | |
| 472 static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k, | |
| 473 OPJ_BYTE * p_header_data, | |
| 474 OPJ_UINT32 p_header_size, | |
| 475 opj_event_mgr_t * p_manager); | |
| 476 | |
| 477 /** | |
| 478 * Writes the COM marker (comment) | |
| 479 * | |
| 480 * @param p_stream the stream to write data to. | |
| 481 * @param p_j2k J2K codec. | |
| 482 * @param p_manager the user event manager. | |
| 483 */ | |
| 484 static OPJ_BOOL opj_j2k_write_com(opj_j2k_t *p_j2k, | |
| 485 opj_stream_private_t *p_stream, | |
| 486 opj_event_mgr_t * p_manager); | |
| 487 | |
| 488 /** | |
| 489 * Reads a COM marker (comments) | |
| 490 * @param p_j2k the jpeg2000 file codec. | |
| 491 * @param p_header_data the data contained in the COM box. | |
| 492 * @param p_header_size the size of the data contained in the COM marker. | |
| 493 * @param p_manager the user event manager. | |
| 494 */ | |
| 495 static OPJ_BOOL opj_j2k_read_com(opj_j2k_t *p_j2k, | |
| 496 OPJ_BYTE * p_header_data, | |
| 497 OPJ_UINT32 p_header_size, | |
| 498 opj_event_mgr_t * p_manager); | |
| 499 /** | |
| 500 * Writes the COD marker (Coding style default) | |
| 501 * | |
| 502 * @param p_stream the stream to write data to. | |
| 503 * @param p_j2k J2K codec. | |
| 504 * @param p_manager the user event manager. | |
| 505 */ | |
| 506 static OPJ_BOOL opj_j2k_write_cod(opj_j2k_t *p_j2k, | |
| 507 opj_stream_private_t *p_stream, | |
| 508 opj_event_mgr_t * p_manager); | |
| 509 | |
| 510 /** | |
| 511 * Reads a COD marker (Coding style defaults) | |
| 512 * @param p_header_data the data contained in the COD box. | |
| 513 * @param p_j2k the jpeg2000 codec. | |
| 514 * @param p_header_size the size of the data contained in the COD marker. | |
| 515 * @param p_manager the user event manager. | |
| 516 */ | |
| 517 static OPJ_BOOL opj_j2k_read_cod(opj_j2k_t *p_j2k, | |
| 518 OPJ_BYTE * p_header_data, | |
| 519 OPJ_UINT32 p_header_size, | |
| 520 opj_event_mgr_t * p_manager); | |
| 521 | |
| 522 /** | |
| 523 * Compares 2 COC markers (Coding style component) | |
| 524 * | |
| 525 * @param p_j2k J2K codec. | |
| 526 * @param p_first_comp_no the index of the first component to compare. | |
| 527 * @param p_second_comp_no the index of the second component to compare. | |
| 528 * | |
| 529 * @return OPJ_TRUE if equals | |
| 530 */ | |
| 531 static OPJ_BOOL opj_j2k_compare_coc(opj_j2k_t *p_j2k, | |
| 532 OPJ_UINT32 p_first_comp_no, OPJ_UINT32 p_second_comp_no); | |
| 533 | |
| 534 /** | |
| 535 * Writes the COC marker (Coding style component) | |
| 536 * | |
| 537 * @param p_j2k J2K codec. | |
| 538 * @param p_comp_no the index of the component to output. | |
| 539 * @param p_stream the stream to write data to. | |
| 540 * @param p_manager the user event manager. | |
| 541 */ | |
| 542 static OPJ_BOOL opj_j2k_write_coc(opj_j2k_t *p_j2k, | |
| 543 OPJ_UINT32 p_comp_no, | |
| 544 opj_stream_private_t *p_stream, | |
| 545 opj_event_mgr_t * p_manager); | |
| 546 | |
| 547 /** | |
| 548 * Writes the COC marker (Coding style component) | |
| 549 * | |
| 550 * @param p_j2k J2K codec. | |
| 551 * @param p_comp_no the index of the component to output. | |
| 552 * @param p_data FIXME DOC | |
| 553 * @param p_data_written FIXME DOC | |
| 554 * @param p_manager the user event manager. | |
| 555 */ | |
| 556 static void opj_j2k_write_coc_in_memory(opj_j2k_t *p_j2k, | |
| 557 OPJ_UINT32 p_comp_no, | |
| 558 OPJ_BYTE * p_data, | |
| 559 OPJ_UINT32 * p_data_written, | |
| 560 opj_event_mgr_t * p_manager); | |
| 561 | |
| 562 /** | |
| 563 * Gets the maximum size taken by a coc. | |
| 564 * | |
| 565 * @param p_j2k the jpeg2000 codec to use. | |
| 566 */ | |
| 567 static OPJ_UINT32 opj_j2k_get_max_coc_size(opj_j2k_t *p_j2k); | |
| 568 | |
| 569 /** | |
| 570 * Reads a COC marker (Coding Style Component) | |
| 571 * @param p_header_data the data contained in the COC box. | |
| 572 * @param p_j2k the jpeg2000 codec. | |
| 573 * @param p_header_size the size of the data contained in the COC marker. | |
| 574 * @param p_manager the user event manager. | |
| 575 */ | |
| 576 static OPJ_BOOL opj_j2k_read_coc(opj_j2k_t *p_j2k, | |
| 577 OPJ_BYTE * p_header_data, | |
| 578 OPJ_UINT32 p_header_size, | |
| 579 opj_event_mgr_t * p_manager); | |
| 580 | |
| 581 /** | |
| 582 * Writes the QCD marker (quantization default) | |
| 583 * | |
| 584 * @param p_j2k J2K codec. | |
| 585 * @param p_stream the stream to write data to. | |
| 586 * @param p_manager the user event manager. | |
| 587 */ | |
| 588 static OPJ_BOOL opj_j2k_write_qcd(opj_j2k_t *p_j2k, | |
| 589 opj_stream_private_t *p_stream, | |
| 590 opj_event_mgr_t * p_manager); | |
| 591 | |
| 592 /** | |
| 593 * Reads a QCD marker (Quantization defaults) | |
| 594 * @param p_header_data the data contained in the QCD box. | |
| 595 * @param p_j2k the jpeg2000 codec. | |
| 596 * @param p_header_size the size of the data contained in the QCD marker. | |
| 597 * @param p_manager the user event manager. | |
| 598 */ | |
| 599 static OPJ_BOOL opj_j2k_read_qcd(opj_j2k_t *p_j2k, | |
| 600 OPJ_BYTE * p_header_data, | |
| 601 OPJ_UINT32 p_header_size, | |
| 602 opj_event_mgr_t * p_manager); | |
| 603 | |
| 604 /** | |
| 605 * Compare QCC markers (quantization component) | |
| 606 * | |
| 607 * @param p_j2k J2K codec. | |
| 608 * @param p_first_comp_no the index of the first component to compare. | |
| 609 * @param p_second_comp_no the index of the second component to compare. | |
| 610 * | |
| 611 * @return OPJ_TRUE if equals. | |
| 612 */ | |
| 613 static OPJ_BOOL opj_j2k_compare_qcc(opj_j2k_t *p_j2k, | |
| 614 OPJ_UINT32 p_first_comp_no, OPJ_UINT32 p_second_comp_no); | |
| 615 | |
| 616 /** | |
| 617 * Writes the QCC marker (quantization component) | |
| 618 * | |
| 619 * @param p_comp_no the index of the component to output. | |
| 620 * @param p_stream the stream to write data to. | |
| 621 * @param p_j2k J2K codec. | |
| 622 * @param p_manager the user event manager. | |
| 623 */ | |
| 624 static OPJ_BOOL opj_j2k_write_qcc(opj_j2k_t *p_j2k, | |
| 625 OPJ_UINT32 p_comp_no, | |
| 626 opj_stream_private_t *p_stream, | |
| 627 opj_event_mgr_t * p_manager); | |
| 628 | |
| 629 /** | |
| 630 * Writes the QCC marker (quantization component) | |
| 631 * | |
| 632 * @param p_j2k J2K codec. | |
| 633 * @param p_comp_no the index of the component to output. | |
| 634 * @param p_data FIXME DOC | |
| 635 * @param p_data_written the stream to write data to. | |
| 636 * @param p_manager the user event manager. | |
| 637 */ | |
| 638 static void opj_j2k_write_qcc_in_memory(opj_j2k_t *p_j2k, | |
| 639 OPJ_UINT32 p_comp_no, | |
| 640 OPJ_BYTE * p_data, | |
| 641 OPJ_UINT32 * p_data_written, | |
| 642 opj_event_mgr_t * p_manager); | |
| 643 | |
| 644 /** | |
| 645 * Gets the maximum size taken by a qcc. | |
| 646 */ | |
| 647 static OPJ_UINT32 opj_j2k_get_max_qcc_size(opj_j2k_t *p_j2k); | |
| 648 | |
| 649 /** | |
| 650 * Reads a QCC marker (Quantization component) | |
| 651 * @param p_header_data the data contained in the QCC box. | |
| 652 * @param p_j2k the jpeg2000 codec. | |
| 653 * @param p_header_size the size of the data contained in the QCC marker. | |
| 654 * @param p_manager the user event manager. | |
| 655 */ | |
| 656 static OPJ_BOOL opj_j2k_read_qcc(opj_j2k_t *p_j2k, | |
| 657 OPJ_BYTE * p_header_data, | |
| 658 OPJ_UINT32 p_header_size, | |
| 659 opj_event_mgr_t * p_manager); | |
| 660 /** | |
| 661 * Writes the POC marker (Progression Order Change) | |
| 662 * | |
| 663 * @param p_stream the stream to write data to. | |
| 664 * @param p_j2k J2K codec. | |
| 665 * @param p_manager the user event manager. | |
| 666 */ | |
| 667 static OPJ_BOOL opj_j2k_write_poc(opj_j2k_t *p_j2k, | |
| 668 opj_stream_private_t *p_stream, | |
| 669 opj_event_mgr_t * p_manager); | |
| 670 /** | |
| 671 * Writes the POC marker (Progression Order Change) | |
| 672 * | |
| 673 * @param p_j2k J2K codec. | |
| 674 * @param p_data FIXME DOC | |
| 675 * @param p_data_written the stream to write data to. | |
| 676 * @param p_manager the user event manager. | |
| 677 */ | |
| 678 static void opj_j2k_write_poc_in_memory(opj_j2k_t *p_j2k, | |
| 679 OPJ_BYTE * p_data, | |
| 680 OPJ_UINT32 * p_data_written, | |
| 681 opj_event_mgr_t * p_manager); | |
| 682 /** | |
| 683 * Gets the maximum size taken by the writing of a POC. | |
| 684 */ | |
| 685 static OPJ_UINT32 opj_j2k_get_max_poc_size(opj_j2k_t *p_j2k); | |
| 686 | |
| 687 /** | |
| 688 * Reads a POC marker (Progression Order Change) | |
| 689 * | |
| 690 * @param p_header_data the data contained in the POC box. | |
| 691 * @param p_j2k the jpeg2000 codec. | |
| 692 * @param p_header_size the size of the data contained in the POC marker. | |
| 693 * @param p_manager the user event manager. | |
| 694 */ | |
| 695 static OPJ_BOOL opj_j2k_read_poc(opj_j2k_t *p_j2k, | |
| 696 OPJ_BYTE * p_header_data, | |
| 697 OPJ_UINT32 p_header_size, | |
| 698 opj_event_mgr_t * p_manager); | |
| 699 | |
| 700 /** | |
| 701 * Gets the maximum size taken by the toc headers of all the tile parts of any given tile. | |
| 702 */ | |
| 703 static OPJ_UINT32 opj_j2k_get_max_toc_size(opj_j2k_t *p_j2k); | |
| 704 | |
| 705 /** | |
| 706 * Gets the maximum size taken by the headers of the SOT. | |
| 707 * | |
| 708 * @param p_j2k the jpeg2000 codec to use. | |
| 709 */ | |
| 710 static OPJ_UINT32 opj_j2k_get_specific_header_sizes(opj_j2k_t *p_j2k); | |
| 711 | |
| 712 /** | |
| 713 * Reads a CRG marker (Component registration) | |
| 714 * | |
| 715 * @param p_header_data the data contained in the TLM box. | |
| 716 * @param p_j2k the jpeg2000 codec. | |
| 717 * @param p_header_size the size of the data contained in the TLM marker. | |
| 718 * @param p_manager the user event manager. | |
| 719 */ | |
| 720 static OPJ_BOOL opj_j2k_read_crg(opj_j2k_t *p_j2k, | |
| 721 OPJ_BYTE * p_header_data, | |
| 722 OPJ_UINT32 p_header_size, | |
| 723 opj_event_mgr_t * p_manager); | |
| 724 /** | |
| 725 * Reads a TLM marker (Tile Length Marker) | |
| 726 * | |
| 727 * @param p_header_data the data contained in the TLM box. | |
| 728 * @param p_j2k the jpeg2000 codec. | |
| 729 * @param p_header_size the size of the data contained in the TLM marker. | |
| 730 * @param p_manager the user event manager. | |
| 731 */ | |
| 732 static OPJ_BOOL opj_j2k_read_tlm(opj_j2k_t *p_j2k, | |
| 733 OPJ_BYTE * p_header_data, | |
| 734 OPJ_UINT32 p_header_size, | |
| 735 opj_event_mgr_t * p_manager); | |
| 736 | |
| 737 /** | |
| 738 * Writes the updated tlm. | |
| 739 * | |
| 740 * @param p_stream the stream to write data to. | |
| 741 * @param p_j2k J2K codec. | |
| 742 * @param p_manager the user event manager. | |
| 743 */ | |
| 744 static OPJ_BOOL opj_j2k_write_updated_tlm(opj_j2k_t *p_j2k, | |
| 745 opj_stream_private_t *p_stream, | |
| 746 opj_event_mgr_t * p_manager); | |
| 747 | |
| 748 /** | |
| 749 * Reads a PLM marker (Packet length, main header marker) | |
| 750 * | |
| 751 * @param p_header_data the data contained in the TLM box. | |
| 752 * @param p_j2k the jpeg2000 codec. | |
| 753 * @param p_header_size the size of the data contained in the TLM marker. | |
| 754 * @param p_manager the user event manager. | |
| 755 */ | |
| 756 static OPJ_BOOL opj_j2k_read_plm(opj_j2k_t *p_j2k, | |
| 757 OPJ_BYTE * p_header_data, | |
| 758 OPJ_UINT32 p_header_size, | |
| 759 opj_event_mgr_t * p_manager); | |
| 760 /** | |
| 761 * Reads a PLT marker (Packet length, tile-part header) | |
| 762 * | |
| 763 * @param p_header_data the data contained in the PLT box. | |
| 764 * @param p_j2k the jpeg2000 codec. | |
| 765 * @param p_header_size the size of the data contained in the PLT marker. | |
| 766 * @param p_manager the user event manager. | |
| 767 */ | |
| 768 static OPJ_BOOL opj_j2k_read_plt(opj_j2k_t *p_j2k, | |
| 769 OPJ_BYTE * p_header_data, | |
| 770 OPJ_UINT32 p_header_size, | |
| 771 opj_event_mgr_t * p_manager); | |
| 772 | |
| 773 /** | |
| 774 * Reads a PPM marker (Packed headers, main header) | |
| 775 * | |
| 776 * @param p_header_data the data contained in the POC box. | |
| 777 * @param p_j2k the jpeg2000 codec. | |
| 778 * @param p_header_size the size of the data contained in the POC marker. | |
| 779 * @param p_manager the user event manager. | |
| 780 */ | |
| 781 | |
| 782 static OPJ_BOOL opj_j2k_read_ppm( | |
| 783 opj_j2k_t *p_j2k, | |
| 784 OPJ_BYTE * p_header_data, | |
| 785 OPJ_UINT32 p_header_size, | |
| 786 opj_event_mgr_t * p_manager); | |
| 787 | |
| 788 /** | |
| 789 * Merges all PPM markers read (Packed headers, main header) | |
| 790 * | |
| 791 * @param p_cp main coding parameters. | |
| 792 * @param p_manager the user event manager. | |
| 793 */ | |
| 794 static OPJ_BOOL opj_j2k_merge_ppm(opj_cp_t *p_cp, opj_event_mgr_t * p_manager); | |
| 795 | |
| 796 /** | |
| 797 * Reads a PPT marker (Packed packet headers, tile-part header) | |
| 798 * | |
| 799 * @param p_header_data the data contained in the PPT box. | |
| 800 * @param p_j2k the jpeg2000 codec. | |
| 801 * @param p_header_size the size of the data contained in the PPT marker. | |
| 802 * @param p_manager the user event manager. | |
| 803 */ | |
| 804 static OPJ_BOOL opj_j2k_read_ppt(opj_j2k_t *p_j2k, | |
| 805 OPJ_BYTE * p_header_data, | |
| 806 OPJ_UINT32 p_header_size, | |
| 807 opj_event_mgr_t * p_manager); | |
| 808 | |
| 809 /** | |
| 810 * Merges all PPT markers read (Packed headers, tile-part header) | |
| 811 * | |
| 812 * @param p_tcp the tile. | |
| 813 * @param p_manager the user event manager. | |
| 814 */ | |
| 815 static OPJ_BOOL opj_j2k_merge_ppt(opj_tcp_t *p_tcp, | |
| 816 opj_event_mgr_t * p_manager); | |
| 817 | |
| 818 | |
| 819 /** | |
| 820 * Writes the TLM marker (Tile Length Marker) | |
| 821 * | |
| 822 * @param p_stream the stream to write data to. | |
| 823 * @param p_j2k J2K codec. | |
| 824 * @param p_manager the user event manager. | |
| 825 */ | |
| 826 static OPJ_BOOL opj_j2k_write_tlm(opj_j2k_t *p_j2k, | |
| 827 opj_stream_private_t *p_stream, | |
| 828 opj_event_mgr_t * p_manager); | |
| 829 | |
| 830 /** | |
| 831 * Writes the SOT marker (Start of tile-part) | |
| 832 * | |
| 833 * @param p_j2k J2K codec. | |
| 834 * @param p_data Output buffer | |
| 835 * @param total_data_size Output buffer size | |
| 836 * @param p_data_written Number of bytes written into stream | |
| 837 * @param p_stream the stream to write data to. | |
| 838 * @param p_manager the user event manager. | |
| 839 */ | |
| 840 static OPJ_BOOL opj_j2k_write_sot(opj_j2k_t *p_j2k, | |
| 841 OPJ_BYTE * p_data, | |
| 842 OPJ_UINT32 total_data_size, | |
| 843 OPJ_UINT32 * p_data_written, | |
| 844 const opj_stream_private_t *p_stream, | |
| 845 opj_event_mgr_t * p_manager); | |
| 846 | |
| 847 /** | |
| 848 * Reads values from a SOT marker (Start of tile-part) | |
| 849 * | |
| 850 * the j2k decoder state is not affected. No side effects, no checks except for p_header_size. | |
| 851 * | |
| 852 * @param p_header_data the data contained in the SOT marker. | |
| 853 * @param p_header_size the size of the data contained in the SOT marker. | |
| 854 * @param p_tile_no Isot. | |
| 855 * @param p_tot_len Psot. | |
| 856 * @param p_current_part TPsot. | |
| 857 * @param p_num_parts TNsot. | |
| 858 * @param p_manager the user event manager. | |
| 859 */ | |
| 860 static OPJ_BOOL opj_j2k_get_sot_values(OPJ_BYTE * p_header_data, | |
| 861 OPJ_UINT32 p_header_size, | |
| 862 OPJ_UINT32* p_tile_no, | |
| 863 OPJ_UINT32* p_tot_len, | |
| 864 OPJ_UINT32* p_current_part, | |
| 865 OPJ_UINT32* p_num_parts, | |
| 866 opj_event_mgr_t * p_manager); | |
| 867 /** | |
| 868 * Reads a SOT marker (Start of tile-part) | |
| 869 * | |
| 870 * @param p_header_data the data contained in the SOT marker. | |
| 871 * @param p_j2k the jpeg2000 codec. | |
| 872 * @param p_header_size the size of the data contained in the PPT marker. | |
| 873 * @param p_manager the user event manager. | |
| 874 */ | |
| 875 static OPJ_BOOL opj_j2k_read_sot(opj_j2k_t *p_j2k, | |
| 876 OPJ_BYTE * p_header_data, | |
| 877 OPJ_UINT32 p_header_size, | |
| 878 opj_event_mgr_t * p_manager); | |
| 879 /** | |
| 880 * Writes the SOD marker (Start of data) | |
| 881 * | |
| 882 * This also writes optional PLT markers (before SOD) | |
| 883 * | |
| 884 * @param p_j2k J2K codec. | |
| 885 * @param p_tile_coder FIXME DOC | |
| 886 * @param p_data FIXME DOC | |
| 887 * @param p_data_written FIXME DOC | |
| 888 * @param total_data_size FIXME DOC | |
| 889 * @param p_stream the stream to write data to. | |
| 890 * @param p_manager the user event manager. | |
| 891 */ | |
| 892 static OPJ_BOOL opj_j2k_write_sod(opj_j2k_t *p_j2k, | |
| 893 opj_tcd_t * p_tile_coder, | |
| 894 OPJ_BYTE * p_data, | |
| 895 OPJ_UINT32 * p_data_written, | |
| 896 OPJ_UINT32 total_data_size, | |
| 897 const opj_stream_private_t *p_stream, | |
| 898 opj_event_mgr_t * p_manager); | |
| 899 | |
| 900 /** | |
| 901 * Reads a SOD marker (Start Of Data) | |
| 902 * | |
| 903 * @param p_j2k the jpeg2000 codec. | |
| 904 * @param p_stream FIXME DOC | |
| 905 * @param p_manager the user event manager. | |
| 906 */ | |
| 907 static OPJ_BOOL opj_j2k_read_sod(opj_j2k_t *p_j2k, | |
| 908 opj_stream_private_t *p_stream, | |
| 909 opj_event_mgr_t * p_manager); | |
| 910 | |
| 911 static void opj_j2k_update_tlm(opj_j2k_t * p_j2k, OPJ_UINT32 p_tile_part_size) | |
| 912 { | |
| 913 if (p_j2k->m_specific_param.m_encoder.m_Ttlmi_is_byte) { | |
| 914 opj_write_bytes(p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current, | |
| 915 p_j2k->m_current_tile_number, 1); | |
| 916 p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current += 1; | |
| 917 } else { | |
| 918 opj_write_bytes(p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current, | |
| 919 p_j2k->m_current_tile_number, 2); | |
| 920 p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current += 2; | |
| 921 } | |
| 922 | |
| 923 opj_write_bytes(p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current, | |
| 924 p_tile_part_size, 4); /* PSOT */ | |
| 925 p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current += 4; | |
| 926 } | |
| 927 | |
| 928 /** | |
| 929 * Writes the RGN marker (Region Of Interest) | |
| 930 * | |
| 931 * @param p_tile_no the tile to output | |
| 932 * @param p_comp_no the component to output | |
| 933 * @param nb_comps the number of components | |
| 934 * @param p_stream the stream to write data to. | |
| 935 * @param p_j2k J2K codec. | |
| 936 * @param p_manager the user event manager. | |
| 937 */ | |
| 938 static OPJ_BOOL opj_j2k_write_rgn(opj_j2k_t *p_j2k, | |
| 939 OPJ_UINT32 p_tile_no, | |
| 940 OPJ_UINT32 p_comp_no, | |
| 941 OPJ_UINT32 nb_comps, | |
| 942 opj_stream_private_t *p_stream, | |
| 943 opj_event_mgr_t * p_manager); | |
| 944 | |
| 945 /** | |
| 946 * Reads a RGN marker (Region Of Interest) | |
| 947 * | |
| 948 * @param p_header_data the data contained in the POC box. | |
| 949 * @param p_j2k the jpeg2000 codec. | |
| 950 * @param p_header_size the size of the data contained in the POC marker. | |
| 951 * @param p_manager the user event manager. | |
| 952 */ | |
| 953 static OPJ_BOOL opj_j2k_read_rgn(opj_j2k_t *p_j2k, | |
| 954 OPJ_BYTE * p_header_data, | |
| 955 OPJ_UINT32 p_header_size, | |
| 956 opj_event_mgr_t * p_manager); | |
| 957 | |
| 958 /** | |
| 959 * Writes the EOC marker (End of Codestream) | |
| 960 * | |
| 961 * @param p_stream the stream to write data to. | |
| 962 * @param p_j2k J2K codec. | |
| 963 * @param p_manager the user event manager. | |
| 964 */ | |
| 965 static OPJ_BOOL opj_j2k_write_eoc(opj_j2k_t *p_j2k, | |
| 966 opj_stream_private_t *p_stream, | |
| 967 opj_event_mgr_t * p_manager); | |
| 968 | |
| 969 #if 0 | |
| 970 /** | |
| 971 * Reads a EOC marker (End Of Codestream) | |
| 972 * | |
| 973 * @param p_j2k the jpeg2000 codec. | |
| 974 * @param p_stream FIXME DOC | |
| 975 * @param p_manager the user event manager. | |
| 976 */ | |
| 977 static OPJ_BOOL opj_j2k_read_eoc(opj_j2k_t *p_j2k, | |
| 978 opj_stream_private_t *p_stream, | |
| 979 opj_event_mgr_t * p_manager); | |
| 980 #endif | |
| 981 | |
| 982 /** | |
| 983 * Writes the CBD-MCT-MCC-MCO markers (Multi components transform) | |
| 984 * | |
| 985 * @param p_stream the stream to write data to. | |
| 986 * @param p_j2k J2K codec. | |
| 987 * @param p_manager the user event manager. | |
| 988 */ | |
| 989 static OPJ_BOOL opj_j2k_write_mct_data_group(opj_j2k_t *p_j2k, | |
| 990 opj_stream_private_t *p_stream, | |
| 991 opj_event_mgr_t * p_manager); | |
| 992 | |
| 993 /** | |
| 994 * Inits the Info | |
| 995 * | |
| 996 * @param p_stream the stream to write data to. | |
| 997 * @param p_j2k J2K codec. | |
| 998 * @param p_manager the user event manager. | |
| 999 */ | |
| 1000 static OPJ_BOOL opj_j2k_init_info(opj_j2k_t *p_j2k, | |
| 1001 opj_stream_private_t *p_stream, | |
| 1002 opj_event_mgr_t * p_manager); | |
| 1003 | |
| 1004 /** | |
| 1005 Add main header marker information | |
| 1006 @param cstr_index Codestream information structure | |
| 1007 @param type marker type | |
| 1008 @param pos byte offset of marker segment | |
| 1009 @param len length of marker segment | |
| 1010 */ | |
| 1011 static OPJ_BOOL opj_j2k_add_mhmarker(opj_codestream_index_t *cstr_index, | |
| 1012 OPJ_UINT32 type, OPJ_OFF_T pos, OPJ_UINT32 len) ; | |
| 1013 /** | |
| 1014 Add tile header marker information | |
| 1015 @param tileno tile index number | |
| 1016 @param cstr_index Codestream information structure | |
| 1017 @param type marker type | |
| 1018 @param pos byte offset of marker segment | |
| 1019 @param len length of marker segment | |
| 1020 */ | |
| 1021 static OPJ_BOOL opj_j2k_add_tlmarker(OPJ_UINT32 tileno, | |
| 1022 opj_codestream_index_t *cstr_index, OPJ_UINT32 type, OPJ_OFF_T pos, | |
| 1023 OPJ_UINT32 len); | |
| 1024 | |
| 1025 /** | |
| 1026 * Reads an unknown marker | |
| 1027 * | |
| 1028 * @param p_j2k the jpeg2000 codec. | |
| 1029 * @param p_stream the stream object to read from. | |
| 1030 * @param output_marker FIXME DOC | |
| 1031 * @param p_manager the user event manager. | |
| 1032 * | |
| 1033 * @return true if the marker could be deduced. | |
| 1034 */ | |
| 1035 static OPJ_BOOL opj_j2k_read_unk(opj_j2k_t *p_j2k, | |
| 1036 opj_stream_private_t *p_stream, | |
| 1037 OPJ_UINT32 *output_marker, | |
| 1038 opj_event_mgr_t * p_manager); | |
| 1039 | |
| 1040 /** | |
| 1041 * Writes the MCT marker (Multiple Component Transform) | |
| 1042 * | |
| 1043 * @param p_j2k J2K codec. | |
| 1044 * @param p_mct_record FIXME DOC | |
| 1045 * @param p_stream the stream to write data to. | |
| 1046 * @param p_manager the user event manager. | |
| 1047 */ | |
| 1048 static OPJ_BOOL opj_j2k_write_mct_record(opj_j2k_t *p_j2k, | |
| 1049 opj_mct_data_t * p_mct_record, | |
| 1050 opj_stream_private_t *p_stream, | |
| 1051 opj_event_mgr_t * p_manager); | |
| 1052 | |
| 1053 /** | |
| 1054 * Reads a MCT marker (Multiple Component Transform) | |
| 1055 * | |
| 1056 * @param p_header_data the data contained in the MCT box. | |
| 1057 * @param p_j2k the jpeg2000 codec. | |
| 1058 * @param p_header_size the size of the data contained in the MCT marker. | |
| 1059 * @param p_manager the user event manager. | |
| 1060 */ | |
| 1061 static OPJ_BOOL opj_j2k_read_mct(opj_j2k_t *p_j2k, | |
| 1062 OPJ_BYTE * p_header_data, | |
| 1063 OPJ_UINT32 p_header_size, | |
| 1064 opj_event_mgr_t * p_manager); | |
| 1065 | |
| 1066 /** | |
| 1067 * Writes the MCC marker (Multiple Component Collection) | |
| 1068 * | |
| 1069 * @param p_j2k J2K codec. | |
| 1070 * @param p_mcc_record FIXME DOC | |
| 1071 * @param p_stream the stream to write data to. | |
| 1072 * @param p_manager the user event manager. | |
| 1073 */ | |
| 1074 static OPJ_BOOL opj_j2k_write_mcc_record(opj_j2k_t *p_j2k, | |
| 1075 opj_simple_mcc_decorrelation_data_t * p_mcc_record, | |
| 1076 opj_stream_private_t *p_stream, | |
| 1077 opj_event_mgr_t * p_manager); | |
| 1078 | |
| 1079 /** | |
| 1080 * Reads a MCC marker (Multiple Component Collection) | |
| 1081 * | |
| 1082 * @param p_header_data the data contained in the MCC box. | |
| 1083 * @param p_j2k the jpeg2000 codec. | |
| 1084 * @param p_header_size the size of the data contained in the MCC marker. | |
| 1085 * @param p_manager the user event manager. | |
| 1086 */ | |
| 1087 static OPJ_BOOL opj_j2k_read_mcc(opj_j2k_t *p_j2k, | |
| 1088 OPJ_BYTE * p_header_data, | |
| 1089 OPJ_UINT32 p_header_size, | |
| 1090 opj_event_mgr_t * p_manager); | |
| 1091 | |
| 1092 /** | |
| 1093 * Writes the MCO marker (Multiple component transformation ordering) | |
| 1094 * | |
| 1095 * @param p_stream the stream to write data to. | |
| 1096 * @param p_j2k J2K codec. | |
| 1097 * @param p_manager the user event manager. | |
| 1098 */ | |
| 1099 static OPJ_BOOL opj_j2k_write_mco(opj_j2k_t *p_j2k, | |
| 1100 opj_stream_private_t *p_stream, | |
| 1101 opj_event_mgr_t * p_manager); | |
| 1102 | |
| 1103 /** | |
| 1104 * Reads a MCO marker (Multiple Component Transform Ordering) | |
| 1105 * | |
| 1106 * @param p_header_data the data contained in the MCO box. | |
| 1107 * @param p_j2k the jpeg2000 codec. | |
| 1108 * @param p_header_size the size of the data contained in the MCO marker. | |
| 1109 * @param p_manager the user event manager. | |
| 1110 */ | |
| 1111 static OPJ_BOOL opj_j2k_read_mco(opj_j2k_t *p_j2k, | |
| 1112 OPJ_BYTE * p_header_data, | |
| 1113 OPJ_UINT32 p_header_size, | |
| 1114 opj_event_mgr_t * p_manager); | |
| 1115 | |
| 1116 static OPJ_BOOL opj_j2k_add_mct(opj_tcp_t * p_tcp, opj_image_t * p_image, | |
| 1117 OPJ_UINT32 p_index); | |
| 1118 | |
| 1119 static void opj_j2k_read_int16_to_float(const void * p_src_data, | |
| 1120 void * p_dest_data, OPJ_UINT32 p_nb_elem); | |
| 1121 static void opj_j2k_read_int32_to_float(const void * p_src_data, | |
| 1122 void * p_dest_data, OPJ_UINT32 p_nb_elem); | |
| 1123 static void opj_j2k_read_float32_to_float(const void * p_src_data, | |
| 1124 void * p_dest_data, OPJ_UINT32 p_nb_elem); | |
| 1125 static void opj_j2k_read_float64_to_float(const void * p_src_data, | |
| 1126 void * p_dest_data, OPJ_UINT32 p_nb_elem); | |
| 1127 | |
| 1128 static void opj_j2k_read_int16_to_int32(const void * p_src_data, | |
| 1129 void * p_dest_data, OPJ_UINT32 p_nb_elem); | |
| 1130 static void opj_j2k_read_int32_to_int32(const void * p_src_data, | |
| 1131 void * p_dest_data, OPJ_UINT32 p_nb_elem); | |
| 1132 static void opj_j2k_read_float32_to_int32(const void * p_src_data, | |
| 1133 void * p_dest_data, OPJ_UINT32 p_nb_elem); | |
| 1134 static void opj_j2k_read_float64_to_int32(const void * p_src_data, | |
| 1135 void * p_dest_data, OPJ_UINT32 p_nb_elem); | |
| 1136 | |
| 1137 static void opj_j2k_write_float_to_int16(const void * p_src_data, | |
| 1138 void * p_dest_data, OPJ_UINT32 p_nb_elem); | |
| 1139 static void opj_j2k_write_float_to_int32(const void * p_src_data, | |
| 1140 void * p_dest_data, OPJ_UINT32 p_nb_elem); | |
| 1141 static void opj_j2k_write_float_to_float(const void * p_src_data, | |
| 1142 void * p_dest_data, OPJ_UINT32 p_nb_elem); | |
| 1143 static void opj_j2k_write_float_to_float64(const void * p_src_data, | |
| 1144 void * p_dest_data, OPJ_UINT32 p_nb_elem); | |
| 1145 | |
| 1146 /** | |
| 1147 * Ends the encoding, i.e. frees memory. | |
| 1148 * | |
| 1149 * @param p_stream the stream to write data to. | |
| 1150 * @param p_j2k J2K codec. | |
| 1151 * @param p_manager the user event manager. | |
| 1152 */ | |
| 1153 static OPJ_BOOL opj_j2k_end_encoding(opj_j2k_t *p_j2k, | |
| 1154 opj_stream_private_t *p_stream, | |
| 1155 opj_event_mgr_t * p_manager); | |
| 1156 | |
| 1157 /** | |
| 1158 * Writes the CBD marker (Component bit depth definition) | |
| 1159 * | |
| 1160 * @param p_stream the stream to write data to. | |
| 1161 * @param p_j2k J2K codec. | |
| 1162 * @param p_manager the user event manager. | |
| 1163 */ | |
| 1164 static OPJ_BOOL opj_j2k_write_cbd(opj_j2k_t *p_j2k, | |
| 1165 opj_stream_private_t *p_stream, | |
| 1166 opj_event_mgr_t * p_manager); | |
| 1167 | |
| 1168 /** | |
| 1169 * Reads a CBD marker (Component bit depth definition) | |
| 1170 * @param p_header_data the data contained in the CBD box. | |
| 1171 * @param p_j2k the jpeg2000 codec. | |
| 1172 * @param p_header_size the size of the data contained in the CBD marker. | |
| 1173 * @param p_manager the user event manager. | |
| 1174 */ | |
| 1175 static OPJ_BOOL opj_j2k_read_cbd(opj_j2k_t *p_j2k, | |
| 1176 OPJ_BYTE * p_header_data, | |
| 1177 OPJ_UINT32 p_header_size, | |
| 1178 opj_event_mgr_t * p_manager); | |
| 1179 | |
| 1180 /** | |
| 1181 * Reads a CAP marker (extended capabilities definition). Empty implementation. | |
| 1182 * Found in HTJ2K files | |
| 1183 * | |
| 1184 * @param p_header_data the data contained in the CAP box. | |
| 1185 * @param p_j2k the jpeg2000 codec. | |
| 1186 * @param p_header_size the size of the data contained in the CAP marker. | |
| 1187 * @param p_manager the user event manager. | |
| 1188 */ | |
| 1189 static OPJ_BOOL opj_j2k_read_cap(opj_j2k_t *p_j2k, | |
| 1190 OPJ_BYTE * p_header_data, | |
| 1191 OPJ_UINT32 p_header_size, | |
| 1192 opj_event_mgr_t * p_manager); | |
| 1193 | |
| 1194 /** | |
| 1195 * Reads a CPF marker (corresponding profile). Empty implementation. Found in HTJ2K files | |
| 1196 * @param p_header_data the data contained in the CPF box. | |
| 1197 * @param p_j2k the jpeg2000 codec. | |
| 1198 * @param p_header_size the size of the data contained in the CPF marker. | |
| 1199 * @param p_manager the user event manager. | |
| 1200 */ | |
| 1201 static OPJ_BOOL opj_j2k_read_cpf(opj_j2k_t *p_j2k, | |
| 1202 OPJ_BYTE * p_header_data, | |
| 1203 OPJ_UINT32 p_header_size, | |
| 1204 opj_event_mgr_t * p_manager); | |
| 1205 | |
| 1206 | |
| 1207 /** | |
| 1208 * Writes COC marker for each component. | |
| 1209 * | |
| 1210 * @param p_stream the stream to write data to. | |
| 1211 * @param p_j2k J2K codec. | |
| 1212 * @param p_manager the user event manager. | |
| 1213 */ | |
| 1214 static OPJ_BOOL opj_j2k_write_all_coc(opj_j2k_t *p_j2k, | |
| 1215 opj_stream_private_t *p_stream, | |
| 1216 opj_event_mgr_t * p_manager); | |
| 1217 | |
| 1218 /** | |
| 1219 * Writes QCC marker for each component. | |
| 1220 * | |
| 1221 * @param p_stream the stream to write data to. | |
| 1222 * @param p_j2k J2K codec. | |
| 1223 * @param p_manager the user event manager. | |
| 1224 */ | |
| 1225 static OPJ_BOOL opj_j2k_write_all_qcc(opj_j2k_t *p_j2k, | |
| 1226 opj_stream_private_t *p_stream, | |
| 1227 opj_event_mgr_t * p_manager); | |
| 1228 | |
| 1229 /** | |
| 1230 * Writes regions of interests. | |
| 1231 * | |
| 1232 * @param p_stream the stream to write data to. | |
| 1233 * @param p_j2k J2K codec. | |
| 1234 * @param p_manager the user event manager. | |
| 1235 */ | |
| 1236 static OPJ_BOOL opj_j2k_write_regions(opj_j2k_t *p_j2k, | |
| 1237 opj_stream_private_t *p_stream, | |
| 1238 opj_event_mgr_t * p_manager); | |
| 1239 | |
| 1240 /** | |
| 1241 * Writes EPC ???? | |
| 1242 * | |
| 1243 * @param p_stream the stream to write data to. | |
| 1244 * @param p_j2k J2K codec. | |
| 1245 * @param p_manager the user event manager. | |
| 1246 */ | |
| 1247 static OPJ_BOOL opj_j2k_write_epc(opj_j2k_t *p_j2k, | |
| 1248 opj_stream_private_t *p_stream, | |
| 1249 opj_event_mgr_t * p_manager); | |
| 1250 | |
| 1251 /** | |
| 1252 * Checks the progression order changes values. Tells of the poc given as input are valid. | |
| 1253 * A nice message is outputted at errors. | |
| 1254 * | |
| 1255 * @param p_pocs the progression order changes. | |
| 1256 * @param tileno the tile number of interest | |
| 1257 * @param p_nb_pocs the number of progression order changes. | |
| 1258 * @param p_nb_resolutions the number of resolutions. | |
| 1259 * @param numcomps the number of components | |
| 1260 * @param numlayers the number of layers. | |
| 1261 * @param p_manager the user event manager. | |
| 1262 * | |
| 1263 * @return true if the pocs are valid. | |
| 1264 */ | |
| 1265 static OPJ_BOOL opj_j2k_check_poc_val(const opj_poc_t *p_pocs, | |
| 1266 OPJ_UINT32 tileno, | |
| 1267 OPJ_UINT32 p_nb_pocs, | |
| 1268 OPJ_UINT32 p_nb_resolutions, | |
| 1269 OPJ_UINT32 numcomps, | |
| 1270 OPJ_UINT32 numlayers, | |
| 1271 opj_event_mgr_t * p_manager); | |
| 1272 | |
| 1273 /** | |
| 1274 * Gets the number of tile parts used for the given change of progression (if any) and the given tile. | |
| 1275 * | |
| 1276 * @param cp the coding parameters. | |
| 1277 * @param pino the offset of the given poc (i.e. its position in the coding parameter). | |
| 1278 * @param tileno the given tile. | |
| 1279 * | |
| 1280 * @return the number of tile parts. | |
| 1281 */ | |
| 1282 static OPJ_UINT32 opj_j2k_get_num_tp(opj_cp_t *cp, OPJ_UINT32 pino, | |
| 1283 OPJ_UINT32 tileno); | |
| 1284 | |
| 1285 /** | |
| 1286 * Calculates the total number of tile parts needed by the encoder to | |
| 1287 * encode such an image. If not enough memory is available, then the function return false. | |
| 1288 * | |
| 1289 * @param p_nb_tiles pointer that will hold the number of tile parts. | |
| 1290 * @param cp the coding parameters for the image. | |
| 1291 * @param image the image to encode. | |
| 1292 * @param p_j2k the p_j2k encoder. | |
| 1293 * @param p_manager the user event manager. | |
| 1294 * | |
| 1295 * @return true if the function was successful, false else. | |
| 1296 */ | |
| 1297 static OPJ_BOOL opj_j2k_calculate_tp(opj_j2k_t *p_j2k, | |
| 1298 opj_cp_t *cp, | |
| 1299 OPJ_UINT32 * p_nb_tiles, | |
| 1300 opj_image_t *image, | |
| 1301 opj_event_mgr_t * p_manager); | |
| 1302 | |
| 1303 static void opj_j2k_dump_MH_info(opj_j2k_t* p_j2k, FILE* out_stream); | |
| 1304 | |
| 1305 static void opj_j2k_dump_MH_index(opj_j2k_t* p_j2k, FILE* out_stream); | |
| 1306 | |
| 1307 static opj_codestream_index_t* opj_j2k_create_cstr_index(void); | |
| 1308 | |
| 1309 static OPJ_FLOAT32 opj_j2k_get_tp_stride(opj_tcp_t * p_tcp); | |
| 1310 | |
| 1311 static OPJ_FLOAT32 opj_j2k_get_default_stride(opj_tcp_t * p_tcp); | |
| 1312 | |
| 1313 static int opj_j2k_initialise_4K_poc(opj_poc_t *POC, int numres); | |
| 1314 | |
| 1315 static void opj_j2k_set_cinema_parameters(opj_cparameters_t *parameters, | |
| 1316 opj_image_t *image, opj_event_mgr_t *p_manager); | |
| 1317 | |
| 1318 static OPJ_BOOL opj_j2k_is_cinema_compliant(opj_image_t *image, OPJ_UINT16 rsiz, | |
| 1319 opj_event_mgr_t *p_manager); | |
| 1320 | |
| 1321 static void opj_j2k_set_imf_parameters(opj_cparameters_t *parameters, | |
| 1322 opj_image_t *image, opj_event_mgr_t *p_manager); | |
| 1323 | |
| 1324 static OPJ_BOOL opj_j2k_is_imf_compliant(opj_cparameters_t *parameters, | |
| 1325 opj_image_t *image, | |
| 1326 opj_event_mgr_t *p_manager); | |
| 1327 | |
| 1328 /** | |
| 1329 * Checks for invalid number of tile-parts in SOT marker (TPsot==TNsot). See issue 254. | |
| 1330 * | |
| 1331 * @param p_stream the stream to read data from. | |
| 1332 * @param tile_no tile number we're looking for. | |
| 1333 * @param p_correction_needed output value. if true, non conformant codestream needs TNsot correction. | |
| 1334 * @param p_manager the user event manager. | |
| 1335 * | |
| 1336 * @return true if the function was successful, false else. | |
| 1337 */ | |
| 1338 static OPJ_BOOL opj_j2k_need_nb_tile_parts_correction(opj_stream_private_t | |
| 1339 *p_stream, OPJ_UINT32 tile_no, OPJ_BOOL* p_correction_needed, | |
| 1340 opj_event_mgr_t * p_manager); | |
| 1341 | |
| 1342 /*@}*/ | |
| 1343 | |
| 1344 /*@}*/ | |
| 1345 | |
| 1346 /* ----------------------------------------------------------------------- */ | |
| 1347 typedef struct j2k_prog_order { | |
| 1348 OPJ_PROG_ORDER enum_prog; | |
| 1349 char str_prog[5]; | |
| 1350 } j2k_prog_order_t; | |
| 1351 | |
| 1352 static const j2k_prog_order_t j2k_prog_order_list[] = { | |
| 1353 {OPJ_CPRL, "CPRL"}, | |
| 1354 {OPJ_LRCP, "LRCP"}, | |
| 1355 {OPJ_PCRL, "PCRL"}, | |
| 1356 {OPJ_RLCP, "RLCP"}, | |
| 1357 {OPJ_RPCL, "RPCL"}, | |
| 1358 {(OPJ_PROG_ORDER) - 1, ""} | |
| 1359 }; | |
| 1360 | |
| 1361 /** | |
| 1362 * FIXME DOC | |
| 1363 */ | |
| 1364 static const OPJ_UINT32 MCT_ELEMENT_SIZE [] = { | |
| 1365 2, | |
| 1366 4, | |
| 1367 4, | |
| 1368 8 | |
| 1369 }; | |
| 1370 | |
| 1371 typedef void (* opj_j2k_mct_function)(const void * p_src_data, | |
| 1372 void * p_dest_data, OPJ_UINT32 p_nb_elem); | |
| 1373 | |
| 1374 static const opj_j2k_mct_function j2k_mct_read_functions_to_float [] = { | |
| 1375 opj_j2k_read_int16_to_float, | |
| 1376 opj_j2k_read_int32_to_float, | |
| 1377 opj_j2k_read_float32_to_float, | |
| 1378 opj_j2k_read_float64_to_float | |
| 1379 }; | |
| 1380 | |
| 1381 static const opj_j2k_mct_function j2k_mct_read_functions_to_int32 [] = { | |
| 1382 opj_j2k_read_int16_to_int32, | |
| 1383 opj_j2k_read_int32_to_int32, | |
| 1384 opj_j2k_read_float32_to_int32, | |
| 1385 opj_j2k_read_float64_to_int32 | |
| 1386 }; | |
| 1387 | |
| 1388 static const opj_j2k_mct_function j2k_mct_write_functions_from_float [] = { | |
| 1389 opj_j2k_write_float_to_int16, | |
| 1390 opj_j2k_write_float_to_int32, | |
| 1391 opj_j2k_write_float_to_float, | |
| 1392 opj_j2k_write_float_to_float64 | |
| 1393 }; | |
| 1394 | |
| 1395 typedef struct opj_dec_memory_marker_handler { | |
| 1396 /** marker value */ | |
| 1397 OPJ_UINT32 id; | |
| 1398 /** value of the state when the marker can appear */ | |
| 1399 OPJ_UINT32 states; | |
| 1400 /** action linked to the marker */ | |
| 1401 OPJ_BOOL(*handler)(opj_j2k_t *p_j2k, | |
| 1402 OPJ_BYTE * p_header_data, | |
| 1403 OPJ_UINT32 p_header_size, | |
| 1404 opj_event_mgr_t * p_manager); | |
| 1405 } | |
| 1406 opj_dec_memory_marker_handler_t; | |
| 1407 | |
| 1408 static const opj_dec_memory_marker_handler_t j2k_memory_marker_handler_tab [] = | |
| 1409 { | |
| 1410 {J2K_MS_SOT, J2K_STATE_MH | J2K_STATE_TPHSOT, opj_j2k_read_sot}, | |
| 1411 {J2K_MS_COD, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_cod}, | |
| 1412 {J2K_MS_COC, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_coc}, | |
| 1413 {J2K_MS_RGN, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_rgn}, | |
| 1414 {J2K_MS_QCD, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_qcd}, | |
| 1415 {J2K_MS_QCC, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_qcc}, | |
| 1416 {J2K_MS_POC, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_poc}, | |
| 1417 {J2K_MS_SIZ, J2K_STATE_MHSIZ, opj_j2k_read_siz}, | |
| 1418 {J2K_MS_TLM, J2K_STATE_MH, opj_j2k_read_tlm}, | |
| 1419 {J2K_MS_PLM, J2K_STATE_MH, opj_j2k_read_plm}, | |
| 1420 {J2K_MS_PLT, J2K_STATE_TPH, opj_j2k_read_plt}, | |
| 1421 {J2K_MS_PPM, J2K_STATE_MH, opj_j2k_read_ppm}, | |
| 1422 {J2K_MS_PPT, J2K_STATE_TPH, opj_j2k_read_ppt}, | |
| 1423 {J2K_MS_SOP, 0, 0}, | |
| 1424 {J2K_MS_CRG, J2K_STATE_MH, opj_j2k_read_crg}, | |
| 1425 {J2K_MS_COM, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_com}, | |
| 1426 {J2K_MS_MCT, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_mct}, | |
| 1427 {J2K_MS_CBD, J2K_STATE_MH, opj_j2k_read_cbd}, | |
| 1428 {J2K_MS_CAP, J2K_STATE_MH, opj_j2k_read_cap}, | |
| 1429 {J2K_MS_CPF, J2K_STATE_MH, opj_j2k_read_cpf}, | |
| 1430 {J2K_MS_MCC, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_mcc}, | |
| 1431 {J2K_MS_MCO, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_mco}, | |
| 1432 #ifdef USE_JPWL | |
| 1433 #ifdef TODO_MS /* remove these functions which are not compatible with the v2 API */ | |
| 1434 {J2K_MS_EPC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_epc}, | |
| 1435 {J2K_MS_EPB, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_epb}, | |
| 1436 {J2K_MS_ESD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_esd}, | |
| 1437 {J2K_MS_RED, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_red}, | |
| 1438 #endif | |
| 1439 #endif /* USE_JPWL */ | |
| 1440 #ifdef USE_JPSEC | |
| 1441 {J2K_MS_SEC, J2K_DEC_STATE_MH, j2k_read_sec}, | |
| 1442 {J2K_MS_INSEC, 0, j2k_read_insec} | |
| 1443 #endif /* USE_JPSEC */ | |
| 1444 {J2K_MS_UNK, J2K_STATE_MH | J2K_STATE_TPH, 0}/*opj_j2k_read_unk is directly used*/ | |
| 1445 }; | |
| 1446 | |
| 1447 static void opj_j2k_read_int16_to_float(const void * p_src_data, | |
| 1448 void * p_dest_data, OPJ_UINT32 p_nb_elem) | |
| 1449 { | |
| 1450 OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data; | |
| 1451 OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data; | |
| 1452 OPJ_UINT32 i; | |
| 1453 OPJ_UINT32 l_temp; | |
| 1454 | |
| 1455 for (i = 0; i < p_nb_elem; ++i) { | |
| 1456 opj_read_bytes(l_src_data, &l_temp, 2); | |
| 1457 | |
| 1458 l_src_data += sizeof(OPJ_INT16); | |
| 1459 | |
| 1460 *(l_dest_data++) = (OPJ_FLOAT32) l_temp; | |
| 1461 } | |
| 1462 } | |
| 1463 | |
| 1464 static void opj_j2k_read_int32_to_float(const void * p_src_data, | |
| 1465 void * p_dest_data, OPJ_UINT32 p_nb_elem) | |
| 1466 { | |
| 1467 OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data; | |
| 1468 OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data; | |
| 1469 OPJ_UINT32 i; | |
| 1470 OPJ_UINT32 l_temp; | |
| 1471 | |
| 1472 for (i = 0; i < p_nb_elem; ++i) { | |
| 1473 opj_read_bytes(l_src_data, &l_temp, 4); | |
| 1474 | |
| 1475 l_src_data += sizeof(OPJ_INT32); | |
| 1476 | |
| 1477 *(l_dest_data++) = (OPJ_FLOAT32) l_temp; | |
| 1478 } | |
| 1479 } | |
| 1480 | |
| 1481 static void opj_j2k_read_float32_to_float(const void * p_src_data, | |
| 1482 void * p_dest_data, OPJ_UINT32 p_nb_elem) | |
| 1483 { | |
| 1484 OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data; | |
| 1485 OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data; | |
| 1486 OPJ_UINT32 i; | |
| 1487 OPJ_FLOAT32 l_temp; | |
| 1488 | |
| 1489 for (i = 0; i < p_nb_elem; ++i) { | |
| 1490 opj_read_float(l_src_data, &l_temp); | |
| 1491 | |
| 1492 l_src_data += sizeof(OPJ_FLOAT32); | |
| 1493 | |
| 1494 *(l_dest_data++) = l_temp; | |
| 1495 } | |
| 1496 } | |
| 1497 | |
| 1498 static void opj_j2k_read_float64_to_float(const void * p_src_data, | |
| 1499 void * p_dest_data, OPJ_UINT32 p_nb_elem) | |
| 1500 { | |
| 1501 OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data; | |
| 1502 OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data; | |
| 1503 OPJ_UINT32 i; | |
| 1504 OPJ_FLOAT64 l_temp; | |
| 1505 | |
| 1506 for (i = 0; i < p_nb_elem; ++i) { | |
| 1507 opj_read_double(l_src_data, &l_temp); | |
| 1508 | |
| 1509 l_src_data += sizeof(OPJ_FLOAT64); | |
| 1510 | |
| 1511 *(l_dest_data++) = (OPJ_FLOAT32) l_temp; | |
| 1512 } | |
| 1513 } | |
| 1514 | |
| 1515 static void opj_j2k_read_int16_to_int32(const void * p_src_data, | |
| 1516 void * p_dest_data, OPJ_UINT32 p_nb_elem) | |
| 1517 { | |
| 1518 OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data; | |
| 1519 OPJ_INT32 * l_dest_data = (OPJ_INT32 *) p_dest_data; | |
| 1520 OPJ_UINT32 i; | |
| 1521 OPJ_UINT32 l_temp; | |
| 1522 | |
| 1523 for (i = 0; i < p_nb_elem; ++i) { | |
| 1524 opj_read_bytes(l_src_data, &l_temp, 2); | |
| 1525 | |
| 1526 l_src_data += sizeof(OPJ_INT16); | |
| 1527 | |
| 1528 *(l_dest_data++) = (OPJ_INT32) l_temp; | |
| 1529 } | |
| 1530 } | |
| 1531 | |
| 1532 static void opj_j2k_read_int32_to_int32(const void * p_src_data, | |
| 1533 void * p_dest_data, OPJ_UINT32 p_nb_elem) | |
| 1534 { | |
| 1535 OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data; | |
| 1536 OPJ_INT32 * l_dest_data = (OPJ_INT32 *) p_dest_data; | |
| 1537 OPJ_UINT32 i; | |
| 1538 OPJ_UINT32 l_temp; | |
| 1539 | |
| 1540 for (i = 0; i < p_nb_elem; ++i) { | |
| 1541 opj_read_bytes(l_src_data, &l_temp, 4); | |
| 1542 | |
| 1543 l_src_data += sizeof(OPJ_INT32); | |
| 1544 | |
| 1545 *(l_dest_data++) = (OPJ_INT32) l_temp; | |
| 1546 } | |
| 1547 } | |
| 1548 | |
| 1549 static void opj_j2k_read_float32_to_int32(const void * p_src_data, | |
| 1550 void * p_dest_data, OPJ_UINT32 p_nb_elem) | |
| 1551 { | |
| 1552 OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data; | |
| 1553 OPJ_INT32 * l_dest_data = (OPJ_INT32 *) p_dest_data; | |
| 1554 OPJ_UINT32 i; | |
| 1555 OPJ_FLOAT32 l_temp; | |
| 1556 | |
| 1557 for (i = 0; i < p_nb_elem; ++i) { | |
| 1558 opj_read_float(l_src_data, &l_temp); | |
| 1559 | |
| 1560 l_src_data += sizeof(OPJ_FLOAT32); | |
| 1561 | |
| 1562 *(l_dest_data++) = (OPJ_INT32) l_temp; | |
| 1563 } | |
| 1564 } | |
| 1565 | |
| 1566 static void opj_j2k_read_float64_to_int32(const void * p_src_data, | |
| 1567 void * p_dest_data, OPJ_UINT32 p_nb_elem) | |
| 1568 { | |
| 1569 OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data; | |
| 1570 OPJ_INT32 * l_dest_data = (OPJ_INT32 *) p_dest_data; | |
| 1571 OPJ_UINT32 i; | |
| 1572 OPJ_FLOAT64 l_temp; | |
| 1573 | |
| 1574 for (i = 0; i < p_nb_elem; ++i) { | |
| 1575 opj_read_double(l_src_data, &l_temp); | |
| 1576 | |
| 1577 l_src_data += sizeof(OPJ_FLOAT64); | |
| 1578 | |
| 1579 *(l_dest_data++) = (OPJ_INT32) l_temp; | |
| 1580 } | |
| 1581 } | |
| 1582 | |
| 1583 static void opj_j2k_write_float_to_int16(const void * p_src_data, | |
| 1584 void * p_dest_data, OPJ_UINT32 p_nb_elem) | |
| 1585 { | |
| 1586 OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data; | |
| 1587 OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data; | |
| 1588 OPJ_UINT32 i; | |
| 1589 OPJ_UINT32 l_temp; | |
| 1590 | |
| 1591 for (i = 0; i < p_nb_elem; ++i) { | |
| 1592 l_temp = (OPJ_UINT32) * (l_src_data++); | |
| 1593 | |
| 1594 opj_write_bytes(l_dest_data, l_temp, sizeof(OPJ_INT16)); | |
| 1595 | |
| 1596 l_dest_data += sizeof(OPJ_INT16); | |
| 1597 } | |
| 1598 } | |
| 1599 | |
| 1600 static void opj_j2k_write_float_to_int32(const void * p_src_data, | |
| 1601 void * p_dest_data, OPJ_UINT32 p_nb_elem) | |
| 1602 { | |
| 1603 OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data; | |
| 1604 OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data; | |
| 1605 OPJ_UINT32 i; | |
| 1606 OPJ_UINT32 l_temp; | |
| 1607 | |
| 1608 for (i = 0; i < p_nb_elem; ++i) { | |
| 1609 l_temp = (OPJ_UINT32) * (l_src_data++); | |
| 1610 | |
| 1611 opj_write_bytes(l_dest_data, l_temp, sizeof(OPJ_INT32)); | |
| 1612 | |
| 1613 l_dest_data += sizeof(OPJ_INT32); | |
| 1614 } | |
| 1615 } | |
| 1616 | |
| 1617 static void opj_j2k_write_float_to_float(const void * p_src_data, | |
| 1618 void * p_dest_data, OPJ_UINT32 p_nb_elem) | |
| 1619 { | |
| 1620 OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data; | |
| 1621 OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data; | |
| 1622 OPJ_UINT32 i; | |
| 1623 OPJ_FLOAT32 l_temp; | |
| 1624 | |
| 1625 for (i = 0; i < p_nb_elem; ++i) { | |
| 1626 l_temp = (OPJ_FLOAT32) * (l_src_data++); | |
| 1627 | |
| 1628 opj_write_float(l_dest_data, l_temp); | |
| 1629 | |
| 1630 l_dest_data += sizeof(OPJ_FLOAT32); | |
| 1631 } | |
| 1632 } | |
| 1633 | |
| 1634 static void opj_j2k_write_float_to_float64(const void * p_src_data, | |
| 1635 void * p_dest_data, OPJ_UINT32 p_nb_elem) | |
| 1636 { | |
| 1637 OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data; | |
| 1638 OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data; | |
| 1639 OPJ_UINT32 i; | |
| 1640 OPJ_FLOAT64 l_temp; | |
| 1641 | |
| 1642 for (i = 0; i < p_nb_elem; ++i) { | |
| 1643 l_temp = (OPJ_FLOAT64) * (l_src_data++); | |
| 1644 | |
| 1645 opj_write_double(l_dest_data, l_temp); | |
| 1646 | |
| 1647 l_dest_data += sizeof(OPJ_FLOAT64); | |
| 1648 } | |
| 1649 } | |
| 1650 | |
| 1651 const char *opj_j2k_convert_progression_order(OPJ_PROG_ORDER prg_order) | |
| 1652 { | |
| 1653 const j2k_prog_order_t *po; | |
| 1654 for (po = j2k_prog_order_list; po->enum_prog != -1; po++) { | |
| 1655 if (po->enum_prog == prg_order) { | |
| 1656 return po->str_prog; | |
| 1657 } | |
| 1658 } | |
| 1659 return po->str_prog; | |
| 1660 } | |
| 1661 | |
| 1662 static OPJ_BOOL opj_j2k_check_poc_val(const opj_poc_t *p_pocs, | |
| 1663 OPJ_UINT32 tileno, | |
| 1664 OPJ_UINT32 p_nb_pocs, | |
| 1665 OPJ_UINT32 p_nb_resolutions, | |
| 1666 OPJ_UINT32 p_num_comps, | |
| 1667 OPJ_UINT32 p_num_layers, | |
| 1668 opj_event_mgr_t * p_manager) | |
| 1669 { | |
| 1670 OPJ_UINT32* packet_array; | |
| 1671 OPJ_UINT32 index, resno, compno, layno; | |
| 1672 OPJ_UINT32 i; | |
| 1673 OPJ_UINT32 step_c = 1; | |
| 1674 OPJ_UINT32 step_r = p_num_comps * step_c; | |
| 1675 OPJ_UINT32 step_l = p_nb_resolutions * step_r; | |
| 1676 OPJ_BOOL loss = OPJ_FALSE; | |
| 1677 | |
| 1678 assert(p_nb_pocs > 0); | |
| 1679 | |
| 1680 packet_array = (OPJ_UINT32*) opj_calloc((size_t)step_l * p_num_layers, | |
| 1681 sizeof(OPJ_UINT32)); | |
| 1682 if (packet_array == 00) { | |
| 1683 opj_event_msg(p_manager, EVT_ERROR, | |
| 1684 "Not enough memory for checking the poc values.\n"); | |
| 1685 return OPJ_FALSE; | |
| 1686 } | |
| 1687 | |
| 1688 /* iterate through all the pocs that match our tile of interest. */ | |
| 1689 for (i = 0; i < p_nb_pocs; ++i) { | |
| 1690 const opj_poc_t *poc = &p_pocs[i]; | |
| 1691 if (tileno + 1 == poc->tile) { | |
| 1692 index = step_r * poc->resno0; | |
| 1693 | |
| 1694 /* take each resolution for each poc */ | |
| 1695 for (resno = poc->resno0 ; | |
| 1696 resno < opj_uint_min(poc->resno1, p_nb_resolutions); ++resno) { | |
| 1697 OPJ_UINT32 res_index = index + poc->compno0 * step_c; | |
| 1698 | |
| 1699 /* take each comp of each resolution for each poc */ | |
| 1700 for (compno = poc->compno0 ; | |
| 1701 compno < opj_uint_min(poc->compno1, p_num_comps); ++compno) { | |
| 1702 /* The layer index always starts at zero for every progression. */ | |
| 1703 const OPJ_UINT32 layno0 = 0; | |
| 1704 OPJ_UINT32 comp_index = res_index + layno0 * step_l; | |
| 1705 | |
| 1706 /* and finally take each layer of each res of ... */ | |
| 1707 for (layno = layno0; layno < opj_uint_min(poc->layno1, p_num_layers); | |
| 1708 ++layno) { | |
| 1709 packet_array[comp_index] = 1; | |
| 1710 comp_index += step_l; | |
| 1711 } | |
| 1712 | |
| 1713 res_index += step_c; | |
| 1714 } | |
| 1715 | |
| 1716 index += step_r; | |
| 1717 } | |
| 1718 } | |
| 1719 } | |
| 1720 | |
| 1721 index = 0; | |
| 1722 for (layno = 0; layno < p_num_layers ; ++layno) { | |
| 1723 for (resno = 0; resno < p_nb_resolutions; ++resno) { | |
| 1724 for (compno = 0; compno < p_num_comps; ++compno) { | |
| 1725 loss |= (packet_array[index] != 1); | |
| 1726 #ifdef DEBUG_VERBOSE | |
| 1727 if (packet_array[index] != 1) { | |
| 1728 fprintf(stderr, | |
| 1729 "Missing packet in POC: layno=%d resno=%d compno=%d\n", | |
| 1730 layno, resno, compno); | |
| 1731 } | |
| 1732 #endif | |
| 1733 index += step_c; | |
| 1734 } | |
| 1735 } | |
| 1736 } | |
| 1737 | |
| 1738 if (loss) { | |
| 1739 opj_event_msg(p_manager, EVT_ERROR, "Missing packets possible loss of data\n"); | |
| 1740 } | |
| 1741 | |
| 1742 opj_free(packet_array); | |
| 1743 | |
| 1744 return !loss; | |
| 1745 } | |
| 1746 | |
| 1747 /* ----------------------------------------------------------------------- */ | |
| 1748 | |
| 1749 static OPJ_UINT32 opj_j2k_get_num_tp(opj_cp_t *cp, OPJ_UINT32 pino, | |
| 1750 OPJ_UINT32 tileno) | |
| 1751 { | |
| 1752 const OPJ_CHAR *prog = 00; | |
| 1753 OPJ_INT32 i; | |
| 1754 OPJ_UINT32 tpnum = 1; | |
| 1755 opj_tcp_t *tcp = 00; | |
| 1756 opj_poc_t * l_current_poc = 00; | |
| 1757 | |
| 1758 /* preconditions */ | |
| 1759 assert(tileno < (cp->tw * cp->th)); | |
| 1760 assert(pino < (cp->tcps[tileno].numpocs + 1)); | |
| 1761 | |
| 1762 /* get the given tile coding parameter */ | |
| 1763 tcp = &cp->tcps[tileno]; | |
| 1764 assert(tcp != 00); | |
| 1765 | |
| 1766 l_current_poc = &(tcp->pocs[pino]); | |
| 1767 assert(l_current_poc != 0); | |
| 1768 | |
| 1769 /* get the progression order as a character string */ | |
| 1770 prog = opj_j2k_convert_progression_order(tcp->prg); | |
| 1771 assert(strlen(prog) > 0); | |
| 1772 | |
| 1773 if (cp->m_specific_param.m_enc.m_tp_on == 1) { | |
| 1774 for (i = 0; i < 4; ++i) { | |
| 1775 switch (prog[i]) { | |
| 1776 /* component wise */ | |
| 1777 case 'C': | |
| 1778 tpnum *= l_current_poc->compE; | |
| 1779 break; | |
| 1780 /* resolution wise */ | |
| 1781 case 'R': | |
| 1782 tpnum *= l_current_poc->resE; | |
| 1783 break; | |
| 1784 /* precinct wise */ | |
| 1785 case 'P': | |
| 1786 tpnum *= l_current_poc->prcE; | |
| 1787 break; | |
| 1788 /* layer wise */ | |
| 1789 case 'L': | |
| 1790 tpnum *= l_current_poc->layE; | |
| 1791 break; | |
| 1792 } | |
| 1793 /* would we split here ? */ | |
| 1794 if (cp->m_specific_param.m_enc.m_tp_flag == prog[i]) { | |
| 1795 cp->m_specific_param.m_enc.m_tp_pos = i; | |
| 1796 break; | |
| 1797 } | |
| 1798 } | |
| 1799 } else { | |
| 1800 tpnum = 1; | |
| 1801 } | |
| 1802 | |
| 1803 return tpnum; | |
| 1804 } | |
| 1805 | |
| 1806 static OPJ_BOOL opj_j2k_calculate_tp(opj_j2k_t *p_j2k, | |
| 1807 opj_cp_t *cp, | |
| 1808 OPJ_UINT32 * p_nb_tiles, | |
| 1809 opj_image_t *image, | |
| 1810 opj_event_mgr_t * p_manager | |
| 1811 ) | |
| 1812 { | |
| 1813 OPJ_UINT32 pino, tileno; | |
| 1814 OPJ_UINT32 l_nb_tiles; | |
| 1815 opj_tcp_t *tcp; | |
| 1816 | |
| 1817 /* preconditions */ | |
| 1818 assert(p_nb_tiles != 00); | |
| 1819 assert(cp != 00); | |
| 1820 assert(image != 00); | |
| 1821 assert(p_j2k != 00); | |
| 1822 assert(p_manager != 00); | |
| 1823 | |
| 1824 OPJ_UNUSED(p_j2k); | |
| 1825 OPJ_UNUSED(p_manager); | |
| 1826 | |
| 1827 l_nb_tiles = cp->tw * cp->th; | |
| 1828 * p_nb_tiles = 0; | |
| 1829 tcp = cp->tcps; | |
| 1830 | |
| 1831 /* INDEX >> */ | |
| 1832 /* TODO mergeV2: check this part which use cstr_info */ | |
| 1833 /*if (p_j2k->cstr_info) { | |
| 1834 opj_tile_info_t * l_info_tile_ptr = p_j2k->cstr_info->tile; | |
| 1835 | |
| 1836 for (tileno = 0; tileno < l_nb_tiles; ++tileno) { | |
| 1837 OPJ_UINT32 cur_totnum_tp = 0; | |
| 1838 | |
| 1839 opj_pi_update_encoding_parameters(image,cp,tileno); | |
| 1840 | |
| 1841 for (pino = 0; pino <= tcp->numpocs; ++pino) | |
| 1842 { | |
| 1843 OPJ_UINT32 tp_num = opj_j2k_get_num_tp(cp,pino,tileno); | |
| 1844 | |
| 1845 *p_nb_tiles = *p_nb_tiles + tp_num; | |
| 1846 | |
| 1847 cur_totnum_tp += tp_num; | |
| 1848 } | |
| 1849 | |
| 1850 tcp->m_nb_tile_parts = cur_totnum_tp; | |
| 1851 | |
| 1852 l_info_tile_ptr->tp = (opj_tp_info_t *) opj_malloc(cur_totnum_tp * sizeof(opj_tp_info_t)); | |
| 1853 if (l_info_tile_ptr->tp == 00) { | |
| 1854 return OPJ_FALSE; | |
| 1855 } | |
| 1856 | |
| 1857 memset(l_info_tile_ptr->tp,0,cur_totnum_tp * sizeof(opj_tp_info_t)); | |
| 1858 | |
| 1859 l_info_tile_ptr->num_tps = cur_totnum_tp; | |
| 1860 | |
| 1861 ++l_info_tile_ptr; | |
| 1862 ++tcp; | |
| 1863 } | |
| 1864 } | |
| 1865 else */{ | |
| 1866 for (tileno = 0; tileno < l_nb_tiles; ++tileno) { | |
| 1867 OPJ_UINT32 cur_totnum_tp = 0; | |
| 1868 | |
| 1869 opj_pi_update_encoding_parameters(image, cp, tileno); | |
| 1870 | |
| 1871 for (pino = 0; pino <= tcp->numpocs; ++pino) { | |
| 1872 OPJ_UINT32 tp_num = opj_j2k_get_num_tp(cp, pino, tileno); | |
| 1873 | |
| 1874 *p_nb_tiles = *p_nb_tiles + tp_num; | |
| 1875 | |
| 1876 cur_totnum_tp += tp_num; | |
| 1877 } | |
| 1878 tcp->m_nb_tile_parts = cur_totnum_tp; | |
| 1879 | |
| 1880 ++tcp; | |
| 1881 } | |
| 1882 } | |
| 1883 | |
| 1884 return OPJ_TRUE; | |
| 1885 } | |
| 1886 | |
| 1887 static OPJ_BOOL opj_j2k_write_soc(opj_j2k_t *p_j2k, | |
| 1888 opj_stream_private_t *p_stream, | |
| 1889 opj_event_mgr_t * p_manager) | |
| 1890 { | |
| 1891 /* 2 bytes will be written */ | |
| 1892 OPJ_BYTE * l_start_stream = 00; | |
| 1893 | |
| 1894 /* preconditions */ | |
| 1895 assert(p_stream != 00); | |
| 1896 assert(p_j2k != 00); | |
| 1897 assert(p_manager != 00); | |
| 1898 | |
| 1899 l_start_stream = p_j2k->m_specific_param.m_encoder.m_header_tile_data; | |
| 1900 | |
| 1901 /* write SOC identifier */ | |
| 1902 opj_write_bytes(l_start_stream, J2K_MS_SOC, 2); | |
| 1903 | |
| 1904 if (opj_stream_write_data(p_stream, l_start_stream, 2, p_manager) != 2) { | |
| 1905 return OPJ_FALSE; | |
| 1906 } | |
| 1907 | |
| 1908 /* UniPG>> */ | |
| 1909 #ifdef USE_JPWL | |
| 1910 /* update markers struct */ | |
| 1911 /* | |
| 1912 OPJ_BOOL res = j2k_add_marker(p_j2k->cstr_info, J2K_MS_SOC, p_stream_tell(p_stream) - 2, 2); | |
| 1913 */ | |
| 1914 assert(0 && "TODO"); | |
| 1915 #endif /* USE_JPWL */ | |
| 1916 /* <<UniPG */ | |
| 1917 | |
| 1918 return OPJ_TRUE; | |
| 1919 } | |
| 1920 | |
| 1921 /** | |
| 1922 * Reads a SOC marker (Start of Codestream) | |
| 1923 * @param p_j2k the jpeg2000 file codec. | |
| 1924 * @param p_stream FIXME DOC | |
| 1925 * @param p_manager the user event manager. | |
| 1926 */ | |
| 1927 static OPJ_BOOL opj_j2k_read_soc(opj_j2k_t *p_j2k, | |
| 1928 opj_stream_private_t *p_stream, | |
| 1929 opj_event_mgr_t * p_manager | |
| 1930 ) | |
| 1931 { | |
| 1932 OPJ_BYTE l_data [2]; | |
| 1933 OPJ_UINT32 l_marker; | |
| 1934 | |
| 1935 /* preconditions */ | |
| 1936 assert(p_j2k != 00); | |
| 1937 assert(p_manager != 00); | |
| 1938 assert(p_stream != 00); | |
| 1939 | |
| 1940 if (opj_stream_read_data(p_stream, l_data, 2, p_manager) != 2) { | |
| 1941 return OPJ_FALSE; | |
| 1942 } | |
| 1943 | |
| 1944 opj_read_bytes(l_data, &l_marker, 2); | |
| 1945 if (l_marker != J2K_MS_SOC) { | |
| 1946 return OPJ_FALSE; | |
| 1947 } | |
| 1948 | |
| 1949 /* Next marker should be a SIZ marker in the main header */ | |
| 1950 p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_MHSIZ; | |
| 1951 | |
| 1952 /* FIXME move it in a index structure included in p_j2k*/ | |
| 1953 p_j2k->cstr_index->main_head_start = opj_stream_tell(p_stream) - 2; | |
| 1954 | |
| 1955 opj_event_msg(p_manager, EVT_INFO, | |
| 1956 "Start to read j2k main header (%" PRId64 ").\n", | |
| 1957 p_j2k->cstr_index->main_head_start); | |
| 1958 | |
| 1959 /* Add the marker to the codestream index*/ | |
| 1960 if (OPJ_FALSE == opj_j2k_add_mhmarker(p_j2k->cstr_index, J2K_MS_SOC, | |
| 1961 p_j2k->cstr_index->main_head_start, 2)) { | |
| 1962 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to add mh marker\n"); | |
| 1963 return OPJ_FALSE; | |
| 1964 } | |
| 1965 return OPJ_TRUE; | |
| 1966 } | |
| 1967 | |
| 1968 static OPJ_BOOL opj_j2k_write_siz(opj_j2k_t *p_j2k, | |
| 1969 opj_stream_private_t *p_stream, | |
| 1970 opj_event_mgr_t * p_manager) | |
| 1971 { | |
| 1972 OPJ_UINT32 i; | |
| 1973 OPJ_UINT32 l_size_len; | |
| 1974 OPJ_BYTE * l_current_ptr; | |
| 1975 opj_image_t * l_image = 00; | |
| 1976 opj_cp_t *cp = 00; | |
| 1977 opj_image_comp_t * l_img_comp = 00; | |
| 1978 | |
| 1979 /* preconditions */ | |
| 1980 assert(p_stream != 00); | |
| 1981 assert(p_j2k != 00); | |
| 1982 assert(p_manager != 00); | |
| 1983 | |
| 1984 l_image = p_j2k->m_private_image; | |
| 1985 cp = &(p_j2k->m_cp); | |
| 1986 l_size_len = 40 + 3 * l_image->numcomps; | |
| 1987 l_img_comp = l_image->comps; | |
| 1988 | |
| 1989 if (l_size_len > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) { | |
| 1990 | |
| 1991 OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc( | |
| 1992 p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_size_len); | |
| 1993 if (! new_header_tile_data) { | |
| 1994 opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data); | |
| 1995 p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL; | |
| 1996 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0; | |
| 1997 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory for the SIZ marker\n"); | |
| 1998 return OPJ_FALSE; | |
| 1999 } | |
| 2000 p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data; | |
| 2001 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_size_len; | |
| 2002 } | |
| 2003 | |
| 2004 l_current_ptr = p_j2k->m_specific_param.m_encoder.m_header_tile_data; | |
| 2005 | |
| 2006 /* write SOC identifier */ | |
| 2007 opj_write_bytes(l_current_ptr, J2K_MS_SIZ, 2); /* SIZ */ | |
| 2008 l_current_ptr += 2; | |
| 2009 | |
| 2010 opj_write_bytes(l_current_ptr, l_size_len - 2, 2); /* L_SIZ */ | |
| 2011 l_current_ptr += 2; | |
| 2012 | |
| 2013 opj_write_bytes(l_current_ptr, cp->rsiz, 2); /* Rsiz (capabilities) */ | |
| 2014 l_current_ptr += 2; | |
| 2015 | |
| 2016 opj_write_bytes(l_current_ptr, l_image->x1, 4); /* Xsiz */ | |
| 2017 l_current_ptr += 4; | |
| 2018 | |
| 2019 opj_write_bytes(l_current_ptr, l_image->y1, 4); /* Ysiz */ | |
| 2020 l_current_ptr += 4; | |
| 2021 | |
| 2022 opj_write_bytes(l_current_ptr, l_image->x0, 4); /* X0siz */ | |
| 2023 l_current_ptr += 4; | |
| 2024 | |
| 2025 opj_write_bytes(l_current_ptr, l_image->y0, 4); /* Y0siz */ | |
| 2026 l_current_ptr += 4; | |
| 2027 | |
| 2028 opj_write_bytes(l_current_ptr, cp->tdx, 4); /* XTsiz */ | |
| 2029 l_current_ptr += 4; | |
| 2030 | |
| 2031 opj_write_bytes(l_current_ptr, cp->tdy, 4); /* YTsiz */ | |
| 2032 l_current_ptr += 4; | |
| 2033 | |
| 2034 opj_write_bytes(l_current_ptr, cp->tx0, 4); /* XT0siz */ | |
| 2035 l_current_ptr += 4; | |
| 2036 | |
| 2037 opj_write_bytes(l_current_ptr, cp->ty0, 4); /* YT0siz */ | |
| 2038 l_current_ptr += 4; | |
| 2039 | |
| 2040 opj_write_bytes(l_current_ptr, l_image->numcomps, 2); /* Csiz */ | |
| 2041 l_current_ptr += 2; | |
| 2042 | |
| 2043 for (i = 0; i < l_image->numcomps; ++i) { | |
| 2044 /* TODO here with MCT ? */ | |
| 2045 opj_write_bytes(l_current_ptr, l_img_comp->prec - 1 + (l_img_comp->sgnd << 7), | |
| 2046 1); /* Ssiz_i */ | |
| 2047 ++l_current_ptr; | |
| 2048 | |
| 2049 opj_write_bytes(l_current_ptr, l_img_comp->dx, 1); /* XRsiz_i */ | |
| 2050 ++l_current_ptr; | |
| 2051 | |
| 2052 opj_write_bytes(l_current_ptr, l_img_comp->dy, 1); /* YRsiz_i */ | |
| 2053 ++l_current_ptr; | |
| 2054 | |
| 2055 ++l_img_comp; | |
| 2056 } | |
| 2057 | |
| 2058 if (opj_stream_write_data(p_stream, | |
| 2059 p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_size_len, | |
| 2060 p_manager) != l_size_len) { | |
| 2061 return OPJ_FALSE; | |
| 2062 } | |
| 2063 | |
| 2064 return OPJ_TRUE; | |
| 2065 } | |
| 2066 | |
| 2067 /** | |
| 2068 * Reads a SIZ marker (image and tile size) | |
| 2069 * @param p_j2k the jpeg2000 file codec. | |
| 2070 * @param p_header_data the data contained in the SIZ box. | |
| 2071 * @param p_header_size the size of the data contained in the SIZ marker. | |
| 2072 * @param p_manager the user event manager. | |
| 2073 */ | |
| 2074 static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k, | |
| 2075 OPJ_BYTE * p_header_data, | |
| 2076 OPJ_UINT32 p_header_size, | |
| 2077 opj_event_mgr_t * p_manager | |
| 2078 ) | |
| 2079 { | |
| 2080 OPJ_UINT32 i; | |
| 2081 OPJ_UINT32 l_nb_comp; | |
| 2082 OPJ_UINT32 l_nb_comp_remain; | |
| 2083 OPJ_UINT32 l_remaining_size; | |
| 2084 OPJ_UINT32 l_nb_tiles; | |
| 2085 OPJ_UINT32 l_tmp, l_tx1, l_ty1; | |
| 2086 OPJ_UINT32 l_prec0, l_sgnd0; | |
| 2087 opj_image_t *l_image = 00; | |
| 2088 opj_cp_t *l_cp = 00; | |
| 2089 opj_image_comp_t * l_img_comp = 00; | |
| 2090 opj_tcp_t * l_current_tile_param = 00; | |
| 2091 | |
| 2092 /* preconditions */ | |
| 2093 assert(p_j2k != 00); | |
| 2094 assert(p_manager != 00); | |
| 2095 assert(p_header_data != 00); | |
| 2096 | |
| 2097 l_image = p_j2k->m_private_image; | |
| 2098 l_cp = &(p_j2k->m_cp); | |
| 2099 | |
| 2100 /* minimum size == 39 - 3 (= minimum component parameter) */ | |
| 2101 if (p_header_size < 36) { | |
| 2102 opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker size\n"); | |
| 2103 return OPJ_FALSE; | |
| 2104 } | |
| 2105 | |
| 2106 l_remaining_size = p_header_size - 36; | |
| 2107 l_nb_comp = l_remaining_size / 3; | |
| 2108 l_nb_comp_remain = l_remaining_size % 3; | |
| 2109 if (l_nb_comp_remain != 0) { | |
| 2110 opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker size\n"); | |
| 2111 return OPJ_FALSE; | |
| 2112 } | |
| 2113 | |
| 2114 opj_read_bytes(p_header_data, &l_tmp, | |
| 2115 2); /* Rsiz (capabilities) */ | |
| 2116 p_header_data += 2; | |
| 2117 l_cp->rsiz = (OPJ_UINT16) l_tmp; | |
| 2118 opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_image->x1, 4); /* Xsiz */ | |
| 2119 p_header_data += 4; | |
| 2120 opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_image->y1, 4); /* Ysiz */ | |
| 2121 p_header_data += 4; | |
| 2122 opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_image->x0, 4); /* X0siz */ | |
| 2123 p_header_data += 4; | |
| 2124 opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_image->y0, 4); /* Y0siz */ | |
| 2125 p_header_data += 4; | |
| 2126 opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_cp->tdx, | |
| 2127 4); /* XTsiz */ | |
| 2128 p_header_data += 4; | |
| 2129 opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_cp->tdy, | |
| 2130 4); /* YTsiz */ | |
| 2131 p_header_data += 4; | |
| 2132 opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_cp->tx0, | |
| 2133 4); /* XT0siz */ | |
| 2134 p_header_data += 4; | |
| 2135 opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_cp->ty0, | |
| 2136 4); /* YT0siz */ | |
| 2137 p_header_data += 4; | |
| 2138 opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_tmp, | |
| 2139 2); /* Csiz */ | |
| 2140 p_header_data += 2; | |
| 2141 if (l_tmp < 16385) { | |
| 2142 l_image->numcomps = (OPJ_UINT16) l_tmp; | |
| 2143 } else { | |
| 2144 opj_event_msg(p_manager, EVT_ERROR, | |
| 2145 "Error with SIZ marker: number of component is illegal -> %d\n", l_tmp); | |
| 2146 return OPJ_FALSE; | |
| 2147 } | |
| 2148 | |
| 2149 if (l_image->numcomps != l_nb_comp) { | |
| 2150 opj_event_msg(p_manager, EVT_ERROR, | |
| 2151 "Error with SIZ marker: number of component is not compatible with the remaining number of parameters ( %d vs %d)\n", | |
| 2152 l_image->numcomps, l_nb_comp); | |
| 2153 return OPJ_FALSE; | |
| 2154 } | |
| 2155 | |
| 2156 /* testcase 4035.pdf.SIGSEGV.d8b.3375 */ | |
| 2157 /* testcase issue427-null-image-size.jp2 */ | |
| 2158 if ((l_image->x0 >= l_image->x1) || (l_image->y0 >= l_image->y1)) { | |
| 2159 opj_event_msg(p_manager, EVT_ERROR, | |
| 2160 "Error with SIZ marker: negative or zero image size (%" PRId64 " x %" PRId64 | |
| 2161 ")\n", (OPJ_INT64)l_image->x1 - l_image->x0, | |
| 2162 (OPJ_INT64)l_image->y1 - l_image->y0); | |
| 2163 return OPJ_FALSE; | |
| 2164 } | |
| 2165 /* testcase 2539.pdf.SIGFPE.706.1712 (also 3622.pdf.SIGFPE.706.2916 and 4008.pdf.SIGFPE.706.3345 and maybe more) */ | |
| 2166 if ((l_cp->tdx == 0U) || (l_cp->tdy == 0U)) { | |
| 2167 opj_event_msg(p_manager, EVT_ERROR, | |
| 2168 "Error with SIZ marker: invalid tile size (tdx: %d, tdy: %d)\n", l_cp->tdx, | |
| 2169 l_cp->tdy); | |
| 2170 return OPJ_FALSE; | |
| 2171 } | |
| 2172 | |
| 2173 /* testcase issue427-illegal-tile-offset.jp2 */ | |
| 2174 l_tx1 = opj_uint_adds(l_cp->tx0, l_cp->tdx); /* manage overflow */ | |
| 2175 l_ty1 = opj_uint_adds(l_cp->ty0, l_cp->tdy); /* manage overflow */ | |
| 2176 if ((l_cp->tx0 > l_image->x0) || (l_cp->ty0 > l_image->y0) || | |
| 2177 (l_tx1 <= l_image->x0) || (l_ty1 <= l_image->y0)) { | |
| 2178 opj_event_msg(p_manager, EVT_ERROR, | |
| 2179 "Error with SIZ marker: illegal tile offset\n"); | |
| 2180 return OPJ_FALSE; | |
| 2181 } | |
| 2182 if (!p_j2k->dump_state) { | |
| 2183 OPJ_UINT32 siz_w, siz_h; | |
| 2184 | |
| 2185 siz_w = l_image->x1 - l_image->x0; | |
| 2186 siz_h = l_image->y1 - l_image->y0; | |
| 2187 | |
| 2188 if (p_j2k->ihdr_w > 0 && p_j2k->ihdr_h > 0 | |
| 2189 && (p_j2k->ihdr_w != siz_w || p_j2k->ihdr_h != siz_h)) { | |
| 2190 opj_event_msg(p_manager, EVT_ERROR, | |
| 2191 "Error with SIZ marker: IHDR w(%u) h(%u) vs. SIZ w(%u) h(%u)\n", p_j2k->ihdr_w, | |
| 2192 p_j2k->ihdr_h, siz_w, siz_h); | |
| 2193 return OPJ_FALSE; | |
| 2194 } | |
| 2195 } | |
| 2196 #ifdef USE_JPWL | |
| 2197 if (l_cp->correct) { | |
| 2198 /* if JPWL is on, we check whether TX errors have damaged | |
| 2199 too much the SIZ parameters */ | |
| 2200 if (!(l_image->x1 * l_image->y1)) { | |
| 2201 opj_event_msg(p_manager, EVT_ERROR, | |
| 2202 "JPWL: bad image size (%d x %d)\n", | |
| 2203 l_image->x1, l_image->y1); | |
| 2204 if (!JPWL_ASSUME) { | |
| 2205 opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n"); | |
| 2206 return OPJ_FALSE; | |
| 2207 } | |
| 2208 } | |
| 2209 | |
| 2210 /* FIXME check previously in the function so why keep this piece of code ? Need by the norm ? | |
| 2211 if (l_image->numcomps != ((len - 38) / 3)) { | |
| 2212 opj_event_msg(p_manager, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR, | |
| 2213 "JPWL: Csiz is %d => space in SIZ only for %d comps.!!!\n", | |
| 2214 l_image->numcomps, ((len - 38) / 3)); | |
| 2215 if (!JPWL_ASSUME) { | |
| 2216 opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n"); | |
| 2217 return OPJ_FALSE; | |
| 2218 } | |
| 2219 */ /* we try to correct */ | |
| 2220 /* opj_event_msg(p_manager, EVT_WARNING, "- trying to adjust this\n"); | |
| 2221 if (l_image->numcomps < ((len - 38) / 3)) { | |
| 2222 len = 38 + 3 * l_image->numcomps; | |
| 2223 opj_event_msg(p_manager, EVT_WARNING, "- setting Lsiz to %d => HYPOTHESIS!!!\n", | |
| 2224 len); | |
| 2225 } else { | |
| 2226 l_image->numcomps = ((len - 38) / 3); | |
| 2227 opj_event_msg(p_manager, EVT_WARNING, "- setting Csiz to %d => HYPOTHESIS!!!\n", | |
| 2228 l_image->numcomps); | |
| 2229 } | |
| 2230 } | |
| 2231 */ | |
| 2232 | |
| 2233 /* update components number in the jpwl_exp_comps filed */ | |
| 2234 l_cp->exp_comps = l_image->numcomps; | |
| 2235 } | |
| 2236 #endif /* USE_JPWL */ | |
| 2237 | |
| 2238 /* Allocate the resulting image components */ | |
| 2239 l_image->comps = (opj_image_comp_t*) opj_calloc(l_image->numcomps, | |
| 2240 sizeof(opj_image_comp_t)); | |
| 2241 if (l_image->comps == 00) { | |
| 2242 l_image->numcomps = 0; | |
| 2243 opj_event_msg(p_manager, EVT_ERROR, | |
| 2244 "Not enough memory to take in charge SIZ marker\n"); | |
| 2245 return OPJ_FALSE; | |
| 2246 } | |
| 2247 | |
| 2248 l_img_comp = l_image->comps; | |
| 2249 | |
| 2250 l_prec0 = 0; | |
| 2251 l_sgnd0 = 0; | |
| 2252 /* Read the component information */ | |
| 2253 for (i = 0; i < l_image->numcomps; ++i) { | |
| 2254 OPJ_UINT32 tmp; | |
| 2255 opj_read_bytes(p_header_data, &tmp, 1); /* Ssiz_i */ | |
| 2256 ++p_header_data; | |
| 2257 l_img_comp->prec = (tmp & 0x7f) + 1; | |
| 2258 l_img_comp->sgnd = tmp >> 7; | |
| 2259 | |
| 2260 if (p_j2k->dump_state == 0) { | |
| 2261 if (i == 0) { | |
| 2262 l_prec0 = l_img_comp->prec; | |
| 2263 l_sgnd0 = l_img_comp->sgnd; | |
| 2264 } else if (!l_cp->allow_different_bit_depth_sign | |
| 2265 && (l_img_comp->prec != l_prec0 || l_img_comp->sgnd != l_sgnd0)) { | |
| 2266 opj_event_msg(p_manager, EVT_WARNING, | |
| 2267 "Despite JP2 BPC!=255, precision and/or sgnd values for comp[%d] is different than comp[0]:\n" | |
| 2268 " [0] prec(%d) sgnd(%d) [%d] prec(%d) sgnd(%d)\n", i, l_prec0, l_sgnd0, | |
| 2269 i, l_img_comp->prec, l_img_comp->sgnd); | |
| 2270 } | |
| 2271 /* TODO: we should perhaps also check against JP2 BPCC values */ | |
| 2272 } | |
| 2273 opj_read_bytes(p_header_data, &tmp, 1); /* XRsiz_i */ | |
| 2274 ++p_header_data; | |
| 2275 l_img_comp->dx = (OPJ_UINT32)tmp; /* should be between 1 and 255 */ | |
| 2276 opj_read_bytes(p_header_data, &tmp, 1); /* YRsiz_i */ | |
| 2277 ++p_header_data; | |
| 2278 l_img_comp->dy = (OPJ_UINT32)tmp; /* should be between 1 and 255 */ | |
| 2279 if (l_img_comp->dx < 1 || l_img_comp->dx > 255 || | |
| 2280 l_img_comp->dy < 1 || l_img_comp->dy > 255) { | |
| 2281 opj_event_msg(p_manager, EVT_ERROR, | |
| 2282 "Invalid values for comp = %d : dx=%u dy=%u (should be between 1 and 255 according to the JPEG2000 norm)\n", | |
| 2283 i, l_img_comp->dx, l_img_comp->dy); | |
| 2284 return OPJ_FALSE; | |
| 2285 } | |
| 2286 /* Avoids later undefined shift in computation of */ | |
| 2287 /* p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps[i].m_dc_level_shift = 1 | |
| 2288 << (l_image->comps[i].prec - 1); */ | |
| 2289 if (l_img_comp->prec > 31) { | |
| 2290 opj_event_msg(p_manager, EVT_ERROR, | |
| 2291 "Invalid values for comp = %d : prec=%u (should be between 1 and 38 according to the JPEG2000 norm. OpenJpeg only supports up to 31)\n", | |
| 2292 i, l_img_comp->prec); | |
| 2293 return OPJ_FALSE; | |
| 2294 } | |
| 2295 #ifdef USE_JPWL | |
| 2296 if (l_cp->correct) { | |
| 2297 /* if JPWL is on, we check whether TX errors have damaged | |
| 2298 too much the SIZ parameters, again */ | |
| 2299 if (!(l_image->comps[i].dx * l_image->comps[i].dy)) { | |
| 2300 opj_event_msg(p_manager, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR, | |
| 2301 "JPWL: bad XRsiz_%d/YRsiz_%d (%d x %d)\n", | |
| 2302 i, i, l_image->comps[i].dx, l_image->comps[i].dy); | |
| 2303 if (!JPWL_ASSUME) { | |
| 2304 opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n"); | |
| 2305 return OPJ_FALSE; | |
| 2306 } | |
| 2307 /* we try to correct */ | |
| 2308 opj_event_msg(p_manager, EVT_WARNING, "- trying to adjust them\n"); | |
| 2309 if (!l_image->comps[i].dx) { | |
| 2310 l_image->comps[i].dx = 1; | |
| 2311 opj_event_msg(p_manager, EVT_WARNING, | |
| 2312 "- setting XRsiz_%d to %d => HYPOTHESIS!!!\n", | |
| 2313 i, l_image->comps[i].dx); | |
| 2314 } | |
| 2315 if (!l_image->comps[i].dy) { | |
| 2316 l_image->comps[i].dy = 1; | |
| 2317 opj_event_msg(p_manager, EVT_WARNING, | |
| 2318 "- setting YRsiz_%d to %d => HYPOTHESIS!!!\n", | |
| 2319 i, l_image->comps[i].dy); | |
| 2320 } | |
| 2321 } | |
| 2322 } | |
| 2323 #endif /* USE_JPWL */ | |
| 2324 l_img_comp->resno_decoded = | |
| 2325 0; /* number of resolution decoded */ | |
| 2326 l_img_comp->factor = | |
| 2327 l_cp->m_specific_param.m_dec.m_reduce; /* reducing factor per component */ | |
| 2328 ++l_img_comp; | |
| 2329 } | |
| 2330 | |
| 2331 if (l_cp->tdx == 0 || l_cp->tdy == 0) { | |
| 2332 return OPJ_FALSE; | |
| 2333 } | |
| 2334 | |
| 2335 /* Compute the number of tiles */ | |
| 2336 l_cp->tw = opj_uint_ceildiv(l_image->x1 - l_cp->tx0, l_cp->tdx); | |
| 2337 l_cp->th = opj_uint_ceildiv(l_image->y1 - l_cp->ty0, l_cp->tdy); | |
| 2338 | |
| 2339 /* Check that the number of tiles is valid */ | |
| 2340 if (l_cp->tw == 0 || l_cp->th == 0 || l_cp->tw > 65535 / l_cp->th) { | |
| 2341 opj_event_msg(p_manager, EVT_ERROR, | |
| 2342 "Invalid number of tiles : %u x %u (maximum fixed by jpeg2000 norm is 65535 tiles)\n", | |
| 2343 l_cp->tw, l_cp->th); | |
| 2344 return OPJ_FALSE; | |
| 2345 } | |
| 2346 l_nb_tiles = l_cp->tw * l_cp->th; | |
| 2347 | |
| 2348 /* Define the tiles which will be decoded */ | |
| 2349 if (p_j2k->m_specific_param.m_decoder.m_discard_tiles) { | |
| 2350 p_j2k->m_specific_param.m_decoder.m_start_tile_x = | |
| 2351 (p_j2k->m_specific_param.m_decoder.m_start_tile_x - l_cp->tx0) / l_cp->tdx; | |
| 2352 p_j2k->m_specific_param.m_decoder.m_start_tile_y = | |
| 2353 (p_j2k->m_specific_param.m_decoder.m_start_tile_y - l_cp->ty0) / l_cp->tdy; | |
| 2354 p_j2k->m_specific_param.m_decoder.m_end_tile_x = opj_uint_ceildiv( | |
| 2355 p_j2k->m_specific_param.m_decoder.m_end_tile_x - l_cp->tx0, | |
| 2356 l_cp->tdx); | |
| 2357 p_j2k->m_specific_param.m_decoder.m_end_tile_y = opj_uint_ceildiv( | |
| 2358 p_j2k->m_specific_param.m_decoder.m_end_tile_y - l_cp->ty0, | |
| 2359 l_cp->tdy); | |
| 2360 } else { | |
| 2361 p_j2k->m_specific_param.m_decoder.m_start_tile_x = 0; | |
| 2362 p_j2k->m_specific_param.m_decoder.m_start_tile_y = 0; | |
| 2363 p_j2k->m_specific_param.m_decoder.m_end_tile_x = l_cp->tw; | |
| 2364 p_j2k->m_specific_param.m_decoder.m_end_tile_y = l_cp->th; | |
| 2365 } | |
| 2366 | |
| 2367 #ifdef USE_JPWL | |
| 2368 if (l_cp->correct) { | |
| 2369 /* if JPWL is on, we check whether TX errors have damaged | |
| 2370 too much the SIZ parameters */ | |
| 2371 if ((l_cp->tw < 1) || (l_cp->th < 1) || (l_cp->tw > l_cp->max_tiles) || | |
| 2372 (l_cp->th > l_cp->max_tiles)) { | |
| 2373 opj_event_msg(p_manager, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR, | |
| 2374 "JPWL: bad number of tiles (%d x %d)\n", | |
| 2375 l_cp->tw, l_cp->th); | |
| 2376 if (!JPWL_ASSUME) { | |
| 2377 opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n"); | |
| 2378 return OPJ_FALSE; | |
| 2379 } | |
| 2380 /* we try to correct */ | |
| 2381 opj_event_msg(p_manager, EVT_WARNING, "- trying to adjust them\n"); | |
| 2382 if (l_cp->tw < 1) { | |
| 2383 l_cp->tw = 1; | |
| 2384 opj_event_msg(p_manager, EVT_WARNING, | |
| 2385 "- setting %d tiles in x => HYPOTHESIS!!!\n", | |
| 2386 l_cp->tw); | |
| 2387 } | |
| 2388 if (l_cp->tw > l_cp->max_tiles) { | |
| 2389 l_cp->tw = 1; | |
| 2390 opj_event_msg(p_manager, EVT_WARNING, | |
| 2391 "- too large x, increase expectance of %d\n" | |
| 2392 "- setting %d tiles in x => HYPOTHESIS!!!\n", | |
| 2393 l_cp->max_tiles, l_cp->tw); | |
| 2394 } | |
| 2395 if (l_cp->th < 1) { | |
| 2396 l_cp->th = 1; | |
| 2397 opj_event_msg(p_manager, EVT_WARNING, | |
| 2398 "- setting %d tiles in y => HYPOTHESIS!!!\n", | |
| 2399 l_cp->th); | |
| 2400 } | |
| 2401 if (l_cp->th > l_cp->max_tiles) { | |
| 2402 l_cp->th = 1; | |
| 2403 opj_event_msg(p_manager, EVT_WARNING, | |
| 2404 "- too large y, increase expectance of %d to continue\n", | |
| 2405 "- setting %d tiles in y => HYPOTHESIS!!!\n", | |
| 2406 l_cp->max_tiles, l_cp->th); | |
| 2407 } | |
| 2408 } | |
| 2409 } | |
| 2410 #endif /* USE_JPWL */ | |
| 2411 | |
| 2412 /* memory allocations */ | |
| 2413 l_cp->tcps = (opj_tcp_t*) opj_calloc(l_nb_tiles, sizeof(opj_tcp_t)); | |
| 2414 if (l_cp->tcps == 00) { | |
| 2415 opj_event_msg(p_manager, EVT_ERROR, | |
| 2416 "Not enough memory to take in charge SIZ marker\n"); | |
| 2417 return OPJ_FALSE; | |
| 2418 } | |
| 2419 | |
| 2420 #ifdef USE_JPWL | |
| 2421 if (l_cp->correct) { | |
| 2422 if (!l_cp->tcps) { | |
| 2423 opj_event_msg(p_manager, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR, | |
| 2424 "JPWL: could not alloc tcps field of cp\n"); | |
| 2425 if (!JPWL_ASSUME) { | |
| 2426 opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n"); | |
| 2427 return OPJ_FALSE; | |
| 2428 } | |
| 2429 } | |
| 2430 } | |
| 2431 #endif /* USE_JPWL */ | |
| 2432 | |
| 2433 p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps = | |
| 2434 (opj_tccp_t*) opj_calloc(l_image->numcomps, sizeof(opj_tccp_t)); | |
| 2435 if (p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps == 00) { | |
| 2436 opj_event_msg(p_manager, EVT_ERROR, | |
| 2437 "Not enough memory to take in charge SIZ marker\n"); | |
| 2438 return OPJ_FALSE; | |
| 2439 } | |
| 2440 | |
| 2441 p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mct_records = | |
| 2442 (opj_mct_data_t*)opj_calloc(OPJ_J2K_MCT_DEFAULT_NB_RECORDS, | |
| 2443 sizeof(opj_mct_data_t)); | |
| 2444 | |
| 2445 if (! p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mct_records) { | |
| 2446 opj_event_msg(p_manager, EVT_ERROR, | |
| 2447 "Not enough memory to take in charge SIZ marker\n"); | |
| 2448 return OPJ_FALSE; | |
| 2449 } | |
| 2450 p_j2k->m_specific_param.m_decoder.m_default_tcp->m_nb_max_mct_records = | |
| 2451 OPJ_J2K_MCT_DEFAULT_NB_RECORDS; | |
| 2452 | |
| 2453 p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mcc_records = | |
| 2454 (opj_simple_mcc_decorrelation_data_t*) | |
| 2455 opj_calloc(OPJ_J2K_MCC_DEFAULT_NB_RECORDS, | |
| 2456 sizeof(opj_simple_mcc_decorrelation_data_t)); | |
| 2457 | |
| 2458 if (! p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mcc_records) { | |
| 2459 opj_event_msg(p_manager, EVT_ERROR, | |
| 2460 "Not enough memory to take in charge SIZ marker\n"); | |
| 2461 return OPJ_FALSE; | |
| 2462 } | |
| 2463 p_j2k->m_specific_param.m_decoder.m_default_tcp->m_nb_max_mcc_records = | |
| 2464 OPJ_J2K_MCC_DEFAULT_NB_RECORDS; | |
| 2465 | |
| 2466 /* set up default dc level shift */ | |
| 2467 for (i = 0; i < l_image->numcomps; ++i) { | |
| 2468 if (! l_image->comps[i].sgnd) { | |
| 2469 p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps[i].m_dc_level_shift = 1 | |
| 2470 << (l_image->comps[i].prec - 1); | |
| 2471 } | |
| 2472 } | |
| 2473 | |
| 2474 l_current_tile_param = l_cp->tcps; | |
| 2475 for (i = 0; i < l_nb_tiles; ++i) { | |
| 2476 l_current_tile_param->tccps = (opj_tccp_t*) opj_calloc(l_image->numcomps, | |
| 2477 sizeof(opj_tccp_t)); | |
| 2478 if (l_current_tile_param->tccps == 00) { | |
| 2479 opj_event_msg(p_manager, EVT_ERROR, | |
| 2480 "Not enough memory to take in charge SIZ marker\n"); | |
| 2481 return OPJ_FALSE; | |
| 2482 } | |
| 2483 | |
| 2484 ++l_current_tile_param; | |
| 2485 } | |
| 2486 | |
| 2487 /*Allocate and initialize some elements of codestrem index*/ | |
| 2488 if (!opj_j2k_allocate_tile_element_cstr_index(p_j2k)) { | |
| 2489 return OPJ_FALSE; | |
| 2490 } | |
| 2491 | |
| 2492 p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_MH; | |
| 2493 opj_image_comp_header_update(l_image, l_cp); | |
| 2494 | |
| 2495 return OPJ_TRUE; | |
| 2496 } | |
| 2497 | |
| 2498 static OPJ_BOOL opj_j2k_write_com(opj_j2k_t *p_j2k, | |
| 2499 opj_stream_private_t *p_stream, | |
| 2500 opj_event_mgr_t * p_manager | |
| 2501 ) | |
| 2502 { | |
| 2503 OPJ_UINT32 l_comment_size; | |
| 2504 OPJ_UINT32 l_total_com_size; | |
| 2505 const OPJ_CHAR *l_comment; | |
| 2506 OPJ_BYTE * l_current_ptr = 00; | |
| 2507 | |
| 2508 /* preconditions */ | |
| 2509 assert(p_j2k != 00); | |
| 2510 assert(p_stream != 00); | |
| 2511 assert(p_manager != 00); | |
| 2512 | |
| 2513 l_comment = p_j2k->m_cp.comment; | |
| 2514 l_comment_size = (OPJ_UINT32)strlen(l_comment); | |
| 2515 l_total_com_size = l_comment_size + 6; | |
| 2516 | |
| 2517 if (l_total_com_size > | |
| 2518 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) { | |
| 2519 OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc( | |
| 2520 p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_total_com_size); | |
| 2521 if (! new_header_tile_data) { | |
| 2522 opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data); | |
| 2523 p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL; | |
| 2524 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0; | |
| 2525 opj_event_msg(p_manager, EVT_ERROR, | |
| 2526 "Not enough memory to write the COM marker\n"); | |
| 2527 return OPJ_FALSE; | |
| 2528 } | |
| 2529 p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data; | |
| 2530 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_total_com_size; | |
| 2531 } | |
| 2532 | |
| 2533 l_current_ptr = p_j2k->m_specific_param.m_encoder.m_header_tile_data; | |
| 2534 | |
| 2535 opj_write_bytes(l_current_ptr, J2K_MS_COM, 2); /* COM */ | |
| 2536 l_current_ptr += 2; | |
| 2537 | |
| 2538 opj_write_bytes(l_current_ptr, l_total_com_size - 2, 2); /* L_COM */ | |
| 2539 l_current_ptr += 2; | |
| 2540 | |
| 2541 opj_write_bytes(l_current_ptr, 1, | |
| 2542 2); /* General use (IS 8859-15:1999 (Latin) values) */ | |
| 2543 l_current_ptr += 2; | |
| 2544 | |
| 2545 memcpy(l_current_ptr, l_comment, l_comment_size); | |
| 2546 | |
| 2547 if (opj_stream_write_data(p_stream, | |
| 2548 p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_total_com_size, | |
| 2549 p_manager) != l_total_com_size) { | |
| 2550 return OPJ_FALSE; | |
| 2551 } | |
| 2552 | |
| 2553 return OPJ_TRUE; | |
| 2554 } | |
| 2555 | |
| 2556 /** | |
| 2557 * Reads a COM marker (comments) | |
| 2558 * @param p_j2k the jpeg2000 file codec. | |
| 2559 * @param p_header_data the data contained in the COM box. | |
| 2560 * @param p_header_size the size of the data contained in the COM marker. | |
| 2561 * @param p_manager the user event manager. | |
| 2562 */ | |
| 2563 static OPJ_BOOL opj_j2k_read_com(opj_j2k_t *p_j2k, | |
| 2564 OPJ_BYTE * p_header_data, | |
| 2565 OPJ_UINT32 p_header_size, | |
| 2566 opj_event_mgr_t * p_manager | |
| 2567 ) | |
| 2568 { | |
| 2569 /* preconditions */ | |
| 2570 assert(p_j2k != 00); | |
| 2571 assert(p_manager != 00); | |
| 2572 assert(p_header_data != 00); | |
| 2573 | |
| 2574 OPJ_UNUSED(p_j2k); | |
| 2575 OPJ_UNUSED(p_header_data); | |
| 2576 OPJ_UNUSED(p_header_size); | |
| 2577 OPJ_UNUSED(p_manager); | |
| 2578 | |
| 2579 return OPJ_TRUE; | |
| 2580 } | |
| 2581 | |
| 2582 static OPJ_BOOL opj_j2k_write_cod(opj_j2k_t *p_j2k, | |
| 2583 opj_stream_private_t *p_stream, | |
| 2584 opj_event_mgr_t * p_manager) | |
| 2585 { | |
| 2586 opj_cp_t *l_cp = 00; | |
| 2587 opj_tcp_t *l_tcp = 00; | |
| 2588 OPJ_UINT32 l_code_size, l_remaining_size; | |
| 2589 OPJ_BYTE * l_current_data = 00; | |
| 2590 | |
| 2591 /* preconditions */ | |
| 2592 assert(p_j2k != 00); | |
| 2593 assert(p_manager != 00); | |
| 2594 assert(p_stream != 00); | |
| 2595 | |
| 2596 l_cp = &(p_j2k->m_cp); | |
| 2597 l_tcp = &l_cp->tcps[p_j2k->m_current_tile_number]; | |
| 2598 l_code_size = 9 + opj_j2k_get_SPCod_SPCoc_size(p_j2k, | |
| 2599 p_j2k->m_current_tile_number, 0); | |
| 2600 l_remaining_size = l_code_size; | |
| 2601 | |
| 2602 if (l_code_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) { | |
| 2603 OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc( | |
| 2604 p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_code_size); | |
| 2605 if (! new_header_tile_data) { | |
| 2606 opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data); | |
| 2607 p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL; | |
| 2608 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0; | |
| 2609 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write COD marker\n"); | |
| 2610 return OPJ_FALSE; | |
| 2611 } | |
| 2612 p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data; | |
| 2613 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_code_size; | |
| 2614 } | |
| 2615 | |
| 2616 l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data; | |
| 2617 | |
| 2618 opj_write_bytes(l_current_data, J2K_MS_COD, 2); /* COD */ | |
| 2619 l_current_data += 2; | |
| 2620 | |
| 2621 opj_write_bytes(l_current_data, l_code_size - 2, 2); /* L_COD */ | |
| 2622 l_current_data += 2; | |
| 2623 | |
| 2624 opj_write_bytes(l_current_data, l_tcp->csty, 1); /* Scod */ | |
| 2625 ++l_current_data; | |
| 2626 | |
| 2627 opj_write_bytes(l_current_data, (OPJ_UINT32)l_tcp->prg, 1); /* SGcod (A) */ | |
| 2628 ++l_current_data; | |
| 2629 | |
| 2630 opj_write_bytes(l_current_data, l_tcp->numlayers, 2); /* SGcod (B) */ | |
| 2631 l_current_data += 2; | |
| 2632 | |
| 2633 opj_write_bytes(l_current_data, l_tcp->mct, 1); /* SGcod (C) */ | |
| 2634 ++l_current_data; | |
| 2635 | |
| 2636 l_remaining_size -= 9; | |
| 2637 | |
| 2638 if (! opj_j2k_write_SPCod_SPCoc(p_j2k, p_j2k->m_current_tile_number, 0, | |
| 2639 l_current_data, &l_remaining_size, p_manager)) { | |
| 2640 opj_event_msg(p_manager, EVT_ERROR, "Error writing COD marker\n"); | |
| 2641 return OPJ_FALSE; | |
| 2642 } | |
| 2643 | |
| 2644 if (l_remaining_size != 0) { | |
| 2645 opj_event_msg(p_manager, EVT_ERROR, "Error writing COD marker\n"); | |
| 2646 return OPJ_FALSE; | |
| 2647 } | |
| 2648 | |
| 2649 if (opj_stream_write_data(p_stream, | |
| 2650 p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_code_size, | |
| 2651 p_manager) != l_code_size) { | |
| 2652 return OPJ_FALSE; | |
| 2653 } | |
| 2654 | |
| 2655 return OPJ_TRUE; | |
| 2656 } | |
| 2657 | |
| 2658 /** | |
| 2659 * Reads a COD marker (Coding style defaults) | |
| 2660 * @param p_header_data the data contained in the COD box. | |
| 2661 * @param p_j2k the jpeg2000 codec. | |
| 2662 * @param p_header_size the size of the data contained in the COD marker. | |
| 2663 * @param p_manager the user event manager. | |
| 2664 */ | |
| 2665 static OPJ_BOOL opj_j2k_read_cod(opj_j2k_t *p_j2k, | |
| 2666 OPJ_BYTE * p_header_data, | |
| 2667 OPJ_UINT32 p_header_size, | |
| 2668 opj_event_mgr_t * p_manager | |
| 2669 ) | |
| 2670 { | |
| 2671 /* loop */ | |
| 2672 OPJ_UINT32 i; | |
| 2673 OPJ_UINT32 l_tmp; | |
| 2674 opj_cp_t *l_cp = 00; | |
| 2675 opj_tcp_t *l_tcp = 00; | |
| 2676 opj_image_t *l_image = 00; | |
| 2677 | |
| 2678 /* preconditions */ | |
| 2679 assert(p_header_data != 00); | |
| 2680 assert(p_j2k != 00); | |
| 2681 assert(p_manager != 00); | |
| 2682 | |
| 2683 l_image = p_j2k->m_private_image; | |
| 2684 l_cp = &(p_j2k->m_cp); | |
| 2685 | |
| 2686 /* If we are in the first tile-part header of the current tile */ | |
| 2687 l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH) ? | |
| 2688 &l_cp->tcps[p_j2k->m_current_tile_number] : | |
| 2689 p_j2k->m_specific_param.m_decoder.m_default_tcp; | |
| 2690 | |
| 2691 #if 0 | |
| 2692 /* This check was added per https://github.com/uclouvain/openjpeg/commit/daed8cc9195555e101ab708a501af2dfe6d5e001 */ | |
| 2693 /* but this is no longer necessary to handle issue476.jp2 */ | |
| 2694 /* and this actually cause issues on legit files. See https://github.com/uclouvain/openjpeg/issues/1043 */ | |
| 2695 /* Only one COD per tile */ | |
| 2696 if (l_tcp->cod) { | |
| 2697 opj_event_msg(p_manager, EVT_ERROR, | |
| 2698 "COD marker already read. No more than one COD marker per tile.\n"); | |
| 2699 return OPJ_FALSE; | |
| 2700 } | |
| 2701 #endif | |
| 2702 l_tcp->cod = 1; | |
| 2703 | |
| 2704 /* Make sure room is sufficient */ | |
| 2705 if (p_header_size < 5) { | |
| 2706 opj_event_msg(p_manager, EVT_ERROR, "Error reading COD marker\n"); | |
| 2707 return OPJ_FALSE; | |
| 2708 } | |
| 2709 | |
| 2710 opj_read_bytes(p_header_data, &l_tcp->csty, 1); /* Scod */ | |
| 2711 ++p_header_data; | |
| 2712 /* Make sure we know how to decode this */ | |
| 2713 if ((l_tcp->csty & ~(OPJ_UINT32)(J2K_CP_CSTY_PRT | J2K_CP_CSTY_SOP | | |
| 2714 J2K_CP_CSTY_EPH)) != 0U) { | |
| 2715 opj_event_msg(p_manager, EVT_ERROR, "Unknown Scod value in COD marker\n"); | |
| 2716 return OPJ_FALSE; | |
| 2717 } | |
| 2718 opj_read_bytes(p_header_data, &l_tmp, 1); /* SGcod (A) */ | |
| 2719 ++p_header_data; | |
| 2720 l_tcp->prg = (OPJ_PROG_ORDER) l_tmp; | |
| 2721 /* Make sure progression order is valid */ | |
| 2722 if (l_tcp->prg > OPJ_CPRL) { | |
| 2723 opj_event_msg(p_manager, EVT_ERROR, | |
| 2724 "Unknown progression order in COD marker\n"); | |
| 2725 l_tcp->prg = OPJ_PROG_UNKNOWN; | |
| 2726 } | |
| 2727 opj_read_bytes(p_header_data, &l_tcp->numlayers, 2); /* SGcod (B) */ | |
| 2728 p_header_data += 2; | |
| 2729 | |
| 2730 if ((l_tcp->numlayers < 1U) || (l_tcp->numlayers > 65535U)) { | |
| 2731 opj_event_msg(p_manager, EVT_ERROR, | |
| 2732 "Invalid number of layers in COD marker : %d not in range [1-65535]\n", | |
| 2733 l_tcp->numlayers); | |
| 2734 return OPJ_FALSE; | |
| 2735 } | |
| 2736 | |
| 2737 /* If user didn't set a number layer to decode take the max specify in the codestream. */ | |
| 2738 if (l_cp->m_specific_param.m_dec.m_layer) { | |
| 2739 l_tcp->num_layers_to_decode = l_cp->m_specific_param.m_dec.m_layer; | |
| 2740 } else { | |
| 2741 l_tcp->num_layers_to_decode = l_tcp->numlayers; | |
| 2742 } | |
| 2743 | |
| 2744 opj_read_bytes(p_header_data, &l_tcp->mct, 1); /* SGcod (C) */ | |
| 2745 ++p_header_data; | |
| 2746 | |
| 2747 if (l_tcp->mct > 1) { | |
| 2748 opj_event_msg(p_manager, EVT_ERROR, | |
| 2749 "Invalid multiple component transformation\n"); | |
| 2750 return OPJ_FALSE; | |
| 2751 } | |
| 2752 | |
| 2753 p_header_size -= 5; | |
| 2754 for (i = 0; i < l_image->numcomps; ++i) { | |
| 2755 l_tcp->tccps[i].csty = l_tcp->csty & J2K_CCP_CSTY_PRT; | |
| 2756 } | |
| 2757 | |
| 2758 if (! opj_j2k_read_SPCod_SPCoc(p_j2k, 0, p_header_data, &p_header_size, | |
| 2759 p_manager)) { | |
| 2760 opj_event_msg(p_manager, EVT_ERROR, "Error reading COD marker\n"); | |
| 2761 return OPJ_FALSE; | |
| 2762 } | |
| 2763 | |
| 2764 if (p_header_size != 0) { | |
| 2765 opj_event_msg(p_manager, EVT_ERROR, "Error reading COD marker\n"); | |
| 2766 return OPJ_FALSE; | |
| 2767 } | |
| 2768 | |
| 2769 /* Apply the coding style to other components of the current tile or the m_default_tcp*/ | |
| 2770 opj_j2k_copy_tile_component_parameters(p_j2k); | |
| 2771 | |
| 2772 /* Index */ | |
| 2773 #ifdef WIP_REMOVE_MSD | |
| 2774 if (p_j2k->cstr_info) { | |
| 2775 /*opj_codestream_info_t *l_cstr_info = p_j2k->cstr_info;*/ | |
| 2776 p_j2k->cstr_info->prog = l_tcp->prg; | |
| 2777 p_j2k->cstr_info->numlayers = l_tcp->numlayers; | |
| 2778 p_j2k->cstr_info->numdecompos = (OPJ_INT32*) opj_malloc( | |
| 2779 l_image->numcomps * sizeof(OPJ_UINT32)); | |
| 2780 if (!p_j2k->cstr_info->numdecompos) { | |
| 2781 return OPJ_FALSE; | |
| 2782 } | |
| 2783 for (i = 0; i < l_image->numcomps; ++i) { | |
| 2784 p_j2k->cstr_info->numdecompos[i] = l_tcp->tccps[i].numresolutions - 1; | |
| 2785 } | |
| 2786 } | |
| 2787 #endif | |
| 2788 | |
| 2789 return OPJ_TRUE; | |
| 2790 } | |
| 2791 | |
| 2792 static OPJ_BOOL opj_j2k_write_coc(opj_j2k_t *p_j2k, | |
| 2793 OPJ_UINT32 p_comp_no, | |
| 2794 opj_stream_private_t *p_stream, | |
| 2795 opj_event_mgr_t * p_manager) | |
| 2796 { | |
| 2797 OPJ_UINT32 l_coc_size, l_remaining_size; | |
| 2798 OPJ_UINT32 l_comp_room; | |
| 2799 | |
| 2800 /* preconditions */ | |
| 2801 assert(p_j2k != 00); | |
| 2802 assert(p_manager != 00); | |
| 2803 assert(p_stream != 00); | |
| 2804 | |
| 2805 l_comp_room = (p_j2k->m_private_image->numcomps <= 256) ? 1 : 2; | |
| 2806 | |
| 2807 l_coc_size = 5 + l_comp_room + opj_j2k_get_SPCod_SPCoc_size(p_j2k, | |
| 2808 p_j2k->m_current_tile_number, p_comp_no); | |
| 2809 | |
| 2810 if (l_coc_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) { | |
| 2811 OPJ_BYTE *new_header_tile_data; | |
| 2812 /*p_j2k->m_specific_param.m_encoder.m_header_tile_data | |
| 2813 = (OPJ_BYTE*)opj_realloc( | |
| 2814 p_j2k->m_specific_param.m_encoder.m_header_tile_data, | |
| 2815 l_coc_size);*/ | |
| 2816 | |
| 2817 new_header_tile_data = (OPJ_BYTE *) opj_realloc( | |
| 2818 p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_coc_size); | |
| 2819 if (! new_header_tile_data) { | |
| 2820 opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data); | |
| 2821 p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL; | |
| 2822 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0; | |
| 2823 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write COC marker\n"); | |
| 2824 return OPJ_FALSE; | |
| 2825 } | |
| 2826 p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data; | |
| 2827 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_coc_size; | |
| 2828 } | |
| 2829 | |
| 2830 opj_j2k_write_coc_in_memory(p_j2k, p_comp_no, | |
| 2831 p_j2k->m_specific_param.m_encoder.m_header_tile_data, &l_remaining_size, | |
| 2832 p_manager); | |
| 2833 | |
| 2834 if (opj_stream_write_data(p_stream, | |
| 2835 p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_coc_size, | |
| 2836 p_manager) != l_coc_size) { | |
| 2837 return OPJ_FALSE; | |
| 2838 } | |
| 2839 | |
| 2840 return OPJ_TRUE; | |
| 2841 } | |
| 2842 | |
| 2843 static OPJ_BOOL opj_j2k_compare_coc(opj_j2k_t *p_j2k, | |
| 2844 OPJ_UINT32 p_first_comp_no, OPJ_UINT32 p_second_comp_no) | |
| 2845 { | |
| 2846 opj_cp_t *l_cp = NULL; | |
| 2847 opj_tcp_t *l_tcp = NULL; | |
| 2848 | |
| 2849 /* preconditions */ | |
| 2850 assert(p_j2k != 00); | |
| 2851 | |
| 2852 l_cp = &(p_j2k->m_cp); | |
| 2853 l_tcp = &l_cp->tcps[p_j2k->m_current_tile_number]; | |
| 2854 | |
| 2855 if (l_tcp->tccps[p_first_comp_no].csty != l_tcp->tccps[p_second_comp_no].csty) { | |
| 2856 return OPJ_FALSE; | |
| 2857 } | |
| 2858 | |
| 2859 | |
| 2860 return opj_j2k_compare_SPCod_SPCoc(p_j2k, p_j2k->m_current_tile_number, | |
| 2861 p_first_comp_no, p_second_comp_no); | |
| 2862 } | |
| 2863 | |
| 2864 static void opj_j2k_write_coc_in_memory(opj_j2k_t *p_j2k, | |
| 2865 OPJ_UINT32 p_comp_no, | |
| 2866 OPJ_BYTE * p_data, | |
| 2867 OPJ_UINT32 * p_data_written, | |
| 2868 opj_event_mgr_t * p_manager | |
| 2869 ) | |
| 2870 { | |
| 2871 opj_cp_t *l_cp = 00; | |
| 2872 opj_tcp_t *l_tcp = 00; | |
| 2873 OPJ_UINT32 l_coc_size, l_remaining_size; | |
| 2874 OPJ_BYTE * l_current_data = 00; | |
| 2875 opj_image_t *l_image = 00; | |
| 2876 OPJ_UINT32 l_comp_room; | |
| 2877 | |
| 2878 /* preconditions */ | |
| 2879 assert(p_j2k != 00); | |
| 2880 assert(p_manager != 00); | |
| 2881 | |
| 2882 l_cp = &(p_j2k->m_cp); | |
| 2883 l_tcp = &l_cp->tcps[p_j2k->m_current_tile_number]; | |
| 2884 l_image = p_j2k->m_private_image; | |
| 2885 l_comp_room = (l_image->numcomps <= 256) ? 1 : 2; | |
| 2886 | |
| 2887 l_coc_size = 5 + l_comp_room + opj_j2k_get_SPCod_SPCoc_size(p_j2k, | |
| 2888 p_j2k->m_current_tile_number, p_comp_no); | |
| 2889 l_remaining_size = l_coc_size; | |
| 2890 | |
| 2891 l_current_data = p_data; | |
| 2892 | |
| 2893 opj_write_bytes(l_current_data, J2K_MS_COC, | |
| 2894 2); /* COC */ | |
| 2895 l_current_data += 2; | |
| 2896 | |
| 2897 opj_write_bytes(l_current_data, l_coc_size - 2, | |
| 2898 2); /* L_COC */ | |
| 2899 l_current_data += 2; | |
| 2900 | |
| 2901 opj_write_bytes(l_current_data, p_comp_no, l_comp_room); /* Ccoc */ | |
| 2902 l_current_data += l_comp_room; | |
| 2903 | |
| 2904 opj_write_bytes(l_current_data, l_tcp->tccps[p_comp_no].csty, | |
| 2905 1); /* Scoc */ | |
| 2906 ++l_current_data; | |
| 2907 | |
| 2908 l_remaining_size -= (5 + l_comp_room); | |
| 2909 opj_j2k_write_SPCod_SPCoc(p_j2k, p_j2k->m_current_tile_number, 0, | |
| 2910 l_current_data, &l_remaining_size, p_manager); | |
| 2911 * p_data_written = l_coc_size; | |
| 2912 } | |
| 2913 | |
| 2914 static OPJ_UINT32 opj_j2k_get_max_coc_size(opj_j2k_t *p_j2k) | |
| 2915 { | |
| 2916 OPJ_UINT32 i, j; | |
| 2917 OPJ_UINT32 l_nb_comp; | |
| 2918 OPJ_UINT32 l_nb_tiles; | |
| 2919 OPJ_UINT32 l_max = 0; | |
| 2920 | |
| 2921 /* preconditions */ | |
| 2922 | |
| 2923 l_nb_tiles = p_j2k->m_cp.tw * p_j2k->m_cp.th ; | |
| 2924 l_nb_comp = p_j2k->m_private_image->numcomps; | |
| 2925 | |
| 2926 for (i = 0; i < l_nb_tiles; ++i) { | |
| 2927 for (j = 0; j < l_nb_comp; ++j) { | |
| 2928 l_max = opj_uint_max(l_max, opj_j2k_get_SPCod_SPCoc_size(p_j2k, i, j)); | |
| 2929 } | |
| 2930 } | |
| 2931 | |
| 2932 return 6 + l_max; | |
| 2933 } | |
| 2934 | |
| 2935 /** | |
| 2936 * Reads a COC marker (Coding Style Component) | |
| 2937 * @param p_header_data the data contained in the COC box. | |
| 2938 * @param p_j2k the jpeg2000 codec. | |
| 2939 * @param p_header_size the size of the data contained in the COC marker. | |
| 2940 * @param p_manager the user event manager. | |
| 2941 */ | |
| 2942 static OPJ_BOOL opj_j2k_read_coc(opj_j2k_t *p_j2k, | |
| 2943 OPJ_BYTE * p_header_data, | |
| 2944 OPJ_UINT32 p_header_size, | |
| 2945 opj_event_mgr_t * p_manager | |
| 2946 ) | |
| 2947 { | |
| 2948 opj_cp_t *l_cp = NULL; | |
| 2949 opj_tcp_t *l_tcp = NULL; | |
| 2950 opj_image_t *l_image = NULL; | |
| 2951 OPJ_UINT32 l_comp_room; | |
| 2952 OPJ_UINT32 l_comp_no; | |
| 2953 | |
| 2954 /* preconditions */ | |
| 2955 assert(p_header_data != 00); | |
| 2956 assert(p_j2k != 00); | |
| 2957 assert(p_manager != 00); | |
| 2958 | |
| 2959 l_cp = &(p_j2k->m_cp); | |
| 2960 l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH) | |
| 2961 ? | |
| 2962 &l_cp->tcps[p_j2k->m_current_tile_number] : | |
| 2963 p_j2k->m_specific_param.m_decoder.m_default_tcp; | |
| 2964 l_image = p_j2k->m_private_image; | |
| 2965 | |
| 2966 l_comp_room = l_image->numcomps <= 256 ? 1 : 2; | |
| 2967 | |
| 2968 /* make sure room is sufficient*/ | |
| 2969 if (p_header_size < l_comp_room + 1) { | |
| 2970 opj_event_msg(p_manager, EVT_ERROR, "Error reading COC marker\n"); | |
| 2971 return OPJ_FALSE; | |
| 2972 } | |
| 2973 p_header_size -= l_comp_room + 1; | |
| 2974 | |
| 2975 opj_read_bytes(p_header_data, &l_comp_no, | |
| 2976 l_comp_room); /* Ccoc */ | |
| 2977 p_header_data += l_comp_room; | |
| 2978 if (l_comp_no >= l_image->numcomps) { | |
| 2979 opj_event_msg(p_manager, EVT_ERROR, | |
| 2980 "Error reading COC marker (bad number of components)\n"); | |
| 2981 return OPJ_FALSE; | |
| 2982 } | |
| 2983 | |
| 2984 opj_read_bytes(p_header_data, &l_tcp->tccps[l_comp_no].csty, | |
| 2985 1); /* Scoc */ | |
| 2986 ++p_header_data ; | |
| 2987 | |
| 2988 if (! opj_j2k_read_SPCod_SPCoc(p_j2k, l_comp_no, p_header_data, &p_header_size, | |
| 2989 p_manager)) { | |
| 2990 opj_event_msg(p_manager, EVT_ERROR, "Error reading COC marker\n"); | |
| 2991 return OPJ_FALSE; | |
| 2992 } | |
| 2993 | |
| 2994 if (p_header_size != 0) { | |
| 2995 opj_event_msg(p_manager, EVT_ERROR, "Error reading COC marker\n"); | |
| 2996 return OPJ_FALSE; | |
| 2997 } | |
| 2998 return OPJ_TRUE; | |
| 2999 } | |
| 3000 | |
| 3001 static OPJ_BOOL opj_j2k_write_qcd(opj_j2k_t *p_j2k, | |
| 3002 opj_stream_private_t *p_stream, | |
| 3003 opj_event_mgr_t * p_manager | |
| 3004 ) | |
| 3005 { | |
| 3006 OPJ_UINT32 l_qcd_size, l_remaining_size; | |
| 3007 OPJ_BYTE * l_current_data = 00; | |
| 3008 | |
| 3009 /* preconditions */ | |
| 3010 assert(p_j2k != 00); | |
| 3011 assert(p_manager != 00); | |
| 3012 assert(p_stream != 00); | |
| 3013 | |
| 3014 l_qcd_size = 4 + opj_j2k_get_SQcd_SQcc_size(p_j2k, p_j2k->m_current_tile_number, | |
| 3015 0); | |
| 3016 l_remaining_size = l_qcd_size; | |
| 3017 | |
| 3018 if (l_qcd_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) { | |
| 3019 OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc( | |
| 3020 p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_qcd_size); | |
| 3021 if (! new_header_tile_data) { | |
| 3022 opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data); | |
| 3023 p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL; | |
| 3024 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0; | |
| 3025 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write QCD marker\n"); | |
| 3026 return OPJ_FALSE; | |
| 3027 } | |
| 3028 p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data; | |
| 3029 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_qcd_size; | |
| 3030 } | |
| 3031 | |
| 3032 l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data; | |
| 3033 | |
| 3034 opj_write_bytes(l_current_data, J2K_MS_QCD, 2); /* QCD */ | |
| 3035 l_current_data += 2; | |
| 3036 | |
| 3037 opj_write_bytes(l_current_data, l_qcd_size - 2, 2); /* L_QCD */ | |
| 3038 l_current_data += 2; | |
| 3039 | |
| 3040 l_remaining_size -= 4; | |
| 3041 | |
| 3042 if (! opj_j2k_write_SQcd_SQcc(p_j2k, p_j2k->m_current_tile_number, 0, | |
| 3043 l_current_data, &l_remaining_size, p_manager)) { | |
| 3044 opj_event_msg(p_manager, EVT_ERROR, "Error writing QCD marker\n"); | |
| 3045 return OPJ_FALSE; | |
| 3046 } | |
| 3047 | |
| 3048 if (l_remaining_size != 0) { | |
| 3049 opj_event_msg(p_manager, EVT_ERROR, "Error writing QCD marker\n"); | |
| 3050 return OPJ_FALSE; | |
| 3051 } | |
| 3052 | |
| 3053 if (opj_stream_write_data(p_stream, | |
| 3054 p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_qcd_size, | |
| 3055 p_manager) != l_qcd_size) { | |
| 3056 return OPJ_FALSE; | |
| 3057 } | |
| 3058 | |
| 3059 return OPJ_TRUE; | |
| 3060 } | |
| 3061 | |
| 3062 /** | |
| 3063 * Reads a QCD marker (Quantization defaults) | |
| 3064 * @param p_header_data the data contained in the QCD box. | |
| 3065 * @param p_j2k the jpeg2000 codec. | |
| 3066 * @param p_header_size the size of the data contained in the QCD marker. | |
| 3067 * @param p_manager the user event manager. | |
| 3068 */ | |
| 3069 static OPJ_BOOL opj_j2k_read_qcd(opj_j2k_t *p_j2k, | |
| 3070 OPJ_BYTE * p_header_data, | |
| 3071 OPJ_UINT32 p_header_size, | |
| 3072 opj_event_mgr_t * p_manager | |
| 3073 ) | |
| 3074 { | |
| 3075 /* preconditions */ | |
| 3076 assert(p_header_data != 00); | |
| 3077 assert(p_j2k != 00); | |
| 3078 assert(p_manager != 00); | |
| 3079 | |
| 3080 if (! opj_j2k_read_SQcd_SQcc(p_j2k, 0, p_header_data, &p_header_size, | |
| 3081 p_manager)) { | |
| 3082 opj_event_msg(p_manager, EVT_ERROR, "Error reading QCD marker\n"); | |
| 3083 return OPJ_FALSE; | |
| 3084 } | |
| 3085 | |
| 3086 if (p_header_size != 0) { | |
| 3087 opj_event_msg(p_manager, EVT_ERROR, "Error reading QCD marker\n"); | |
| 3088 return OPJ_FALSE; | |
| 3089 } | |
| 3090 | |
| 3091 /* Apply the quantization parameters to other components of the current tile or the m_default_tcp */ | |
| 3092 opj_j2k_copy_tile_quantization_parameters(p_j2k); | |
| 3093 | |
| 3094 return OPJ_TRUE; | |
| 3095 } | |
| 3096 | |
| 3097 static OPJ_BOOL opj_j2k_write_qcc(opj_j2k_t *p_j2k, | |
| 3098 OPJ_UINT32 p_comp_no, | |
| 3099 opj_stream_private_t *p_stream, | |
| 3100 opj_event_mgr_t * p_manager | |
| 3101 ) | |
| 3102 { | |
| 3103 OPJ_UINT32 l_qcc_size, l_remaining_size; | |
| 3104 | |
| 3105 /* preconditions */ | |
| 3106 assert(p_j2k != 00); | |
| 3107 assert(p_manager != 00); | |
| 3108 assert(p_stream != 00); | |
| 3109 | |
| 3110 l_qcc_size = 5 + opj_j2k_get_SQcd_SQcc_size(p_j2k, p_j2k->m_current_tile_number, | |
| 3111 p_comp_no); | |
| 3112 l_qcc_size += p_j2k->m_private_image->numcomps <= 256 ? 0 : 1; | |
| 3113 l_remaining_size = l_qcc_size; | |
| 3114 | |
| 3115 if (l_qcc_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) { | |
| 3116 OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc( | |
| 3117 p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_qcc_size); | |
| 3118 if (! new_header_tile_data) { | |
| 3119 opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data); | |
| 3120 p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL; | |
| 3121 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0; | |
| 3122 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write QCC marker\n"); | |
| 3123 return OPJ_FALSE; | |
| 3124 } | |
| 3125 p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data; | |
| 3126 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_qcc_size; | |
| 3127 } | |
| 3128 | |
| 3129 opj_j2k_write_qcc_in_memory(p_j2k, p_comp_no, | |
| 3130 p_j2k->m_specific_param.m_encoder.m_header_tile_data, &l_remaining_size, | |
| 3131 p_manager); | |
| 3132 | |
| 3133 if (opj_stream_write_data(p_stream, | |
| 3134 p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_qcc_size, | |
| 3135 p_manager) != l_qcc_size) { | |
| 3136 return OPJ_FALSE; | |
| 3137 } | |
| 3138 | |
| 3139 return OPJ_TRUE; | |
| 3140 } | |
| 3141 | |
| 3142 static OPJ_BOOL opj_j2k_compare_qcc(opj_j2k_t *p_j2k, | |
| 3143 OPJ_UINT32 p_first_comp_no, OPJ_UINT32 p_second_comp_no) | |
| 3144 { | |
| 3145 return opj_j2k_compare_SQcd_SQcc(p_j2k, p_j2k->m_current_tile_number, | |
| 3146 p_first_comp_no, p_second_comp_no); | |
| 3147 } | |
| 3148 | |
| 3149 static void opj_j2k_write_qcc_in_memory(opj_j2k_t *p_j2k, | |
| 3150 OPJ_UINT32 p_comp_no, | |
| 3151 OPJ_BYTE * p_data, | |
| 3152 OPJ_UINT32 * p_data_written, | |
| 3153 opj_event_mgr_t * p_manager | |
| 3154 ) | |
| 3155 { | |
| 3156 OPJ_UINT32 l_qcc_size, l_remaining_size; | |
| 3157 OPJ_BYTE * l_current_data = 00; | |
| 3158 | |
| 3159 /* preconditions */ | |
| 3160 assert(p_j2k != 00); | |
| 3161 assert(p_manager != 00); | |
| 3162 | |
| 3163 l_qcc_size = 6 + opj_j2k_get_SQcd_SQcc_size(p_j2k, p_j2k->m_current_tile_number, | |
| 3164 p_comp_no); | |
| 3165 l_remaining_size = l_qcc_size; | |
| 3166 | |
| 3167 l_current_data = p_data; | |
| 3168 | |
| 3169 opj_write_bytes(l_current_data, J2K_MS_QCC, 2); /* QCC */ | |
| 3170 l_current_data += 2; | |
| 3171 | |
| 3172 if (p_j2k->m_private_image->numcomps <= 256) { | |
| 3173 --l_qcc_size; | |
| 3174 | |
| 3175 opj_write_bytes(l_current_data, l_qcc_size - 2, 2); /* L_QCC */ | |
| 3176 l_current_data += 2; | |
| 3177 | |
| 3178 opj_write_bytes(l_current_data, p_comp_no, 1); /* Cqcc */ | |
| 3179 ++l_current_data; | |
| 3180 | |
| 3181 /* in the case only one byte is sufficient the last byte allocated is useless -> still do -6 for available */ | |
| 3182 l_remaining_size -= 6; | |
| 3183 } else { | |
| 3184 opj_write_bytes(l_current_data, l_qcc_size - 2, 2); /* L_QCC */ | |
| 3185 l_current_data += 2; | |
| 3186 | |
| 3187 opj_write_bytes(l_current_data, p_comp_no, 2); /* Cqcc */ | |
| 3188 l_current_data += 2; | |
| 3189 | |
| 3190 l_remaining_size -= 6; | |
| 3191 } | |
| 3192 | |
| 3193 opj_j2k_write_SQcd_SQcc(p_j2k, p_j2k->m_current_tile_number, p_comp_no, | |
| 3194 l_current_data, &l_remaining_size, p_manager); | |
| 3195 | |
| 3196 *p_data_written = l_qcc_size; | |
| 3197 } | |
| 3198 | |
| 3199 static OPJ_UINT32 opj_j2k_get_max_qcc_size(opj_j2k_t *p_j2k) | |
| 3200 { | |
| 3201 return opj_j2k_get_max_coc_size(p_j2k); | |
| 3202 } | |
| 3203 | |
| 3204 /** | |
| 3205 * Reads a QCC marker (Quantization component) | |
| 3206 * @param p_header_data the data contained in the QCC box. | |
| 3207 * @param p_j2k the jpeg2000 codec. | |
| 3208 * @param p_header_size the size of the data contained in the QCC marker. | |
| 3209 * @param p_manager the user event manager. | |
| 3210 */ | |
| 3211 static OPJ_BOOL opj_j2k_read_qcc(opj_j2k_t *p_j2k, | |
| 3212 OPJ_BYTE * p_header_data, | |
| 3213 OPJ_UINT32 p_header_size, | |
| 3214 opj_event_mgr_t * p_manager | |
| 3215 ) | |
| 3216 { | |
| 3217 OPJ_UINT32 l_num_comp, l_comp_no; | |
| 3218 | |
| 3219 /* preconditions */ | |
| 3220 assert(p_header_data != 00); | |
| 3221 assert(p_j2k != 00); | |
| 3222 assert(p_manager != 00); | |
| 3223 | |
| 3224 l_num_comp = p_j2k->m_private_image->numcomps; | |
| 3225 | |
| 3226 if (l_num_comp <= 256) { | |
| 3227 if (p_header_size < 1) { | |
| 3228 opj_event_msg(p_manager, EVT_ERROR, "Error reading QCC marker\n"); | |
| 3229 return OPJ_FALSE; | |
| 3230 } | |
| 3231 opj_read_bytes(p_header_data, &l_comp_no, 1); | |
| 3232 ++p_header_data; | |
| 3233 --p_header_size; | |
| 3234 } else { | |
| 3235 if (p_header_size < 2) { | |
| 3236 opj_event_msg(p_manager, EVT_ERROR, "Error reading QCC marker\n"); | |
| 3237 return OPJ_FALSE; | |
| 3238 } | |
| 3239 opj_read_bytes(p_header_data, &l_comp_no, 2); | |
| 3240 p_header_data += 2; | |
| 3241 p_header_size -= 2; | |
| 3242 } | |
| 3243 | |
| 3244 #ifdef USE_JPWL | |
| 3245 if (p_j2k->m_cp.correct) { | |
| 3246 | |
| 3247 static OPJ_UINT32 backup_compno = 0; | |
| 3248 | |
| 3249 /* compno is negative or larger than the number of components!!! */ | |
| 3250 if (/*(l_comp_no < 0) ||*/ (l_comp_no >= l_num_comp)) { | |
| 3251 opj_event_msg(p_manager, EVT_ERROR, | |
| 3252 "JPWL: bad component number in QCC (%d out of a maximum of %d)\n", | |
| 3253 l_comp_no, l_num_comp); | |
| 3254 if (!JPWL_ASSUME) { | |
| 3255 opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n"); | |
| 3256 return OPJ_FALSE; | |
| 3257 } | |
| 3258 /* we try to correct */ | |
| 3259 l_comp_no = backup_compno % l_num_comp; | |
| 3260 opj_event_msg(p_manager, EVT_WARNING, "- trying to adjust this\n" | |
| 3261 "- setting component number to %d\n", | |
| 3262 l_comp_no); | |
| 3263 } | |
| 3264 | |
| 3265 /* keep your private count of tiles */ | |
| 3266 backup_compno++; | |
| 3267 }; | |
| 3268 #endif /* USE_JPWL */ | |
| 3269 | |
| 3270 if (l_comp_no >= p_j2k->m_private_image->numcomps) { | |
| 3271 opj_event_msg(p_manager, EVT_ERROR, | |
| 3272 "Invalid component number: %d, regarding the number of components %d\n", | |
| 3273 l_comp_no, p_j2k->m_private_image->numcomps); | |
| 3274 return OPJ_FALSE; | |
| 3275 } | |
| 3276 | |
| 3277 if (! opj_j2k_read_SQcd_SQcc(p_j2k, l_comp_no, p_header_data, &p_header_size, | |
| 3278 p_manager)) { | |
| 3279 opj_event_msg(p_manager, EVT_ERROR, "Error reading QCC marker\n"); | |
| 3280 return OPJ_FALSE; | |
| 3281 } | |
| 3282 | |
| 3283 if (p_header_size != 0) { | |
| 3284 opj_event_msg(p_manager, EVT_ERROR, "Error reading QCC marker\n"); | |
| 3285 return OPJ_FALSE; | |
| 3286 } | |
| 3287 | |
| 3288 return OPJ_TRUE; | |
| 3289 } | |
| 3290 | |
| 3291 static OPJ_BOOL opj_j2k_write_poc(opj_j2k_t *p_j2k, | |
| 3292 opj_stream_private_t *p_stream, | |
| 3293 opj_event_mgr_t * p_manager | |
| 3294 ) | |
| 3295 { | |
| 3296 OPJ_UINT32 l_nb_comp; | |
| 3297 OPJ_UINT32 l_nb_poc; | |
| 3298 OPJ_UINT32 l_poc_size; | |
| 3299 OPJ_UINT32 l_written_size = 0; | |
| 3300 opj_tcp_t *l_tcp = 00; | |
| 3301 OPJ_UINT32 l_poc_room; | |
| 3302 | |
| 3303 /* preconditions */ | |
| 3304 assert(p_j2k != 00); | |
| 3305 assert(p_manager != 00); | |
| 3306 assert(p_stream != 00); | |
| 3307 | |
| 3308 l_tcp = &p_j2k->m_cp.tcps[p_j2k->m_current_tile_number]; | |
| 3309 l_nb_comp = p_j2k->m_private_image->numcomps; | |
| 3310 l_nb_poc = 1 + l_tcp->numpocs; | |
| 3311 | |
| 3312 if (l_nb_comp <= 256) { | |
| 3313 l_poc_room = 1; | |
| 3314 } else { | |
| 3315 l_poc_room = 2; | |
| 3316 } | |
| 3317 l_poc_size = 4 + (5 + 2 * l_poc_room) * l_nb_poc; | |
| 3318 | |
| 3319 if (l_poc_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) { | |
| 3320 OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc( | |
| 3321 p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_poc_size); | |
| 3322 if (! new_header_tile_data) { | |
| 3323 opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data); | |
| 3324 p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL; | |
| 3325 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0; | |
| 3326 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write POC marker\n"); | |
| 3327 return OPJ_FALSE; | |
| 3328 } | |
| 3329 p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data; | |
| 3330 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_poc_size; | |
| 3331 } | |
| 3332 | |
| 3333 opj_j2k_write_poc_in_memory(p_j2k, | |
| 3334 p_j2k->m_specific_param.m_encoder.m_header_tile_data, &l_written_size, | |
| 3335 p_manager); | |
| 3336 | |
| 3337 if (opj_stream_write_data(p_stream, | |
| 3338 p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_poc_size, | |
| 3339 p_manager) != l_poc_size) { | |
| 3340 return OPJ_FALSE; | |
| 3341 } | |
| 3342 | |
| 3343 return OPJ_TRUE; | |
| 3344 } | |
| 3345 | |
| 3346 static void opj_j2k_write_poc_in_memory(opj_j2k_t *p_j2k, | |
| 3347 OPJ_BYTE * p_data, | |
| 3348 OPJ_UINT32 * p_data_written, | |
| 3349 opj_event_mgr_t * p_manager | |
| 3350 ) | |
| 3351 { | |
| 3352 OPJ_UINT32 i; | |
| 3353 OPJ_BYTE * l_current_data = 00; | |
| 3354 OPJ_UINT32 l_nb_comp; | |
| 3355 OPJ_UINT32 l_nb_poc; | |
| 3356 OPJ_UINT32 l_poc_size; | |
| 3357 opj_image_t *l_image = 00; | |
| 3358 opj_tcp_t *l_tcp = 00; | |
| 3359 opj_tccp_t *l_tccp = 00; | |
| 3360 opj_poc_t *l_current_poc = 00; | |
| 3361 OPJ_UINT32 l_poc_room; | |
| 3362 | |
| 3363 /* preconditions */ | |
| 3364 assert(p_j2k != 00); | |
| 3365 assert(p_manager != 00); | |
| 3366 | |
| 3367 OPJ_UNUSED(p_manager); | |
| 3368 | |
| 3369 l_tcp = &p_j2k->m_cp.tcps[p_j2k->m_current_tile_number]; | |
| 3370 l_tccp = &l_tcp->tccps[0]; | |
| 3371 l_image = p_j2k->m_private_image; | |
| 3372 l_nb_comp = l_image->numcomps; | |
| 3373 l_nb_poc = 1 + l_tcp->numpocs; | |
| 3374 | |
| 3375 if (l_nb_comp <= 256) { | |
| 3376 l_poc_room = 1; | |
| 3377 } else { | |
| 3378 l_poc_room = 2; | |
| 3379 } | |
| 3380 | |
| 3381 l_poc_size = 4 + (5 + 2 * l_poc_room) * l_nb_poc; | |
| 3382 | |
| 3383 l_current_data = p_data; | |
| 3384 | |
| 3385 opj_write_bytes(l_current_data, J2K_MS_POC, | |
| 3386 2); /* POC */ | |
| 3387 l_current_data += 2; | |
| 3388 | |
| 3389 opj_write_bytes(l_current_data, l_poc_size - 2, | |
| 3390 2); /* Lpoc */ | |
| 3391 l_current_data += 2; | |
| 3392 | |
| 3393 l_current_poc = l_tcp->pocs; | |
| 3394 for (i = 0; i < l_nb_poc; ++i) { | |
| 3395 opj_write_bytes(l_current_data, l_current_poc->resno0, | |
| 3396 1); /* RSpoc_i */ | |
| 3397 ++l_current_data; | |
| 3398 | |
| 3399 opj_write_bytes(l_current_data, l_current_poc->compno0, | |
| 3400 l_poc_room); /* CSpoc_i */ | |
| 3401 l_current_data += l_poc_room; | |
| 3402 | |
| 3403 opj_write_bytes(l_current_data, l_current_poc->layno1, | |
| 3404 2); /* LYEpoc_i */ | |
| 3405 l_current_data += 2; | |
| 3406 | |
| 3407 opj_write_bytes(l_current_data, l_current_poc->resno1, | |
| 3408 1); /* REpoc_i */ | |
| 3409 ++l_current_data; | |
| 3410 | |
| 3411 opj_write_bytes(l_current_data, l_current_poc->compno1, | |
| 3412 l_poc_room); /* CEpoc_i */ | |
| 3413 l_current_data += l_poc_room; | |
| 3414 | |
| 3415 opj_write_bytes(l_current_data, (OPJ_UINT32)l_current_poc->prg, | |
| 3416 1); /* Ppoc_i */ | |
| 3417 ++l_current_data; | |
| 3418 | |
| 3419 /* change the value of the max layer according to the actual number of layers in the file, components and resolutions*/ | |
| 3420 l_current_poc->layno1 = (OPJ_UINT32)opj_int_min((OPJ_INT32) | |
| 3421 l_current_poc->layno1, (OPJ_INT32)l_tcp->numlayers); | |
| 3422 l_current_poc->resno1 = (OPJ_UINT32)opj_int_min((OPJ_INT32) | |
| 3423 l_current_poc->resno1, (OPJ_INT32)l_tccp->numresolutions); | |
| 3424 l_current_poc->compno1 = (OPJ_UINT32)opj_int_min((OPJ_INT32) | |
| 3425 l_current_poc->compno1, (OPJ_INT32)l_nb_comp); | |
| 3426 | |
| 3427 ++l_current_poc; | |
| 3428 } | |
| 3429 | |
| 3430 *p_data_written = l_poc_size; | |
| 3431 } | |
| 3432 | |
| 3433 static OPJ_UINT32 opj_j2k_get_max_poc_size(opj_j2k_t *p_j2k) | |
| 3434 { | |
| 3435 opj_tcp_t * l_tcp = 00; | |
| 3436 OPJ_UINT32 l_nb_tiles = 0; | |
| 3437 OPJ_UINT32 l_max_poc = 0; | |
| 3438 OPJ_UINT32 i; | |
| 3439 | |
| 3440 l_tcp = p_j2k->m_cp.tcps; | |
| 3441 l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw; | |
| 3442 | |
| 3443 for (i = 0; i < l_nb_tiles; ++i) { | |
| 3444 l_max_poc = opj_uint_max(l_max_poc, l_tcp->numpocs); | |
| 3445 ++l_tcp; | |
| 3446 } | |
| 3447 | |
| 3448 ++l_max_poc; | |
| 3449 | |
| 3450 return 4 + 9 * l_max_poc; | |
| 3451 } | |
| 3452 | |
| 3453 static OPJ_UINT32 opj_j2k_get_max_toc_size(opj_j2k_t *p_j2k) | |
| 3454 { | |
| 3455 OPJ_UINT32 i; | |
| 3456 OPJ_UINT32 l_nb_tiles; | |
| 3457 OPJ_UINT32 l_max = 0; | |
| 3458 opj_tcp_t * l_tcp = 00; | |
| 3459 | |
| 3460 l_tcp = p_j2k->m_cp.tcps; | |
| 3461 l_nb_tiles = p_j2k->m_cp.tw * p_j2k->m_cp.th ; | |
| 3462 | |
| 3463 for (i = 0; i < l_nb_tiles; ++i) { | |
| 3464 l_max = opj_uint_max(l_max, l_tcp->m_nb_tile_parts); | |
| 3465 | |
| 3466 ++l_tcp; | |
| 3467 } | |
| 3468 | |
| 3469 return 12 * l_max; | |
| 3470 } | |
| 3471 | |
| 3472 static OPJ_UINT32 opj_j2k_get_specific_header_sizes(opj_j2k_t *p_j2k) | |
| 3473 { | |
| 3474 OPJ_UINT32 l_nb_bytes = 0; | |
| 3475 OPJ_UINT32 l_nb_comps; | |
| 3476 OPJ_UINT32 l_coc_bytes, l_qcc_bytes; | |
| 3477 | |
| 3478 l_nb_comps = p_j2k->m_private_image->numcomps - 1; | |
| 3479 l_nb_bytes += opj_j2k_get_max_toc_size(p_j2k); | |
| 3480 | |
| 3481 if (!(OPJ_IS_CINEMA(p_j2k->m_cp.rsiz))) { | |
| 3482 l_coc_bytes = opj_j2k_get_max_coc_size(p_j2k); | |
| 3483 l_nb_bytes += l_nb_comps * l_coc_bytes; | |
| 3484 | |
| 3485 l_qcc_bytes = opj_j2k_get_max_qcc_size(p_j2k); | |
| 3486 l_nb_bytes += l_nb_comps * l_qcc_bytes; | |
| 3487 } | |
| 3488 | |
| 3489 l_nb_bytes += opj_j2k_get_max_poc_size(p_j2k); | |
| 3490 | |
| 3491 if (p_j2k->m_specific_param.m_encoder.m_PLT) { | |
| 3492 /* Reserve space for PLT markers */ | |
| 3493 | |
| 3494 OPJ_UINT32 i; | |
| 3495 const opj_cp_t * l_cp = &(p_j2k->m_cp); | |
| 3496 OPJ_UINT32 l_max_packet_count = 0; | |
| 3497 for (i = 0; i < l_cp->th * l_cp->tw; ++i) { | |
| 3498 l_max_packet_count = opj_uint_max(l_max_packet_count, | |
| 3499 opj_get_encoding_packet_count(p_j2k->m_private_image, l_cp, i)); | |
| 3500 } | |
| 3501 /* Minimum 6 bytes per PLT marker, and at a minimum (taking a pessimistic */ | |
| 3502 /* estimate of 4 bytes for a packet size), one can write */ | |
| 3503 /* (65536-6) / 4 = 16382 paquet sizes per PLT marker */ | |
| 3504 p_j2k->m_specific_param.m_encoder.m_reserved_bytes_for_PLT = | |
| 3505 6 * opj_uint_ceildiv(l_max_packet_count, 16382); | |
| 3506 /* Maximum 5 bytes per packet to encode a full UINT32 */ | |
| 3507 p_j2k->m_specific_param.m_encoder.m_reserved_bytes_for_PLT += | |
| 3508 l_nb_bytes += 5 * l_max_packet_count; | |
| 3509 p_j2k->m_specific_param.m_encoder.m_reserved_bytes_for_PLT += 1; | |
| 3510 l_nb_bytes += p_j2k->m_specific_param.m_encoder.m_reserved_bytes_for_PLT; | |
| 3511 } | |
| 3512 | |
| 3513 /*** DEVELOPER CORNER, Add room for your headers ***/ | |
| 3514 | |
| 3515 return l_nb_bytes; | |
| 3516 } | |
| 3517 | |
| 3518 /** | |
| 3519 * Reads a POC marker (Progression Order Change) | |
| 3520 * | |
| 3521 * @param p_header_data the data contained in the POC box. | |
| 3522 * @param p_j2k the jpeg2000 codec. | |
| 3523 * @param p_header_size the size of the data contained in the POC marker. | |
| 3524 * @param p_manager the user event manager. | |
| 3525 */ | |
| 3526 static OPJ_BOOL opj_j2k_read_poc(opj_j2k_t *p_j2k, | |
| 3527 OPJ_BYTE * p_header_data, | |
| 3528 OPJ_UINT32 p_header_size, | |
| 3529 opj_event_mgr_t * p_manager | |
| 3530 ) | |
| 3531 { | |
| 3532 OPJ_UINT32 i, l_nb_comp, l_tmp; | |
| 3533 opj_image_t * l_image = 00; | |
| 3534 OPJ_UINT32 l_old_poc_nb, l_current_poc_nb, l_current_poc_remaining; | |
| 3535 OPJ_UINT32 l_chunk_size, l_comp_room; | |
| 3536 | |
| 3537 opj_cp_t *l_cp = 00; | |
| 3538 opj_tcp_t *l_tcp = 00; | |
| 3539 opj_poc_t *l_current_poc = 00; | |
| 3540 | |
| 3541 /* preconditions */ | |
| 3542 assert(p_header_data != 00); | |
| 3543 assert(p_j2k != 00); | |
| 3544 assert(p_manager != 00); | |
| 3545 | |
| 3546 l_image = p_j2k->m_private_image; | |
| 3547 l_nb_comp = l_image->numcomps; | |
| 3548 if (l_nb_comp <= 256) { | |
| 3549 l_comp_room = 1; | |
| 3550 } else { | |
| 3551 l_comp_room = 2; | |
| 3552 } | |
| 3553 l_chunk_size = 5 + 2 * l_comp_room; | |
| 3554 l_current_poc_nb = p_header_size / l_chunk_size; | |
| 3555 l_current_poc_remaining = p_header_size % l_chunk_size; | |
| 3556 | |
| 3557 if ((l_current_poc_nb <= 0) || (l_current_poc_remaining != 0)) { | |
| 3558 opj_event_msg(p_manager, EVT_ERROR, "Error reading POC marker\n"); | |
| 3559 return OPJ_FALSE; | |
| 3560 } | |
| 3561 | |
| 3562 l_cp = &(p_j2k->m_cp); | |
| 3563 l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH) ? | |
| 3564 &l_cp->tcps[p_j2k->m_current_tile_number] : | |
| 3565 p_j2k->m_specific_param.m_decoder.m_default_tcp; | |
| 3566 l_old_poc_nb = l_tcp->POC ? l_tcp->numpocs + 1 : 0; | |
| 3567 l_current_poc_nb += l_old_poc_nb; | |
| 3568 | |
| 3569 if (l_current_poc_nb >= J2K_MAX_POCS) { | |
| 3570 opj_event_msg(p_manager, EVT_ERROR, "Too many POCs %d\n", l_current_poc_nb); | |
| 3571 return OPJ_FALSE; | |
| 3572 } | |
| 3573 | |
| 3574 /* now poc is in use.*/ | |
| 3575 l_tcp->POC = 1; | |
| 3576 | |
| 3577 l_current_poc = &l_tcp->pocs[l_old_poc_nb]; | |
| 3578 for (i = l_old_poc_nb; i < l_current_poc_nb; ++i) { | |
| 3579 opj_read_bytes(p_header_data, &(l_current_poc->resno0), | |
| 3580 1); /* RSpoc_i */ | |
| 3581 ++p_header_data; | |
| 3582 opj_read_bytes(p_header_data, &(l_current_poc->compno0), | |
| 3583 l_comp_room); /* CSpoc_i */ | |
| 3584 p_header_data += l_comp_room; | |
| 3585 opj_read_bytes(p_header_data, &(l_current_poc->layno1), | |
| 3586 2); /* LYEpoc_i */ | |
| 3587 /* make sure layer end is in acceptable bounds */ | |
| 3588 l_current_poc->layno1 = opj_uint_min(l_current_poc->layno1, l_tcp->numlayers); | |
| 3589 p_header_data += 2; | |
| 3590 opj_read_bytes(p_header_data, &(l_current_poc->resno1), | |
| 3591 1); /* REpoc_i */ | |
| 3592 ++p_header_data; | |
| 3593 opj_read_bytes(p_header_data, &(l_current_poc->compno1), | |
| 3594 l_comp_room); /* CEpoc_i */ | |
| 3595 p_header_data += l_comp_room; | |
| 3596 opj_read_bytes(p_header_data, &l_tmp, | |
| 3597 1); /* Ppoc_i */ | |
| 3598 ++p_header_data; | |
| 3599 l_current_poc->prg = (OPJ_PROG_ORDER) l_tmp; | |
| 3600 /* make sure comp is in acceptable bounds */ | |
| 3601 l_current_poc->compno1 = opj_uint_min(l_current_poc->compno1, l_nb_comp); | |
| 3602 ++l_current_poc; | |
| 3603 } | |
| 3604 | |
| 3605 l_tcp->numpocs = l_current_poc_nb - 1; | |
| 3606 return OPJ_TRUE; | |
| 3607 } | |
| 3608 | |
| 3609 /** | |
| 3610 * Reads a CRG marker (Component registration) | |
| 3611 * | |
| 3612 * @param p_header_data the data contained in the TLM box. | |
| 3613 * @param p_j2k the jpeg2000 codec. | |
| 3614 * @param p_header_size the size of the data contained in the TLM marker. | |
| 3615 * @param p_manager the user event manager. | |
| 3616 */ | |
| 3617 static OPJ_BOOL opj_j2k_read_crg(opj_j2k_t *p_j2k, | |
| 3618 OPJ_BYTE * p_header_data, | |
| 3619 OPJ_UINT32 p_header_size, | |
| 3620 opj_event_mgr_t * p_manager | |
| 3621 ) | |
| 3622 { | |
| 3623 OPJ_UINT32 l_nb_comp; | |
| 3624 /* preconditions */ | |
| 3625 assert(p_header_data != 00); | |
| 3626 assert(p_j2k != 00); | |
| 3627 assert(p_manager != 00); | |
| 3628 | |
| 3629 OPJ_UNUSED(p_header_data); | |
| 3630 | |
| 3631 l_nb_comp = p_j2k->m_private_image->numcomps; | |
| 3632 | |
| 3633 if (p_header_size != l_nb_comp * 4) { | |
| 3634 opj_event_msg(p_manager, EVT_ERROR, "Error reading CRG marker\n"); | |
| 3635 return OPJ_FALSE; | |
| 3636 } | |
| 3637 /* Do not care of this at the moment since only local variables are set here */ | |
| 3638 /* | |
| 3639 for | |
| 3640 (i = 0; i < l_nb_comp; ++i) | |
| 3641 { | |
| 3642 opj_read_bytes(p_header_data,&l_Xcrg_i,2); // Xcrg_i | |
| 3643 p_header_data+=2; | |
| 3644 opj_read_bytes(p_header_data,&l_Ycrg_i,2); // Xcrg_i | |
| 3645 p_header_data+=2; | |
| 3646 } | |
| 3647 */ | |
| 3648 return OPJ_TRUE; | |
| 3649 } | |
| 3650 | |
| 3651 /** | |
| 3652 * Reads a TLM marker (Tile Length Marker) | |
| 3653 * | |
| 3654 * @param p_header_data the data contained in the TLM box. | |
| 3655 * @param p_j2k the jpeg2000 codec. | |
| 3656 * @param p_header_size the size of the data contained in the TLM marker. | |
| 3657 * @param p_manager the user event manager. | |
| 3658 */ | |
| 3659 static OPJ_BOOL opj_j2k_read_tlm(opj_j2k_t *p_j2k, | |
| 3660 OPJ_BYTE * p_header_data, | |
| 3661 OPJ_UINT32 p_header_size, | |
| 3662 opj_event_mgr_t * p_manager | |
| 3663 ) | |
| 3664 { | |
| 3665 OPJ_UINT32 l_Ztlm, l_Stlm, l_ST, l_SP, | |
| 3666 l_Ptlm_size, l_entry_size, l_num_tileparts; | |
| 3667 OPJ_UINT32 i; | |
| 3668 opj_j2k_tlm_tile_part_info_t* l_tile_part_infos; | |
| 3669 opj_j2k_tlm_info_t* l_tlm; | |
| 3670 | |
| 3671 /* preconditions */ | |
| 3672 assert(p_header_data != 00); | |
| 3673 assert(p_j2k != 00); | |
| 3674 assert(p_manager != 00); | |
| 3675 | |
| 3676 l_tlm = &(p_j2k->m_specific_param.m_decoder.m_tlm); | |
| 3677 | |
| 3678 if (p_header_size < 2) { | |
| 3679 opj_event_msg(p_manager, EVT_ERROR, "Error reading TLM marker.\n"); | |
| 3680 return OPJ_FALSE; | |
| 3681 } | |
| 3682 p_header_size -= 2; | |
| 3683 | |
| 3684 if (l_tlm->m_is_invalid) { | |
| 3685 return OPJ_TRUE; | |
| 3686 } | |
| 3687 | |
| 3688 opj_read_bytes(p_header_data, &l_Ztlm, | |
| 3689 1); /* Ztlm */ | |
| 3690 ++p_header_data; | |
| 3691 opj_read_bytes(p_header_data, &l_Stlm, | |
| 3692 1); /* Stlm */ | |
| 3693 ++p_header_data; | |
| 3694 | |
| 3695 l_ST = ((l_Stlm >> 4) & 0x3); | |
| 3696 if (l_ST == 3) { | |
| 3697 l_tlm->m_is_invalid = OPJ_TRUE; | |
| 3698 opj_event_msg(p_manager, EVT_WARNING, | |
| 3699 "opj_j2k_read_tlm(): ST = 3 is invalid.\n"); | |
| 3700 return OPJ_TRUE; | |
| 3701 } | |
| 3702 l_SP = (l_Stlm >> 6) & 0x1; | |
| 3703 | |
| 3704 l_Ptlm_size = (l_SP + 1) * 2; | |
| 3705 l_entry_size = l_Ptlm_size + l_ST; | |
| 3706 | |
| 3707 if ((p_header_size % l_entry_size) != 0) { | |
| 3708 l_tlm->m_is_invalid = OPJ_TRUE; | |
| 3709 opj_event_msg(p_manager, EVT_WARNING, | |
| 3710 "opj_j2k_read_tlm(): TLM marker not of expected size.\n"); | |
| 3711 return OPJ_TRUE; | |
| 3712 } | |
| 3713 | |
| 3714 l_num_tileparts = p_header_size / l_entry_size; | |
| 3715 if (l_num_tileparts == 0) { | |
| 3716 /* not totally sure if this is valid... */ | |
| 3717 return OPJ_TRUE; | |
| 3718 } | |
| 3719 | |
| 3720 /* Highly unlikely, unless there are gazillions of TLM markers */ | |
| 3721 if (l_tlm->m_entries_count > UINT32_MAX - l_num_tileparts || | |
| 3722 l_tlm->m_entries_count + l_num_tileparts > UINT32_MAX / sizeof( | |
| 3723 opj_j2k_tlm_tile_part_info_t)) { | |
| 3724 l_tlm->m_is_invalid = OPJ_TRUE; | |
| 3725 opj_event_msg(p_manager, EVT_WARNING, | |
| 3726 "opj_j2k_read_tlm(): too many TLM markers.\n"); | |
| 3727 return OPJ_TRUE; | |
| 3728 } | |
| 3729 | |
| 3730 l_tile_part_infos = (opj_j2k_tlm_tile_part_info_t*)opj_realloc( | |
| 3731 l_tlm->m_tile_part_infos, | |
| 3732 (l_tlm->m_entries_count + l_num_tileparts) * sizeof( | |
| 3733 opj_j2k_tlm_tile_part_info_t)); | |
| 3734 if (!l_tile_part_infos) { | |
| 3735 l_tlm->m_is_invalid = OPJ_TRUE; | |
| 3736 opj_event_msg(p_manager, EVT_WARNING, | |
| 3737 "opj_j2k_read_tlm(): cannot allocate m_tile_part_infos.\n"); | |
| 3738 return OPJ_TRUE; | |
| 3739 } | |
| 3740 | |
| 3741 l_tlm->m_tile_part_infos = l_tile_part_infos; | |
| 3742 | |
| 3743 for (i = 0; i < l_num_tileparts; ++ i) { | |
| 3744 OPJ_UINT32 l_tile_index; | |
| 3745 OPJ_UINT32 l_length; | |
| 3746 | |
| 3747 /* Read Ttlm_i */ | |
| 3748 if (l_ST == 0) { | |
| 3749 l_tile_index = l_tlm->m_entries_count; | |
| 3750 } else { | |
| 3751 opj_read_bytes(p_header_data, &l_tile_index, l_ST); | |
| 3752 p_header_data += l_ST; | |
| 3753 } | |
| 3754 | |
| 3755 if (l_tile_index >= p_j2k->m_cp.tw * p_j2k->m_cp.th) { | |
| 3756 l_tlm->m_is_invalid = OPJ_TRUE; | |
| 3757 opj_event_msg(p_manager, EVT_WARNING, | |
| 3758 "opj_j2k_read_tlm(): invalid tile number %d\n", | |
| 3759 l_tile_index); | |
| 3760 return OPJ_TRUE; | |
| 3761 } | |
| 3762 | |
| 3763 /* Read Ptlm_i */ | |
| 3764 opj_read_bytes(p_header_data, &l_length, l_Ptlm_size); | |
| 3765 p_header_data += l_Ptlm_size; | |
| 3766 | |
| 3767 l_tile_part_infos[l_tlm->m_entries_count].m_tile_index = | |
| 3768 (OPJ_UINT16)l_tile_index; | |
| 3769 l_tile_part_infos[l_tlm->m_entries_count].m_length = l_length; | |
| 3770 ++l_tlm->m_entries_count; | |
| 3771 } | |
| 3772 | |
| 3773 return OPJ_TRUE; | |
| 3774 } | |
| 3775 | |
| 3776 /** | |
| 3777 * Reads a PLM marker (Packet length, main header marker) | |
| 3778 * | |
| 3779 * @param p_header_data the data contained in the TLM box. | |
| 3780 * @param p_j2k the jpeg2000 codec. | |
| 3781 * @param p_header_size the size of the data contained in the TLM marker. | |
| 3782 * @param p_manager the user event manager. | |
| 3783 */ | |
| 3784 static OPJ_BOOL opj_j2k_read_plm(opj_j2k_t *p_j2k, | |
| 3785 OPJ_BYTE * p_header_data, | |
| 3786 OPJ_UINT32 p_header_size, | |
| 3787 opj_event_mgr_t * p_manager | |
| 3788 ) | |
| 3789 { | |
| 3790 /* preconditions */ | |
| 3791 assert(p_header_data != 00); | |
| 3792 assert(p_j2k != 00); | |
| 3793 assert(p_manager != 00); | |
| 3794 | |
| 3795 OPJ_UNUSED(p_j2k); | |
| 3796 OPJ_UNUSED(p_header_data); | |
| 3797 | |
| 3798 if (p_header_size < 1) { | |
| 3799 opj_event_msg(p_manager, EVT_ERROR, "Error reading PLM marker\n"); | |
| 3800 return OPJ_FALSE; | |
| 3801 } | |
| 3802 /* Do not care of this at the moment since only local variables are set here */ | |
| 3803 /* | |
| 3804 opj_read_bytes(p_header_data,&l_Zplm,1); // Zplm | |
| 3805 ++p_header_data; | |
| 3806 --p_header_size; | |
| 3807 | |
| 3808 while | |
| 3809 (p_header_size > 0) | |
| 3810 { | |
| 3811 opj_read_bytes(p_header_data,&l_Nplm,1); // Nplm | |
| 3812 ++p_header_data; | |
| 3813 p_header_size -= (1+l_Nplm); | |
| 3814 if | |
| 3815 (p_header_size < 0) | |
| 3816 { | |
| 3817 opj_event_msg(p_manager, EVT_ERROR, "Error reading PLM marker\n"); | |
| 3818 return false; | |
| 3819 } | |
| 3820 for | |
| 3821 (i = 0; i < l_Nplm; ++i) | |
| 3822 { | |
| 3823 opj_read_bytes(p_header_data,&l_tmp,1); // Iplm_ij | |
| 3824 ++p_header_data; | |
| 3825 // take only the last seven bytes | |
| 3826 l_packet_len |= (l_tmp & 0x7f); | |
| 3827 if | |
| 3828 (l_tmp & 0x80) | |
| 3829 { | |
| 3830 l_packet_len <<= 7; | |
| 3831 } | |
| 3832 else | |
| 3833 { | |
| 3834 // store packet length and proceed to next packet | |
| 3835 l_packet_len = 0; | |
| 3836 } | |
| 3837 } | |
| 3838 if | |
| 3839 (l_packet_len != 0) | |
| 3840 { | |
| 3841 opj_event_msg(p_manager, EVT_ERROR, "Error reading PLM marker\n"); | |
| 3842 return false; | |
| 3843 } | |
| 3844 } | |
| 3845 */ | |
| 3846 return OPJ_TRUE; | |
| 3847 } | |
| 3848 | |
| 3849 /** | |
| 3850 * Reads a PLT marker (Packet length, tile-part header) | |
| 3851 * | |
| 3852 * @param p_header_data the data contained in the PLT box. | |
| 3853 * @param p_j2k the jpeg2000 codec. | |
| 3854 * @param p_header_size the size of the data contained in the PLT marker. | |
| 3855 * @param p_manager the user event manager. | |
| 3856 */ | |
| 3857 static OPJ_BOOL opj_j2k_read_plt(opj_j2k_t *p_j2k, | |
| 3858 OPJ_BYTE * p_header_data, | |
| 3859 OPJ_UINT32 p_header_size, | |
| 3860 opj_event_mgr_t * p_manager | |
| 3861 ) | |
| 3862 { | |
| 3863 OPJ_UINT32 l_Zplt, l_tmp, l_packet_len = 0, i; | |
| 3864 | |
| 3865 /* preconditions */ | |
| 3866 assert(p_header_data != 00); | |
| 3867 assert(p_j2k != 00); | |
| 3868 assert(p_manager != 00); | |
| 3869 | |
| 3870 OPJ_UNUSED(p_j2k); | |
| 3871 | |
| 3872 if (p_header_size < 1) { | |
| 3873 opj_event_msg(p_manager, EVT_ERROR, "Error reading PLT marker\n"); | |
| 3874 return OPJ_FALSE; | |
| 3875 } | |
| 3876 | |
| 3877 opj_read_bytes(p_header_data, &l_Zplt, 1); /* Zplt */ | |
| 3878 ++p_header_data; | |
| 3879 --p_header_size; | |
| 3880 | |
| 3881 for (i = 0; i < p_header_size; ++i) { | |
| 3882 opj_read_bytes(p_header_data, &l_tmp, 1); /* Iplt_ij */ | |
| 3883 ++p_header_data; | |
| 3884 /* take only the last seven bytes */ | |
| 3885 l_packet_len |= (l_tmp & 0x7f); | |
| 3886 if (l_tmp & 0x80) { | |
| 3887 l_packet_len <<= 7; | |
| 3888 } else { | |
| 3889 /* store packet length and proceed to next packet */ | |
| 3890 l_packet_len = 0; | |
| 3891 } | |
| 3892 } | |
| 3893 | |
| 3894 if (l_packet_len != 0) { | |
| 3895 opj_event_msg(p_manager, EVT_ERROR, "Error reading PLT marker\n"); | |
| 3896 return OPJ_FALSE; | |
| 3897 } | |
| 3898 | |
| 3899 return OPJ_TRUE; | |
| 3900 } | |
| 3901 | |
| 3902 /** | |
| 3903 * Reads a PPM marker (Packed packet headers, main header) | |
| 3904 * | |
| 3905 * @param p_header_data the data contained in the POC box. | |
| 3906 * @param p_j2k the jpeg2000 codec. | |
| 3907 * @param p_header_size the size of the data contained in the POC marker. | |
| 3908 * @param p_manager the user event manager. | |
| 3909 */ | |
| 3910 | |
| 3911 static OPJ_BOOL opj_j2k_read_ppm( | |
| 3912 opj_j2k_t *p_j2k, | |
| 3913 OPJ_BYTE * p_header_data, | |
| 3914 OPJ_UINT32 p_header_size, | |
| 3915 opj_event_mgr_t * p_manager) | |
| 3916 { | |
| 3917 opj_cp_t *l_cp = 00; | |
| 3918 OPJ_UINT32 l_Z_ppm; | |
| 3919 | |
| 3920 /* preconditions */ | |
| 3921 assert(p_header_data != 00); | |
| 3922 assert(p_j2k != 00); | |
| 3923 assert(p_manager != 00); | |
| 3924 | |
| 3925 /* We need to have the Z_ppm element + 1 byte of Nppm/Ippm at minimum */ | |
| 3926 if (p_header_size < 2) { | |
| 3927 opj_event_msg(p_manager, EVT_ERROR, "Error reading PPM marker\n"); | |
| 3928 return OPJ_FALSE; | |
| 3929 } | |
| 3930 | |
| 3931 l_cp = &(p_j2k->m_cp); | |
| 3932 l_cp->ppm = 1; | |
| 3933 | |
| 3934 opj_read_bytes(p_header_data, &l_Z_ppm, 1); /* Z_ppm */ | |
| 3935 ++p_header_data; | |
| 3936 --p_header_size; | |
| 3937 | |
| 3938 /* check allocation needed */ | |
| 3939 if (l_cp->ppm_markers == NULL) { /* first PPM marker */ | |
| 3940 OPJ_UINT32 l_newCount = l_Z_ppm + 1U; /* can't overflow, l_Z_ppm is UINT8 */ | |
| 3941 assert(l_cp->ppm_markers_count == 0U); | |
| 3942 | |
| 3943 l_cp->ppm_markers = (opj_ppx *) opj_calloc(l_newCount, sizeof(opj_ppx)); | |
| 3944 if (l_cp->ppm_markers == NULL) { | |
| 3945 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPM marker\n"); | |
| 3946 return OPJ_FALSE; | |
| 3947 } | |
| 3948 l_cp->ppm_markers_count = l_newCount; | |
| 3949 } else if (l_cp->ppm_markers_count <= l_Z_ppm) { | |
| 3950 OPJ_UINT32 l_newCount = l_Z_ppm + 1U; /* can't overflow, l_Z_ppm is UINT8 */ | |
| 3951 opj_ppx *new_ppm_markers; | |
| 3952 new_ppm_markers = (opj_ppx *) opj_realloc(l_cp->ppm_markers, | |
| 3953 l_newCount * sizeof(opj_ppx)); | |
| 3954 if (new_ppm_markers == NULL) { | |
| 3955 /* clean up to be done on l_cp destruction */ | |
| 3956 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPM marker\n"); | |
| 3957 return OPJ_FALSE; | |
| 3958 } | |
| 3959 l_cp->ppm_markers = new_ppm_markers; | |
| 3960 memset(l_cp->ppm_markers + l_cp->ppm_markers_count, 0, | |
| 3961 (l_newCount - l_cp->ppm_markers_count) * sizeof(opj_ppx)); | |
| 3962 l_cp->ppm_markers_count = l_newCount; | |
| 3963 } | |
| 3964 | |
| 3965 if (l_cp->ppm_markers[l_Z_ppm].m_data != NULL) { | |
| 3966 /* clean up to be done on l_cp destruction */ | |
| 3967 opj_event_msg(p_manager, EVT_ERROR, "Zppm %u already read\n", l_Z_ppm); | |
| 3968 return OPJ_FALSE; | |
| 3969 } | |
| 3970 | |
| 3971 l_cp->ppm_markers[l_Z_ppm].m_data = (OPJ_BYTE *) opj_malloc(p_header_size); | |
| 3972 if (l_cp->ppm_markers[l_Z_ppm].m_data == NULL) { | |
| 3973 /* clean up to be done on l_cp destruction */ | |
| 3974 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPM marker\n"); | |
| 3975 return OPJ_FALSE; | |
| 3976 } | |
| 3977 l_cp->ppm_markers[l_Z_ppm].m_data_size = p_header_size; | |
| 3978 memcpy(l_cp->ppm_markers[l_Z_ppm].m_data, p_header_data, p_header_size); | |
| 3979 | |
| 3980 return OPJ_TRUE; | |
| 3981 } | |
| 3982 | |
| 3983 /** | |
| 3984 * Merges all PPM markers read (Packed headers, main header) | |
| 3985 * | |
| 3986 * @param p_cp main coding parameters. | |
| 3987 * @param p_manager the user event manager. | |
| 3988 */ | |
| 3989 static OPJ_BOOL opj_j2k_merge_ppm(opj_cp_t *p_cp, opj_event_mgr_t * p_manager) | |
| 3990 { | |
| 3991 OPJ_UINT32 i, l_ppm_data_size, l_N_ppm_remaining; | |
| 3992 | |
| 3993 /* preconditions */ | |
| 3994 assert(p_cp != 00); | |
| 3995 assert(p_manager != 00); | |
| 3996 assert(p_cp->ppm_buffer == NULL); | |
| 3997 | |
| 3998 if (p_cp->ppm == 0U) { | |
| 3999 return OPJ_TRUE; | |
| 4000 } | |
| 4001 | |
| 4002 l_ppm_data_size = 0U; | |
| 4003 l_N_ppm_remaining = 0U; | |
| 4004 for (i = 0U; i < p_cp->ppm_markers_count; ++i) { | |
| 4005 if (p_cp->ppm_markers[i].m_data != | |
| 4006 NULL) { /* standard doesn't seem to require contiguous Zppm */ | |
| 4007 OPJ_UINT32 l_N_ppm; | |
| 4008 OPJ_UINT32 l_data_size = p_cp->ppm_markers[i].m_data_size; | |
| 4009 const OPJ_BYTE* l_data = p_cp->ppm_markers[i].m_data; | |
| 4010 | |
| 4011 if (l_N_ppm_remaining >= l_data_size) { | |
| 4012 l_N_ppm_remaining -= l_data_size; | |
| 4013 l_data_size = 0U; | |
| 4014 } else { | |
| 4015 l_data += l_N_ppm_remaining; | |
| 4016 l_data_size -= l_N_ppm_remaining; | |
| 4017 l_N_ppm_remaining = 0U; | |
| 4018 } | |
| 4019 | |
| 4020 if (l_data_size > 0U) { | |
| 4021 do { | |
| 4022 /* read Nppm */ | |
| 4023 if (l_data_size < 4U) { | |
| 4024 /* clean up to be done on l_cp destruction */ | |
| 4025 opj_event_msg(p_manager, EVT_ERROR, "Not enough bytes to read Nppm\n"); | |
| 4026 return OPJ_FALSE; | |
| 4027 } | |
| 4028 opj_read_bytes(l_data, &l_N_ppm, 4); | |
| 4029 l_data += 4; | |
| 4030 l_data_size -= 4; | |
| 4031 | |
| 4032 if (l_ppm_data_size > UINT_MAX - l_N_ppm) { | |
| 4033 opj_event_msg(p_manager, EVT_ERROR, "Too large value for Nppm\n"); | |
| 4034 return OPJ_FALSE; | |
| 4035 } | |
| 4036 l_ppm_data_size += l_N_ppm; | |
| 4037 if (l_data_size >= l_N_ppm) { | |
| 4038 l_data_size -= l_N_ppm; | |
| 4039 l_data += l_N_ppm; | |
| 4040 } else { | |
| 4041 l_N_ppm_remaining = l_N_ppm - l_data_size; | |
| 4042 l_data_size = 0U; | |
| 4043 } | |
| 4044 } while (l_data_size > 0U); | |
| 4045 } | |
| 4046 } | |
| 4047 } | |
| 4048 | |
| 4049 if (l_N_ppm_remaining != 0U) { | |
| 4050 /* clean up to be done on l_cp destruction */ | |
| 4051 opj_event_msg(p_manager, EVT_ERROR, "Corrupted PPM markers\n"); | |
| 4052 return OPJ_FALSE; | |
| 4053 } | |
| 4054 | |
| 4055 p_cp->ppm_buffer = (OPJ_BYTE *) opj_malloc(l_ppm_data_size); | |
| 4056 if (p_cp->ppm_buffer == 00) { | |
| 4057 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPM marker\n"); | |
| 4058 return OPJ_FALSE; | |
| 4059 } | |
| 4060 p_cp->ppm_len = l_ppm_data_size; | |
| 4061 l_ppm_data_size = 0U; | |
| 4062 l_N_ppm_remaining = 0U; | |
| 4063 for (i = 0U; i < p_cp->ppm_markers_count; ++i) { | |
| 4064 if (p_cp->ppm_markers[i].m_data != | |
| 4065 NULL) { /* standard doesn't seem to require contiguous Zppm */ | |
| 4066 OPJ_UINT32 l_N_ppm; | |
| 4067 OPJ_UINT32 l_data_size = p_cp->ppm_markers[i].m_data_size; | |
| 4068 const OPJ_BYTE* l_data = p_cp->ppm_markers[i].m_data; | |
| 4069 | |
| 4070 if (l_N_ppm_remaining >= l_data_size) { | |
| 4071 memcpy(p_cp->ppm_buffer + l_ppm_data_size, l_data, l_data_size); | |
| 4072 l_ppm_data_size += l_data_size; | |
| 4073 l_N_ppm_remaining -= l_data_size; | |
| 4074 l_data_size = 0U; | |
| 4075 } else { | |
| 4076 memcpy(p_cp->ppm_buffer + l_ppm_data_size, l_data, l_N_ppm_remaining); | |
| 4077 l_ppm_data_size += l_N_ppm_remaining; | |
| 4078 l_data += l_N_ppm_remaining; | |
| 4079 l_data_size -= l_N_ppm_remaining; | |
| 4080 l_N_ppm_remaining = 0U; | |
| 4081 } | |
| 4082 | |
| 4083 if (l_data_size > 0U) { | |
| 4084 do { | |
| 4085 /* read Nppm */ | |
| 4086 if (l_data_size < 4U) { | |
| 4087 /* clean up to be done on l_cp destruction */ | |
| 4088 opj_event_msg(p_manager, EVT_ERROR, "Not enough bytes to read Nppm\n"); | |
| 4089 return OPJ_FALSE; | |
| 4090 } | |
| 4091 opj_read_bytes(l_data, &l_N_ppm, 4); | |
| 4092 l_data += 4; | |
| 4093 l_data_size -= 4; | |
| 4094 | |
| 4095 if (l_data_size >= l_N_ppm) { | |
| 4096 memcpy(p_cp->ppm_buffer + l_ppm_data_size, l_data, l_N_ppm); | |
| 4097 l_ppm_data_size += l_N_ppm; | |
| 4098 l_data_size -= l_N_ppm; | |
| 4099 l_data += l_N_ppm; | |
| 4100 } else { | |
| 4101 memcpy(p_cp->ppm_buffer + l_ppm_data_size, l_data, l_data_size); | |
| 4102 l_ppm_data_size += l_data_size; | |
| 4103 l_N_ppm_remaining = l_N_ppm - l_data_size; | |
| 4104 l_data_size = 0U; | |
| 4105 } | |
| 4106 } while (l_data_size > 0U); | |
| 4107 } | |
| 4108 opj_free(p_cp->ppm_markers[i].m_data); | |
| 4109 p_cp->ppm_markers[i].m_data = NULL; | |
| 4110 p_cp->ppm_markers[i].m_data_size = 0U; | |
| 4111 } | |
| 4112 } | |
| 4113 | |
| 4114 p_cp->ppm_data = p_cp->ppm_buffer; | |
| 4115 p_cp->ppm_data_size = p_cp->ppm_len; | |
| 4116 | |
| 4117 p_cp->ppm_markers_count = 0U; | |
| 4118 opj_free(p_cp->ppm_markers); | |
| 4119 p_cp->ppm_markers = NULL; | |
| 4120 | |
| 4121 return OPJ_TRUE; | |
| 4122 } | |
| 4123 | |
| 4124 /** | |
| 4125 * Reads a PPT marker (Packed packet headers, tile-part header) | |
| 4126 * | |
| 4127 * @param p_header_data the data contained in the PPT box. | |
| 4128 * @param p_j2k the jpeg2000 codec. | |
| 4129 * @param p_header_size the size of the data contained in the PPT marker. | |
| 4130 * @param p_manager the user event manager. | |
| 4131 */ | |
| 4132 static OPJ_BOOL opj_j2k_read_ppt(opj_j2k_t *p_j2k, | |
| 4133 OPJ_BYTE * p_header_data, | |
| 4134 OPJ_UINT32 p_header_size, | |
| 4135 opj_event_mgr_t * p_manager | |
| 4136 ) | |
| 4137 { | |
| 4138 opj_cp_t *l_cp = 00; | |
| 4139 opj_tcp_t *l_tcp = 00; | |
| 4140 OPJ_UINT32 l_Z_ppt; | |
| 4141 | |
| 4142 /* preconditions */ | |
| 4143 assert(p_header_data != 00); | |
| 4144 assert(p_j2k != 00); | |
| 4145 assert(p_manager != 00); | |
| 4146 | |
| 4147 /* We need to have the Z_ppt element + 1 byte of Ippt at minimum */ | |
| 4148 if (p_header_size < 2) { | |
| 4149 opj_event_msg(p_manager, EVT_ERROR, "Error reading PPT marker\n"); | |
| 4150 return OPJ_FALSE; | |
| 4151 } | |
| 4152 | |
| 4153 l_cp = &(p_j2k->m_cp); | |
| 4154 if (l_cp->ppm) { | |
| 4155 opj_event_msg(p_manager, EVT_ERROR, | |
| 4156 "Error reading PPT marker: packet header have been previously found in the main header (PPM marker).\n"); | |
| 4157 return OPJ_FALSE; | |
| 4158 } | |
| 4159 | |
| 4160 l_tcp = &(l_cp->tcps[p_j2k->m_current_tile_number]); | |
| 4161 l_tcp->ppt = 1; | |
| 4162 | |
| 4163 opj_read_bytes(p_header_data, &l_Z_ppt, 1); /* Z_ppt */ | |
| 4164 ++p_header_data; | |
| 4165 --p_header_size; | |
| 4166 | |
| 4167 /* check allocation needed */ | |
| 4168 if (l_tcp->ppt_markers == NULL) { /* first PPT marker */ | |
| 4169 OPJ_UINT32 l_newCount = l_Z_ppt + 1U; /* can't overflow, l_Z_ppt is UINT8 */ | |
| 4170 assert(l_tcp->ppt_markers_count == 0U); | |
| 4171 | |
| 4172 l_tcp->ppt_markers = (opj_ppx *) opj_calloc(l_newCount, sizeof(opj_ppx)); | |
| 4173 if (l_tcp->ppt_markers == NULL) { | |
| 4174 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n"); | |
| 4175 return OPJ_FALSE; | |
| 4176 } | |
| 4177 l_tcp->ppt_markers_count = l_newCount; | |
| 4178 } else if (l_tcp->ppt_markers_count <= l_Z_ppt) { | |
| 4179 OPJ_UINT32 l_newCount = l_Z_ppt + 1U; /* can't overflow, l_Z_ppt is UINT8 */ | |
| 4180 opj_ppx *new_ppt_markers; | |
| 4181 new_ppt_markers = (opj_ppx *) opj_realloc(l_tcp->ppt_markers, | |
| 4182 l_newCount * sizeof(opj_ppx)); | |
| 4183 if (new_ppt_markers == NULL) { | |
| 4184 /* clean up to be done on l_tcp destruction */ | |
| 4185 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n"); | |
| 4186 return OPJ_FALSE; | |
| 4187 } | |
| 4188 l_tcp->ppt_markers = new_ppt_markers; | |
| 4189 memset(l_tcp->ppt_markers + l_tcp->ppt_markers_count, 0, | |
| 4190 (l_newCount - l_tcp->ppt_markers_count) * sizeof(opj_ppx)); | |
| 4191 l_tcp->ppt_markers_count = l_newCount; | |
| 4192 } | |
| 4193 | |
| 4194 if (l_tcp->ppt_markers[l_Z_ppt].m_data != NULL) { | |
| 4195 /* clean up to be done on l_tcp destruction */ | |
| 4196 opj_event_msg(p_manager, EVT_ERROR, "Zppt %u already read\n", l_Z_ppt); | |
| 4197 return OPJ_FALSE; | |
| 4198 } | |
| 4199 | |
| 4200 l_tcp->ppt_markers[l_Z_ppt].m_data = (OPJ_BYTE *) opj_malloc(p_header_size); | |
| 4201 if (l_tcp->ppt_markers[l_Z_ppt].m_data == NULL) { | |
| 4202 /* clean up to be done on l_tcp destruction */ | |
| 4203 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n"); | |
| 4204 return OPJ_FALSE; | |
| 4205 } | |
| 4206 l_tcp->ppt_markers[l_Z_ppt].m_data_size = p_header_size; | |
| 4207 memcpy(l_tcp->ppt_markers[l_Z_ppt].m_data, p_header_data, p_header_size); | |
| 4208 return OPJ_TRUE; | |
| 4209 } | |
| 4210 | |
| 4211 /** | |
| 4212 * Merges all PPT markers read (Packed packet headers, tile-part header) | |
| 4213 * | |
| 4214 * @param p_tcp the tile. | |
| 4215 * @param p_manager the user event manager. | |
| 4216 */ | |
| 4217 static OPJ_BOOL opj_j2k_merge_ppt(opj_tcp_t *p_tcp, opj_event_mgr_t * p_manager) | |
| 4218 { | |
| 4219 OPJ_UINT32 i, l_ppt_data_size; | |
| 4220 /* preconditions */ | |
| 4221 assert(p_tcp != 00); | |
| 4222 assert(p_manager != 00); | |
| 4223 | |
| 4224 if (p_tcp->ppt_buffer != NULL) { | |
| 4225 opj_event_msg(p_manager, EVT_ERROR, | |
| 4226 "opj_j2k_merge_ppt() has already been called\n"); | |
| 4227 return OPJ_FALSE; | |
| 4228 } | |
| 4229 | |
| 4230 if (p_tcp->ppt == 0U) { | |
| 4231 return OPJ_TRUE; | |
| 4232 } | |
| 4233 | |
| 4234 l_ppt_data_size = 0U; | |
| 4235 for (i = 0U; i < p_tcp->ppt_markers_count; ++i) { | |
| 4236 l_ppt_data_size += | |
| 4237 p_tcp->ppt_markers[i].m_data_size; /* can't overflow, max 256 markers of max 65536 bytes */ | |
| 4238 } | |
| 4239 | |
| 4240 p_tcp->ppt_buffer = (OPJ_BYTE *) opj_malloc(l_ppt_data_size); | |
| 4241 if (p_tcp->ppt_buffer == 00) { | |
| 4242 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n"); | |
| 4243 return OPJ_FALSE; | |
| 4244 } | |
| 4245 p_tcp->ppt_len = l_ppt_data_size; | |
| 4246 l_ppt_data_size = 0U; | |
| 4247 for (i = 0U; i < p_tcp->ppt_markers_count; ++i) { | |
| 4248 if (p_tcp->ppt_markers[i].m_data != | |
| 4249 NULL) { /* standard doesn't seem to require contiguous Zppt */ | |
| 4250 memcpy(p_tcp->ppt_buffer + l_ppt_data_size, p_tcp->ppt_markers[i].m_data, | |
| 4251 p_tcp->ppt_markers[i].m_data_size); | |
| 4252 l_ppt_data_size += | |
| 4253 p_tcp->ppt_markers[i].m_data_size; /* can't overflow, max 256 markers of max 65536 bytes */ | |
| 4254 | |
| 4255 opj_free(p_tcp->ppt_markers[i].m_data); | |
| 4256 p_tcp->ppt_markers[i].m_data = NULL; | |
| 4257 p_tcp->ppt_markers[i].m_data_size = 0U; | |
| 4258 } | |
| 4259 } | |
| 4260 | |
| 4261 p_tcp->ppt_markers_count = 0U; | |
| 4262 opj_free(p_tcp->ppt_markers); | |
| 4263 p_tcp->ppt_markers = NULL; | |
| 4264 | |
| 4265 p_tcp->ppt_data = p_tcp->ppt_buffer; | |
| 4266 p_tcp->ppt_data_size = p_tcp->ppt_len; | |
| 4267 return OPJ_TRUE; | |
| 4268 } | |
| 4269 | |
| 4270 static OPJ_BOOL opj_j2k_write_tlm(opj_j2k_t *p_j2k, | |
| 4271 opj_stream_private_t *p_stream, | |
| 4272 opj_event_mgr_t * p_manager | |
| 4273 ) | |
| 4274 { | |
| 4275 OPJ_BYTE * l_current_data = 00; | |
| 4276 OPJ_UINT32 l_tlm_size; | |
| 4277 OPJ_UINT32 size_per_tile_part; | |
| 4278 | |
| 4279 /* preconditions */ | |
| 4280 assert(p_j2k != 00); | |
| 4281 assert(p_manager != 00); | |
| 4282 assert(p_stream != 00); | |
| 4283 | |
| 4284 /* 10921 = (65535 - header_size) / size_per_tile_part where */ | |
| 4285 /* header_size = 4 and size_per_tile_part = 6 */ | |
| 4286 if (p_j2k->m_specific_param.m_encoder.m_total_tile_parts > 10921) { | |
| 4287 /* We could do more but it would require writing several TLM markers */ | |
| 4288 opj_event_msg(p_manager, EVT_ERROR, | |
| 4289 "A maximum of 10921 tile-parts are supported currently " | |
| 4290 "when writing TLM marker\n"); | |
| 4291 return OPJ_FALSE; | |
| 4292 } | |
| 4293 | |
| 4294 if (p_j2k->m_specific_param.m_encoder.m_total_tile_parts <= 255) { | |
| 4295 size_per_tile_part = 5; | |
| 4296 p_j2k->m_specific_param.m_encoder.m_Ttlmi_is_byte = OPJ_TRUE; | |
| 4297 } else { | |
| 4298 size_per_tile_part = 6; | |
| 4299 p_j2k->m_specific_param.m_encoder.m_Ttlmi_is_byte = OPJ_FALSE; | |
| 4300 } | |
| 4301 | |
| 4302 l_tlm_size = 2 + 4 + (size_per_tile_part * | |
| 4303 p_j2k->m_specific_param.m_encoder.m_total_tile_parts); | |
| 4304 | |
| 4305 if (l_tlm_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) { | |
| 4306 OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc( | |
| 4307 p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_tlm_size); | |
| 4308 if (! new_header_tile_data) { | |
| 4309 opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data); | |
| 4310 p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL; | |
| 4311 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0; | |
| 4312 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write TLM marker\n"); | |
| 4313 return OPJ_FALSE; | |
| 4314 } | |
| 4315 p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data; | |
| 4316 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_tlm_size; | |
| 4317 } | |
| 4318 memset(p_j2k->m_specific_param.m_encoder.m_header_tile_data, 0, l_tlm_size); | |
| 4319 | |
| 4320 l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data; | |
| 4321 | |
| 4322 /* change the way data is written to avoid seeking if possible */ | |
| 4323 /* TODO */ | |
| 4324 p_j2k->m_specific_param.m_encoder.m_tlm_start = opj_stream_tell(p_stream); | |
| 4325 | |
| 4326 opj_write_bytes(l_current_data, J2K_MS_TLM, | |
| 4327 2); /* TLM */ | |
| 4328 l_current_data += 2; | |
| 4329 | |
| 4330 opj_write_bytes(l_current_data, l_tlm_size - 2, | |
| 4331 2); /* Lpoc */ | |
| 4332 l_current_data += 2; | |
| 4333 | |
| 4334 opj_write_bytes(l_current_data, 0, | |
| 4335 1); /* Ztlm=0*/ | |
| 4336 ++l_current_data; | |
| 4337 | |
| 4338 /* Stlm 0x50= ST=1(8bits-255 tiles max),SP=1(Ptlm=32bits) */ | |
| 4339 /* Stlm 0x60= ST=2(16bits-65535 tiles max),SP=1(Ptlm=32bits) */ | |
| 4340 opj_write_bytes(l_current_data, | |
| 4341 size_per_tile_part == 5 ? 0x50 : 0x60, | |
| 4342 1); | |
| 4343 ++l_current_data; | |
| 4344 | |
| 4345 /* do nothing on the size_per_tile_part * l_j2k->m_specific_param.m_encoder.m_total_tile_parts remaining data */ | |
| 4346 if (opj_stream_write_data(p_stream, | |
| 4347 p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_tlm_size, | |
| 4348 p_manager) != l_tlm_size) { | |
| 4349 return OPJ_FALSE; | |
| 4350 } | |
| 4351 | |
| 4352 return OPJ_TRUE; | |
| 4353 } | |
| 4354 | |
| 4355 static OPJ_BOOL opj_j2k_write_sot(opj_j2k_t *p_j2k, | |
| 4356 OPJ_BYTE * p_data, | |
| 4357 OPJ_UINT32 total_data_size, | |
| 4358 OPJ_UINT32 * p_data_written, | |
| 4359 const opj_stream_private_t *p_stream, | |
| 4360 opj_event_mgr_t * p_manager | |
| 4361 ) | |
| 4362 { | |
| 4363 /* preconditions */ | |
| 4364 assert(p_j2k != 00); | |
| 4365 assert(p_manager != 00); | |
| 4366 assert(p_stream != 00); | |
| 4367 | |
| 4368 OPJ_UNUSED(p_stream); | |
| 4369 | |
| 4370 if (total_data_size < 12) { | |
| 4371 opj_event_msg(p_manager, EVT_ERROR, | |
| 4372 "Not enough bytes in output buffer to write SOT marker\n"); | |
| 4373 return OPJ_FALSE; | |
| 4374 } | |
| 4375 | |
| 4376 opj_write_bytes(p_data, J2K_MS_SOT, | |
| 4377 2); /* SOT */ | |
| 4378 p_data += 2; | |
| 4379 | |
| 4380 opj_write_bytes(p_data, 10, | |
| 4381 2); /* Lsot */ | |
| 4382 p_data += 2; | |
| 4383 | |
| 4384 opj_write_bytes(p_data, p_j2k->m_current_tile_number, | |
| 4385 2); /* Isot */ | |
| 4386 p_data += 2; | |
| 4387 | |
| 4388 /* Psot */ | |
| 4389 p_data += 4; | |
| 4390 | |
| 4391 opj_write_bytes(p_data, | |
| 4392 p_j2k->m_specific_param.m_encoder.m_current_tile_part_number, | |
| 4393 1); /* TPsot */ | |
| 4394 ++p_data; | |
| 4395 | |
| 4396 opj_write_bytes(p_data, | |
| 4397 p_j2k->m_cp.tcps[p_j2k->m_current_tile_number].m_nb_tile_parts, | |
| 4398 1); /* TNsot */ | |
| 4399 ++p_data; | |
| 4400 | |
| 4401 /* UniPG>> */ | |
| 4402 #ifdef USE_JPWL | |
| 4403 /* update markers struct */ | |
| 4404 /* | |
| 4405 OPJ_BOOL res = j2k_add_marker(p_j2k->cstr_info, J2K_MS_SOT, p_j2k->sot_start, len + 2); | |
| 4406 */ | |
| 4407 assert(0 && "TODO"); | |
| 4408 #endif /* USE_JPWL */ | |
| 4409 | |
| 4410 * p_data_written = 12; | |
| 4411 | |
| 4412 return OPJ_TRUE; | |
| 4413 } | |
| 4414 | |
| 4415 static OPJ_BOOL opj_j2k_get_sot_values(OPJ_BYTE * p_header_data, | |
| 4416 OPJ_UINT32 p_header_size, | |
| 4417 OPJ_UINT32* p_tile_no, | |
| 4418 OPJ_UINT32* p_tot_len, | |
| 4419 OPJ_UINT32* p_current_part, | |
| 4420 OPJ_UINT32* p_num_parts, | |
| 4421 opj_event_mgr_t * p_manager) | |
| 4422 { | |
| 4423 /* preconditions */ | |
| 4424 assert(p_header_data != 00); | |
| 4425 assert(p_manager != 00); | |
| 4426 | |
| 4427 /* Size of this marker is fixed = 12 (we have already read marker and its size)*/ | |
| 4428 if (p_header_size != 8) { | |
| 4429 opj_event_msg(p_manager, EVT_ERROR, "Error reading SOT marker\n"); | |
| 4430 return OPJ_FALSE; | |
| 4431 } | |
| 4432 | |
| 4433 opj_read_bytes(p_header_data, p_tile_no, 2); /* Isot */ | |
| 4434 p_header_data += 2; | |
| 4435 opj_read_bytes(p_header_data, p_tot_len, 4); /* Psot */ | |
| 4436 p_header_data += 4; | |
| 4437 opj_read_bytes(p_header_data, p_current_part, 1); /* TPsot */ | |
| 4438 ++p_header_data; | |
| 4439 opj_read_bytes(p_header_data, p_num_parts, 1); /* TNsot */ | |
| 4440 ++p_header_data; | |
| 4441 return OPJ_TRUE; | |
| 4442 } | |
| 4443 | |
| 4444 static OPJ_BOOL opj_j2k_read_sot(opj_j2k_t *p_j2k, | |
| 4445 OPJ_BYTE * p_header_data, | |
| 4446 OPJ_UINT32 p_header_size, | |
| 4447 opj_event_mgr_t * p_manager) | |
| 4448 { | |
| 4449 opj_cp_t *l_cp = 00; | |
| 4450 opj_tcp_t *l_tcp = 00; | |
| 4451 OPJ_UINT32 l_tot_len, l_num_parts = 0; | |
| 4452 OPJ_UINT32 l_current_part; | |
| 4453 OPJ_UINT32 l_tile_x, l_tile_y; | |
| 4454 | |
| 4455 /* preconditions */ | |
| 4456 | |
| 4457 assert(p_j2k != 00); | |
| 4458 assert(p_manager != 00); | |
| 4459 | |
| 4460 if (! opj_j2k_get_sot_values(p_header_data, p_header_size, | |
| 4461 &(p_j2k->m_current_tile_number), &l_tot_len, &l_current_part, &l_num_parts, | |
| 4462 p_manager)) { | |
| 4463 opj_event_msg(p_manager, EVT_ERROR, "Error reading SOT marker\n"); | |
| 4464 return OPJ_FALSE; | |
| 4465 } | |
| 4466 #ifdef DEBUG_VERBOSE | |
| 4467 fprintf(stderr, "SOT %d %d %d %d\n", | |
| 4468 p_j2k->m_current_tile_number, l_tot_len, l_current_part, l_num_parts); | |
| 4469 #endif | |
| 4470 | |
| 4471 l_cp = &(p_j2k->m_cp); | |
| 4472 | |
| 4473 /* testcase 2.pdf.SIGFPE.706.1112 */ | |
| 4474 if (p_j2k->m_current_tile_number >= l_cp->tw * l_cp->th) { | |
| 4475 opj_event_msg(p_manager, EVT_ERROR, "Invalid tile number %d\n", | |
| 4476 p_j2k->m_current_tile_number); | |
| 4477 return OPJ_FALSE; | |
| 4478 } | |
| 4479 | |
| 4480 l_tcp = &l_cp->tcps[p_j2k->m_current_tile_number]; | |
| 4481 l_tile_x = p_j2k->m_current_tile_number % l_cp->tw; | |
| 4482 l_tile_y = p_j2k->m_current_tile_number / l_cp->tw; | |
| 4483 | |
| 4484 if (p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec < 0 || | |
| 4485 p_j2k->m_current_tile_number == (OPJ_UINT32) | |
| 4486 p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec) { | |
| 4487 /* Do only this check if we decode all tile part headers, or if */ | |
| 4488 /* we decode one precise tile. Otherwise the m_current_tile_part_number */ | |
| 4489 /* might not be valid */ | |
| 4490 /* Fixes issue with id_000020,sig_06,src_001958,op_flip4,pos_149 */ | |
| 4491 /* of https://github.com/uclouvain/openjpeg/issues/939 */ | |
| 4492 /* We must avoid reading twice the same tile part number for a given tile */ | |
| 4493 /* so as to avoid various issues, like opj_j2k_merge_ppt being called */ | |
| 4494 /* several times. */ | |
| 4495 /* ISO 15444-1 A.4.2 Start of tile-part (SOT) mandates that tile parts */ | |
| 4496 /* should appear in increasing order. */ | |
| 4497 if (l_tcp->m_current_tile_part_number + 1 != (OPJ_INT32)l_current_part) { | |
| 4498 opj_event_msg(p_manager, EVT_ERROR, | |
| 4499 "Invalid tile part index for tile number %d. " | |
| 4500 "Got %d, expected %d\n", | |
| 4501 p_j2k->m_current_tile_number, | |
| 4502 l_current_part, | |
| 4503 l_tcp->m_current_tile_part_number + 1); | |
| 4504 return OPJ_FALSE; | |
| 4505 } | |
| 4506 } | |
| 4507 | |
| 4508 l_tcp->m_current_tile_part_number = (OPJ_INT32) l_current_part; | |
| 4509 | |
| 4510 #ifdef USE_JPWL | |
| 4511 if (l_cp->correct) { | |
| 4512 | |
| 4513 OPJ_UINT32 tileno = p_j2k->m_current_tile_number; | |
| 4514 static OPJ_UINT32 backup_tileno = 0; | |
| 4515 | |
| 4516 /* tileno is negative or larger than the number of tiles!!! */ | |
| 4517 if (tileno > (l_cp->tw * l_cp->th)) { | |
| 4518 opj_event_msg(p_manager, EVT_ERROR, | |
| 4519 "JPWL: bad tile number (%d out of a maximum of %d)\n", | |
| 4520 tileno, (l_cp->tw * l_cp->th)); | |
| 4521 if (!JPWL_ASSUME) { | |
| 4522 opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n"); | |
| 4523 return OPJ_FALSE; | |
| 4524 } | |
| 4525 /* we try to correct */ | |
| 4526 tileno = backup_tileno; | |
| 4527 opj_event_msg(p_manager, EVT_WARNING, "- trying to adjust this\n" | |
| 4528 "- setting tile number to %d\n", | |
| 4529 tileno); | |
| 4530 } | |
| 4531 | |
| 4532 /* keep your private count of tiles */ | |
| 4533 backup_tileno++; | |
| 4534 }; | |
| 4535 #endif /* USE_JPWL */ | |
| 4536 | |
| 4537 /* look for the tile in the list of already processed tile (in parts). */ | |
| 4538 /* Optimization possible here with a more complex data structure and with the removing of tiles */ | |
| 4539 /* since the time taken by this function can only grow at the time */ | |
| 4540 | |
| 4541 /* PSot should be equal to zero or >=14 or <= 2^32-1 */ | |
| 4542 if ((l_tot_len != 0) && (l_tot_len < 14)) { | |
| 4543 if (l_tot_len == | |
| 4544 12) { /* MSD: Special case for the PHR data which are read by kakadu*/ | |
| 4545 opj_event_msg(p_manager, EVT_WARNING, "Empty SOT marker detected: Psot=%d.\n", | |
| 4546 l_tot_len); | |
| 4547 } else { | |
| 4548 opj_event_msg(p_manager, EVT_ERROR, | |
| 4549 "Psot value is not correct regards to the JPEG2000 norm: %d.\n", l_tot_len); | |
| 4550 return OPJ_FALSE; | |
| 4551 } | |
| 4552 } | |
| 4553 | |
| 4554 #ifdef USE_JPWL | |
| 4555 if (l_cp->correct) { | |
| 4556 | |
| 4557 /* totlen is negative or larger than the bytes left!!! */ | |
| 4558 if (/*(l_tot_len < 0) ||*/ (l_tot_len > | |
| 4559 p_header_size)) { /* FIXME it seems correct; for info in V1 -> (p_stream_numbytesleft(p_stream) + 8))) { */ | |
| 4560 opj_event_msg(p_manager, EVT_ERROR, | |
| 4561 "JPWL: bad tile byte size (%d bytes against %d bytes left)\n", | |
| 4562 l_tot_len, | |
| 4563 p_header_size); /* FIXME it seems correct; for info in V1 -> p_stream_numbytesleft(p_stream) + 8); */ | |
| 4564 if (!JPWL_ASSUME) { | |
| 4565 opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n"); | |
| 4566 return OPJ_FALSE; | |
| 4567 } | |
| 4568 /* we try to correct */ | |
| 4569 l_tot_len = 0; | |
| 4570 opj_event_msg(p_manager, EVT_WARNING, "- trying to adjust this\n" | |
| 4571 "- setting Psot to %d => assuming it is the last tile\n", | |
| 4572 l_tot_len); | |
| 4573 } | |
| 4574 }; | |
| 4575 #endif /* USE_JPWL */ | |
| 4576 | |
| 4577 /* Ref A.4.2: Psot could be equal zero if it is the last tile-part of the codestream.*/ | |
| 4578 if (!l_tot_len) { | |
| 4579 opj_event_msg(p_manager, EVT_INFO, | |
| 4580 "Psot value of the current tile-part is equal to zero, " | |
| 4581 "we assuming it is the last tile-part of the codestream.\n"); | |
| 4582 p_j2k->m_specific_param.m_decoder.m_last_tile_part = 1; | |
| 4583 } | |
| 4584 | |
| 4585 if (l_tcp->m_nb_tile_parts != 0 && l_current_part >= l_tcp->m_nb_tile_parts) { | |
| 4586 /* Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2851 */ | |
| 4587 opj_event_msg(p_manager, EVT_ERROR, | |
| 4588 "In SOT marker, TPSot (%d) is not valid regards to the previous " | |
| 4589 "number of tile-part (%d), giving up\n", l_current_part, | |
| 4590 l_tcp->m_nb_tile_parts); | |
| 4591 p_j2k->m_specific_param.m_decoder.m_last_tile_part = 1; | |
| 4592 return OPJ_FALSE; | |
| 4593 } | |
| 4594 | |
| 4595 if (l_num_parts != | |
| 4596 0) { /* Number of tile-part header is provided by this tile-part header */ | |
| 4597 l_num_parts += p_j2k->m_specific_param.m_decoder.m_nb_tile_parts_correction; | |
| 4598 /* Useful to manage the case of textGBR.jp2 file because two values of TNSot are allowed: the correct numbers of | |
| 4599 * tile-parts for that tile and zero (A.4.2 of 15444-1 : 2002). */ | |
| 4600 if (l_tcp->m_nb_tile_parts) { | |
| 4601 if (l_current_part >= l_tcp->m_nb_tile_parts) { | |
| 4602 opj_event_msg(p_manager, EVT_ERROR, | |
| 4603 "In SOT marker, TPSot (%d) is not valid regards to the current " | |
| 4604 "number of tile-part (%d), giving up\n", l_current_part, | |
| 4605 l_tcp->m_nb_tile_parts); | |
| 4606 p_j2k->m_specific_param.m_decoder.m_last_tile_part = 1; | |
| 4607 return OPJ_FALSE; | |
| 4608 } | |
| 4609 } | |
| 4610 if (l_current_part >= l_num_parts) { | |
| 4611 /* testcase 451.pdf.SIGSEGV.ce9.3723 */ | |
| 4612 opj_event_msg(p_manager, EVT_ERROR, | |
| 4613 "In SOT marker, TPSot (%d) is not valid regards to the current " | |
| 4614 "number of tile-part (header) (%d), giving up\n", l_current_part, l_num_parts); | |
| 4615 p_j2k->m_specific_param.m_decoder.m_last_tile_part = 1; | |
| 4616 return OPJ_FALSE; | |
| 4617 } | |
| 4618 l_tcp->m_nb_tile_parts = l_num_parts; | |
| 4619 } | |
| 4620 | |
| 4621 /* If know the number of tile part header we will check if we didn't read the last*/ | |
| 4622 if (l_tcp->m_nb_tile_parts) { | |
| 4623 if (l_tcp->m_nb_tile_parts == (l_current_part + 1)) { | |
| 4624 p_j2k->m_specific_param.m_decoder.m_can_decode = | |
| 4625 1; /* Process the last tile-part header*/ | |
| 4626 } | |
| 4627 } | |
| 4628 | |
| 4629 if (!p_j2k->m_specific_param.m_decoder.m_last_tile_part) { | |
| 4630 /* Keep the size of data to skip after this marker */ | |
| 4631 p_j2k->m_specific_param.m_decoder.m_sot_length = l_tot_len - | |
| 4632 12; /* SOT_marker_size = 12 */ | |
| 4633 } else { | |
| 4634 /* FIXME: need to be computed from the number of bytes remaining in the codestream */ | |
| 4635 p_j2k->m_specific_param.m_decoder.m_sot_length = 0; | |
| 4636 } | |
| 4637 | |
| 4638 p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_TPH; | |
| 4639 | |
| 4640 /* Check if the current tile is outside the area we want decode or not corresponding to the tile index*/ | |
| 4641 if (p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec == -1) { | |
| 4642 p_j2k->m_specific_param.m_decoder.m_skip_data = | |
| 4643 (l_tile_x < p_j2k->m_specific_param.m_decoder.m_start_tile_x) | |
| 4644 || (l_tile_x >= p_j2k->m_specific_param.m_decoder.m_end_tile_x) | |
| 4645 || (l_tile_y < p_j2k->m_specific_param.m_decoder.m_start_tile_y) | |
| 4646 || (l_tile_y >= p_j2k->m_specific_param.m_decoder.m_end_tile_y); | |
| 4647 } else { | |
| 4648 assert(p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec >= 0); | |
| 4649 p_j2k->m_specific_param.m_decoder.m_skip_data = | |
| 4650 (p_j2k->m_current_tile_number != (OPJ_UINT32) | |
| 4651 p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec); | |
| 4652 } | |
| 4653 | |
| 4654 /* Index */ | |
| 4655 { | |
| 4656 assert(p_j2k->cstr_index->tile_index != 00); | |
| 4657 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tileno = | |
| 4658 p_j2k->m_current_tile_number; | |
| 4659 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_tpsno = | |
| 4660 l_current_part; | |
| 4661 | |
| 4662 if (!p_j2k->m_specific_param.m_decoder.m_tlm.m_is_invalid && | |
| 4663 l_num_parts > | |
| 4664 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].nb_tps) { | |
| 4665 opj_event_msg(p_manager, EVT_WARNING, | |
| 4666 "SOT marker for tile %u declares more tile-parts than found in TLM marker.", | |
| 4667 p_j2k->m_current_tile_number); | |
| 4668 p_j2k->m_specific_param.m_decoder.m_tlm.m_is_invalid = OPJ_TRUE; | |
| 4669 } | |
| 4670 | |
| 4671 if (!p_j2k->m_specific_param.m_decoder.m_tlm.m_is_invalid) { | |
| 4672 /* do nothing */ | |
| 4673 } else if (l_num_parts != 0) { | |
| 4674 | |
| 4675 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].nb_tps = | |
| 4676 l_num_parts; | |
| 4677 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps = | |
| 4678 l_num_parts; | |
| 4679 | |
| 4680 if (!p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index) { | |
| 4681 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index = | |
| 4682 (opj_tp_index_t*)opj_calloc(l_num_parts, sizeof(opj_tp_index_t)); | |
| 4683 if (!p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index) { | |
| 4684 opj_event_msg(p_manager, EVT_ERROR, | |
| 4685 "Not enough memory to read SOT marker. Tile index allocation failed\n"); | |
| 4686 return OPJ_FALSE; | |
| 4687 } | |
| 4688 } else { | |
| 4689 opj_tp_index_t *new_tp_index = (opj_tp_index_t *) opj_realloc( | |
| 4690 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index, | |
| 4691 l_num_parts * sizeof(opj_tp_index_t)); | |
| 4692 if (! new_tp_index) { | |
| 4693 opj_free(p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index); | |
| 4694 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index = NULL; | |
| 4695 opj_event_msg(p_manager, EVT_ERROR, | |
| 4696 "Not enough memory to read SOT marker. Tile index allocation failed\n"); | |
| 4697 return OPJ_FALSE; | |
| 4698 } | |
| 4699 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index = | |
| 4700 new_tp_index; | |
| 4701 } | |
| 4702 } else { | |
| 4703 /*if (!p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index)*/ { | |
| 4704 | |
| 4705 if (!p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index) { | |
| 4706 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps = 10; | |
| 4707 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index = | |
| 4708 (opj_tp_index_t*)opj_calloc( | |
| 4709 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps, | |
| 4710 sizeof(opj_tp_index_t)); | |
| 4711 if (!p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index) { | |
| 4712 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps = 0; | |
| 4713 opj_event_msg(p_manager, EVT_ERROR, | |
| 4714 "Not enough memory to read SOT marker. Tile index allocation failed\n"); | |
| 4715 return OPJ_FALSE; | |
| 4716 } | |
| 4717 } | |
| 4718 | |
| 4719 if (l_current_part >= | |
| 4720 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps) { | |
| 4721 opj_tp_index_t *new_tp_index; | |
| 4722 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps = | |
| 4723 l_current_part + 1; | |
| 4724 new_tp_index = (opj_tp_index_t *) opj_realloc( | |
| 4725 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index, | |
| 4726 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps * | |
| 4727 sizeof(opj_tp_index_t)); | |
| 4728 if (! new_tp_index) { | |
| 4729 opj_free(p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index); | |
| 4730 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index = NULL; | |
| 4731 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps = 0; | |
| 4732 opj_event_msg(p_manager, EVT_ERROR, | |
| 4733 "Not enough memory to read SOT marker. Tile index allocation failed\n"); | |
| 4734 return OPJ_FALSE; | |
| 4735 } | |
| 4736 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index = | |
| 4737 new_tp_index; | |
| 4738 } | |
| 4739 } | |
| 4740 | |
| 4741 } | |
| 4742 | |
| 4743 } | |
| 4744 | |
| 4745 return OPJ_TRUE; | |
| 4746 } | |
| 4747 | |
| 4748 /** | |
| 4749 * Write one or more PLT markers in the provided buffer | |
| 4750 */ | |
| 4751 static OPJ_BOOL opj_j2k_write_plt_in_memory(opj_j2k_t *p_j2k, | |
| 4752 opj_tcd_marker_info_t* marker_info, | |
| 4753 OPJ_BYTE * p_data, | |
| 4754 OPJ_UINT32 * p_data_written, | |
| 4755 opj_event_mgr_t * p_manager) | |
| 4756 { | |
| 4757 OPJ_BYTE Zplt = 0; | |
| 4758 OPJ_UINT16 Lplt; | |
| 4759 OPJ_BYTE* p_data_start = p_data; | |
| 4760 OPJ_BYTE* p_data_Lplt = p_data + 2; | |
| 4761 OPJ_UINT32 i; | |
| 4762 | |
| 4763 OPJ_UNUSED(p_j2k); | |
| 4764 | |
| 4765 opj_write_bytes(p_data, J2K_MS_PLT, 2); | |
| 4766 p_data += 2; | |
| 4767 | |
| 4768 /* Reserve space for Lplt */ | |
| 4769 p_data += 2; | |
| 4770 | |
| 4771 opj_write_bytes(p_data, Zplt, 1); | |
| 4772 p_data += 1; | |
| 4773 | |
| 4774 Lplt = 3; | |
| 4775 | |
| 4776 for (i = 0; i < marker_info->packet_count; i++) { | |
| 4777 OPJ_BYTE var_bytes[5]; | |
| 4778 OPJ_UINT8 var_bytes_size = 0; | |
| 4779 OPJ_UINT32 packet_size = marker_info->p_packet_size[i]; | |
| 4780 | |
| 4781 /* Packet size written in variable-length way, starting with LSB */ | |
| 4782 var_bytes[var_bytes_size] = (OPJ_BYTE)(packet_size & 0x7f); | |
| 4783 var_bytes_size ++; | |
| 4784 packet_size >>= 7; | |
| 4785 while (packet_size > 0) { | |
| 4786 var_bytes[var_bytes_size] = (OPJ_BYTE)((packet_size & 0x7f) | 0x80); | |
| 4787 var_bytes_size ++; | |
| 4788 packet_size >>= 7; | |
| 4789 } | |
| 4790 | |
| 4791 /* Check if that can fit in the current PLT marker. If not, finish */ | |
| 4792 /* current one, and start a new one */ | |
| 4793 if (Lplt + var_bytes_size > 65535) { | |
| 4794 if (Zplt == 255) { | |
| 4795 opj_event_msg(p_manager, EVT_ERROR, | |
| 4796 "More than 255 PLT markers would be needed for current tile-part !\n"); | |
| 4797 return OPJ_FALSE; | |
| 4798 } | |
| 4799 | |
| 4800 /* Patch Lplt */ | |
| 4801 opj_write_bytes(p_data_Lplt, Lplt, 2); | |
| 4802 | |
| 4803 /* Start new segment */ | |
| 4804 opj_write_bytes(p_data, J2K_MS_PLT, 2); | |
| 4805 p_data += 2; | |
| 4806 | |
| 4807 /* Reserve space for Lplt */ | |
| 4808 p_data_Lplt = p_data; | |
| 4809 p_data += 2; | |
| 4810 | |
| 4811 Zplt ++; | |
| 4812 opj_write_bytes(p_data, Zplt, 1); | |
| 4813 p_data += 1; | |
| 4814 | |
| 4815 Lplt = 3; | |
| 4816 } | |
| 4817 | |
| 4818 Lplt = (OPJ_UINT16)(Lplt + var_bytes_size); | |
| 4819 | |
| 4820 /* Serialize variable-length packet size, starting with MSB */ | |
| 4821 for (; var_bytes_size > 0; --var_bytes_size) { | |
| 4822 opj_write_bytes(p_data, var_bytes[var_bytes_size - 1], 1); | |
| 4823 p_data += 1; | |
| 4824 } | |
| 4825 } | |
| 4826 | |
| 4827 *p_data_written = (OPJ_UINT32)(p_data - p_data_start); | |
| 4828 | |
| 4829 /* Patch Lplt */ | |
| 4830 opj_write_bytes(p_data_Lplt, Lplt, 2); | |
| 4831 | |
| 4832 return OPJ_TRUE; | |
| 4833 } | |
| 4834 | |
| 4835 static OPJ_BOOL opj_j2k_write_sod(opj_j2k_t *p_j2k, | |
| 4836 opj_tcd_t * p_tile_coder, | |
| 4837 OPJ_BYTE * p_data, | |
| 4838 OPJ_UINT32 * p_data_written, | |
| 4839 OPJ_UINT32 total_data_size, | |
| 4840 const opj_stream_private_t *p_stream, | |
| 4841 opj_event_mgr_t * p_manager | |
| 4842 ) | |
| 4843 { | |
| 4844 opj_codestream_info_t *l_cstr_info = 00; | |
| 4845 OPJ_UINT32 l_remaining_data; | |
| 4846 opj_tcd_marker_info_t* marker_info = NULL; | |
| 4847 | |
| 4848 /* preconditions */ | |
| 4849 assert(p_j2k != 00); | |
| 4850 assert(p_manager != 00); | |
| 4851 assert(p_stream != 00); | |
| 4852 | |
| 4853 OPJ_UNUSED(p_stream); | |
| 4854 | |
| 4855 if (total_data_size < 4) { | |
| 4856 opj_event_msg(p_manager, EVT_ERROR, | |
| 4857 "Not enough bytes in output buffer to write SOD marker\n"); | |
| 4858 return OPJ_FALSE; | |
| 4859 } | |
| 4860 | |
| 4861 opj_write_bytes(p_data, J2K_MS_SOD, | |
| 4862 2); /* SOD */ | |
| 4863 | |
| 4864 /* make room for the EOF marker */ | |
| 4865 l_remaining_data = total_data_size - 4; | |
| 4866 | |
| 4867 /* update tile coder */ | |
| 4868 p_tile_coder->tp_num = | |
| 4869 p_j2k->m_specific_param.m_encoder.m_current_poc_tile_part_number ; | |
| 4870 p_tile_coder->cur_tp_num = | |
| 4871 p_j2k->m_specific_param.m_encoder.m_current_tile_part_number; | |
| 4872 | |
| 4873 /* INDEX >> */ | |
| 4874 /* TODO mergeV2: check this part which use cstr_info */ | |
| 4875 /*l_cstr_info = p_j2k->cstr_info; | |
| 4876 if (l_cstr_info) { | |
| 4877 if (!p_j2k->m_specific_param.m_encoder.m_current_tile_part_number ) { | |
| 4878 //TODO cstr_info->tile[p_j2k->m_current_tile_number].end_header = p_stream_tell(p_stream) + p_j2k->pos_correction - 1; | |
| 4879 l_cstr_info->tile[p_j2k->m_current_tile_number].tileno = p_j2k->m_current_tile_number; | |
| 4880 } | |
| 4881 else {*/ | |
| 4882 /* | |
| 4883 TODO | |
| 4884 if | |
| 4885 (cstr_info->tile[p_j2k->m_current_tile_number].packet[cstr_info->packno - 1].end_pos < p_stream_tell(p_stream)) | |
| 4886 { | |
| 4887 cstr_info->tile[p_j2k->m_current_tile_number].packet[cstr_info->packno].start_pos = p_stream_tell(p_stream); | |
| 4888 }*/ | |
| 4889 /*}*/ | |
| 4890 /* UniPG>> */ | |
| 4891 #ifdef USE_JPWL | |
| 4892 /* update markers struct */ | |
| 4893 /*OPJ_BOOL res = j2k_add_marker(p_j2k->cstr_info, J2K_MS_SOD, p_j2k->sod_start, 2); | |
| 4894 */ | |
| 4895 assert(0 && "TODO"); | |
| 4896 #endif /* USE_JPWL */ | |
| 4897 /* <<UniPG */ | |
| 4898 /*}*/ | |
| 4899 /* << INDEX */ | |
| 4900 | |
| 4901 if (p_j2k->m_specific_param.m_encoder.m_current_tile_part_number == 0) { | |
| 4902 p_tile_coder->tcd_image->tiles->packno = 0; | |
| 4903 #ifdef deadcode | |
| 4904 if (l_cstr_info) { | |
| 4905 l_cstr_info->packno = 0; | |
| 4906 } | |
| 4907 #endif | |
| 4908 } | |
| 4909 | |
| 4910 *p_data_written = 0; | |
| 4911 | |
| 4912 if (p_j2k->m_specific_param.m_encoder.m_PLT) { | |
| 4913 marker_info = opj_tcd_marker_info_create( | |
| 4914 p_j2k->m_specific_param.m_encoder.m_PLT); | |
| 4915 if (marker_info == NULL) { | |
| 4916 opj_event_msg(p_manager, EVT_ERROR, | |
| 4917 "Cannot encode tile: opj_tcd_marker_info_create() failed\n"); | |
| 4918 return OPJ_FALSE; | |
| 4919 } | |
| 4920 } | |
| 4921 | |
| 4922 if (l_remaining_data < | |
| 4923 p_j2k->m_specific_param.m_encoder.m_reserved_bytes_for_PLT) { | |
| 4924 opj_event_msg(p_manager, EVT_ERROR, | |
| 4925 "Not enough bytes in output buffer to write SOD marker\n"); | |
| 4926 opj_tcd_marker_info_destroy(marker_info); | |
| 4927 return OPJ_FALSE; | |
| 4928 } | |
| 4929 l_remaining_data -= p_j2k->m_specific_param.m_encoder.m_reserved_bytes_for_PLT; | |
| 4930 | |
| 4931 if (! opj_tcd_encode_tile(p_tile_coder, p_j2k->m_current_tile_number, | |
| 4932 p_data + 2, | |
| 4933 p_data_written, l_remaining_data, l_cstr_info, | |
| 4934 marker_info, | |
| 4935 p_manager)) { | |
| 4936 opj_event_msg(p_manager, EVT_ERROR, "Cannot encode tile\n"); | |
| 4937 opj_tcd_marker_info_destroy(marker_info); | |
| 4938 return OPJ_FALSE; | |
| 4939 } | |
| 4940 | |
| 4941 /* For SOD */ | |
| 4942 *p_data_written += 2; | |
| 4943 | |
| 4944 if (p_j2k->m_specific_param.m_encoder.m_PLT) { | |
| 4945 OPJ_UINT32 l_data_written_PLT = 0; | |
| 4946 OPJ_BYTE* p_PLT_buffer = (OPJ_BYTE*)opj_malloc( | |
| 4947 p_j2k->m_specific_param.m_encoder.m_reserved_bytes_for_PLT); | |
| 4948 if (!p_PLT_buffer) { | |
| 4949 opj_event_msg(p_manager, EVT_ERROR, "Cannot allocate memory\n"); | |
| 4950 opj_tcd_marker_info_destroy(marker_info); | |
| 4951 return OPJ_FALSE; | |
| 4952 } | |
| 4953 if (!opj_j2k_write_plt_in_memory(p_j2k, | |
| 4954 marker_info, | |
| 4955 p_PLT_buffer, | |
| 4956 &l_data_written_PLT, | |
| 4957 p_manager)) { | |
| 4958 opj_tcd_marker_info_destroy(marker_info); | |
| 4959 opj_free(p_PLT_buffer); | |
| 4960 return OPJ_FALSE; | |
| 4961 } | |
| 4962 | |
| 4963 assert(l_data_written_PLT <= | |
| 4964 p_j2k->m_specific_param.m_encoder.m_reserved_bytes_for_PLT); | |
| 4965 | |
| 4966 /* Move PLT marker(s) before SOD */ | |
| 4967 memmove(p_data + l_data_written_PLT, p_data, *p_data_written); | |
| 4968 memcpy(p_data, p_PLT_buffer, l_data_written_PLT); | |
| 4969 opj_free(p_PLT_buffer); | |
| 4970 *p_data_written += l_data_written_PLT; | |
| 4971 } | |
| 4972 | |
| 4973 opj_tcd_marker_info_destroy(marker_info); | |
| 4974 | |
| 4975 return OPJ_TRUE; | |
| 4976 } | |
| 4977 | |
| 4978 static OPJ_BOOL opj_j2k_read_sod(opj_j2k_t *p_j2k, | |
| 4979 opj_stream_private_t *p_stream, | |
| 4980 opj_event_mgr_t * p_manager | |
| 4981 ) | |
| 4982 { | |
| 4983 OPJ_SIZE_T l_current_read_size; | |
| 4984 opj_codestream_index_t * l_cstr_index = 00; | |
| 4985 OPJ_BYTE ** l_current_data = 00; | |
| 4986 opj_tcp_t * l_tcp = 00; | |
| 4987 OPJ_UINT32 * l_tile_len = 00; | |
| 4988 OPJ_BOOL l_sot_length_pb_detected = OPJ_FALSE; | |
| 4989 | |
| 4990 /* preconditions */ | |
| 4991 assert(p_j2k != 00); | |
| 4992 assert(p_manager != 00); | |
| 4993 assert(p_stream != 00); | |
| 4994 | |
| 4995 l_tcp = &(p_j2k->m_cp.tcps[p_j2k->m_current_tile_number]); | |
| 4996 | |
| 4997 if (p_j2k->m_specific_param.m_decoder.m_last_tile_part) { | |
| 4998 /* opj_stream_get_number_byte_left returns OPJ_OFF_T | |
| 4999 // but we are in the last tile part, | |
| 5000 // so its result will fit on OPJ_UINT32 unless we find | |
| 5001 // a file with a single tile part of more than 4 GB...*/ | |
| 5002 p_j2k->m_specific_param.m_decoder.m_sot_length = (OPJ_UINT32)( | |
| 5003 opj_stream_get_number_byte_left(p_stream) - 2); | |
| 5004 } else { | |
| 5005 /* Check to avoid pass the limit of OPJ_UINT32 */ | |
| 5006 if (p_j2k->m_specific_param.m_decoder.m_sot_length >= 2) { | |
| 5007 p_j2k->m_specific_param.m_decoder.m_sot_length -= 2; | |
| 5008 } else { | |
| 5009 /* MSD: case commented to support empty SOT marker (PHR data) */ | |
| 5010 } | |
| 5011 } | |
| 5012 | |
| 5013 l_current_data = &(l_tcp->m_data); | |
| 5014 l_tile_len = &l_tcp->m_data_size; | |
| 5015 | |
| 5016 /* Patch to support new PHR data */ | |
| 5017 if (p_j2k->m_specific_param.m_decoder.m_sot_length) { | |
| 5018 /* If we are here, we'll try to read the data after allocation */ | |
| 5019 /* Check enough bytes left in stream before allocation */ | |
| 5020 if ((OPJ_OFF_T)p_j2k->m_specific_param.m_decoder.m_sot_length > | |
| 5021 opj_stream_get_number_byte_left(p_stream)) { | |
| 5022 if (p_j2k->m_cp.strict) { | |
| 5023 opj_event_msg(p_manager, EVT_ERROR, | |
| 5024 "Tile part length size inconsistent with stream length\n"); | |
| 5025 return OPJ_FALSE; | |
| 5026 } else { | |
| 5027 opj_event_msg(p_manager, EVT_WARNING, | |
| 5028 "Tile part length size inconsistent with stream length\n"); | |
| 5029 } | |
| 5030 } | |
| 5031 if (p_j2k->m_specific_param.m_decoder.m_sot_length > | |
| 5032 UINT_MAX - OPJ_COMMON_CBLK_DATA_EXTRA) { | |
| 5033 opj_event_msg(p_manager, EVT_ERROR, | |
| 5034 "p_j2k->m_specific_param.m_decoder.m_sot_length > " | |
| 5035 "UINT_MAX - OPJ_COMMON_CBLK_DATA_EXTRA"); | |
| 5036 return OPJ_FALSE; | |
| 5037 } | |
| 5038 /* Add a margin of OPJ_COMMON_CBLK_DATA_EXTRA to the allocation we */ | |
| 5039 /* do so that opj_mqc_init_dec_common() can safely add a synthetic */ | |
| 5040 /* 0xFFFF marker. */ | |
| 5041 if (! *l_current_data) { | |
| 5042 /* LH: oddly enough, in this path, l_tile_len!=0. | |
| 5043 * TODO: If this was consistent, we could simplify the code to only use realloc(), as realloc(0,...) default to malloc(0,...). | |
| 5044 */ | |
| 5045 *l_current_data = (OPJ_BYTE*) opj_malloc( | |
| 5046 p_j2k->m_specific_param.m_decoder.m_sot_length + OPJ_COMMON_CBLK_DATA_EXTRA); | |
| 5047 } else { | |
| 5048 OPJ_BYTE *l_new_current_data; | |
| 5049 if (*l_tile_len > UINT_MAX - OPJ_COMMON_CBLK_DATA_EXTRA - | |
| 5050 p_j2k->m_specific_param.m_decoder.m_sot_length) { | |
| 5051 opj_event_msg(p_manager, EVT_ERROR, | |
| 5052 "*l_tile_len > UINT_MAX - OPJ_COMMON_CBLK_DATA_EXTRA - " | |
| 5053 "p_j2k->m_specific_param.m_decoder.m_sot_length"); | |
| 5054 return OPJ_FALSE; | |
| 5055 } | |
| 5056 | |
| 5057 l_new_current_data = (OPJ_BYTE *) opj_realloc(*l_current_data, | |
| 5058 *l_tile_len + p_j2k->m_specific_param.m_decoder.m_sot_length + | |
| 5059 OPJ_COMMON_CBLK_DATA_EXTRA); | |
| 5060 if (! l_new_current_data) { | |
| 5061 opj_free(*l_current_data); | |
| 5062 /*nothing more is done as l_current_data will be set to null, and just | |
| 5063 afterward we enter in the error path | |
| 5064 and the actual tile_len is updated (committed) at the end of the | |
| 5065 function. */ | |
| 5066 } | |
| 5067 *l_current_data = l_new_current_data; | |
| 5068 } | |
| 5069 | |
| 5070 if (*l_current_data == 00) { | |
| 5071 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to decode tile\n"); | |
| 5072 return OPJ_FALSE; | |
| 5073 } | |
| 5074 } else { | |
| 5075 l_sot_length_pb_detected = OPJ_TRUE; | |
| 5076 } | |
| 5077 | |
| 5078 /* Index */ | |
| 5079 l_cstr_index = p_j2k->cstr_index; | |
| 5080 { | |
| 5081 OPJ_OFF_T l_current_pos = opj_stream_tell(p_stream) - 2; | |
| 5082 | |
| 5083 OPJ_UINT32 l_current_tile_part = | |
| 5084 l_cstr_index->tile_index[p_j2k->m_current_tile_number].current_tpsno; | |
| 5085 l_cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index[l_current_tile_part].end_header | |
| 5086 = | |
| 5087 l_current_pos; | |
| 5088 l_cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index[l_current_tile_part].end_pos | |
| 5089 = | |
| 5090 l_current_pos + p_j2k->m_specific_param.m_decoder.m_sot_length + 2; | |
| 5091 | |
| 5092 if (OPJ_FALSE == opj_j2k_add_tlmarker(p_j2k->m_current_tile_number, | |
| 5093 l_cstr_index, | |
| 5094 J2K_MS_SOD, | |
| 5095 l_current_pos, | |
| 5096 p_j2k->m_specific_param.m_decoder.m_sot_length + 2)) { | |
| 5097 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to add tl marker\n"); | |
| 5098 return OPJ_FALSE; | |
| 5099 } | |
| 5100 | |
| 5101 /*l_cstr_index->packno = 0;*/ | |
| 5102 } | |
| 5103 | |
| 5104 /* Patch to support new PHR data */ | |
| 5105 if (!l_sot_length_pb_detected) { | |
| 5106 l_current_read_size = opj_stream_read_data( | |
| 5107 p_stream, | |
| 5108 *l_current_data + *l_tile_len, | |
| 5109 p_j2k->m_specific_param.m_decoder.m_sot_length, | |
| 5110 p_manager); | |
| 5111 } else { | |
| 5112 l_current_read_size = 0; | |
| 5113 } | |
| 5114 | |
| 5115 if (l_current_read_size != p_j2k->m_specific_param.m_decoder.m_sot_length) { | |
| 5116 if (l_current_read_size == (OPJ_SIZE_T)(-1)) { | |
| 5117 /* Avoid issue of https://github.com/uclouvain/openjpeg/issues/1533 */ | |
| 5118 opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); | |
| 5119 return OPJ_FALSE; | |
| 5120 } | |
| 5121 p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_NEOC; | |
| 5122 } else { | |
| 5123 p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_TPHSOT; | |
| 5124 } | |
| 5125 | |
| 5126 *l_tile_len += (OPJ_UINT32)l_current_read_size; | |
| 5127 | |
| 5128 return OPJ_TRUE; | |
| 5129 } | |
| 5130 | |
| 5131 static OPJ_BOOL opj_j2k_write_rgn(opj_j2k_t *p_j2k, | |
| 5132 OPJ_UINT32 p_tile_no, | |
| 5133 OPJ_UINT32 p_comp_no, | |
| 5134 OPJ_UINT32 nb_comps, | |
| 5135 opj_stream_private_t *p_stream, | |
| 5136 opj_event_mgr_t * p_manager | |
| 5137 ) | |
| 5138 { | |
| 5139 OPJ_BYTE * l_current_data = 00; | |
| 5140 OPJ_UINT32 l_rgn_size; | |
| 5141 opj_cp_t *l_cp = 00; | |
| 5142 opj_tcp_t *l_tcp = 00; | |
| 5143 opj_tccp_t *l_tccp = 00; | |
| 5144 OPJ_UINT32 l_comp_room; | |
| 5145 | |
| 5146 /* preconditions */ | |
| 5147 assert(p_j2k != 00); | |
| 5148 assert(p_manager != 00); | |
| 5149 assert(p_stream != 00); | |
| 5150 | |
| 5151 l_cp = &(p_j2k->m_cp); | |
| 5152 l_tcp = &l_cp->tcps[p_tile_no]; | |
| 5153 l_tccp = &l_tcp->tccps[p_comp_no]; | |
| 5154 | |
| 5155 if (nb_comps <= 256) { | |
| 5156 l_comp_room = 1; | |
| 5157 } else { | |
| 5158 l_comp_room = 2; | |
| 5159 } | |
| 5160 | |
| 5161 l_rgn_size = 6 + l_comp_room; | |
| 5162 | |
| 5163 l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data; | |
| 5164 | |
| 5165 opj_write_bytes(l_current_data, J2K_MS_RGN, | |
| 5166 2); /* RGN */ | |
| 5167 l_current_data += 2; | |
| 5168 | |
| 5169 opj_write_bytes(l_current_data, l_rgn_size - 2, | |
| 5170 2); /* Lrgn */ | |
| 5171 l_current_data += 2; | |
| 5172 | |
| 5173 opj_write_bytes(l_current_data, p_comp_no, | |
| 5174 l_comp_room); /* Crgn */ | |
| 5175 l_current_data += l_comp_room; | |
| 5176 | |
| 5177 opj_write_bytes(l_current_data, 0, | |
| 5178 1); /* Srgn */ | |
| 5179 ++l_current_data; | |
| 5180 | |
| 5181 opj_write_bytes(l_current_data, (OPJ_UINT32)l_tccp->roishift, | |
| 5182 1); /* SPrgn */ | |
| 5183 ++l_current_data; | |
| 5184 | |
| 5185 if (opj_stream_write_data(p_stream, | |
| 5186 p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_rgn_size, | |
| 5187 p_manager) != l_rgn_size) { | |
| 5188 return OPJ_FALSE; | |
| 5189 } | |
| 5190 | |
| 5191 return OPJ_TRUE; | |
| 5192 } | |
| 5193 | |
| 5194 static OPJ_BOOL opj_j2k_write_eoc(opj_j2k_t *p_j2k, | |
| 5195 opj_stream_private_t *p_stream, | |
| 5196 opj_event_mgr_t * p_manager | |
| 5197 ) | |
| 5198 { | |
| 5199 /* preconditions */ | |
| 5200 assert(p_j2k != 00); | |
| 5201 assert(p_manager != 00); | |
| 5202 assert(p_stream != 00); | |
| 5203 | |
| 5204 opj_write_bytes(p_j2k->m_specific_param.m_encoder.m_header_tile_data, | |
| 5205 J2K_MS_EOC, 2); /* EOC */ | |
| 5206 | |
| 5207 /* UniPG>> */ | |
| 5208 #ifdef USE_JPWL | |
| 5209 /* update markers struct */ | |
| 5210 /* | |
| 5211 OPJ_BOOL res = j2k_add_marker(p_j2k->cstr_info, J2K_MS_EOC, p_stream_tell(p_stream) - 2, 2); | |
| 5212 */ | |
| 5213 #endif /* USE_JPWL */ | |
| 5214 | |
| 5215 if (opj_stream_write_data(p_stream, | |
| 5216 p_j2k->m_specific_param.m_encoder.m_header_tile_data, 2, p_manager) != 2) { | |
| 5217 return OPJ_FALSE; | |
| 5218 } | |
| 5219 | |
| 5220 if (! opj_stream_flush(p_stream, p_manager)) { | |
| 5221 return OPJ_FALSE; | |
| 5222 } | |
| 5223 | |
| 5224 return OPJ_TRUE; | |
| 5225 } | |
| 5226 | |
| 5227 /** | |
| 5228 * Reads a RGN marker (Region Of Interest) | |
| 5229 * | |
| 5230 * @param p_header_data the data contained in the POC box. | |
| 5231 * @param p_j2k the jpeg2000 codec. | |
| 5232 * @param p_header_size the size of the data contained in the POC marker. | |
| 5233 * @param p_manager the user event manager. | |
| 5234 */ | |
| 5235 static OPJ_BOOL opj_j2k_read_rgn(opj_j2k_t *p_j2k, | |
| 5236 OPJ_BYTE * p_header_data, | |
| 5237 OPJ_UINT32 p_header_size, | |
| 5238 opj_event_mgr_t * p_manager | |
| 5239 ) | |
| 5240 { | |
| 5241 OPJ_UINT32 l_nb_comp; | |
| 5242 opj_image_t * l_image = 00; | |
| 5243 | |
| 5244 opj_cp_t *l_cp = 00; | |
| 5245 opj_tcp_t *l_tcp = 00; | |
| 5246 OPJ_UINT32 l_comp_room, l_comp_no, l_roi_sty; | |
| 5247 | |
| 5248 /* preconditions*/ | |
| 5249 assert(p_header_data != 00); | |
| 5250 assert(p_j2k != 00); | |
| 5251 assert(p_manager != 00); | |
| 5252 | |
| 5253 l_image = p_j2k->m_private_image; | |
| 5254 l_nb_comp = l_image->numcomps; | |
| 5255 | |
| 5256 if (l_nb_comp <= 256) { | |
| 5257 l_comp_room = 1; | |
| 5258 } else { | |
| 5259 l_comp_room = 2; | |
| 5260 } | |
| 5261 | |
| 5262 if (p_header_size != 2 + l_comp_room) { | |
| 5263 opj_event_msg(p_manager, EVT_ERROR, "Error reading RGN marker\n"); | |
| 5264 return OPJ_FALSE; | |
| 5265 } | |
| 5266 | |
| 5267 l_cp = &(p_j2k->m_cp); | |
| 5268 l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH) ? | |
| 5269 &l_cp->tcps[p_j2k->m_current_tile_number] : | |
| 5270 p_j2k->m_specific_param.m_decoder.m_default_tcp; | |
| 5271 | |
| 5272 opj_read_bytes(p_header_data, &l_comp_no, l_comp_room); /* Crgn */ | |
| 5273 p_header_data += l_comp_room; | |
| 5274 opj_read_bytes(p_header_data, &l_roi_sty, | |
| 5275 1); /* Srgn */ | |
| 5276 ++p_header_data; | |
| 5277 | |
| 5278 #ifdef USE_JPWL | |
| 5279 if (l_cp->correct) { | |
| 5280 /* totlen is negative or larger than the bytes left!!! */ | |
| 5281 if (l_comp_room >= l_nb_comp) { | |
| 5282 opj_event_msg(p_manager, EVT_ERROR, | |
| 5283 "JPWL: bad component number in RGN (%d when there are only %d)\n", | |
| 5284 l_comp_room, l_nb_comp); | |
| 5285 if (!JPWL_ASSUME) { | |
| 5286 opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n"); | |
| 5287 return OPJ_FALSE; | |
| 5288 } | |
| 5289 } | |
| 5290 }; | |
| 5291 #endif /* USE_JPWL */ | |
| 5292 | |
| 5293 /* testcase 3635.pdf.asan.77.2930 */ | |
| 5294 if (l_comp_no >= l_nb_comp) { | |
| 5295 opj_event_msg(p_manager, EVT_ERROR, | |
| 5296 "bad component number in RGN (%d when there are only %d)\n", | |
| 5297 l_comp_no, l_nb_comp); | |
| 5298 return OPJ_FALSE; | |
| 5299 } | |
| 5300 | |
| 5301 opj_read_bytes(p_header_data, | |
| 5302 (OPJ_UINT32 *)(&(l_tcp->tccps[l_comp_no].roishift)), 1); /* SPrgn */ | |
| 5303 ++p_header_data; | |
| 5304 | |
| 5305 return OPJ_TRUE; | |
| 5306 | |
| 5307 } | |
| 5308 | |
| 5309 static OPJ_FLOAT32 opj_j2k_get_tp_stride(opj_tcp_t * p_tcp) | |
| 5310 { | |
| 5311 return (OPJ_FLOAT32)((p_tcp->m_nb_tile_parts - 1) * 14); | |
| 5312 } | |
| 5313 | |
| 5314 static OPJ_FLOAT32 opj_j2k_get_default_stride(opj_tcp_t * p_tcp) | |
| 5315 { | |
| 5316 (void)p_tcp; | |
| 5317 return 0; | |
| 5318 } | |
| 5319 | |
| 5320 static OPJ_BOOL opj_j2k_update_rates(opj_j2k_t *p_j2k, | |
| 5321 opj_stream_private_t *p_stream, | |
| 5322 opj_event_mgr_t * p_manager) | |
| 5323 { | |
| 5324 opj_cp_t * l_cp = 00; | |
| 5325 opj_image_t * l_image = 00; | |
| 5326 opj_tcp_t * l_tcp = 00; | |
| 5327 opj_image_comp_t * l_img_comp = 00; | |
| 5328 | |
| 5329 OPJ_UINT32 i, j, k; | |
| 5330 OPJ_INT32 l_x0, l_y0, l_x1, l_y1; | |
| 5331 OPJ_FLOAT32 * l_rates = 0; | |
| 5332 OPJ_FLOAT32 l_sot_remove; | |
| 5333 OPJ_UINT32 l_bits_empty, l_size_pixel; | |
| 5334 OPJ_UINT64 l_tile_size = 0; | |
| 5335 OPJ_UINT32 l_last_res; | |
| 5336 OPJ_FLOAT32(* l_tp_stride_func)(opj_tcp_t *) = 00; | |
| 5337 | |
| 5338 /* preconditions */ | |
| 5339 assert(p_j2k != 00); | |
| 5340 assert(p_manager != 00); | |
| 5341 assert(p_stream != 00); | |
| 5342 | |
| 5343 OPJ_UNUSED(p_manager); | |
| 5344 | |
| 5345 l_cp = &(p_j2k->m_cp); | |
| 5346 l_image = p_j2k->m_private_image; | |
| 5347 l_tcp = l_cp->tcps; | |
| 5348 | |
| 5349 l_bits_empty = 8 * l_image->comps->dx * l_image->comps->dy; | |
| 5350 l_size_pixel = l_image->numcomps * l_image->comps->prec; | |
| 5351 l_sot_remove = (OPJ_FLOAT32) opj_stream_tell(p_stream) / (OPJ_FLOAT32)( | |
| 5352 l_cp->th * l_cp->tw); | |
| 5353 | |
| 5354 if (l_cp->m_specific_param.m_enc.m_tp_on) { | |
| 5355 l_tp_stride_func = opj_j2k_get_tp_stride; | |
| 5356 } else { | |
| 5357 l_tp_stride_func = opj_j2k_get_default_stride; | |
| 5358 } | |
| 5359 | |
| 5360 for (i = 0; i < l_cp->th; ++i) { | |
| 5361 for (j = 0; j < l_cp->tw; ++j) { | |
| 5362 OPJ_FLOAT32 l_offset = (OPJ_FLOAT32)(*l_tp_stride_func)(l_tcp) / | |
| 5363 (OPJ_FLOAT32)l_tcp->numlayers; | |
| 5364 | |
| 5365 /* 4 borders of the tile rescale on the image if necessary */ | |
| 5366 l_x0 = opj_int_max((OPJ_INT32)(l_cp->tx0 + j * l_cp->tdx), | |
| 5367 (OPJ_INT32)l_image->x0); | |
| 5368 l_y0 = opj_int_max((OPJ_INT32)(l_cp->ty0 + i * l_cp->tdy), | |
| 5369 (OPJ_INT32)l_image->y0); | |
| 5370 l_x1 = opj_int_min((OPJ_INT32)(l_cp->tx0 + (j + 1) * l_cp->tdx), | |
| 5371 (OPJ_INT32)l_image->x1); | |
| 5372 l_y1 = opj_int_min((OPJ_INT32)(l_cp->ty0 + (i + 1) * l_cp->tdy), | |
| 5373 (OPJ_INT32)l_image->y1); | |
| 5374 | |
| 5375 l_rates = l_tcp->rates; | |
| 5376 | |
| 5377 /* Modification of the RATE >> */ | |
| 5378 for (k = 0; k < l_tcp->numlayers; ++k) { | |
| 5379 if (*l_rates > 0.0f) { | |
| 5380 *l_rates = (OPJ_FLOAT32)(((OPJ_FLOAT64)l_size_pixel * (OPJ_UINT32)( | |
| 5381 l_x1 - l_x0) * | |
| 5382 (OPJ_UINT32)(l_y1 - l_y0)) | |
| 5383 / ((*l_rates) * (OPJ_FLOAT32)l_bits_empty)) | |
| 5384 - | |
| 5385 l_offset; | |
| 5386 } | |
| 5387 | |
| 5388 ++l_rates; | |
| 5389 } | |
| 5390 | |
| 5391 ++l_tcp; | |
| 5392 | |
| 5393 } | |
| 5394 } | |
| 5395 | |
| 5396 l_tcp = l_cp->tcps; | |
| 5397 | |
| 5398 for (i = 0; i < l_cp->th; ++i) { | |
| 5399 for (j = 0; j < l_cp->tw; ++j) { | |
| 5400 l_rates = l_tcp->rates; | |
| 5401 | |
| 5402 if (*l_rates > 0.0f) { | |
| 5403 *l_rates -= l_sot_remove; | |
| 5404 | |
| 5405 if (*l_rates < 30.0f) { | |
| 5406 *l_rates = 30.0f; | |
| 5407 } | |
| 5408 } | |
| 5409 | |
| 5410 ++l_rates; | |
| 5411 | |
| 5412 l_last_res = l_tcp->numlayers - 1; | |
| 5413 | |
| 5414 for (k = 1; k < l_last_res; ++k) { | |
| 5415 | |
| 5416 if (*l_rates > 0.0f) { | |
| 5417 *l_rates -= l_sot_remove; | |
| 5418 | |
| 5419 if (*l_rates < * (l_rates - 1) + 10.0f) { | |
| 5420 *l_rates = (*(l_rates - 1)) + 20.0f; | |
| 5421 } | |
| 5422 } | |
| 5423 | |
| 5424 ++l_rates; | |
| 5425 } | |
| 5426 | |
| 5427 if (*l_rates > 0.0f) { | |
| 5428 *l_rates -= (l_sot_remove + 2.f); | |
| 5429 | |
| 5430 if (*l_rates < * (l_rates - 1) + 10.0f) { | |
| 5431 *l_rates = (*(l_rates - 1)) + 20.0f; | |
| 5432 } | |
| 5433 } | |
| 5434 | |
| 5435 ++l_tcp; | |
| 5436 } | |
| 5437 } | |
| 5438 | |
| 5439 l_img_comp = l_image->comps; | |
| 5440 l_tile_size = 0; | |
| 5441 | |
| 5442 for (i = 0; i < l_image->numcomps; ++i) { | |
| 5443 l_tile_size += (OPJ_UINT64)opj_uint_ceildiv(l_cp->tdx, l_img_comp->dx) | |
| 5444 * | |
| 5445 opj_uint_ceildiv(l_cp->tdy, l_img_comp->dy) | |
| 5446 * | |
| 5447 l_img_comp->prec; | |
| 5448 | |
| 5449 ++l_img_comp; | |
| 5450 } | |
| 5451 | |
| 5452 /* TODO: where does this magic value come from ? */ | |
| 5453 /* This used to be 1.3 / 8, but with random data and very small code */ | |
| 5454 /* block sizes, this is not enough. For example with */ | |
| 5455 /* bin/test_tile_encoder 1 256 256 32 32 8 0 reversible_with_precinct.j2k 4 4 3 0 0 1 16 16 */ | |
| 5456 /* TODO revise this to take into account the overhead linked to the */ | |
| 5457 /* number of packets and number of code blocks in packets */ | |
| 5458 l_tile_size = (OPJ_UINT64)((double)l_tile_size * 1.4 / 8); | |
| 5459 | |
| 5460 /* Arbitrary amount to make the following work: */ | |
| 5461 /* bin/test_tile_encoder 1 256 256 17 16 8 0 reversible_no_precinct.j2k 4 4 3 0 0 1 */ | |
| 5462 l_tile_size += 500; | |
| 5463 | |
| 5464 l_tile_size += opj_j2k_get_specific_header_sizes(p_j2k); | |
| 5465 | |
| 5466 if (l_tile_size > UINT_MAX) { | |
| 5467 l_tile_size = UINT_MAX; | |
| 5468 } | |
| 5469 | |
| 5470 p_j2k->m_specific_param.m_encoder.m_encoded_tile_size = (OPJ_UINT32)l_tile_size; | |
| 5471 p_j2k->m_specific_param.m_encoder.m_encoded_tile_data = | |
| 5472 (OPJ_BYTE *) opj_malloc(p_j2k->m_specific_param.m_encoder.m_encoded_tile_size); | |
| 5473 if (p_j2k->m_specific_param.m_encoder.m_encoded_tile_data == 00) { | |
| 5474 opj_event_msg(p_manager, EVT_ERROR, | |
| 5475 "Not enough memory to allocate m_encoded_tile_data. %u MB required\n", | |
| 5476 (OPJ_UINT32)(l_tile_size / 1024 / 1024)); | |
| 5477 return OPJ_FALSE; | |
| 5478 } | |
| 5479 | |
| 5480 if (p_j2k->m_specific_param.m_encoder.m_TLM) { | |
| 5481 p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer = | |
| 5482 (OPJ_BYTE *) opj_malloc(6 * | |
| 5483 p_j2k->m_specific_param.m_encoder.m_total_tile_parts); | |
| 5484 if (! p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer) { | |
| 5485 return OPJ_FALSE; | |
| 5486 } | |
| 5487 | |
| 5488 p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current = | |
| 5489 p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer; | |
| 5490 } | |
| 5491 | |
| 5492 return OPJ_TRUE; | |
| 5493 } | |
| 5494 | |
| 5495 #if 0 | |
| 5496 static OPJ_BOOL opj_j2k_read_eoc(opj_j2k_t *p_j2k, | |
| 5497 opj_stream_private_t *p_stream, | |
| 5498 opj_event_mgr_t * p_manager) | |
| 5499 { | |
| 5500 OPJ_UINT32 i; | |
| 5501 opj_tcd_t * l_tcd = 00; | |
| 5502 OPJ_UINT32 l_nb_tiles; | |
| 5503 opj_tcp_t * l_tcp = 00; | |
| 5504 OPJ_BOOL l_success; | |
| 5505 | |
| 5506 /* preconditions */ | |
| 5507 assert(p_j2k != 00); | |
| 5508 assert(p_manager != 00); | |
| 5509 assert(p_stream != 00); | |
| 5510 | |
| 5511 l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw; | |
| 5512 l_tcp = p_j2k->m_cp.tcps; | |
| 5513 | |
| 5514 l_tcd = opj_tcd_create(OPJ_TRUE); | |
| 5515 if (l_tcd == 00) { | |
| 5516 opj_event_msg(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n"); | |
| 5517 return OPJ_FALSE; | |
| 5518 } | |
| 5519 | |
| 5520 for (i = 0; i < l_nb_tiles; ++i) { | |
| 5521 if (l_tcp->m_data) { | |
| 5522 if (! opj_tcd_init_decode_tile(l_tcd, i)) { | |
| 5523 opj_tcd_destroy(l_tcd); | |
| 5524 opj_event_msg(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n"); | |
| 5525 return OPJ_FALSE; | |
| 5526 } | |
| 5527 | |
| 5528 l_success = opj_tcd_decode_tile(l_tcd, l_tcp->m_data, l_tcp->m_data_size, i, | |
| 5529 p_j2k->cstr_index); | |
| 5530 /* cleanup */ | |
| 5531 | |
| 5532 if (! l_success) { | |
| 5533 p_j2k->m_specific_param.m_decoder.m_state |= J2K_STATE_ERR; | |
| 5534 break; | |
| 5535 } | |
| 5536 } | |
| 5537 | |
| 5538 opj_j2k_tcp_destroy(l_tcp); | |
| 5539 ++l_tcp; | |
| 5540 } | |
| 5541 | |
| 5542 opj_tcd_destroy(l_tcd); | |
| 5543 return OPJ_TRUE; | |
| 5544 } | |
| 5545 #endif | |
| 5546 | |
| 5547 static OPJ_BOOL opj_j2k_get_end_header(opj_j2k_t *p_j2k, | |
| 5548 struct opj_stream_private *p_stream, | |
| 5549 struct opj_event_mgr * p_manager) | |
| 5550 { | |
| 5551 /* preconditions */ | |
| 5552 assert(p_j2k != 00); | |
| 5553 assert(p_manager != 00); | |
| 5554 assert(p_stream != 00); | |
| 5555 | |
| 5556 OPJ_UNUSED(p_manager); | |
| 5557 | |
| 5558 p_j2k->cstr_index->main_head_end = opj_stream_tell(p_stream); | |
| 5559 | |
| 5560 return OPJ_TRUE; | |
| 5561 } | |
| 5562 | |
| 5563 static OPJ_BOOL opj_j2k_write_mct_data_group(opj_j2k_t *p_j2k, | |
| 5564 struct opj_stream_private *p_stream, | |
| 5565 struct opj_event_mgr * p_manager) | |
| 5566 { | |
| 5567 OPJ_UINT32 i; | |
| 5568 opj_simple_mcc_decorrelation_data_t * l_mcc_record; | |
| 5569 opj_mct_data_t * l_mct_record; | |
| 5570 opj_tcp_t * l_tcp; | |
| 5571 | |
| 5572 /* preconditions */ | |
| 5573 assert(p_j2k != 00); | |
| 5574 assert(p_stream != 00); | |
| 5575 assert(p_manager != 00); | |
| 5576 | |
| 5577 if (! opj_j2k_write_cbd(p_j2k, p_stream, p_manager)) { | |
| 5578 return OPJ_FALSE; | |
| 5579 } | |
| 5580 | |
| 5581 l_tcp = &(p_j2k->m_cp.tcps[p_j2k->m_current_tile_number]); | |
| 5582 l_mct_record = l_tcp->m_mct_records; | |
| 5583 | |
| 5584 for (i = 0; i < l_tcp->m_nb_mct_records; ++i) { | |
| 5585 | |
| 5586 if (! opj_j2k_write_mct_record(p_j2k, l_mct_record, p_stream, p_manager)) { | |
| 5587 return OPJ_FALSE; | |
| 5588 } | |
| 5589 | |
| 5590 ++l_mct_record; | |
| 5591 } | |
| 5592 | |
| 5593 l_mcc_record = l_tcp->m_mcc_records; | |
| 5594 | |
| 5595 for (i = 0; i < l_tcp->m_nb_mcc_records; ++i) { | |
| 5596 | |
| 5597 if (! opj_j2k_write_mcc_record(p_j2k, l_mcc_record, p_stream, p_manager)) { | |
| 5598 return OPJ_FALSE; | |
| 5599 } | |
| 5600 | |
| 5601 ++l_mcc_record; | |
| 5602 } | |
| 5603 | |
| 5604 if (! opj_j2k_write_mco(p_j2k, p_stream, p_manager)) { | |
| 5605 return OPJ_FALSE; | |
| 5606 } | |
| 5607 | |
| 5608 return OPJ_TRUE; | |
| 5609 } | |
| 5610 | |
| 5611 static OPJ_BOOL opj_j2k_write_all_coc( | |
| 5612 opj_j2k_t *p_j2k, | |
| 5613 struct opj_stream_private *p_stream, | |
| 5614 struct opj_event_mgr * p_manager) | |
| 5615 { | |
| 5616 OPJ_UINT32 compno; | |
| 5617 | |
| 5618 /* preconditions */ | |
| 5619 assert(p_j2k != 00); | |
| 5620 assert(p_manager != 00); | |
| 5621 assert(p_stream != 00); | |
| 5622 | |
| 5623 for (compno = 1; compno < p_j2k->m_private_image->numcomps; ++compno) { | |
| 5624 /* cod is first component of first tile */ | |
| 5625 if (! opj_j2k_compare_coc(p_j2k, 0, compno)) { | |
| 5626 if (! opj_j2k_write_coc(p_j2k, compno, p_stream, p_manager)) { | |
| 5627 return OPJ_FALSE; | |
| 5628 } | |
| 5629 } | |
| 5630 } | |
| 5631 | |
| 5632 return OPJ_TRUE; | |
| 5633 } | |
| 5634 | |
| 5635 static OPJ_BOOL opj_j2k_write_all_qcc( | |
| 5636 opj_j2k_t *p_j2k, | |
| 5637 struct opj_stream_private *p_stream, | |
| 5638 struct opj_event_mgr * p_manager) | |
| 5639 { | |
| 5640 OPJ_UINT32 compno; | |
| 5641 | |
| 5642 /* preconditions */ | |
| 5643 assert(p_j2k != 00); | |
| 5644 assert(p_manager != 00); | |
| 5645 assert(p_stream != 00); | |
| 5646 | |
| 5647 for (compno = 1; compno < p_j2k->m_private_image->numcomps; ++compno) { | |
| 5648 /* qcd is first component of first tile */ | |
| 5649 if (! opj_j2k_compare_qcc(p_j2k, 0, compno)) { | |
| 5650 if (! opj_j2k_write_qcc(p_j2k, compno, p_stream, p_manager)) { | |
| 5651 return OPJ_FALSE; | |
| 5652 } | |
| 5653 } | |
| 5654 } | |
| 5655 return OPJ_TRUE; | |
| 5656 } | |
| 5657 | |
| 5658 static OPJ_BOOL opj_j2k_write_regions(opj_j2k_t *p_j2k, | |
| 5659 struct opj_stream_private *p_stream, | |
| 5660 struct opj_event_mgr * p_manager) | |
| 5661 { | |
| 5662 OPJ_UINT32 compno; | |
| 5663 const opj_tccp_t *l_tccp = 00; | |
| 5664 | |
| 5665 /* preconditions */ | |
| 5666 assert(p_j2k != 00); | |
| 5667 assert(p_manager != 00); | |
| 5668 assert(p_stream != 00); | |
| 5669 | |
| 5670 l_tccp = p_j2k->m_cp.tcps->tccps; | |
| 5671 | |
| 5672 for (compno = 0; compno < p_j2k->m_private_image->numcomps; ++compno) { | |
| 5673 if (l_tccp->roishift) { | |
| 5674 | |
| 5675 if (! opj_j2k_write_rgn(p_j2k, 0, compno, p_j2k->m_private_image->numcomps, | |
| 5676 p_stream, p_manager)) { | |
| 5677 return OPJ_FALSE; | |
| 5678 } | |
| 5679 } | |
| 5680 | |
| 5681 ++l_tccp; | |
| 5682 } | |
| 5683 | |
| 5684 return OPJ_TRUE; | |
| 5685 } | |
| 5686 | |
| 5687 static OPJ_BOOL opj_j2k_write_epc(opj_j2k_t *p_j2k, | |
| 5688 struct opj_stream_private *p_stream, | |
| 5689 struct opj_event_mgr * p_manager) | |
| 5690 { | |
| 5691 opj_codestream_index_t * l_cstr_index = 00; | |
| 5692 | |
| 5693 /* preconditions */ | |
| 5694 assert(p_j2k != 00); | |
| 5695 assert(p_manager != 00); | |
| 5696 assert(p_stream != 00); | |
| 5697 | |
| 5698 OPJ_UNUSED(p_manager); | |
| 5699 | |
| 5700 l_cstr_index = p_j2k->cstr_index; | |
| 5701 if (l_cstr_index) { | |
| 5702 l_cstr_index->codestream_size = (OPJ_UINT64)opj_stream_tell(p_stream); | |
| 5703 /* UniPG>> */ | |
| 5704 /* The following adjustment is done to adjust the codestream size */ | |
| 5705 /* if SOD is not at 0 in the buffer. Useful in case of JP2, where */ | |
| 5706 /* the first bunch of bytes is not in the codestream */ | |
| 5707 l_cstr_index->codestream_size -= (OPJ_UINT64)l_cstr_index->main_head_start; | |
| 5708 /* <<UniPG */ | |
| 5709 } | |
| 5710 | |
| 5711 #ifdef USE_JPWL | |
| 5712 /* preparation of JPWL marker segments */ | |
| 5713 #if 0 | |
| 5714 if (cp->epc_on) { | |
| 5715 | |
| 5716 /* encode according to JPWL */ | |
| 5717 jpwl_encode(p_j2k, p_stream, image); | |
| 5718 | |
| 5719 } | |
| 5720 #endif | |
| 5721 assert(0 && "TODO"); | |
| 5722 #endif /* USE_JPWL */ | |
| 5723 | |
| 5724 return OPJ_TRUE; | |
| 5725 } | |
| 5726 | |
| 5727 static OPJ_BOOL opj_j2k_read_unk(opj_j2k_t *p_j2k, | |
| 5728 opj_stream_private_t *p_stream, | |
| 5729 OPJ_UINT32 *output_marker, | |
| 5730 opj_event_mgr_t * p_manager | |
| 5731 ) | |
| 5732 { | |
| 5733 OPJ_UINT32 l_unknown_marker; | |
| 5734 const opj_dec_memory_marker_handler_t * l_marker_handler; | |
| 5735 OPJ_UINT32 l_size_unk = 2; | |
| 5736 | |
| 5737 /* preconditions*/ | |
| 5738 assert(p_j2k != 00); | |
| 5739 assert(p_manager != 00); | |
| 5740 assert(p_stream != 00); | |
| 5741 | |
| 5742 opj_event_msg(p_manager, EVT_WARNING, "Unknown marker\n"); | |
| 5743 | |
| 5744 for (;;) { | |
| 5745 /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer*/ | |
| 5746 if (opj_stream_read_data(p_stream, | |
| 5747 p_j2k->m_specific_param.m_decoder.m_header_data, 2, p_manager) != 2) { | |
| 5748 opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); | |
| 5749 return OPJ_FALSE; | |
| 5750 } | |
| 5751 | |
| 5752 /* read 2 bytes as the new marker ID*/ | |
| 5753 opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data, | |
| 5754 &l_unknown_marker, 2); | |
| 5755 | |
| 5756 if (!(l_unknown_marker < 0xff00)) { | |
| 5757 | |
| 5758 /* Get the marker handler from the marker ID*/ | |
| 5759 l_marker_handler = opj_j2k_get_marker_handler(l_unknown_marker); | |
| 5760 | |
| 5761 if (!(p_j2k->m_specific_param.m_decoder.m_state & l_marker_handler->states)) { | |
| 5762 opj_event_msg(p_manager, EVT_ERROR, | |
| 5763 "Marker is not compliant with its position\n"); | |
| 5764 return OPJ_FALSE; | |
| 5765 } else { | |
| 5766 if (l_marker_handler->id != J2K_MS_UNK) { | |
| 5767 /* Add the marker to the codestream index*/ | |
| 5768 if (l_marker_handler->id != J2K_MS_SOT) { | |
| 5769 OPJ_BOOL res = opj_j2k_add_mhmarker(p_j2k->cstr_index, J2K_MS_UNK, | |
| 5770 (OPJ_UINT32) opj_stream_tell(p_stream) - l_size_unk, | |
| 5771 l_size_unk); | |
| 5772 if (res == OPJ_FALSE) { | |
| 5773 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to add mh marker\n"); | |
| 5774 return OPJ_FALSE; | |
| 5775 } | |
| 5776 } | |
| 5777 break; /* next marker is known and well located */ | |
| 5778 } else { | |
| 5779 l_size_unk += 2; | |
| 5780 } | |
| 5781 } | |
| 5782 } | |
| 5783 } | |
| 5784 | |
| 5785 *output_marker = l_marker_handler->id ; | |
| 5786 | |
| 5787 return OPJ_TRUE; | |
| 5788 } | |
| 5789 | |
| 5790 static OPJ_BOOL opj_j2k_write_mct_record(opj_j2k_t *p_j2k, | |
| 5791 opj_mct_data_t * p_mct_record, | |
| 5792 struct opj_stream_private *p_stream, | |
| 5793 struct opj_event_mgr * p_manager) | |
| 5794 { | |
| 5795 OPJ_UINT32 l_mct_size; | |
| 5796 OPJ_BYTE * l_current_data = 00; | |
| 5797 OPJ_UINT32 l_tmp; | |
| 5798 | |
| 5799 /* preconditions */ | |
| 5800 assert(p_j2k != 00); | |
| 5801 assert(p_manager != 00); | |
| 5802 assert(p_stream != 00); | |
| 5803 | |
| 5804 l_mct_size = 10 + p_mct_record->m_data_size; | |
| 5805 | |
| 5806 if (l_mct_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) { | |
| 5807 OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc( | |
| 5808 p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_mct_size); | |
| 5809 if (! new_header_tile_data) { | |
| 5810 opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data); | |
| 5811 p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL; | |
| 5812 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0; | |
| 5813 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write MCT marker\n"); | |
| 5814 return OPJ_FALSE; | |
| 5815 } | |
| 5816 p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data; | |
| 5817 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_mct_size; | |
| 5818 } | |
| 5819 | |
| 5820 l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data; | |
| 5821 | |
| 5822 opj_write_bytes(l_current_data, J2K_MS_MCT, | |
| 5823 2); /* MCT */ | |
| 5824 l_current_data += 2; | |
| 5825 | |
| 5826 opj_write_bytes(l_current_data, l_mct_size - 2, | |
| 5827 2); /* Lmct */ | |
| 5828 l_current_data += 2; | |
| 5829 | |
| 5830 opj_write_bytes(l_current_data, 0, | |
| 5831 2); /* Zmct */ | |
| 5832 l_current_data += 2; | |
| 5833 | |
| 5834 /* only one marker atm */ | |
| 5835 l_tmp = (p_mct_record->m_index & 0xff) | (p_mct_record->m_array_type << 8) | | |
| 5836 (p_mct_record->m_element_type << 10); | |
| 5837 | |
| 5838 opj_write_bytes(l_current_data, l_tmp, 2); | |
| 5839 l_current_data += 2; | |
| 5840 | |
| 5841 opj_write_bytes(l_current_data, 0, | |
| 5842 2); /* Ymct */ | |
| 5843 l_current_data += 2; | |
| 5844 | |
| 5845 memcpy(l_current_data, p_mct_record->m_data, p_mct_record->m_data_size); | |
| 5846 | |
| 5847 if (opj_stream_write_data(p_stream, | |
| 5848 p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_mct_size, | |
| 5849 p_manager) != l_mct_size) { | |
| 5850 return OPJ_FALSE; | |
| 5851 } | |
| 5852 | |
| 5853 return OPJ_TRUE; | |
| 5854 } | |
| 5855 | |
| 5856 /** | |
| 5857 * Reads a MCT marker (Multiple Component Transform) | |
| 5858 * | |
| 5859 * @param p_header_data the data contained in the MCT box. | |
| 5860 * @param p_j2k the jpeg2000 codec. | |
| 5861 * @param p_header_size the size of the data contained in the MCT marker. | |
| 5862 * @param p_manager the user event manager. | |
| 5863 */ | |
| 5864 static OPJ_BOOL opj_j2k_read_mct(opj_j2k_t *p_j2k, | |
| 5865 OPJ_BYTE * p_header_data, | |
| 5866 OPJ_UINT32 p_header_size, | |
| 5867 opj_event_mgr_t * p_manager | |
| 5868 ) | |
| 5869 { | |
| 5870 OPJ_UINT32 i; | |
| 5871 opj_tcp_t *l_tcp = 00; | |
| 5872 OPJ_UINT32 l_tmp; | |
| 5873 OPJ_UINT32 l_indix; | |
| 5874 opj_mct_data_t * l_mct_data; | |
| 5875 | |
| 5876 /* preconditions */ | |
| 5877 assert(p_header_data != 00); | |
| 5878 assert(p_j2k != 00); | |
| 5879 | |
| 5880 l_tcp = p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH ? | |
| 5881 &p_j2k->m_cp.tcps[p_j2k->m_current_tile_number] : | |
| 5882 p_j2k->m_specific_param.m_decoder.m_default_tcp; | |
| 5883 | |
| 5884 if (p_header_size < 2) { | |
| 5885 opj_event_msg(p_manager, EVT_ERROR, "Error reading MCT marker\n"); | |
| 5886 return OPJ_FALSE; | |
| 5887 } | |
| 5888 | |
| 5889 /* first marker */ | |
| 5890 opj_read_bytes(p_header_data, &l_tmp, 2); /* Zmct */ | |
| 5891 p_header_data += 2; | |
| 5892 if (l_tmp != 0) { | |
| 5893 opj_event_msg(p_manager, EVT_WARNING, | |
| 5894 "Cannot take in charge mct data within multiple MCT records\n"); | |
| 5895 return OPJ_TRUE; | |
| 5896 } | |
| 5897 | |
| 5898 if (p_header_size <= 6) { | |
| 5899 opj_event_msg(p_manager, EVT_ERROR, "Error reading MCT marker\n"); | |
| 5900 return OPJ_FALSE; | |
| 5901 } | |
| 5902 | |
| 5903 /* Imct -> no need for other values, take the first, type is double with decorrelation x0000 1101 0000 0000*/ | |
| 5904 opj_read_bytes(p_header_data, &l_tmp, 2); /* Imct */ | |
| 5905 p_header_data += 2; | |
| 5906 | |
| 5907 l_indix = l_tmp & 0xff; | |
| 5908 l_mct_data = l_tcp->m_mct_records; | |
| 5909 | |
| 5910 for (i = 0; i < l_tcp->m_nb_mct_records; ++i) { | |
| 5911 if (l_mct_data->m_index == l_indix) { | |
| 5912 break; | |
| 5913 } | |
| 5914 ++l_mct_data; | |
| 5915 } | |
| 5916 | |
| 5917 /* NOT FOUND */ | |
| 5918 if (i == l_tcp->m_nb_mct_records) { | |
| 5919 if (l_tcp->m_nb_mct_records == l_tcp->m_nb_max_mct_records) { | |
| 5920 opj_mct_data_t *new_mct_records; | |
| 5921 l_tcp->m_nb_max_mct_records += OPJ_J2K_MCT_DEFAULT_NB_RECORDS; | |
| 5922 | |
| 5923 new_mct_records = (opj_mct_data_t *) opj_realloc(l_tcp->m_mct_records, | |
| 5924 l_tcp->m_nb_max_mct_records * sizeof(opj_mct_data_t)); | |
| 5925 if (! new_mct_records) { | |
| 5926 opj_free(l_tcp->m_mct_records); | |
| 5927 l_tcp->m_mct_records = NULL; | |
| 5928 l_tcp->m_nb_max_mct_records = 0; | |
| 5929 l_tcp->m_nb_mct_records = 0; | |
| 5930 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read MCT marker\n"); | |
| 5931 return OPJ_FALSE; | |
| 5932 } | |
| 5933 | |
| 5934 /* Update m_mcc_records[].m_offset_array and m_decorrelation_array | |
| 5935 * to point to the new addresses */ | |
| 5936 if (new_mct_records != l_tcp->m_mct_records) { | |
| 5937 for (i = 0; i < l_tcp->m_nb_mcc_records; ++i) { | |
| 5938 opj_simple_mcc_decorrelation_data_t* l_mcc_record = | |
| 5939 &(l_tcp->m_mcc_records[i]); | |
| 5940 if (l_mcc_record->m_decorrelation_array) { | |
| 5941 l_mcc_record->m_decorrelation_array = | |
| 5942 new_mct_records + | |
| 5943 (l_mcc_record->m_decorrelation_array - | |
| 5944 l_tcp->m_mct_records); | |
| 5945 } | |
| 5946 if (l_mcc_record->m_offset_array) { | |
| 5947 l_mcc_record->m_offset_array = | |
| 5948 new_mct_records + | |
| 5949 (l_mcc_record->m_offset_array - | |
| 5950 l_tcp->m_mct_records); | |
| 5951 } | |
| 5952 } | |
| 5953 } | |
| 5954 | |
| 5955 l_tcp->m_mct_records = new_mct_records; | |
| 5956 l_mct_data = l_tcp->m_mct_records + l_tcp->m_nb_mct_records; | |
| 5957 memset(l_mct_data, 0, (l_tcp->m_nb_max_mct_records - l_tcp->m_nb_mct_records) * | |
| 5958 sizeof(opj_mct_data_t)); | |
| 5959 } | |
| 5960 | |
| 5961 l_mct_data = l_tcp->m_mct_records + l_tcp->m_nb_mct_records; | |
| 5962 ++l_tcp->m_nb_mct_records; | |
| 5963 } | |
| 5964 | |
| 5965 if (l_mct_data->m_data) { | |
| 5966 opj_free(l_mct_data->m_data); | |
| 5967 l_mct_data->m_data = 00; | |
| 5968 l_mct_data->m_data_size = 0; | |
| 5969 } | |
| 5970 | |
| 5971 l_mct_data->m_index = l_indix; | |
| 5972 l_mct_data->m_array_type = (J2K_MCT_ARRAY_TYPE)((l_tmp >> 8) & 3); | |
| 5973 l_mct_data->m_element_type = (J2K_MCT_ELEMENT_TYPE)((l_tmp >> 10) & 3); | |
| 5974 | |
| 5975 opj_read_bytes(p_header_data, &l_tmp, 2); /* Ymct */ | |
| 5976 p_header_data += 2; | |
| 5977 if (l_tmp != 0) { | |
| 5978 opj_event_msg(p_manager, EVT_WARNING, | |
| 5979 "Cannot take in charge multiple MCT markers\n"); | |
| 5980 return OPJ_TRUE; | |
| 5981 } | |
| 5982 | |
| 5983 p_header_size -= 6; | |
| 5984 | |
| 5985 l_mct_data->m_data = (OPJ_BYTE*)opj_malloc(p_header_size); | |
| 5986 if (! l_mct_data->m_data) { | |
| 5987 opj_event_msg(p_manager, EVT_ERROR, "Error reading MCT marker\n"); | |
| 5988 return OPJ_FALSE; | |
| 5989 } | |
| 5990 memcpy(l_mct_data->m_data, p_header_data, p_header_size); | |
| 5991 | |
| 5992 l_mct_data->m_data_size = p_header_size; | |
| 5993 | |
| 5994 return OPJ_TRUE; | |
| 5995 } | |
| 5996 | |
| 5997 static OPJ_BOOL opj_j2k_write_mcc_record(opj_j2k_t *p_j2k, | |
| 5998 struct opj_simple_mcc_decorrelation_data * p_mcc_record, | |
| 5999 struct opj_stream_private *p_stream, | |
| 6000 struct opj_event_mgr * p_manager) | |
| 6001 { | |
| 6002 OPJ_UINT32 i; | |
| 6003 OPJ_UINT32 l_mcc_size; | |
| 6004 OPJ_BYTE * l_current_data = 00; | |
| 6005 OPJ_UINT32 l_nb_bytes_for_comp; | |
| 6006 OPJ_UINT32 l_mask; | |
| 6007 OPJ_UINT32 l_tmcc; | |
| 6008 | |
| 6009 /* preconditions */ | |
| 6010 assert(p_j2k != 00); | |
| 6011 assert(p_manager != 00); | |
| 6012 assert(p_stream != 00); | |
| 6013 | |
| 6014 if (p_mcc_record->m_nb_comps > 255) { | |
| 6015 l_nb_bytes_for_comp = 2; | |
| 6016 l_mask = 0x8000; | |
| 6017 } else { | |
| 6018 l_nb_bytes_for_comp = 1; | |
| 6019 l_mask = 0; | |
| 6020 } | |
| 6021 | |
| 6022 l_mcc_size = p_mcc_record->m_nb_comps * 2 * l_nb_bytes_for_comp + 19; | |
| 6023 if (l_mcc_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) { | |
| 6024 OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc( | |
| 6025 p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_mcc_size); | |
| 6026 if (! new_header_tile_data) { | |
| 6027 opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data); | |
| 6028 p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL; | |
| 6029 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0; | |
| 6030 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write MCC marker\n"); | |
| 6031 return OPJ_FALSE; | |
| 6032 } | |
| 6033 p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data; | |
| 6034 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_mcc_size; | |
| 6035 } | |
| 6036 | |
| 6037 l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data; | |
| 6038 | |
| 6039 opj_write_bytes(l_current_data, J2K_MS_MCC, | |
| 6040 2); /* MCC */ | |
| 6041 l_current_data += 2; | |
| 6042 | |
| 6043 opj_write_bytes(l_current_data, l_mcc_size - 2, | |
| 6044 2); /* Lmcc */ | |
| 6045 l_current_data += 2; | |
| 6046 | |
| 6047 /* first marker */ | |
| 6048 opj_write_bytes(l_current_data, 0, | |
| 6049 2); /* Zmcc */ | |
| 6050 l_current_data += 2; | |
| 6051 | |
| 6052 opj_write_bytes(l_current_data, p_mcc_record->m_index, | |
| 6053 1); /* Imcc -> no need for other values, take the first */ | |
| 6054 ++l_current_data; | |
| 6055 | |
| 6056 /* only one marker atm */ | |
| 6057 opj_write_bytes(l_current_data, 0, | |
| 6058 2); /* Ymcc */ | |
| 6059 l_current_data += 2; | |
| 6060 | |
| 6061 opj_write_bytes(l_current_data, 1, | |
| 6062 2); /* Qmcc -> number of collections -> 1 */ | |
| 6063 l_current_data += 2; | |
| 6064 | |
| 6065 opj_write_bytes(l_current_data, 0x1, | |
| 6066 1); /* Xmcci type of component transformation -> array based decorrelation */ | |
| 6067 ++l_current_data; | |
| 6068 | |
| 6069 opj_write_bytes(l_current_data, p_mcc_record->m_nb_comps | l_mask, | |
| 6070 2); /* Nmcci number of input components involved and size for each component offset = 8 bits */ | |
| 6071 l_current_data += 2; | |
| 6072 | |
| 6073 for (i = 0; i < p_mcc_record->m_nb_comps; ++i) { | |
| 6074 opj_write_bytes(l_current_data, i, | |
| 6075 l_nb_bytes_for_comp); /* Cmccij Component offset*/ | |
| 6076 l_current_data += l_nb_bytes_for_comp; | |
| 6077 } | |
| 6078 | |
| 6079 opj_write_bytes(l_current_data, p_mcc_record->m_nb_comps | l_mask, | |
| 6080 2); /* Mmcci number of output components involved and size for each component offset = 8 bits */ | |
| 6081 l_current_data += 2; | |
| 6082 | |
| 6083 for (i = 0; i < p_mcc_record->m_nb_comps; ++i) { | |
| 6084 opj_write_bytes(l_current_data, i, | |
| 6085 l_nb_bytes_for_comp); /* Wmccij Component offset*/ | |
| 6086 l_current_data += l_nb_bytes_for_comp; | |
| 6087 } | |
| 6088 | |
| 6089 l_tmcc = ((!p_mcc_record->m_is_irreversible) & 1U) << 16; | |
| 6090 | |
| 6091 if (p_mcc_record->m_decorrelation_array) { | |
| 6092 l_tmcc |= p_mcc_record->m_decorrelation_array->m_index; | |
| 6093 } | |
| 6094 | |
| 6095 if (p_mcc_record->m_offset_array) { | |
| 6096 l_tmcc |= ((p_mcc_record->m_offset_array->m_index) << 8); | |
| 6097 } | |
| 6098 | |
| 6099 opj_write_bytes(l_current_data, l_tmcc, | |
| 6100 3); /* Tmcci : use MCT defined as number 1 and irreversible array based. */ | |
| 6101 l_current_data += 3; | |
| 6102 | |
| 6103 if (opj_stream_write_data(p_stream, | |
| 6104 p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_mcc_size, | |
| 6105 p_manager) != l_mcc_size) { | |
| 6106 return OPJ_FALSE; | |
| 6107 } | |
| 6108 | |
| 6109 return OPJ_TRUE; | |
| 6110 } | |
| 6111 | |
| 6112 static OPJ_BOOL opj_j2k_read_mcc(opj_j2k_t *p_j2k, | |
| 6113 OPJ_BYTE * p_header_data, | |
| 6114 OPJ_UINT32 p_header_size, | |
| 6115 opj_event_mgr_t * p_manager) | |
| 6116 { | |
| 6117 OPJ_UINT32 i, j; | |
| 6118 OPJ_UINT32 l_tmp; | |
| 6119 OPJ_UINT32 l_indix; | |
| 6120 opj_tcp_t * l_tcp; | |
| 6121 opj_simple_mcc_decorrelation_data_t * l_mcc_record; | |
| 6122 opj_mct_data_t * l_mct_data; | |
| 6123 OPJ_UINT32 l_nb_collections; | |
| 6124 OPJ_UINT32 l_nb_comps; | |
| 6125 OPJ_UINT32 l_nb_bytes_by_comp; | |
| 6126 OPJ_BOOL l_new_mcc = OPJ_FALSE; | |
| 6127 | |
| 6128 /* preconditions */ | |
| 6129 assert(p_header_data != 00); | |
| 6130 assert(p_j2k != 00); | |
| 6131 assert(p_manager != 00); | |
| 6132 | |
| 6133 l_tcp = p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH ? | |
| 6134 &p_j2k->m_cp.tcps[p_j2k->m_current_tile_number] : | |
| 6135 p_j2k->m_specific_param.m_decoder.m_default_tcp; | |
| 6136 | |
| 6137 if (p_header_size < 2) { | |
| 6138 opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n"); | |
| 6139 return OPJ_FALSE; | |
| 6140 } | |
| 6141 | |
| 6142 /* first marker */ | |
| 6143 opj_read_bytes(p_header_data, &l_tmp, 2); /* Zmcc */ | |
| 6144 p_header_data += 2; | |
| 6145 if (l_tmp != 0) { | |
| 6146 opj_event_msg(p_manager, EVT_WARNING, | |
| 6147 "Cannot take in charge multiple data spanning\n"); | |
| 6148 return OPJ_TRUE; | |
| 6149 } | |
| 6150 | |
| 6151 if (p_header_size < 7) { | |
| 6152 opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n"); | |
| 6153 return OPJ_FALSE; | |
| 6154 } | |
| 6155 | |
| 6156 opj_read_bytes(p_header_data, &l_indix, | |
| 6157 1); /* Imcc -> no need for other values, take the first */ | |
| 6158 ++p_header_data; | |
| 6159 | |
| 6160 l_mcc_record = l_tcp->m_mcc_records; | |
| 6161 | |
| 6162 for (i = 0; i < l_tcp->m_nb_mcc_records; ++i) { | |
| 6163 if (l_mcc_record->m_index == l_indix) { | |
| 6164 break; | |
| 6165 } | |
| 6166 ++l_mcc_record; | |
| 6167 } | |
| 6168 | |
| 6169 /** NOT FOUND */ | |
| 6170 if (i == l_tcp->m_nb_mcc_records) { | |
| 6171 if (l_tcp->m_nb_mcc_records == l_tcp->m_nb_max_mcc_records) { | |
| 6172 opj_simple_mcc_decorrelation_data_t *new_mcc_records; | |
| 6173 l_tcp->m_nb_max_mcc_records += OPJ_J2K_MCC_DEFAULT_NB_RECORDS; | |
| 6174 | |
| 6175 new_mcc_records = (opj_simple_mcc_decorrelation_data_t *) opj_realloc( | |
| 6176 l_tcp->m_mcc_records, l_tcp->m_nb_max_mcc_records * sizeof( | |
| 6177 opj_simple_mcc_decorrelation_data_t)); | |
| 6178 if (! new_mcc_records) { | |
| 6179 opj_free(l_tcp->m_mcc_records); | |
| 6180 l_tcp->m_mcc_records = NULL; | |
| 6181 l_tcp->m_nb_max_mcc_records = 0; | |
| 6182 l_tcp->m_nb_mcc_records = 0; | |
| 6183 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read MCC marker\n"); | |
| 6184 return OPJ_FALSE; | |
| 6185 } | |
| 6186 l_tcp->m_mcc_records = new_mcc_records; | |
| 6187 l_mcc_record = l_tcp->m_mcc_records + l_tcp->m_nb_mcc_records; | |
| 6188 memset(l_mcc_record, 0, (l_tcp->m_nb_max_mcc_records - l_tcp->m_nb_mcc_records) | |
| 6189 * sizeof(opj_simple_mcc_decorrelation_data_t)); | |
| 6190 } | |
| 6191 l_mcc_record = l_tcp->m_mcc_records + l_tcp->m_nb_mcc_records; | |
| 6192 l_new_mcc = OPJ_TRUE; | |
| 6193 } | |
| 6194 l_mcc_record->m_index = l_indix; | |
| 6195 | |
| 6196 /* only one marker atm */ | |
| 6197 opj_read_bytes(p_header_data, &l_tmp, 2); /* Ymcc */ | |
| 6198 p_header_data += 2; | |
| 6199 if (l_tmp != 0) { | |
| 6200 opj_event_msg(p_manager, EVT_WARNING, | |
| 6201 "Cannot take in charge multiple data spanning\n"); | |
| 6202 return OPJ_TRUE; | |
| 6203 } | |
| 6204 | |
| 6205 opj_read_bytes(p_header_data, &l_nb_collections, | |
| 6206 2); /* Qmcc -> number of collections -> 1 */ | |
| 6207 p_header_data += 2; | |
| 6208 | |
| 6209 if (l_nb_collections > 1) { | |
| 6210 opj_event_msg(p_manager, EVT_WARNING, | |
| 6211 "Cannot take in charge multiple collections\n"); | |
| 6212 return OPJ_TRUE; | |
| 6213 } | |
| 6214 | |
| 6215 p_header_size -= 7; | |
| 6216 | |
| 6217 for (i = 0; i < l_nb_collections; ++i) { | |
| 6218 if (p_header_size < 3) { | |
| 6219 opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n"); | |
| 6220 return OPJ_FALSE; | |
| 6221 } | |
| 6222 | |
| 6223 opj_read_bytes(p_header_data, &l_tmp, | |
| 6224 1); /* Xmcci type of component transformation -> array based decorrelation */ | |
| 6225 ++p_header_data; | |
| 6226 | |
| 6227 if (l_tmp != 1) { | |
| 6228 opj_event_msg(p_manager, EVT_WARNING, | |
| 6229 "Cannot take in charge collections other than array decorrelation\n"); | |
| 6230 return OPJ_TRUE; | |
| 6231 } | |
| 6232 | |
| 6233 opj_read_bytes(p_header_data, &l_nb_comps, 2); | |
| 6234 | |
| 6235 p_header_data += 2; | |
| 6236 p_header_size -= 3; | |
| 6237 | |
| 6238 l_nb_bytes_by_comp = 1 + (l_nb_comps >> 15); | |
| 6239 l_mcc_record->m_nb_comps = l_nb_comps & 0x7fff; | |
| 6240 | |
| 6241 if (p_header_size < (l_nb_bytes_by_comp * l_mcc_record->m_nb_comps + 2)) { | |
| 6242 opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n"); | |
| 6243 return OPJ_FALSE; | |
| 6244 } | |
| 6245 | |
| 6246 p_header_size -= (l_nb_bytes_by_comp * l_mcc_record->m_nb_comps + 2); | |
| 6247 | |
| 6248 for (j = 0; j < l_mcc_record->m_nb_comps; ++j) { | |
| 6249 opj_read_bytes(p_header_data, &l_tmp, | |
| 6250 l_nb_bytes_by_comp); /* Cmccij Component offset*/ | |
| 6251 p_header_data += l_nb_bytes_by_comp; | |
| 6252 | |
| 6253 if (l_tmp != j) { | |
| 6254 opj_event_msg(p_manager, EVT_WARNING, | |
| 6255 "Cannot take in charge collections with indix shuffle\n"); | |
| 6256 return OPJ_TRUE; | |
| 6257 } | |
| 6258 } | |
| 6259 | |
| 6260 opj_read_bytes(p_header_data, &l_nb_comps, 2); | |
| 6261 p_header_data += 2; | |
| 6262 | |
| 6263 l_nb_bytes_by_comp = 1 + (l_nb_comps >> 15); | |
| 6264 l_nb_comps &= 0x7fff; | |
| 6265 | |
| 6266 if (l_nb_comps != l_mcc_record->m_nb_comps) { | |
| 6267 opj_event_msg(p_manager, EVT_WARNING, | |
| 6268 "Cannot take in charge collections without same number of indixes\n"); | |
| 6269 return OPJ_TRUE; | |
| 6270 } | |
| 6271 | |
| 6272 if (p_header_size < (l_nb_bytes_by_comp * l_mcc_record->m_nb_comps + 3)) { | |
| 6273 opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n"); | |
| 6274 return OPJ_FALSE; | |
| 6275 } | |
| 6276 | |
| 6277 p_header_size -= (l_nb_bytes_by_comp * l_mcc_record->m_nb_comps + 3); | |
| 6278 | |
| 6279 for (j = 0; j < l_mcc_record->m_nb_comps; ++j) { | |
| 6280 opj_read_bytes(p_header_data, &l_tmp, | |
| 6281 l_nb_bytes_by_comp); /* Wmccij Component offset*/ | |
| 6282 p_header_data += l_nb_bytes_by_comp; | |
| 6283 | |
| 6284 if (l_tmp != j) { | |
| 6285 opj_event_msg(p_manager, EVT_WARNING, | |
| 6286 "Cannot take in charge collections with indix shuffle\n"); | |
| 6287 return OPJ_TRUE; | |
| 6288 } | |
| 6289 } | |
| 6290 | |
| 6291 opj_read_bytes(p_header_data, &l_tmp, 3); /* Wmccij Component offset*/ | |
| 6292 p_header_data += 3; | |
| 6293 | |
| 6294 l_mcc_record->m_is_irreversible = !((l_tmp >> 16) & 1); | |
| 6295 l_mcc_record->m_decorrelation_array = 00; | |
| 6296 l_mcc_record->m_offset_array = 00; | |
| 6297 | |
| 6298 l_indix = l_tmp & 0xff; | |
| 6299 if (l_indix != 0) { | |
| 6300 l_mct_data = l_tcp->m_mct_records; | |
| 6301 for (j = 0; j < l_tcp->m_nb_mct_records; ++j) { | |
| 6302 if (l_mct_data->m_index == l_indix) { | |
| 6303 l_mcc_record->m_decorrelation_array = l_mct_data; | |
| 6304 break; | |
| 6305 } | |
| 6306 ++l_mct_data; | |
| 6307 } | |
| 6308 | |
| 6309 if (l_mcc_record->m_decorrelation_array == 00) { | |
| 6310 opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n"); | |
| 6311 return OPJ_FALSE; | |
| 6312 } | |
| 6313 } | |
| 6314 | |
| 6315 l_indix = (l_tmp >> 8) & 0xff; | |
| 6316 if (l_indix != 0) { | |
| 6317 l_mct_data = l_tcp->m_mct_records; | |
| 6318 for (j = 0; j < l_tcp->m_nb_mct_records; ++j) { | |
| 6319 if (l_mct_data->m_index == l_indix) { | |
| 6320 l_mcc_record->m_offset_array = l_mct_data; | |
| 6321 break; | |
| 6322 } | |
| 6323 ++l_mct_data; | |
| 6324 } | |
| 6325 | |
| 6326 if (l_mcc_record->m_offset_array == 00) { | |
| 6327 opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n"); | |
| 6328 return OPJ_FALSE; | |
| 6329 } | |
| 6330 } | |
| 6331 } | |
| 6332 | |
| 6333 if (p_header_size != 0) { | |
| 6334 opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n"); | |
| 6335 return OPJ_FALSE; | |
| 6336 } | |
| 6337 | |
| 6338 if (l_new_mcc) { | |
| 6339 ++l_tcp->m_nb_mcc_records; | |
| 6340 } | |
| 6341 | |
| 6342 return OPJ_TRUE; | |
| 6343 } | |
| 6344 | |
| 6345 static OPJ_BOOL opj_j2k_write_mco(opj_j2k_t *p_j2k, | |
| 6346 struct opj_stream_private *p_stream, | |
| 6347 struct opj_event_mgr * p_manager | |
| 6348 ) | |
| 6349 { | |
| 6350 OPJ_BYTE * l_current_data = 00; | |
| 6351 OPJ_UINT32 l_mco_size; | |
| 6352 opj_tcp_t * l_tcp = 00; | |
| 6353 opj_simple_mcc_decorrelation_data_t * l_mcc_record; | |
| 6354 OPJ_UINT32 i; | |
| 6355 | |
| 6356 /* preconditions */ | |
| 6357 assert(p_j2k != 00); | |
| 6358 assert(p_manager != 00); | |
| 6359 assert(p_stream != 00); | |
| 6360 | |
| 6361 l_tcp = &(p_j2k->m_cp.tcps[p_j2k->m_current_tile_number]); | |
| 6362 | |
| 6363 l_mco_size = 5 + l_tcp->m_nb_mcc_records; | |
| 6364 if (l_mco_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) { | |
| 6365 | |
| 6366 OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc( | |
| 6367 p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_mco_size); | |
| 6368 if (! new_header_tile_data) { | |
| 6369 opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data); | |
| 6370 p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL; | |
| 6371 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0; | |
| 6372 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write MCO marker\n"); | |
| 6373 return OPJ_FALSE; | |
| 6374 } | |
| 6375 p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data; | |
| 6376 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_mco_size; | |
| 6377 } | |
| 6378 l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data; | |
| 6379 | |
| 6380 | |
| 6381 opj_write_bytes(l_current_data, J2K_MS_MCO, 2); /* MCO */ | |
| 6382 l_current_data += 2; | |
| 6383 | |
| 6384 opj_write_bytes(l_current_data, l_mco_size - 2, 2); /* Lmco */ | |
| 6385 l_current_data += 2; | |
| 6386 | |
| 6387 opj_write_bytes(l_current_data, l_tcp->m_nb_mcc_records, | |
| 6388 1); /* Nmco : only one transform stage*/ | |
| 6389 ++l_current_data; | |
| 6390 | |
| 6391 l_mcc_record = l_tcp->m_mcc_records; | |
| 6392 for (i = 0; i < l_tcp->m_nb_mcc_records; ++i) { | |
| 6393 opj_write_bytes(l_current_data, l_mcc_record->m_index, | |
| 6394 1); /* Imco -> use the mcc indicated by 1*/ | |
| 6395 ++l_current_data; | |
| 6396 ++l_mcc_record; | |
| 6397 } | |
| 6398 | |
| 6399 if (opj_stream_write_data(p_stream, | |
| 6400 p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_mco_size, | |
| 6401 p_manager) != l_mco_size) { | |
| 6402 return OPJ_FALSE; | |
| 6403 } | |
| 6404 | |
| 6405 return OPJ_TRUE; | |
| 6406 } | |
| 6407 | |
| 6408 /** | |
| 6409 * Reads a MCO marker (Multiple Component Transform Ordering) | |
| 6410 * | |
| 6411 * @param p_header_data the data contained in the MCO box. | |
| 6412 * @param p_j2k the jpeg2000 codec. | |
| 6413 * @param p_header_size the size of the data contained in the MCO marker. | |
| 6414 * @param p_manager the user event manager. | |
| 6415 */ | |
| 6416 static OPJ_BOOL opj_j2k_read_mco(opj_j2k_t *p_j2k, | |
| 6417 OPJ_BYTE * p_header_data, | |
| 6418 OPJ_UINT32 p_header_size, | |
| 6419 opj_event_mgr_t * p_manager | |
| 6420 ) | |
| 6421 { | |
| 6422 OPJ_UINT32 l_tmp, i; | |
| 6423 OPJ_UINT32 l_nb_stages; | |
| 6424 opj_tcp_t * l_tcp; | |
| 6425 opj_tccp_t * l_tccp; | |
| 6426 opj_image_t * l_image; | |
| 6427 | |
| 6428 /* preconditions */ | |
| 6429 assert(p_header_data != 00); | |
| 6430 assert(p_j2k != 00); | |
| 6431 assert(p_manager != 00); | |
| 6432 | |
| 6433 l_image = p_j2k->m_private_image; | |
| 6434 l_tcp = p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH ? | |
| 6435 &p_j2k->m_cp.tcps[p_j2k->m_current_tile_number] : | |
| 6436 p_j2k->m_specific_param.m_decoder.m_default_tcp; | |
| 6437 | |
| 6438 if (p_header_size < 1) { | |
| 6439 opj_event_msg(p_manager, EVT_ERROR, "Error reading MCO marker\n"); | |
| 6440 return OPJ_FALSE; | |
| 6441 } | |
| 6442 | |
| 6443 opj_read_bytes(p_header_data, &l_nb_stages, | |
| 6444 1); /* Nmco : only one transform stage*/ | |
| 6445 ++p_header_data; | |
| 6446 | |
| 6447 if (l_nb_stages > 1) { | |
| 6448 opj_event_msg(p_manager, EVT_WARNING, | |
| 6449 "Cannot take in charge multiple transformation stages.\n"); | |
| 6450 return OPJ_TRUE; | |
| 6451 } | |
| 6452 | |
| 6453 if (p_header_size != l_nb_stages + 1) { | |
| 6454 opj_event_msg(p_manager, EVT_WARNING, "Error reading MCO marker\n"); | |
| 6455 return OPJ_FALSE; | |
| 6456 } | |
| 6457 | |
| 6458 l_tccp = l_tcp->tccps; | |
| 6459 | |
| 6460 for (i = 0; i < l_image->numcomps; ++i) { | |
| 6461 l_tccp->m_dc_level_shift = 0; | |
| 6462 ++l_tccp; | |
| 6463 } | |
| 6464 | |
| 6465 if (l_tcp->m_mct_decoding_matrix) { | |
| 6466 opj_free(l_tcp->m_mct_decoding_matrix); | |
| 6467 l_tcp->m_mct_decoding_matrix = 00; | |
| 6468 } | |
| 6469 | |
| 6470 for (i = 0; i < l_nb_stages; ++i) { | |
| 6471 opj_read_bytes(p_header_data, &l_tmp, 1); | |
| 6472 ++p_header_data; | |
| 6473 | |
| 6474 if (! opj_j2k_add_mct(l_tcp, p_j2k->m_private_image, l_tmp)) { | |
| 6475 return OPJ_FALSE; | |
| 6476 } | |
| 6477 } | |
| 6478 | |
| 6479 return OPJ_TRUE; | |
| 6480 } | |
| 6481 | |
| 6482 static OPJ_BOOL opj_j2k_add_mct(opj_tcp_t * p_tcp, opj_image_t * p_image, | |
| 6483 OPJ_UINT32 p_index) | |
| 6484 { | |
| 6485 OPJ_UINT32 i; | |
| 6486 opj_simple_mcc_decorrelation_data_t * l_mcc_record; | |
| 6487 opj_mct_data_t * l_deco_array, * l_offset_array; | |
| 6488 OPJ_UINT32 l_data_size, l_mct_size, l_offset_size; | |
| 6489 OPJ_UINT32 l_nb_elem; | |
| 6490 OPJ_UINT32 * l_offset_data, * l_current_offset_data; | |
| 6491 opj_tccp_t * l_tccp; | |
| 6492 | |
| 6493 /* preconditions */ | |
| 6494 assert(p_tcp != 00); | |
| 6495 | |
| 6496 l_mcc_record = p_tcp->m_mcc_records; | |
| 6497 | |
| 6498 for (i = 0; i < p_tcp->m_nb_mcc_records; ++i) { | |
| 6499 if (l_mcc_record->m_index == p_index) { | |
| 6500 break; | |
| 6501 } | |
| 6502 } | |
| 6503 | |
| 6504 if (i == p_tcp->m_nb_mcc_records) { | |
| 6505 /** element discarded **/ | |
| 6506 return OPJ_TRUE; | |
| 6507 } | |
| 6508 | |
| 6509 if (l_mcc_record->m_nb_comps != p_image->numcomps) { | |
| 6510 /** do not support number of comps != image */ | |
| 6511 return OPJ_TRUE; | |
| 6512 } | |
| 6513 | |
| 6514 l_deco_array = l_mcc_record->m_decorrelation_array; | |
| 6515 | |
| 6516 if (l_deco_array) { | |
| 6517 l_data_size = MCT_ELEMENT_SIZE[l_deco_array->m_element_type] * p_image->numcomps | |
| 6518 * p_image->numcomps; | |
| 6519 if (l_deco_array->m_data_size != l_data_size) { | |
| 6520 return OPJ_FALSE; | |
| 6521 } | |
| 6522 | |
| 6523 l_nb_elem = p_image->numcomps * p_image->numcomps; | |
| 6524 l_mct_size = l_nb_elem * (OPJ_UINT32)sizeof(OPJ_FLOAT32); | |
| 6525 p_tcp->m_mct_decoding_matrix = (OPJ_FLOAT32*)opj_malloc(l_mct_size); | |
| 6526 | |
| 6527 if (! p_tcp->m_mct_decoding_matrix) { | |
| 6528 return OPJ_FALSE; | |
| 6529 } | |
| 6530 | |
| 6531 j2k_mct_read_functions_to_float[l_deco_array->m_element_type]( | |
| 6532 l_deco_array->m_data, p_tcp->m_mct_decoding_matrix, l_nb_elem); | |
| 6533 } | |
| 6534 | |
| 6535 l_offset_array = l_mcc_record->m_offset_array; | |
| 6536 | |
| 6537 if (l_offset_array) { | |
| 6538 l_data_size = MCT_ELEMENT_SIZE[l_offset_array->m_element_type] * | |
| 6539 p_image->numcomps; | |
| 6540 if (l_offset_array->m_data_size != l_data_size) { | |
| 6541 return OPJ_FALSE; | |
| 6542 } | |
| 6543 | |
| 6544 l_nb_elem = p_image->numcomps; | |
| 6545 l_offset_size = l_nb_elem * (OPJ_UINT32)sizeof(OPJ_UINT32); | |
| 6546 l_offset_data = (OPJ_UINT32*)opj_malloc(l_offset_size); | |
| 6547 | |
| 6548 if (! l_offset_data) { | |
| 6549 return OPJ_FALSE; | |
| 6550 } | |
| 6551 | |
| 6552 j2k_mct_read_functions_to_int32[l_offset_array->m_element_type]( | |
| 6553 l_offset_array->m_data, l_offset_data, l_nb_elem); | |
| 6554 | |
| 6555 l_tccp = p_tcp->tccps; | |
| 6556 l_current_offset_data = l_offset_data; | |
| 6557 | |
| 6558 for (i = 0; i < p_image->numcomps; ++i) { | |
| 6559 l_tccp->m_dc_level_shift = (OPJ_INT32) * (l_current_offset_data++); | |
| 6560 ++l_tccp; | |
| 6561 } | |
| 6562 | |
| 6563 opj_free(l_offset_data); | |
| 6564 } | |
| 6565 | |
| 6566 return OPJ_TRUE; | |
| 6567 } | |
| 6568 | |
| 6569 static OPJ_BOOL opj_j2k_write_cbd(opj_j2k_t *p_j2k, | |
| 6570 struct opj_stream_private *p_stream, | |
| 6571 struct opj_event_mgr * p_manager) | |
| 6572 { | |
| 6573 OPJ_UINT32 i; | |
| 6574 OPJ_UINT32 l_cbd_size; | |
| 6575 OPJ_BYTE * l_current_data = 00; | |
| 6576 opj_image_t *l_image = 00; | |
| 6577 opj_image_comp_t * l_comp = 00; | |
| 6578 | |
| 6579 /* preconditions */ | |
| 6580 assert(p_j2k != 00); | |
| 6581 assert(p_manager != 00); | |
| 6582 assert(p_stream != 00); | |
| 6583 | |
| 6584 l_image = p_j2k->m_private_image; | |
| 6585 l_cbd_size = 6 + p_j2k->m_private_image->numcomps; | |
| 6586 | |
| 6587 if (l_cbd_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) { | |
| 6588 OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc( | |
| 6589 p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_cbd_size); | |
| 6590 if (! new_header_tile_data) { | |
| 6591 opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data); | |
| 6592 p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL; | |
| 6593 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0; | |
| 6594 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write CBD marker\n"); | |
| 6595 return OPJ_FALSE; | |
| 6596 } | |
| 6597 p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data; | |
| 6598 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_cbd_size; | |
| 6599 } | |
| 6600 | |
| 6601 l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data; | |
| 6602 | |
| 6603 opj_write_bytes(l_current_data, J2K_MS_CBD, 2); /* CBD */ | |
| 6604 l_current_data += 2; | |
| 6605 | |
| 6606 opj_write_bytes(l_current_data, l_cbd_size - 2, 2); /* L_CBD */ | |
| 6607 l_current_data += 2; | |
| 6608 | |
| 6609 opj_write_bytes(l_current_data, l_image->numcomps, 2); /* Ncbd */ | |
| 6610 l_current_data += 2; | |
| 6611 | |
| 6612 l_comp = l_image->comps; | |
| 6613 | |
| 6614 for (i = 0; i < l_image->numcomps; ++i) { | |
| 6615 opj_write_bytes(l_current_data, (l_comp->sgnd << 7) | (l_comp->prec - 1), | |
| 6616 1); /* Component bit depth */ | |
| 6617 ++l_current_data; | |
| 6618 | |
| 6619 ++l_comp; | |
| 6620 } | |
| 6621 | |
| 6622 if (opj_stream_write_data(p_stream, | |
| 6623 p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_cbd_size, | |
| 6624 p_manager) != l_cbd_size) { | |
| 6625 return OPJ_FALSE; | |
| 6626 } | |
| 6627 | |
| 6628 return OPJ_TRUE; | |
| 6629 } | |
| 6630 | |
| 6631 /** | |
| 6632 * Reads a CBD marker (Component bit depth definition) | |
| 6633 * @param p_header_data the data contained in the CBD box. | |
| 6634 * @param p_j2k the jpeg2000 codec. | |
| 6635 * @param p_header_size the size of the data contained in the CBD marker. | |
| 6636 * @param p_manager the user event manager. | |
| 6637 */ | |
| 6638 static OPJ_BOOL opj_j2k_read_cbd(opj_j2k_t *p_j2k, | |
| 6639 OPJ_BYTE * p_header_data, | |
| 6640 OPJ_UINT32 p_header_size, | |
| 6641 opj_event_mgr_t * p_manager | |
| 6642 ) | |
| 6643 { | |
| 6644 OPJ_UINT32 l_nb_comp, l_num_comp; | |
| 6645 OPJ_UINT32 l_comp_def; | |
| 6646 OPJ_UINT32 i; | |
| 6647 opj_image_comp_t * l_comp = 00; | |
| 6648 | |
| 6649 /* preconditions */ | |
| 6650 assert(p_header_data != 00); | |
| 6651 assert(p_j2k != 00); | |
| 6652 assert(p_manager != 00); | |
| 6653 | |
| 6654 l_num_comp = p_j2k->m_private_image->numcomps; | |
| 6655 | |
| 6656 if (p_header_size != (p_j2k->m_private_image->numcomps + 2)) { | |
| 6657 opj_event_msg(p_manager, EVT_ERROR, "Crror reading CBD marker\n"); | |
| 6658 return OPJ_FALSE; | |
| 6659 } | |
| 6660 | |
| 6661 opj_read_bytes(p_header_data, &l_nb_comp, | |
| 6662 2); /* Ncbd */ | |
| 6663 p_header_data += 2; | |
| 6664 | |
| 6665 if (l_nb_comp != l_num_comp) { | |
| 6666 opj_event_msg(p_manager, EVT_ERROR, "Crror reading CBD marker\n"); | |
| 6667 return OPJ_FALSE; | |
| 6668 } | |
| 6669 | |
| 6670 l_comp = p_j2k->m_private_image->comps; | |
| 6671 for (i = 0; i < l_num_comp; ++i) { | |
| 6672 opj_read_bytes(p_header_data, &l_comp_def, | |
| 6673 1); /* Component bit depth */ | |
| 6674 ++p_header_data; | |
| 6675 l_comp->sgnd = (l_comp_def >> 7) & 1; | |
| 6676 l_comp->prec = (l_comp_def & 0x7f) + 1; | |
| 6677 | |
| 6678 if (l_comp->prec > 31) { | |
| 6679 opj_event_msg(p_manager, EVT_ERROR, | |
| 6680 "Invalid values for comp = %d : prec=%u (should be between 1 and 38 according to the JPEG2000 norm. OpenJpeg only supports up to 31)\n", | |
| 6681 i, l_comp->prec); | |
| 6682 return OPJ_FALSE; | |
| 6683 } | |
| 6684 ++l_comp; | |
| 6685 } | |
| 6686 | |
| 6687 return OPJ_TRUE; | |
| 6688 } | |
| 6689 | |
| 6690 /** | |
| 6691 * Reads a CAP marker (extended capabilities definition). Empty implementation. | |
| 6692 * Found in HTJ2K files. | |
| 6693 * | |
| 6694 * @param p_header_data the data contained in the CAP box. | |
| 6695 * @param p_j2k the jpeg2000 codec. | |
| 6696 * @param p_header_size the size of the data contained in the CAP marker. | |
| 6697 * @param p_manager the user event manager. | |
| 6698 */ | |
| 6699 static OPJ_BOOL opj_j2k_read_cap(opj_j2k_t *p_j2k, | |
| 6700 OPJ_BYTE * p_header_data, | |
| 6701 OPJ_UINT32 p_header_size, | |
| 6702 opj_event_mgr_t * p_manager | |
| 6703 ) | |
| 6704 { | |
| 6705 /* preconditions */ | |
| 6706 assert(p_header_data != 00); | |
| 6707 assert(p_j2k != 00); | |
| 6708 assert(p_manager != 00); | |
| 6709 | |
| 6710 (void)p_j2k; | |
| 6711 (void)p_header_data; | |
| 6712 (void)p_header_size; | |
| 6713 (void)p_manager; | |
| 6714 | |
| 6715 return OPJ_TRUE; | |
| 6716 } | |
| 6717 | |
| 6718 /** | |
| 6719 * Reads a CPF marker (corresponding profile). Empty implementation. Found in HTJ2K files | |
| 6720 * @param p_header_data the data contained in the CPF box. | |
| 6721 * @param p_j2k the jpeg2000 codec. | |
| 6722 * @param p_header_size the size of the data contained in the CPF marker. | |
| 6723 * @param p_manager the user event manager. | |
| 6724 */ | |
| 6725 static OPJ_BOOL opj_j2k_read_cpf(opj_j2k_t *p_j2k, | |
| 6726 OPJ_BYTE * p_header_data, | |
| 6727 OPJ_UINT32 p_header_size, | |
| 6728 opj_event_mgr_t * p_manager | |
| 6729 ) | |
| 6730 { | |
| 6731 /* preconditions */ | |
| 6732 assert(p_header_data != 00); | |
| 6733 assert(p_j2k != 00); | |
| 6734 assert(p_manager != 00); | |
| 6735 | |
| 6736 (void)p_j2k; | |
| 6737 (void)p_header_data; | |
| 6738 (void)p_header_size; | |
| 6739 (void)p_manager; | |
| 6740 | |
| 6741 return OPJ_TRUE; | |
| 6742 } | |
| 6743 | |
| 6744 /* ----------------------------------------------------------------------- */ | |
| 6745 /* J2K / JPT decoder interface */ | |
| 6746 /* ----------------------------------------------------------------------- */ | |
| 6747 | |
| 6748 void opj_j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters) | |
| 6749 { | |
| 6750 if (j2k && parameters) { | |
| 6751 j2k->m_cp.m_specific_param.m_dec.m_layer = parameters->cp_layer; | |
| 6752 j2k->m_cp.m_specific_param.m_dec.m_reduce = parameters->cp_reduce; | |
| 6753 | |
| 6754 j2k->dump_state = (parameters->flags & OPJ_DPARAMETERS_DUMP_FLAG); | |
| 6755 #ifdef USE_JPWL | |
| 6756 j2k->m_cp.correct = parameters->jpwl_correct; | |
| 6757 j2k->m_cp.exp_comps = parameters->jpwl_exp_comps; | |
| 6758 j2k->m_cp.max_tiles = parameters->jpwl_max_tiles; | |
| 6759 #endif /* USE_JPWL */ | |
| 6760 } | |
| 6761 } | |
| 6762 | |
| 6763 void opj_j2k_decoder_set_strict_mode(opj_j2k_t *j2k, OPJ_BOOL strict) | |
| 6764 { | |
| 6765 if (j2k) { | |
| 6766 j2k->m_cp.strict = strict; | |
| 6767 if (strict) { | |
| 6768 j2k->m_specific_param.m_decoder.m_nb_tile_parts_correction_checked = 1; | |
| 6769 } | |
| 6770 } | |
| 6771 } | |
| 6772 | |
| 6773 OPJ_BOOL opj_j2k_set_threads(opj_j2k_t *j2k, OPJ_UINT32 num_threads) | |
| 6774 { | |
| 6775 /* Currently we pass the thread-pool to the tcd, so we cannot re-set it */ | |
| 6776 /* afterwards */ | |
| 6777 if (opj_has_thread_support() && j2k->m_tcd == NULL) { | |
| 6778 opj_thread_pool_destroy(j2k->m_tp); | |
| 6779 j2k->m_tp = NULL; | |
| 6780 if (num_threads <= (OPJ_UINT32)INT_MAX) { | |
| 6781 j2k->m_tp = opj_thread_pool_create((int)num_threads); | |
| 6782 } | |
| 6783 if (j2k->m_tp == NULL) { | |
| 6784 j2k->m_tp = opj_thread_pool_create(0); | |
| 6785 return OPJ_FALSE; | |
| 6786 } | |
| 6787 return OPJ_TRUE; | |
| 6788 } | |
| 6789 return OPJ_FALSE; | |
| 6790 } | |
| 6791 | |
| 6792 static int opj_j2k_get_default_thread_count(void) | |
| 6793 { | |
| 6794 const char* num_threads_str = getenv("OPJ_NUM_THREADS"); | |
| 6795 int num_cpus; | |
| 6796 int num_threads; | |
| 6797 | |
| 6798 if (num_threads_str == NULL || !opj_has_thread_support()) { | |
| 6799 return 0; | |
| 6800 } | |
| 6801 num_cpus = opj_get_num_cpus(); | |
| 6802 if (strcmp(num_threads_str, "ALL_CPUS") == 0) { | |
| 6803 return num_cpus; | |
| 6804 } | |
| 6805 if (num_cpus == 0) { | |
| 6806 num_cpus = 32; | |
| 6807 } | |
| 6808 num_threads = atoi(num_threads_str); | |
| 6809 if (num_threads < 0) { | |
| 6810 num_threads = 0; | |
| 6811 } else if (num_threads > 2 * num_cpus) { | |
| 6812 num_threads = 2 * num_cpus; | |
| 6813 } | |
| 6814 return num_threads; | |
| 6815 } | |
| 6816 | |
| 6817 /* ----------------------------------------------------------------------- */ | |
| 6818 /* J2K encoder interface */ | |
| 6819 /* ----------------------------------------------------------------------- */ | |
| 6820 | |
| 6821 opj_j2k_t* opj_j2k_create_compress(void) | |
| 6822 { | |
| 6823 opj_j2k_t *l_j2k = (opj_j2k_t*) opj_calloc(1, sizeof(opj_j2k_t)); | |
| 6824 if (!l_j2k) { | |
| 6825 return NULL; | |
| 6826 } | |
| 6827 | |
| 6828 | |
| 6829 l_j2k->m_is_decoder = 0; | |
| 6830 l_j2k->m_cp.m_is_decoder = 0; | |
| 6831 | |
| 6832 l_j2k->m_specific_param.m_encoder.m_header_tile_data = (OPJ_BYTE *) opj_malloc( | |
| 6833 OPJ_J2K_DEFAULT_HEADER_SIZE); | |
| 6834 if (! l_j2k->m_specific_param.m_encoder.m_header_tile_data) { | |
| 6835 opj_j2k_destroy(l_j2k); | |
| 6836 return NULL; | |
| 6837 } | |
| 6838 | |
| 6839 l_j2k->m_specific_param.m_encoder.m_header_tile_data_size = | |
| 6840 OPJ_J2K_DEFAULT_HEADER_SIZE; | |
| 6841 | |
| 6842 /* validation list creation*/ | |
| 6843 l_j2k->m_validation_list = opj_procedure_list_create(); | |
| 6844 if (! l_j2k->m_validation_list) { | |
| 6845 opj_j2k_destroy(l_j2k); | |
| 6846 return NULL; | |
| 6847 } | |
| 6848 | |
| 6849 /* execution list creation*/ | |
| 6850 l_j2k->m_procedure_list = opj_procedure_list_create(); | |
| 6851 if (! l_j2k->m_procedure_list) { | |
| 6852 opj_j2k_destroy(l_j2k); | |
| 6853 return NULL; | |
| 6854 } | |
| 6855 | |
| 6856 l_j2k->m_tp = opj_thread_pool_create(opj_j2k_get_default_thread_count()); | |
| 6857 if (!l_j2k->m_tp) { | |
| 6858 l_j2k->m_tp = opj_thread_pool_create(0); | |
| 6859 } | |
| 6860 if (!l_j2k->m_tp) { | |
| 6861 opj_j2k_destroy(l_j2k); | |
| 6862 return NULL; | |
| 6863 } | |
| 6864 | |
| 6865 return l_j2k; | |
| 6866 } | |
| 6867 | |
| 6868 static int opj_j2k_initialise_4K_poc(opj_poc_t *POC, int numres) | |
| 6869 { | |
| 6870 POC[0].tile = 1; | |
| 6871 POC[0].resno0 = 0; | |
| 6872 POC[0].compno0 = 0; | |
| 6873 POC[0].layno1 = 1; | |
| 6874 POC[0].resno1 = (OPJ_UINT32)(numres - 1); | |
| 6875 POC[0].compno1 = 3; | |
| 6876 POC[0].prg1 = OPJ_CPRL; | |
| 6877 POC[1].tile = 1; | |
| 6878 POC[1].resno0 = (OPJ_UINT32)(numres - 1); | |
| 6879 POC[1].compno0 = 0; | |
| 6880 POC[1].layno1 = 1; | |
| 6881 POC[1].resno1 = (OPJ_UINT32)numres; | |
| 6882 POC[1].compno1 = 3; | |
| 6883 POC[1].prg1 = OPJ_CPRL; | |
| 6884 return 2; | |
| 6885 } | |
| 6886 | |
| 6887 static void opj_j2k_set_cinema_parameters(opj_cparameters_t *parameters, | |
| 6888 opj_image_t *image, opj_event_mgr_t *p_manager) | |
| 6889 { | |
| 6890 /* Configure cinema parameters */ | |
| 6891 int i; | |
| 6892 | |
| 6893 /* No tiling */ | |
| 6894 parameters->tile_size_on = OPJ_FALSE; | |
| 6895 parameters->cp_tdx = 1; | |
| 6896 parameters->cp_tdy = 1; | |
| 6897 | |
| 6898 /* One tile part for each component */ | |
| 6899 parameters->tp_flag = 'C'; | |
| 6900 parameters->tp_on = 1; | |
| 6901 | |
| 6902 /* Tile and Image shall be at (0,0) */ | |
| 6903 parameters->cp_tx0 = 0; | |
| 6904 parameters->cp_ty0 = 0; | |
| 6905 parameters->image_offset_x0 = 0; | |
| 6906 parameters->image_offset_y0 = 0; | |
| 6907 | |
| 6908 /* Codeblock size= 32*32 */ | |
| 6909 parameters->cblockw_init = 32; | |
| 6910 parameters->cblockh_init = 32; | |
| 6911 | |
| 6912 /* Codeblock style: no mode switch enabled */ | |
| 6913 parameters->mode = 0; | |
| 6914 | |
| 6915 /* No ROI */ | |
| 6916 parameters->roi_compno = -1; | |
| 6917 | |
| 6918 /* No subsampling */ | |
| 6919 parameters->subsampling_dx = 1; | |
| 6920 parameters->subsampling_dy = 1; | |
| 6921 | |
| 6922 /* 9-7 transform */ | |
| 6923 parameters->irreversible = 1; | |
| 6924 | |
| 6925 /* Number of layers */ | |
| 6926 if (parameters->tcp_numlayers > 1) { | |
| 6927 opj_event_msg(p_manager, EVT_WARNING, | |
| 6928 "JPEG 2000 Profile-3 and 4 (2k/4k dc profile) requires:\n" | |
| 6929 "1 single quality layer" | |
| 6930 "-> Number of layers forced to 1 (rather than %d)\n" | |
| 6931 "-> Rate of the last layer (%3.1f) will be used", | |
| 6932 parameters->tcp_numlayers, | |
| 6933 parameters->tcp_rates[parameters->tcp_numlayers - 1]); | |
| 6934 parameters->tcp_rates[0] = parameters->tcp_rates[parameters->tcp_numlayers - 1]; | |
| 6935 parameters->tcp_numlayers = 1; | |
| 6936 } | |
| 6937 | |
| 6938 /* Resolution levels */ | |
| 6939 switch (parameters->rsiz) { | |
| 6940 case OPJ_PROFILE_CINEMA_2K: | |
| 6941 if (parameters->numresolution > 6) { | |
| 6942 opj_event_msg(p_manager, EVT_WARNING, | |
| 6943 "JPEG 2000 Profile-3 (2k dc profile) requires:\n" | |
| 6944 "Number of decomposition levels <= 5\n" | |
| 6945 "-> Number of decomposition levels forced to 5 (rather than %d)\n", | |
| 6946 parameters->numresolution + 1); | |
| 6947 parameters->numresolution = 6; | |
| 6948 } | |
| 6949 break; | |
| 6950 case OPJ_PROFILE_CINEMA_4K: | |
| 6951 if (parameters->numresolution < 2) { | |
| 6952 opj_event_msg(p_manager, EVT_WARNING, | |
| 6953 "JPEG 2000 Profile-4 (4k dc profile) requires:\n" | |
| 6954 "Number of decomposition levels >= 1 && <= 6\n" | |
| 6955 "-> Number of decomposition levels forced to 1 (rather than %d)\n", | |
| 6956 parameters->numresolution + 1); | |
| 6957 parameters->numresolution = 1; | |
| 6958 } else if (parameters->numresolution > 7) { | |
| 6959 opj_event_msg(p_manager, EVT_WARNING, | |
| 6960 "JPEG 2000 Profile-4 (4k dc profile) requires:\n" | |
| 6961 "Number of decomposition levels >= 1 && <= 6\n" | |
| 6962 "-> Number of decomposition levels forced to 6 (rather than %d)\n", | |
| 6963 parameters->numresolution + 1); | |
| 6964 parameters->numresolution = 7; | |
| 6965 } | |
| 6966 break; | |
| 6967 default : | |
| 6968 break; | |
| 6969 } | |
| 6970 | |
| 6971 /* Precincts */ | |
| 6972 parameters->csty |= J2K_CP_CSTY_PRT; | |
| 6973 if (parameters->numresolution == 1) { | |
| 6974 parameters->res_spec = 1; | |
| 6975 parameters->prcw_init[0] = 128; | |
| 6976 parameters->prch_init[0] = 128; | |
| 6977 } else { | |
| 6978 parameters->res_spec = parameters->numresolution - 1; | |
| 6979 for (i = 0; i < parameters->res_spec; i++) { | |
| 6980 parameters->prcw_init[i] = 256; | |
| 6981 parameters->prch_init[i] = 256; | |
| 6982 } | |
| 6983 } | |
| 6984 | |
| 6985 /* The progression order shall be CPRL */ | |
| 6986 parameters->prog_order = OPJ_CPRL; | |
| 6987 | |
| 6988 /* Progression order changes for 4K, disallowed for 2K */ | |
| 6989 if (parameters->rsiz == OPJ_PROFILE_CINEMA_4K) { | |
| 6990 parameters->numpocs = (OPJ_UINT32)opj_j2k_initialise_4K_poc(parameters->POC, | |
| 6991 parameters->numresolution); | |
| 6992 } else { | |
| 6993 parameters->numpocs = 0; | |
| 6994 } | |
| 6995 | |
| 6996 /* Limited bit-rate */ | |
| 6997 parameters->cp_disto_alloc = 1; | |
| 6998 if (parameters->max_cs_size <= 0) { | |
| 6999 /* No rate has been introduced, 24 fps is assumed */ | |
| 7000 parameters->max_cs_size = OPJ_CINEMA_24_CS; | |
| 7001 opj_event_msg(p_manager, EVT_WARNING, | |
| 7002 "JPEG 2000 Profile-3 and 4 (2k/4k dc profile) requires:\n" | |
| 7003 "Maximum 1302083 compressed bytes @ 24fps\n" | |
| 7004 "As no rate has been given, this limit will be used.\n"); | |
| 7005 } else if (parameters->max_cs_size > OPJ_CINEMA_24_CS) { | |
| 7006 opj_event_msg(p_manager, EVT_WARNING, | |
| 7007 "JPEG 2000 Profile-3 and 4 (2k/4k dc profile) requires:\n" | |
| 7008 "Maximum 1302083 compressed bytes @ 24fps\n" | |
| 7009 "-> Specified rate exceeds this limit. Rate will be forced to 1302083 bytes.\n"); | |
| 7010 parameters->max_cs_size = OPJ_CINEMA_24_CS; | |
| 7011 } | |
| 7012 | |
| 7013 if (parameters->max_comp_size <= 0) { | |
| 7014 /* No rate has been introduced, 24 fps is assumed */ | |
| 7015 parameters->max_comp_size = OPJ_CINEMA_24_COMP; | |
| 7016 opj_event_msg(p_manager, EVT_WARNING, | |
| 7017 "JPEG 2000 Profile-3 and 4 (2k/4k dc profile) requires:\n" | |
| 7018 "Maximum 1041666 compressed bytes @ 24fps\n" | |
| 7019 "As no rate has been given, this limit will be used.\n"); | |
| 7020 } else if (parameters->max_comp_size > OPJ_CINEMA_24_COMP) { | |
| 7021 opj_event_msg(p_manager, EVT_WARNING, | |
| 7022 "JPEG 2000 Profile-3 and 4 (2k/4k dc profile) requires:\n" | |
| 7023 "Maximum 1041666 compressed bytes @ 24fps\n" | |
| 7024 "-> Specified rate exceeds this limit. Rate will be forced to 1041666 bytes.\n"); | |
| 7025 parameters->max_comp_size = OPJ_CINEMA_24_COMP; | |
| 7026 } | |
| 7027 | |
| 7028 parameters->tcp_rates[0] = (OPJ_FLOAT32)(image->numcomps * image->comps[0].w * | |
| 7029 image->comps[0].h * image->comps[0].prec) / | |
| 7030 (OPJ_FLOAT32)(((OPJ_UINT32)parameters->max_cs_size) * 8 * image->comps[0].dx * | |
| 7031 image->comps[0].dy); | |
| 7032 | |
| 7033 } | |
| 7034 | |
| 7035 static OPJ_BOOL opj_j2k_is_cinema_compliant(opj_image_t *image, OPJ_UINT16 rsiz, | |
| 7036 opj_event_mgr_t *p_manager) | |
| 7037 { | |
| 7038 OPJ_UINT32 i; | |
| 7039 | |
| 7040 /* Number of components */ | |
| 7041 if (image->numcomps != 3) { | |
| 7042 opj_event_msg(p_manager, EVT_WARNING, | |
| 7043 "JPEG 2000 Profile-3 (2k dc profile) requires:\n" | |
| 7044 "3 components" | |
| 7045 "-> Number of components of input image (%d) is not compliant\n" | |
| 7046 "-> Non-profile-3 codestream will be generated\n", | |
| 7047 image->numcomps); | |
| 7048 return OPJ_FALSE; | |
| 7049 } | |
| 7050 | |
| 7051 /* Bitdepth */ | |
| 7052 for (i = 0; i < image->numcomps; i++) { | |
| 7053 if ((image->comps[i].prec != 12) | (image->comps[i].sgnd)) { | |
| 7054 char signed_str[] = "signed"; | |
| 7055 char unsigned_str[] = "unsigned"; | |
| 7056 char *tmp_str = image->comps[i].sgnd ? signed_str : unsigned_str; | |
| 7057 opj_event_msg(p_manager, EVT_WARNING, | |
| 7058 "JPEG 2000 Profile-3 (2k dc profile) requires:\n" | |
| 7059 "Precision of each component shall be 12 bits unsigned" | |
| 7060 "-> At least component %d of input image (%d bits, %s) is not compliant\n" | |
| 7061 "-> Non-profile-3 codestream will be generated\n", | |
| 7062 i, image->comps[i].prec, tmp_str); | |
| 7063 return OPJ_FALSE; | |
| 7064 } | |
| 7065 } | |
| 7066 | |
| 7067 /* Image size */ | |
| 7068 switch (rsiz) { | |
| 7069 case OPJ_PROFILE_CINEMA_2K: | |
| 7070 if (((image->comps[0].w > 2048) | (image->comps[0].h > 1080))) { | |
| 7071 opj_event_msg(p_manager, EVT_WARNING, | |
| 7072 "JPEG 2000 Profile-3 (2k dc profile) requires:\n" | |
| 7073 "width <= 2048 and height <= 1080\n" | |
| 7074 "-> Input image size %d x %d is not compliant\n" | |
| 7075 "-> Non-profile-3 codestream will be generated\n", | |
| 7076 image->comps[0].w, image->comps[0].h); | |
| 7077 return OPJ_FALSE; | |
| 7078 } | |
| 7079 break; | |
| 7080 case OPJ_PROFILE_CINEMA_4K: | |
| 7081 if (((image->comps[0].w > 4096) | (image->comps[0].h > 2160))) { | |
| 7082 opj_event_msg(p_manager, EVT_WARNING, | |
| 7083 "JPEG 2000 Profile-4 (4k dc profile) requires:\n" | |
| 7084 "width <= 4096 and height <= 2160\n" | |
| 7085 "-> Image size %d x %d is not compliant\n" | |
| 7086 "-> Non-profile-4 codestream will be generated\n", | |
| 7087 image->comps[0].w, image->comps[0].h); | |
| 7088 return OPJ_FALSE; | |
| 7089 } | |
| 7090 break; | |
| 7091 default : | |
| 7092 break; | |
| 7093 } | |
| 7094 | |
| 7095 return OPJ_TRUE; | |
| 7096 } | |
| 7097 | |
| 7098 static int opj_j2k_get_imf_max_NL(opj_cparameters_t *parameters, | |
| 7099 opj_image_t *image) | |
| 7100 { | |
| 7101 /* Decomposition levels */ | |
| 7102 const OPJ_UINT16 rsiz = parameters->rsiz; | |
| 7103 const OPJ_UINT16 profile = OPJ_GET_IMF_PROFILE(rsiz); | |
| 7104 const OPJ_UINT32 XTsiz = parameters->tile_size_on ? (OPJ_UINT32) | |
| 7105 parameters->cp_tdx : image->x1; | |
| 7106 switch (profile) { | |
| 7107 case OPJ_PROFILE_IMF_2K: | |
| 7108 return 5; | |
| 7109 case OPJ_PROFILE_IMF_4K: | |
| 7110 return 6; | |
| 7111 case OPJ_PROFILE_IMF_8K: | |
| 7112 return 7; | |
| 7113 case OPJ_PROFILE_IMF_2K_R: { | |
| 7114 if (XTsiz >= 2048) { | |
| 7115 return 5; | |
| 7116 } else if (XTsiz >= 1024) { | |
| 7117 return 4; | |
| 7118 } | |
| 7119 break; | |
| 7120 } | |
| 7121 case OPJ_PROFILE_IMF_4K_R: { | |
| 7122 if (XTsiz >= 4096) { | |
| 7123 return 6; | |
| 7124 } else if (XTsiz >= 2048) { | |
| 7125 return 5; | |
| 7126 } else if (XTsiz >= 1024) { | |
| 7127 return 4; | |
| 7128 } | |
| 7129 break; | |
| 7130 } | |
| 7131 case OPJ_PROFILE_IMF_8K_R: { | |
| 7132 if (XTsiz >= 8192) { | |
| 7133 return 7; | |
| 7134 } else if (XTsiz >= 4096) { | |
| 7135 return 6; | |
| 7136 } else if (XTsiz >= 2048) { | |
| 7137 return 5; | |
| 7138 } else if (XTsiz >= 1024) { | |
| 7139 return 4; | |
| 7140 } | |
| 7141 break; | |
| 7142 } | |
| 7143 default: | |
| 7144 break; | |
| 7145 } | |
| 7146 return -1; | |
| 7147 } | |
| 7148 | |
| 7149 static void opj_j2k_set_imf_parameters(opj_cparameters_t *parameters, | |
| 7150 opj_image_t *image, opj_event_mgr_t *p_manager) | |
| 7151 { | |
| 7152 const OPJ_UINT16 rsiz = parameters->rsiz; | |
| 7153 const OPJ_UINT16 profile = OPJ_GET_IMF_PROFILE(rsiz); | |
| 7154 | |
| 7155 OPJ_UNUSED(p_manager); | |
| 7156 | |
| 7157 /* Override defaults set by opj_set_default_encoder_parameters */ | |
| 7158 if (parameters->cblockw_init == OPJ_COMP_PARAM_DEFAULT_CBLOCKW && | |
| 7159 parameters->cblockh_init == OPJ_COMP_PARAM_DEFAULT_CBLOCKH) { | |
| 7160 parameters->cblockw_init = 32; | |
| 7161 parameters->cblockh_init = 32; | |
| 7162 } | |
| 7163 | |
| 7164 /* One tile part for each component */ | |
| 7165 parameters->tp_flag = 'C'; | |
| 7166 parameters->tp_on = 1; | |
| 7167 | |
| 7168 if (parameters->prog_order == OPJ_COMP_PARAM_DEFAULT_PROG_ORDER) { | |
| 7169 parameters->prog_order = OPJ_CPRL; | |
| 7170 } | |
| 7171 | |
| 7172 if (profile == OPJ_PROFILE_IMF_2K || | |
| 7173 profile == OPJ_PROFILE_IMF_4K || | |
| 7174 profile == OPJ_PROFILE_IMF_8K) { | |
| 7175 /* 9-7 transform */ | |
| 7176 parameters->irreversible = 1; | |
| 7177 } | |
| 7178 | |
| 7179 /* Adjust the number of resolutions if set to its defaults */ | |
| 7180 if (parameters->numresolution == OPJ_COMP_PARAM_DEFAULT_NUMRESOLUTION && | |
| 7181 image->x0 == 0 && | |
| 7182 image->y0 == 0) { | |
| 7183 const int max_NL = opj_j2k_get_imf_max_NL(parameters, image); | |
| 7184 if (max_NL >= 0 && parameters->numresolution > max_NL) { | |
| 7185 parameters->numresolution = max_NL + 1; | |
| 7186 } | |
| 7187 | |
| 7188 /* Note: below is generic logic */ | |
| 7189 if (!parameters->tile_size_on) { | |
| 7190 while (parameters->numresolution > 0) { | |
| 7191 if (image->x1 < (1U << ((OPJ_UINT32)parameters->numresolution - 1U))) { | |
| 7192 parameters->numresolution --; | |
| 7193 continue; | |
| 7194 } | |
| 7195 if (image->y1 < (1U << ((OPJ_UINT32)parameters->numresolution - 1U))) { | |
| 7196 parameters->numresolution --; | |
| 7197 continue; | |
| 7198 } | |
| 7199 break; | |
| 7200 } | |
| 7201 } | |
| 7202 } | |
| 7203 | |
| 7204 /* Set defaults precincts */ | |
| 7205 if (parameters->csty == 0) { | |
| 7206 parameters->csty |= J2K_CP_CSTY_PRT; | |
| 7207 if (parameters->numresolution == 1) { | |
| 7208 parameters->res_spec = 1; | |
| 7209 parameters->prcw_init[0] = 128; | |
| 7210 parameters->prch_init[0] = 128; | |
| 7211 } else { | |
| 7212 int i; | |
| 7213 parameters->res_spec = parameters->numresolution - 1; | |
| 7214 for (i = 0; i < parameters->res_spec; i++) { | |
| 7215 parameters->prcw_init[i] = 256; | |
| 7216 parameters->prch_init[i] = 256; | |
| 7217 } | |
| 7218 } | |
| 7219 } | |
| 7220 } | |
| 7221 | |
| 7222 /* Table A.53 from JPEG2000 standard */ | |
| 7223 static const OPJ_UINT16 tabMaxSubLevelFromMainLevel[] = { | |
| 7224 15, /* unspecified */ | |
| 7225 1, | |
| 7226 1, | |
| 7227 1, | |
| 7228 2, | |
| 7229 3, | |
| 7230 4, | |
| 7231 5, | |
| 7232 6, | |
| 7233 7, | |
| 7234 8, | |
| 7235 9 | |
| 7236 }; | |
| 7237 | |
| 7238 static OPJ_BOOL opj_j2k_is_imf_compliant(opj_cparameters_t *parameters, | |
| 7239 opj_image_t *image, | |
| 7240 opj_event_mgr_t *p_manager) | |
| 7241 { | |
| 7242 OPJ_UINT32 i; | |
| 7243 const OPJ_UINT16 rsiz = parameters->rsiz; | |
| 7244 const OPJ_UINT16 profile = OPJ_GET_IMF_PROFILE(rsiz); | |
| 7245 const OPJ_UINT16 mainlevel = OPJ_GET_IMF_MAINLEVEL(rsiz); | |
| 7246 const OPJ_UINT16 sublevel = OPJ_GET_IMF_SUBLEVEL(rsiz); | |
| 7247 const int NL = parameters->numresolution - 1; | |
| 7248 const OPJ_UINT32 XTsiz = parameters->tile_size_on ? (OPJ_UINT32) | |
| 7249 parameters->cp_tdx : image->x1; | |
| 7250 OPJ_BOOL ret = OPJ_TRUE; | |
| 7251 | |
| 7252 /* Validate mainlevel */ | |
| 7253 if (mainlevel > OPJ_IMF_MAINLEVEL_MAX) { | |
| 7254 opj_event_msg(p_manager, EVT_WARNING, | |
| 7255 "IMF profile require mainlevel <= 11.\n" | |
| 7256 "-> %d is thus not compliant\n" | |
| 7257 "-> Non-IMF codestream will be generated\n", | |
| 7258 mainlevel); | |
| 7259 ret = OPJ_FALSE; | |
| 7260 } else { | |
| 7261 /* Validate sublevel */ | |
| 7262 assert(sizeof(tabMaxSubLevelFromMainLevel) == | |
| 7263 (OPJ_IMF_MAINLEVEL_MAX + 1) * sizeof(tabMaxSubLevelFromMainLevel[0])); | |
| 7264 if (sublevel > tabMaxSubLevelFromMainLevel[mainlevel]) { | |
| 7265 opj_event_msg(p_manager, EVT_WARNING, | |
| 7266 "IMF profile require sublevel <= %d for mainlevel = %d.\n" | |
| 7267 "-> %d is thus not compliant\n" | |
| 7268 "-> Non-IMF codestream will be generated\n", | |
| 7269 tabMaxSubLevelFromMainLevel[mainlevel], | |
| 7270 mainlevel, | |
| 7271 sublevel); | |
| 7272 ret = OPJ_FALSE; | |
| 7273 } | |
| 7274 } | |
| 7275 | |
| 7276 /* Number of components */ | |
| 7277 if (image->numcomps > 3) { | |
| 7278 opj_event_msg(p_manager, EVT_WARNING, | |
| 7279 "IMF profiles require at most 3 components.\n" | |
| 7280 "-> Number of components of input image (%d) is not compliant\n" | |
| 7281 "-> Non-IMF codestream will be generated\n", | |
| 7282 image->numcomps); | |
| 7283 ret = OPJ_FALSE; | |
| 7284 } | |
| 7285 | |
| 7286 if (image->x0 != 0 || image->y0 != 0) { | |
| 7287 opj_event_msg(p_manager, EVT_WARNING, | |
| 7288 "IMF profiles require image origin to be at 0,0.\n" | |
| 7289 "-> %d,%d is not compliant\n" | |
| 7290 "-> Non-IMF codestream will be generated\n", | |
| 7291 image->x0, image->y0 != 0); | |
| 7292 ret = OPJ_FALSE; | |
| 7293 } | |
| 7294 | |
| 7295 if (parameters->cp_tx0 != 0 || parameters->cp_ty0 != 0) { | |
| 7296 opj_event_msg(p_manager, EVT_WARNING, | |
| 7297 "IMF profiles require tile origin to be at 0,0.\n" | |
| 7298 "-> %d,%d is not compliant\n" | |
| 7299 "-> Non-IMF codestream will be generated\n", | |
| 7300 parameters->cp_tx0, parameters->cp_ty0); | |
| 7301 ret = OPJ_FALSE; | |
| 7302 } | |
| 7303 | |
| 7304 if (parameters->tile_size_on) { | |
| 7305 if (profile == OPJ_PROFILE_IMF_2K || | |
| 7306 profile == OPJ_PROFILE_IMF_4K || | |
| 7307 profile == OPJ_PROFILE_IMF_8K) { | |
| 7308 if ((OPJ_UINT32)parameters->cp_tdx < image->x1 || | |
| 7309 (OPJ_UINT32)parameters->cp_tdy < image->y1) { | |
| 7310 opj_event_msg(p_manager, EVT_WARNING, | |
| 7311 "IMF 2K/4K/8K single tile profiles require tile to be greater or equal to image size.\n" | |
| 7312 "-> %d,%d is lesser than %d,%d\n" | |
| 7313 "-> Non-IMF codestream will be generated\n", | |
| 7314 parameters->cp_tdx, | |
| 7315 parameters->cp_tdy, | |
| 7316 image->x1, | |
| 7317 image->y1); | |
| 7318 ret = OPJ_FALSE; | |
| 7319 } | |
| 7320 } else { | |
| 7321 if ((OPJ_UINT32)parameters->cp_tdx >= image->x1 && | |
| 7322 (OPJ_UINT32)parameters->cp_tdy >= image->y1) { | |
| 7323 /* ok */ | |
| 7324 } else if (parameters->cp_tdx == 1024 && | |
| 7325 parameters->cp_tdy == 1024) { | |
| 7326 /* ok */ | |
| 7327 } else if (parameters->cp_tdx == 2048 && | |
| 7328 parameters->cp_tdy == 2048 && | |
| 7329 (profile == OPJ_PROFILE_IMF_4K || | |
| 7330 profile == OPJ_PROFILE_IMF_8K)) { | |
| 7331 /* ok */ | |
| 7332 } else if (parameters->cp_tdx == 4096 && | |
| 7333 parameters->cp_tdy == 4096 && | |
| 7334 profile == OPJ_PROFILE_IMF_8K) { | |
| 7335 /* ok */ | |
| 7336 } else { | |
| 7337 opj_event_msg(p_manager, EVT_WARNING, | |
| 7338 "IMF 2K_R/4K_R/8K_R single/multiple tile profiles " | |
| 7339 "require tile to be greater or equal to image size,\n" | |
| 7340 "or to be (1024,1024), or (2048,2048) for 4K_R/8K_R " | |
| 7341 "or (4096,4096) for 8K_R.\n" | |
| 7342 "-> %d,%d is non conformant\n" | |
| 7343 "-> Non-IMF codestream will be generated\n", | |
| 7344 parameters->cp_tdx, | |
| 7345 parameters->cp_tdy); | |
| 7346 ret = OPJ_FALSE; | |
| 7347 } | |
| 7348 } | |
| 7349 } | |
| 7350 | |
| 7351 /* Bitdepth */ | |
| 7352 for (i = 0; i < image->numcomps; i++) { | |
| 7353 if (!(image->comps[i].prec >= 8 && image->comps[i].prec <= 16) || | |
| 7354 (image->comps[i].sgnd)) { | |
| 7355 char signed_str[] = "signed"; | |
| 7356 char unsigned_str[] = "unsigned"; | |
| 7357 char *tmp_str = image->comps[i].sgnd ? signed_str : unsigned_str; | |
| 7358 opj_event_msg(p_manager, EVT_WARNING, | |
| 7359 "IMF profiles require precision of each component to b in [8-16] bits unsigned" | |
| 7360 "-> At least component %d of input image (%d bits, %s) is not compliant\n" | |
| 7361 "-> Non-IMF codestream will be generated\n", | |
| 7362 i, image->comps[i].prec, tmp_str); | |
| 7363 ret = OPJ_FALSE; | |
| 7364 } | |
| 7365 } | |
| 7366 | |
| 7367 /* Sub-sampling */ | |
| 7368 for (i = 0; i < image->numcomps; i++) { | |
| 7369 if (i == 0 && image->comps[i].dx != 1) { | |
| 7370 opj_event_msg(p_manager, EVT_WARNING, | |
| 7371 "IMF profiles require XRSiz1 == 1. Here it is set to %d.\n" | |
| 7372 "-> Non-IMF codestream will be generated\n", | |
| 7373 image->comps[i].dx); | |
| 7374 ret = OPJ_FALSE; | |
| 7375 } | |
| 7376 if (i == 1 && image->comps[i].dx != 1 && image->comps[i].dx != 2) { | |
| 7377 opj_event_msg(p_manager, EVT_WARNING, | |
| 7378 "IMF profiles require XRSiz2 == 1 or 2. Here it is set to %d.\n" | |
| 7379 "-> Non-IMF codestream will be generated\n", | |
| 7380 image->comps[i].dx); | |
| 7381 ret = OPJ_FALSE; | |
| 7382 } | |
| 7383 if (i > 1 && image->comps[i].dx != image->comps[i - 1].dx) { | |
| 7384 opj_event_msg(p_manager, EVT_WARNING, | |
| 7385 "IMF profiles require XRSiz%d to be the same as XRSiz2. " | |
| 7386 "Here it is set to %d instead of %d.\n" | |
| 7387 "-> Non-IMF codestream will be generated\n", | |
| 7388 i + 1, image->comps[i].dx, image->comps[i - 1].dx); | |
| 7389 ret = OPJ_FALSE; | |
| 7390 } | |
| 7391 if (image->comps[i].dy != 1) { | |
| 7392 opj_event_msg(p_manager, EVT_WARNING, | |
| 7393 "IMF profiles require YRsiz == 1. " | |
| 7394 "Here it is set to %d for component %d.\n" | |
| 7395 "-> Non-IMF codestream will be generated\n", | |
| 7396 image->comps[i].dy, i); | |
| 7397 ret = OPJ_FALSE; | |
| 7398 } | |
| 7399 } | |
| 7400 | |
| 7401 /* Image size */ | |
| 7402 switch (profile) { | |
| 7403 case OPJ_PROFILE_IMF_2K: | |
| 7404 case OPJ_PROFILE_IMF_2K_R: | |
| 7405 if (((image->comps[0].w > 2048) | (image->comps[0].h > 1556))) { | |
| 7406 opj_event_msg(p_manager, EVT_WARNING, | |
| 7407 "IMF 2K/2K_R profile require:\n" | |
| 7408 "width <= 2048 and height <= 1556\n" | |
| 7409 "-> Input image size %d x %d is not compliant\n" | |
| 7410 "-> Non-IMF codestream will be generated\n", | |
| 7411 image->comps[0].w, image->comps[0].h); | |
| 7412 ret = OPJ_FALSE; | |
| 7413 } | |
| 7414 break; | |
| 7415 case OPJ_PROFILE_IMF_4K: | |
| 7416 case OPJ_PROFILE_IMF_4K_R: | |
| 7417 if (((image->comps[0].w > 4096) | (image->comps[0].h > 3112))) { | |
| 7418 opj_event_msg(p_manager, EVT_WARNING, | |
| 7419 "IMF 4K/4K_R profile require:\n" | |
| 7420 "width <= 4096 and height <= 3112\n" | |
| 7421 "-> Input image size %d x %d is not compliant\n" | |
| 7422 "-> Non-IMF codestream will be generated\n", | |
| 7423 image->comps[0].w, image->comps[0].h); | |
| 7424 ret = OPJ_FALSE; | |
| 7425 } | |
| 7426 break; | |
| 7427 case OPJ_PROFILE_IMF_8K: | |
| 7428 case OPJ_PROFILE_IMF_8K_R: | |
| 7429 if (((image->comps[0].w > 8192) | (image->comps[0].h > 6224))) { | |
| 7430 opj_event_msg(p_manager, EVT_WARNING, | |
| 7431 "IMF 8K/8K_R profile require:\n" | |
| 7432 "width <= 8192 and height <= 6224\n" | |
| 7433 "-> Input image size %d x %d is not compliant\n" | |
| 7434 "-> Non-IMF codestream will be generated\n", | |
| 7435 image->comps[0].w, image->comps[0].h); | |
| 7436 ret = OPJ_FALSE; | |
| 7437 } | |
| 7438 break; | |
| 7439 default : | |
| 7440 assert(0); | |
| 7441 return OPJ_FALSE; | |
| 7442 } | |
| 7443 | |
| 7444 if (parameters->roi_compno != -1) { | |
| 7445 opj_event_msg(p_manager, EVT_WARNING, | |
| 7446 "IMF profile forbid RGN / region of interest marker.\n" | |
| 7447 "-> Compression parameters specify a ROI\n" | |
| 7448 "-> Non-IMF codestream will be generated\n"); | |
| 7449 ret = OPJ_FALSE; | |
| 7450 } | |
| 7451 | |
| 7452 if (parameters->cblockw_init != 32 || parameters->cblockh_init != 32) { | |
| 7453 opj_event_msg(p_manager, EVT_WARNING, | |
| 7454 "IMF profile require code block size to be 32x32.\n" | |
| 7455 "-> Compression parameters set it to %dx%d.\n" | |
| 7456 "-> Non-IMF codestream will be generated\n", | |
| 7457 parameters->cblockw_init, | |
| 7458 parameters->cblockh_init); | |
| 7459 ret = OPJ_FALSE; | |
| 7460 } | |
| 7461 | |
| 7462 if (parameters->prog_order != OPJ_CPRL) { | |
| 7463 opj_event_msg(p_manager, EVT_WARNING, | |
| 7464 "IMF profile require progression order to be CPRL.\n" | |
| 7465 "-> Compression parameters set it to %d.\n" | |
| 7466 "-> Non-IMF codestream will be generated\n", | |
| 7467 parameters->prog_order); | |
| 7468 ret = OPJ_FALSE; | |
| 7469 } | |
| 7470 | |
| 7471 if (parameters->numpocs != 0) { | |
| 7472 opj_event_msg(p_manager, EVT_WARNING, | |
| 7473 "IMF profile forbid POC markers.\n" | |
| 7474 "-> Compression parameters set %d POC.\n" | |
| 7475 "-> Non-IMF codestream will be generated\n", | |
| 7476 parameters->numpocs); | |
| 7477 ret = OPJ_FALSE; | |
| 7478 } | |
| 7479 | |
| 7480 /* Codeblock style: no mode switch enabled */ | |
| 7481 if (parameters->mode != 0) { | |
| 7482 opj_event_msg(p_manager, EVT_WARNING, | |
| 7483 "IMF profile forbid mode switch in code block style.\n" | |
| 7484 "-> Compression parameters set code block style to %d.\n" | |
| 7485 "-> Non-IMF codestream will be generated\n", | |
| 7486 parameters->mode); | |
| 7487 ret = OPJ_FALSE; | |
| 7488 } | |
| 7489 | |
| 7490 if (profile == OPJ_PROFILE_IMF_2K || | |
| 7491 profile == OPJ_PROFILE_IMF_4K || | |
| 7492 profile == OPJ_PROFILE_IMF_8K) { | |
| 7493 /* Expect 9-7 transform */ | |
| 7494 if (parameters->irreversible != 1) { | |
| 7495 opj_event_msg(p_manager, EVT_WARNING, | |
| 7496 "IMF 2K/4K/8K profiles require 9-7 Irreversible Transform.\n" | |
| 7497 "-> Compression parameters set it to reversible.\n" | |
| 7498 "-> Non-IMF codestream will be generated\n"); | |
| 7499 ret = OPJ_FALSE; | |
| 7500 } | |
| 7501 } else { | |
| 7502 /* Expect 5-3 transform */ | |
| 7503 if (parameters->irreversible != 0) { | |
| 7504 opj_event_msg(p_manager, EVT_WARNING, | |
| 7505 "IMF 2K/4K/8K profiles require 5-3 reversible Transform.\n" | |
| 7506 "-> Compression parameters set it to irreversible.\n" | |
| 7507 "-> Non-IMF codestream will be generated\n"); | |
| 7508 ret = OPJ_FALSE; | |
| 7509 } | |
| 7510 } | |
| 7511 | |
| 7512 /* Number of layers */ | |
| 7513 if (parameters->tcp_numlayers != 1) { | |
| 7514 opj_event_msg(p_manager, EVT_WARNING, | |
| 7515 "IMF 2K/4K/8K profiles require 1 single quality layer.\n" | |
| 7516 "-> Number of layers is %d.\n" | |
| 7517 "-> Non-IMF codestream will be generated\n", | |
| 7518 parameters->tcp_numlayers); | |
| 7519 ret = OPJ_FALSE; | |
| 7520 } | |
| 7521 | |
| 7522 /* Decomposition levels */ | |
| 7523 switch (profile) { | |
| 7524 case OPJ_PROFILE_IMF_2K: | |
| 7525 if (!(NL >= 1 && NL <= 5)) { | |
| 7526 opj_event_msg(p_manager, EVT_WARNING, | |
| 7527 "IMF 2K profile requires 1 <= NL <= 5:\n" | |
| 7528 "-> Number of decomposition levels is %d.\n" | |
| 7529 "-> Non-IMF codestream will be generated\n", | |
| 7530 NL); | |
| 7531 ret = OPJ_FALSE; | |
| 7532 } | |
| 7533 break; | |
| 7534 case OPJ_PROFILE_IMF_4K: | |
| 7535 if (!(NL >= 1 && NL <= 6)) { | |
| 7536 opj_event_msg(p_manager, EVT_WARNING, | |
| 7537 "IMF 4K profile requires 1 <= NL <= 6:\n" | |
| 7538 "-> Number of decomposition levels is %d.\n" | |
| 7539 "-> Non-IMF codestream will be generated\n", | |
| 7540 NL); | |
| 7541 ret = OPJ_FALSE; | |
| 7542 } | |
| 7543 break; | |
| 7544 case OPJ_PROFILE_IMF_8K: | |
| 7545 if (!(NL >= 1 && NL <= 7)) { | |
| 7546 opj_event_msg(p_manager, EVT_WARNING, | |
| 7547 "IMF 8K profile requires 1 <= NL <= 7:\n" | |
| 7548 "-> Number of decomposition levels is %d.\n" | |
| 7549 "-> Non-IMF codestream will be generated\n", | |
| 7550 NL); | |
| 7551 ret = OPJ_FALSE; | |
| 7552 } | |
| 7553 break; | |
| 7554 case OPJ_PROFILE_IMF_2K_R: { | |
| 7555 if (XTsiz >= 2048) { | |
| 7556 if (!(NL >= 1 && NL <= 5)) { | |
| 7557 opj_event_msg(p_manager, EVT_WARNING, | |
| 7558 "IMF 2K_R profile requires 1 <= NL <= 5 for XTsiz >= 2048:\n" | |
| 7559 "-> Number of decomposition levels is %d.\n" | |
| 7560 "-> Non-IMF codestream will be generated\n", | |
| 7561 NL); | |
| 7562 ret = OPJ_FALSE; | |
| 7563 } | |
| 7564 } else if (XTsiz >= 1024) { | |
| 7565 if (!(NL >= 1 && NL <= 4)) { | |
| 7566 opj_event_msg(p_manager, EVT_WARNING, | |
| 7567 "IMF 2K_R profile requires 1 <= NL <= 4 for XTsiz in [1024,2048[:\n" | |
| 7568 "-> Number of decomposition levels is %d.\n" | |
| 7569 "-> Non-IMF codestream will be generated\n", | |
| 7570 NL); | |
| 7571 ret = OPJ_FALSE; | |
| 7572 } | |
| 7573 } | |
| 7574 break; | |
| 7575 } | |
| 7576 case OPJ_PROFILE_IMF_4K_R: { | |
| 7577 if (XTsiz >= 4096) { | |
| 7578 if (!(NL >= 1 && NL <= 6)) { | |
| 7579 opj_event_msg(p_manager, EVT_WARNING, | |
| 7580 "IMF 4K_R profile requires 1 <= NL <= 6 for XTsiz >= 4096:\n" | |
| 7581 "-> Number of decomposition levels is %d.\n" | |
| 7582 "-> Non-IMF codestream will be generated\n", | |
| 7583 NL); | |
| 7584 ret = OPJ_FALSE; | |
| 7585 } | |
| 7586 } else if (XTsiz >= 2048) { | |
| 7587 if (!(NL >= 1 && NL <= 5)) { | |
| 7588 opj_event_msg(p_manager, EVT_WARNING, | |
| 7589 "IMF 4K_R profile requires 1 <= NL <= 5 for XTsiz in [2048,4096[:\n" | |
| 7590 "-> Number of decomposition levels is %d.\n" | |
| 7591 "-> Non-IMF codestream will be generated\n", | |
| 7592 NL); | |
| 7593 ret = OPJ_FALSE; | |
| 7594 } | |
| 7595 } else if (XTsiz >= 1024) { | |
| 7596 if (!(NL >= 1 && NL <= 4)) { | |
| 7597 opj_event_msg(p_manager, EVT_WARNING, | |
| 7598 "IMF 4K_R profile requires 1 <= NL <= 4 for XTsiz in [1024,2048[:\n" | |
| 7599 "-> Number of decomposition levels is %d.\n" | |
| 7600 "-> Non-IMF codestream will be generated\n", | |
| 7601 NL); | |
| 7602 ret = OPJ_FALSE; | |
| 7603 } | |
| 7604 } | |
| 7605 break; | |
| 7606 } | |
| 7607 case OPJ_PROFILE_IMF_8K_R: { | |
| 7608 if (XTsiz >= 8192) { | |
| 7609 if (!(NL >= 1 && NL <= 7)) { | |
| 7610 opj_event_msg(p_manager, EVT_WARNING, | |
| 7611 "IMF 4K_R profile requires 1 <= NL <= 7 for XTsiz >= 8192:\n" | |
| 7612 "-> Number of decomposition levels is %d.\n" | |
| 7613 "-> Non-IMF codestream will be generated\n", | |
| 7614 NL); | |
| 7615 ret = OPJ_FALSE; | |
| 7616 } | |
| 7617 } else if (XTsiz >= 4096) { | |
| 7618 if (!(NL >= 1 && NL <= 6)) { | |
| 7619 opj_event_msg(p_manager, EVT_WARNING, | |
| 7620 "IMF 4K_R profile requires 1 <= NL <= 6 for XTsiz in [4096,8192[:\n" | |
| 7621 "-> Number of decomposition levels is %d.\n" | |
| 7622 "-> Non-IMF codestream will be generated\n", | |
| 7623 NL); | |
| 7624 ret = OPJ_FALSE; | |
| 7625 } | |
| 7626 } else if (XTsiz >= 2048) { | |
| 7627 if (!(NL >= 1 && NL <= 5)) { | |
| 7628 opj_event_msg(p_manager, EVT_WARNING, | |
| 7629 "IMF 4K_R profile requires 1 <= NL <= 5 for XTsiz in [2048,4096[:\n" | |
| 7630 "-> Number of decomposition levels is %d.\n" | |
| 7631 "-> Non-IMF codestream will be generated\n", | |
| 7632 NL); | |
| 7633 ret = OPJ_FALSE; | |
| 7634 } | |
| 7635 } else if (XTsiz >= 1024) { | |
| 7636 if (!(NL >= 1 && NL <= 4)) { | |
| 7637 opj_event_msg(p_manager, EVT_WARNING, | |
| 7638 "IMF 4K_R profile requires 1 <= NL <= 4 for XTsiz in [1024,2048[:\n" | |
| 7639 "-> Number of decomposition levels is %d.\n" | |
| 7640 "-> Non-IMF codestream will be generated\n", | |
| 7641 NL); | |
| 7642 ret = OPJ_FALSE; | |
| 7643 } | |
| 7644 } | |
| 7645 break; | |
| 7646 } | |
| 7647 default: | |
| 7648 break; | |
| 7649 } | |
| 7650 | |
| 7651 if (parameters->numresolution == 1) { | |
| 7652 if (parameters->res_spec != 1 || | |
| 7653 parameters->prcw_init[0] != 128 || | |
| 7654 parameters->prch_init[0] != 128) { | |
| 7655 opj_event_msg(p_manager, EVT_WARNING, | |
| 7656 "IMF profiles require PPx = PPy = 7 for NLLL band, else 8.\n" | |
| 7657 "-> Supplied values are different from that.\n" | |
| 7658 "-> Non-IMF codestream will be generated\n"); | |
| 7659 ret = OPJ_FALSE; | |
| 7660 } | |
| 7661 } else { | |
| 7662 int i; | |
| 7663 for (i = 0; i < parameters->res_spec; i++) { | |
| 7664 if (parameters->prcw_init[i] != 256 || | |
| 7665 parameters->prch_init[i] != 256) { | |
| 7666 opj_event_msg(p_manager, EVT_WARNING, | |
| 7667 "IMF profiles require PPx = PPy = 7 for NLLL band, else 8.\n" | |
| 7668 "-> Supplied values are different from that.\n" | |
| 7669 "-> Non-IMF codestream will be generated\n"); | |
| 7670 ret = OPJ_FALSE; | |
| 7671 } | |
| 7672 } | |
| 7673 } | |
| 7674 | |
| 7675 return ret; | |
| 7676 } | |
| 7677 | |
| 7678 | |
| 7679 OPJ_BOOL opj_j2k_setup_encoder(opj_j2k_t *p_j2k, | |
| 7680 opj_cparameters_t *parameters, | |
| 7681 opj_image_t *image, | |
| 7682 opj_event_mgr_t * p_manager) | |
| 7683 { | |
| 7684 OPJ_UINT32 i, j, tileno, numpocs_tile; | |
| 7685 opj_cp_t *cp = 00; | |
| 7686 OPJ_UINT32 cblkw, cblkh; | |
| 7687 | |
| 7688 if (!p_j2k || !parameters || ! image) { | |
| 7689 return OPJ_FALSE; | |
| 7690 } | |
| 7691 | |
| 7692 if ((parameters->numresolution <= 0) || | |
| 7693 (parameters->numresolution > OPJ_J2K_MAXRLVLS)) { | |
| 7694 opj_event_msg(p_manager, EVT_ERROR, | |
| 7695 "Invalid number of resolutions : %d not in range [1,%d]\n", | |
| 7696 parameters->numresolution, OPJ_J2K_MAXRLVLS); | |
| 7697 return OPJ_FALSE; | |
| 7698 } | |
| 7699 | |
| 7700 if (parameters->cblockw_init < 4 || parameters->cblockw_init > 1024) { | |
| 7701 opj_event_msg(p_manager, EVT_ERROR, | |
| 7702 "Invalid value for cblockw_init: %d not a power of 2 in range [4,1024]\n", | |
| 7703 parameters->cblockw_init); | |
| 7704 return OPJ_FALSE; | |
| 7705 } | |
| 7706 if (parameters->cblockh_init < 4 || parameters->cblockh_init > 1024) { | |
| 7707 opj_event_msg(p_manager, EVT_ERROR, | |
| 7708 "Invalid value for cblockh_init: %d not a power of 2 not in range [4,1024]\n", | |
| 7709 parameters->cblockh_init); | |
| 7710 return OPJ_FALSE; | |
| 7711 } | |
| 7712 if (parameters->cblockw_init * parameters->cblockh_init > 4096) { | |
| 7713 opj_event_msg(p_manager, EVT_ERROR, | |
| 7714 "Invalid value for cblockw_init * cblockh_init: should be <= 4096\n"); | |
| 7715 return OPJ_FALSE; | |
| 7716 } | |
| 7717 cblkw = (OPJ_UINT32)opj_int_floorlog2(parameters->cblockw_init); | |
| 7718 cblkh = (OPJ_UINT32)opj_int_floorlog2(parameters->cblockh_init); | |
| 7719 if (parameters->cblockw_init != (1 << cblkw)) { | |
| 7720 opj_event_msg(p_manager, EVT_ERROR, | |
| 7721 "Invalid value for cblockw_init: %d not a power of 2 in range [4,1024]\n", | |
| 7722 parameters->cblockw_init); | |
| 7723 return OPJ_FALSE; | |
| 7724 } | |
| 7725 if (parameters->cblockh_init != (1 << cblkh)) { | |
| 7726 opj_event_msg(p_manager, EVT_ERROR, | |
| 7727 "Invalid value for cblockw_init: %d not a power of 2 in range [4,1024]\n", | |
| 7728 parameters->cblockh_init); | |
| 7729 return OPJ_FALSE; | |
| 7730 } | |
| 7731 | |
| 7732 if (parameters->cp_fixed_alloc) { | |
| 7733 if (parameters->cp_matrice == NULL) { | |
| 7734 opj_event_msg(p_manager, EVT_ERROR, | |
| 7735 "cp_fixed_alloc set, but cp_matrice missing\n"); | |
| 7736 return OPJ_FALSE; | |
| 7737 } | |
| 7738 | |
| 7739 if (parameters->tcp_numlayers > J2K_TCD_MATRIX_MAX_LAYER_COUNT) { | |
| 7740 opj_event_msg(p_manager, EVT_ERROR, | |
| 7741 "tcp_numlayers when cp_fixed_alloc set should not exceed %d\n", | |
| 7742 J2K_TCD_MATRIX_MAX_LAYER_COUNT); | |
| 7743 return OPJ_FALSE; | |
| 7744 } | |
| 7745 if (parameters->numresolution > J2K_TCD_MATRIX_MAX_RESOLUTION_COUNT) { | |
| 7746 opj_event_msg(p_manager, EVT_ERROR, | |
| 7747 "numresolution when cp_fixed_alloc set should not exceed %d\n", | |
| 7748 J2K_TCD_MATRIX_MAX_RESOLUTION_COUNT); | |
| 7749 return OPJ_FALSE; | |
| 7750 } | |
| 7751 } | |
| 7752 | |
| 7753 p_j2k->m_specific_param.m_encoder.m_nb_comps = image->numcomps; | |
| 7754 | |
| 7755 /* keep a link to cp so that we can destroy it later in j2k_destroy_compress */ | |
| 7756 cp = &(p_j2k->m_cp); | |
| 7757 | |
| 7758 /* set default values for cp */ | |
| 7759 cp->tw = 1; | |
| 7760 cp->th = 1; | |
| 7761 | |
| 7762 /* FIXME ADE: to be removed once deprecated cp_cinema and cp_rsiz have been removed */ | |
| 7763 if (parameters->rsiz == | |
| 7764 OPJ_PROFILE_NONE) { /* consider deprecated fields only if RSIZ has not been set */ | |
| 7765 OPJ_BOOL deprecated_used = OPJ_FALSE; | |
| 7766 switch (parameters->cp_cinema) { | |
| 7767 case OPJ_CINEMA2K_24: | |
| 7768 parameters->rsiz = OPJ_PROFILE_CINEMA_2K; | |
| 7769 parameters->max_cs_size = OPJ_CINEMA_24_CS; | |
| 7770 parameters->max_comp_size = OPJ_CINEMA_24_COMP; | |
| 7771 deprecated_used = OPJ_TRUE; | |
| 7772 break; | |
| 7773 case OPJ_CINEMA2K_48: | |
| 7774 parameters->rsiz = OPJ_PROFILE_CINEMA_2K; | |
| 7775 parameters->max_cs_size = OPJ_CINEMA_48_CS; | |
| 7776 parameters->max_comp_size = OPJ_CINEMA_48_COMP; | |
| 7777 deprecated_used = OPJ_TRUE; | |
| 7778 break; | |
| 7779 case OPJ_CINEMA4K_24: | |
| 7780 parameters->rsiz = OPJ_PROFILE_CINEMA_4K; | |
| 7781 parameters->max_cs_size = OPJ_CINEMA_24_CS; | |
| 7782 parameters->max_comp_size = OPJ_CINEMA_24_COMP; | |
| 7783 deprecated_used = OPJ_TRUE; | |
| 7784 break; | |
| 7785 case OPJ_OFF: | |
| 7786 default: | |
| 7787 break; | |
| 7788 } | |
| 7789 switch (parameters->cp_rsiz) { | |
| 7790 case OPJ_CINEMA2K: | |
| 7791 parameters->rsiz = OPJ_PROFILE_CINEMA_2K; | |
| 7792 deprecated_used = OPJ_TRUE; | |
| 7793 break; | |
| 7794 case OPJ_CINEMA4K: | |
| 7795 parameters->rsiz = OPJ_PROFILE_CINEMA_4K; | |
| 7796 deprecated_used = OPJ_TRUE; | |
| 7797 break; | |
| 7798 case OPJ_MCT: | |
| 7799 parameters->rsiz = OPJ_PROFILE_PART2 | OPJ_EXTENSION_MCT; | |
| 7800 deprecated_used = OPJ_TRUE; | |
| 7801 case OPJ_STD_RSIZ: | |
| 7802 default: | |
| 7803 break; | |
| 7804 } | |
| 7805 if (deprecated_used) { | |
| 7806 opj_event_msg(p_manager, EVT_WARNING, | |
| 7807 "Deprecated fields cp_cinema or cp_rsiz are used\n" | |
| 7808 "Please consider using only the rsiz field\n" | |
| 7809 "See openjpeg.h documentation for more details\n"); | |
| 7810 } | |
| 7811 } | |
| 7812 | |
| 7813 /* If no explicit layers are provided, use lossless settings */ | |
| 7814 if (parameters->tcp_numlayers == 0) { | |
| 7815 parameters->tcp_numlayers = 1; | |
| 7816 parameters->cp_disto_alloc = 1; | |
| 7817 parameters->tcp_rates[0] = 0; | |
| 7818 } | |
| 7819 | |
| 7820 if (parameters->cp_disto_alloc) { | |
| 7821 /* Emit warnings if tcp_rates are not decreasing */ | |
| 7822 for (i = 1; i < (OPJ_UINT32) parameters->tcp_numlayers; i++) { | |
| 7823 OPJ_FLOAT32 rate_i_corr = parameters->tcp_rates[i]; | |
| 7824 OPJ_FLOAT32 rate_i_m_1_corr = parameters->tcp_rates[i - 1]; | |
| 7825 if (rate_i_corr <= 1.0) { | |
| 7826 rate_i_corr = 1.0; | |
| 7827 } | |
| 7828 if (rate_i_m_1_corr <= 1.0) { | |
| 7829 rate_i_m_1_corr = 1.0; | |
| 7830 } | |
| 7831 if (rate_i_corr >= rate_i_m_1_corr) { | |
| 7832 if (rate_i_corr != parameters->tcp_rates[i] && | |
| 7833 rate_i_m_1_corr != parameters->tcp_rates[i - 1]) { | |
| 7834 opj_event_msg(p_manager, EVT_WARNING, | |
| 7835 "tcp_rates[%d]=%f (corrected as %f) should be strictly lesser " | |
| 7836 "than tcp_rates[%d]=%f (corrected as %f)\n", | |
| 7837 i, parameters->tcp_rates[i], rate_i_corr, | |
| 7838 i - 1, parameters->tcp_rates[i - 1], rate_i_m_1_corr); | |
| 7839 } else if (rate_i_corr != parameters->tcp_rates[i]) { | |
| 7840 opj_event_msg(p_manager, EVT_WARNING, | |
| 7841 "tcp_rates[%d]=%f (corrected as %f) should be strictly lesser " | |
| 7842 "than tcp_rates[%d]=%f\n", | |
| 7843 i, parameters->tcp_rates[i], rate_i_corr, | |
| 7844 i - 1, parameters->tcp_rates[i - 1]); | |
| 7845 } else if (rate_i_m_1_corr != parameters->tcp_rates[i - 1]) { | |
| 7846 opj_event_msg(p_manager, EVT_WARNING, | |
| 7847 "tcp_rates[%d]=%f should be strictly lesser " | |
| 7848 "than tcp_rates[%d]=%f (corrected as %f)\n", | |
| 7849 i, parameters->tcp_rates[i], | |
| 7850 i - 1, parameters->tcp_rates[i - 1], rate_i_m_1_corr); | |
| 7851 } else { | |
| 7852 opj_event_msg(p_manager, EVT_WARNING, | |
| 7853 "tcp_rates[%d]=%f should be strictly lesser " | |
| 7854 "than tcp_rates[%d]=%f\n", | |
| 7855 i, parameters->tcp_rates[i], | |
| 7856 i - 1, parameters->tcp_rates[i - 1]); | |
| 7857 } | |
| 7858 } | |
| 7859 } | |
| 7860 } else if (parameters->cp_fixed_quality) { | |
| 7861 /* Emit warnings if tcp_distoratio are not increasing */ | |
| 7862 for (i = 1; i < (OPJ_UINT32) parameters->tcp_numlayers; i++) { | |
| 7863 if (parameters->tcp_distoratio[i] < parameters->tcp_distoratio[i - 1] && | |
| 7864 !(i == (OPJ_UINT32)parameters->tcp_numlayers - 1 && | |
| 7865 parameters->tcp_distoratio[i] == 0)) { | |
| 7866 opj_event_msg(p_manager, EVT_WARNING, | |
| 7867 "tcp_distoratio[%d]=%f should be strictly greater " | |
| 7868 "than tcp_distoratio[%d]=%f\n", | |
| 7869 i, parameters->tcp_distoratio[i], i - 1, | |
| 7870 parameters->tcp_distoratio[i - 1]); | |
| 7871 } | |
| 7872 } | |
| 7873 } | |
| 7874 | |
| 7875 /* see if max_codestream_size does limit input rate */ | |
| 7876 if (parameters->max_cs_size <= 0) { | |
| 7877 if (parameters->tcp_rates[parameters->tcp_numlayers - 1] > 0) { | |
| 7878 OPJ_FLOAT32 temp_size; | |
| 7879 temp_size = (OPJ_FLOAT32)(((double)image->numcomps * image->comps[0].w * | |
| 7880 image->comps[0].h * image->comps[0].prec) / | |
| 7881 ((double)parameters->tcp_rates[parameters->tcp_numlayers - 1] * 8 * | |
| 7882 image->comps[0].dx * image->comps[0].dy)); | |
| 7883 if (temp_size > (OPJ_FLOAT32)INT_MAX) { | |
| 7884 parameters->max_cs_size = INT_MAX; | |
| 7885 } else { | |
| 7886 parameters->max_cs_size = (int) floor(temp_size); | |
| 7887 } | |
| 7888 } else { | |
| 7889 parameters->max_cs_size = 0; | |
| 7890 } | |
| 7891 } else { | |
| 7892 OPJ_FLOAT32 temp_rate; | |
| 7893 OPJ_BOOL cap = OPJ_FALSE; | |
| 7894 | |
| 7895 if (OPJ_IS_IMF(parameters->rsiz) && parameters->max_cs_size > 0 && | |
| 7896 parameters->tcp_numlayers == 1 && parameters->tcp_rates[0] == 0) { | |
| 7897 parameters->tcp_rates[0] = (OPJ_FLOAT32)(image->numcomps * image->comps[0].w * | |
| 7898 image->comps[0].h * image->comps[0].prec) / | |
| 7899 (OPJ_FLOAT32)(((OPJ_UINT32)parameters->max_cs_size) * 8 * image->comps[0].dx * | |
| 7900 image->comps[0].dy); | |
| 7901 } | |
| 7902 | |
| 7903 temp_rate = (OPJ_FLOAT32)(((double)image->numcomps * image->comps[0].w * | |
| 7904 image->comps[0].h * image->comps[0].prec) / | |
| 7905 (((double)parameters->max_cs_size) * 8 * image->comps[0].dx * | |
| 7906 image->comps[0].dy)); | |
| 7907 for (i = 0; i < (OPJ_UINT32) parameters->tcp_numlayers; i++) { | |
| 7908 if (parameters->tcp_rates[i] < temp_rate) { | |
| 7909 parameters->tcp_rates[i] = temp_rate; | |
| 7910 cap = OPJ_TRUE; | |
| 7911 } | |
| 7912 } | |
| 7913 if (cap) { | |
| 7914 opj_event_msg(p_manager, EVT_WARNING, | |
| 7915 "The desired maximum codestream size has limited\n" | |
| 7916 "at least one of the desired quality layers\n"); | |
| 7917 } | |
| 7918 } | |
| 7919 | |
| 7920 if (OPJ_IS_CINEMA(parameters->rsiz) || OPJ_IS_IMF(parameters->rsiz)) { | |
| 7921 p_j2k->m_specific_param.m_encoder.m_TLM = OPJ_TRUE; | |
| 7922 } | |
| 7923 | |
| 7924 /* Manage profiles and applications and set RSIZ */ | |
| 7925 /* set cinema parameters if required */ | |
| 7926 if (OPJ_IS_CINEMA(parameters->rsiz)) { | |
| 7927 if ((parameters->rsiz == OPJ_PROFILE_CINEMA_S2K) | |
| 7928 || (parameters->rsiz == OPJ_PROFILE_CINEMA_S4K)) { | |
| 7929 opj_event_msg(p_manager, EVT_WARNING, | |
| 7930 "JPEG 2000 Scalable Digital Cinema profiles not yet supported\n"); | |
| 7931 parameters->rsiz = OPJ_PROFILE_NONE; | |
| 7932 } else { | |
| 7933 opj_j2k_set_cinema_parameters(parameters, image, p_manager); | |
| 7934 if (!opj_j2k_is_cinema_compliant(image, parameters->rsiz, p_manager)) { | |
| 7935 parameters->rsiz = OPJ_PROFILE_NONE; | |
| 7936 } | |
| 7937 } | |
| 7938 } else if (OPJ_IS_STORAGE(parameters->rsiz)) { | |
| 7939 opj_event_msg(p_manager, EVT_WARNING, | |
| 7940 "JPEG 2000 Long Term Storage profile not yet supported\n"); | |
| 7941 parameters->rsiz = OPJ_PROFILE_NONE; | |
| 7942 } else if (OPJ_IS_BROADCAST(parameters->rsiz)) { | |
| 7943 opj_event_msg(p_manager, EVT_WARNING, | |
| 7944 "JPEG 2000 Broadcast profiles not yet supported\n"); | |
| 7945 parameters->rsiz = OPJ_PROFILE_NONE; | |
| 7946 } else if (OPJ_IS_IMF(parameters->rsiz)) { | |
| 7947 opj_j2k_set_imf_parameters(parameters, image, p_manager); | |
| 7948 if (!opj_j2k_is_imf_compliant(parameters, image, p_manager)) { | |
| 7949 parameters->rsiz = OPJ_PROFILE_NONE; | |
| 7950 } | |
| 7951 } else if (OPJ_IS_PART2(parameters->rsiz)) { | |
| 7952 if (parameters->rsiz == ((OPJ_PROFILE_PART2) | (OPJ_EXTENSION_NONE))) { | |
| 7953 opj_event_msg(p_manager, EVT_WARNING, | |
| 7954 "JPEG 2000 Part-2 profile defined\n" | |
| 7955 "but no Part-2 extension enabled.\n" | |
| 7956 "Profile set to NONE.\n"); | |
| 7957 parameters->rsiz = OPJ_PROFILE_NONE; | |
| 7958 } else if (parameters->rsiz != ((OPJ_PROFILE_PART2) | (OPJ_EXTENSION_MCT))) { | |
| 7959 opj_event_msg(p_manager, EVT_WARNING, | |
| 7960 "Unsupported Part-2 extension enabled\n" | |
| 7961 "Profile set to NONE.\n"); | |
| 7962 parameters->rsiz = OPJ_PROFILE_NONE; | |
| 7963 } | |
| 7964 } | |
| 7965 | |
| 7966 /* | |
| 7967 copy user encoding parameters | |
| 7968 */ | |
| 7969 cp->m_specific_param.m_enc.m_max_comp_size = (OPJ_UINT32) | |
| 7970 parameters->max_comp_size; | |
| 7971 cp->rsiz = parameters->rsiz; | |
| 7972 if (parameters->cp_fixed_alloc) { | |
| 7973 cp->m_specific_param.m_enc.m_quality_layer_alloc_strategy = FIXED_LAYER; | |
| 7974 } else if (parameters->cp_fixed_quality) { | |
| 7975 cp->m_specific_param.m_enc.m_quality_layer_alloc_strategy = | |
| 7976 FIXED_DISTORTION_RATIO; | |
| 7977 } else { | |
| 7978 cp->m_specific_param.m_enc.m_quality_layer_alloc_strategy = | |
| 7979 RATE_DISTORTION_RATIO; | |
| 7980 } | |
| 7981 | |
| 7982 if (parameters->cp_fixed_alloc) { | |
| 7983 size_t array_size = (size_t)parameters->tcp_numlayers * | |
| 7984 (size_t)parameters->numresolution * 3 * sizeof(OPJ_INT32); | |
| 7985 cp->m_specific_param.m_enc.m_matrice = (OPJ_INT32 *) opj_malloc(array_size); | |
| 7986 if (!cp->m_specific_param.m_enc.m_matrice) { | |
| 7987 opj_event_msg(p_manager, EVT_ERROR, | |
| 7988 "Not enough memory to allocate copy of user encoding parameters matrix \n"); | |
| 7989 return OPJ_FALSE; | |
| 7990 } | |
| 7991 memcpy(cp->m_specific_param.m_enc.m_matrice, parameters->cp_matrice, | |
| 7992 array_size); | |
| 7993 } | |
| 7994 | |
| 7995 /* tiles */ | |
| 7996 cp->tdx = (OPJ_UINT32)parameters->cp_tdx; | |
| 7997 cp->tdy = (OPJ_UINT32)parameters->cp_tdy; | |
| 7998 | |
| 7999 /* tile offset */ | |
| 8000 cp->tx0 = (OPJ_UINT32)parameters->cp_tx0; | |
| 8001 cp->ty0 = (OPJ_UINT32)parameters->cp_ty0; | |
| 8002 | |
| 8003 /* comment string */ | |
| 8004 if (parameters->cp_comment) { | |
| 8005 cp->comment = (char*)opj_malloc(strlen(parameters->cp_comment) + 1U); | |
| 8006 if (!cp->comment) { | |
| 8007 opj_event_msg(p_manager, EVT_ERROR, | |
| 8008 "Not enough memory to allocate copy of comment string\n"); | |
| 8009 return OPJ_FALSE; | |
| 8010 } | |
| 8011 strcpy(cp->comment, parameters->cp_comment); | |
| 8012 } else { | |
| 8013 /* Create default comment for codestream */ | |
| 8014 const char comment[] = "Created by OpenJPEG version "; | |
| 8015 const size_t clen = strlen(comment); | |
| 8016 const char *version = opj_version(); | |
| 8017 | |
| 8018 /* UniPG>> */ | |
| 8019 #ifdef USE_JPWL | |
| 8020 const size_t cp_comment_buf_size = clen + strlen(version) + 11; | |
| 8021 cp->comment = (char*)opj_malloc(cp_comment_buf_size); | |
| 8022 if (!cp->comment) { | |
| 8023 opj_event_msg(p_manager, EVT_ERROR, | |
| 8024 "Not enough memory to allocate comment string\n"); | |
| 8025 return OPJ_FALSE; | |
| 8026 } | |
| 8027 snprintf(cp->comment, cp_comment_buf_size, "%s%s with JPWL", | |
| 8028 comment, version); | |
| 8029 #else | |
| 8030 const size_t cp_comment_buf_size = clen + strlen(version) + 1; | |
| 8031 cp->comment = (char*)opj_malloc(cp_comment_buf_size); | |
| 8032 if (!cp->comment) { | |
| 8033 opj_event_msg(p_manager, EVT_ERROR, | |
| 8034 "Not enough memory to allocate comment string\n"); | |
| 8035 return OPJ_FALSE; | |
| 8036 } | |
| 8037 snprintf(cp->comment, cp_comment_buf_size, "%s%s", comment, version); | |
| 8038 #endif | |
| 8039 /* <<UniPG */ | |
| 8040 } | |
| 8041 | |
| 8042 /* | |
| 8043 calculate other encoding parameters | |
| 8044 */ | |
| 8045 | |
| 8046 if (parameters->tile_size_on) { | |
| 8047 if (cp->tdx == 0) { | |
| 8048 opj_event_msg(p_manager, EVT_ERROR, "Invalid tile width\n"); | |
| 8049 return OPJ_FALSE; | |
| 8050 } | |
| 8051 if (cp->tdy == 0) { | |
| 8052 opj_event_msg(p_manager, EVT_ERROR, "Invalid tile height\n"); | |
| 8053 return OPJ_FALSE; | |
| 8054 } | |
| 8055 cp->tw = opj_uint_ceildiv(image->x1 - cp->tx0, cp->tdx); | |
| 8056 cp->th = opj_uint_ceildiv(image->y1 - cp->ty0, cp->tdy); | |
| 8057 /* Check that the number of tiles is valid */ | |
| 8058 if (cp->tw > 65535 / cp->th) { | |
| 8059 opj_event_msg(p_manager, EVT_ERROR, | |
| 8060 "Invalid number of tiles : %u x %u (maximum fixed by jpeg2000 norm is 65535 tiles)\n", | |
| 8061 cp->tw, cp->th); | |
| 8062 return OPJ_FALSE; | |
| 8063 } | |
| 8064 } else { | |
| 8065 cp->tdx = image->x1 - cp->tx0; | |
| 8066 cp->tdy = image->y1 - cp->ty0; | |
| 8067 } | |
| 8068 | |
| 8069 if (parameters->tp_on) { | |
| 8070 cp->m_specific_param.m_enc.m_tp_flag = (OPJ_BYTE)parameters->tp_flag; | |
| 8071 cp->m_specific_param.m_enc.m_tp_on = 1; | |
| 8072 } | |
| 8073 | |
| 8074 #ifdef USE_JPWL | |
| 8075 /* | |
| 8076 calculate JPWL encoding parameters | |
| 8077 */ | |
| 8078 | |
| 8079 if (parameters->jpwl_epc_on) { | |
| 8080 OPJ_INT32 i; | |
| 8081 | |
| 8082 /* set JPWL on */ | |
| 8083 cp->epc_on = OPJ_TRUE; | |
| 8084 cp->info_on = OPJ_FALSE; /* no informative technique */ | |
| 8085 | |
| 8086 /* set EPB on */ | |
| 8087 if ((parameters->jpwl_hprot_MH > 0) || (parameters->jpwl_hprot_TPH[0] > 0)) { | |
| 8088 cp->epb_on = OPJ_TRUE; | |
| 8089 | |
| 8090 cp->hprot_MH = parameters->jpwl_hprot_MH; | |
| 8091 for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) { | |
| 8092 cp->hprot_TPH_tileno[i] = parameters->jpwl_hprot_TPH_tileno[i]; | |
| 8093 cp->hprot_TPH[i] = parameters->jpwl_hprot_TPH[i]; | |
| 8094 } | |
| 8095 /* if tile specs are not specified, copy MH specs */ | |
| 8096 if (cp->hprot_TPH[0] == -1) { | |
| 8097 cp->hprot_TPH_tileno[0] = 0; | |
| 8098 cp->hprot_TPH[0] = parameters->jpwl_hprot_MH; | |
| 8099 } | |
| 8100 for (i = 0; i < JPWL_MAX_NO_PACKSPECS; i++) { | |
| 8101 cp->pprot_tileno[i] = parameters->jpwl_pprot_tileno[i]; | |
| 8102 cp->pprot_packno[i] = parameters->jpwl_pprot_packno[i]; | |
| 8103 cp->pprot[i] = parameters->jpwl_pprot[i]; | |
| 8104 } | |
| 8105 } | |
| 8106 | |
| 8107 /* set ESD writing */ | |
| 8108 if ((parameters->jpwl_sens_size == 1) || (parameters->jpwl_sens_size == 2)) { | |
| 8109 cp->esd_on = OPJ_TRUE; | |
| 8110 | |
| 8111 cp->sens_size = parameters->jpwl_sens_size; | |
| 8112 cp->sens_addr = parameters->jpwl_sens_addr; | |
| 8113 cp->sens_range = parameters->jpwl_sens_range; | |
| 8114 | |
| 8115 cp->sens_MH = parameters->jpwl_sens_MH; | |
| 8116 for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) { | |
| 8117 cp->sens_TPH_tileno[i] = parameters->jpwl_sens_TPH_tileno[i]; | |
| 8118 cp->sens_TPH[i] = parameters->jpwl_sens_TPH[i]; | |
| 8119 } | |
| 8120 } | |
| 8121 | |
| 8122 /* always set RED writing to false: we are at the encoder */ | |
| 8123 cp->red_on = OPJ_FALSE; | |
| 8124 | |
| 8125 } else { | |
| 8126 cp->epc_on = OPJ_FALSE; | |
| 8127 } | |
| 8128 #endif /* USE_JPWL */ | |
| 8129 | |
| 8130 /* initialize the multiple tiles */ | |
| 8131 /* ---------------------------- */ | |
| 8132 cp->tcps = (opj_tcp_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tcp_t)); | |
| 8133 if (!cp->tcps) { | |
| 8134 opj_event_msg(p_manager, EVT_ERROR, | |
| 8135 "Not enough memory to allocate tile coding parameters\n"); | |
| 8136 return OPJ_FALSE; | |
| 8137 } | |
| 8138 | |
| 8139 for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { | |
| 8140 opj_tcp_t *tcp = &cp->tcps[tileno]; | |
| 8141 const OPJ_BOOL fixed_distoratio = | |
| 8142 cp->m_specific_param.m_enc.m_quality_layer_alloc_strategy == | |
| 8143 FIXED_DISTORTION_RATIO; | |
| 8144 tcp->numlayers = (OPJ_UINT32)parameters->tcp_numlayers; | |
| 8145 | |
| 8146 for (j = 0; j < tcp->numlayers; j++) { | |
| 8147 if (OPJ_IS_CINEMA(cp->rsiz) || OPJ_IS_IMF(cp->rsiz)) { | |
| 8148 if (fixed_distoratio) { | |
| 8149 tcp->distoratio[j] = parameters->tcp_distoratio[j]; | |
| 8150 } | |
| 8151 tcp->rates[j] = parameters->tcp_rates[j]; | |
| 8152 } else { | |
| 8153 if (fixed_distoratio) { | |
| 8154 tcp->distoratio[j] = parameters->tcp_distoratio[j]; | |
| 8155 } else { | |
| 8156 tcp->rates[j] = parameters->tcp_rates[j]; | |
| 8157 } | |
| 8158 } | |
| 8159 if (!fixed_distoratio && | |
| 8160 tcp->rates[j] <= 1.0) { | |
| 8161 tcp->rates[j] = 0.0; /* force lossless */ | |
| 8162 } | |
| 8163 } | |
| 8164 | |
| 8165 tcp->csty = (OPJ_UINT32)parameters->csty; | |
| 8166 tcp->prg = parameters->prog_order; | |
| 8167 tcp->mct = (OPJ_UINT32)parameters->tcp_mct; | |
| 8168 | |
| 8169 numpocs_tile = 0; | |
| 8170 tcp->POC = 0; | |
| 8171 | |
| 8172 if (parameters->numpocs) { | |
| 8173 /* initialisation of POC */ | |
| 8174 for (i = 0; i < parameters->numpocs; i++) { | |
| 8175 if (tileno + 1 == parameters->POC[i].tile) { | |
| 8176 opj_poc_t *tcp_poc = &tcp->pocs[numpocs_tile]; | |
| 8177 | |
| 8178 if (parameters->POC[numpocs_tile].compno0 >= image->numcomps) { | |
| 8179 opj_event_msg(p_manager, EVT_ERROR, | |
| 8180 "Invalid compno0 for POC %d\n", i); | |
| 8181 return OPJ_FALSE; | |
| 8182 } | |
| 8183 | |
| 8184 tcp_poc->resno0 = parameters->POC[numpocs_tile].resno0; | |
| 8185 tcp_poc->compno0 = parameters->POC[numpocs_tile].compno0; | |
| 8186 tcp_poc->layno1 = parameters->POC[numpocs_tile].layno1; | |
| 8187 tcp_poc->resno1 = parameters->POC[numpocs_tile].resno1; | |
| 8188 tcp_poc->compno1 = opj_uint_min(parameters->POC[numpocs_tile].compno1, | |
| 8189 image->numcomps); | |
| 8190 tcp_poc->prg1 = parameters->POC[numpocs_tile].prg1; | |
| 8191 tcp_poc->tile = parameters->POC[numpocs_tile].tile; | |
| 8192 | |
| 8193 numpocs_tile++; | |
| 8194 } | |
| 8195 } | |
| 8196 | |
| 8197 if (numpocs_tile) { | |
| 8198 | |
| 8199 /* TODO MSD use the return value*/ | |
| 8200 opj_j2k_check_poc_val(parameters->POC, tileno, parameters->numpocs, | |
| 8201 (OPJ_UINT32)parameters->numresolution, image->numcomps, | |
| 8202 (OPJ_UINT32)parameters->tcp_numlayers, p_manager); | |
| 8203 | |
| 8204 tcp->POC = 1; | |
| 8205 tcp->numpocs = numpocs_tile - 1 ; | |
| 8206 } | |
| 8207 } else { | |
| 8208 tcp->numpocs = 0; | |
| 8209 } | |
| 8210 | |
| 8211 tcp->tccps = (opj_tccp_t*) opj_calloc(image->numcomps, sizeof(opj_tccp_t)); | |
| 8212 if (!tcp->tccps) { | |
| 8213 opj_event_msg(p_manager, EVT_ERROR, | |
| 8214 "Not enough memory to allocate tile component coding parameters\n"); | |
| 8215 return OPJ_FALSE; | |
| 8216 } | |
| 8217 if (parameters->mct_data) { | |
| 8218 | |
| 8219 OPJ_UINT32 lMctSize = image->numcomps * image->numcomps * (OPJ_UINT32)sizeof( | |
| 8220 OPJ_FLOAT32); | |
| 8221 OPJ_FLOAT32 * lTmpBuf = (OPJ_FLOAT32*)opj_malloc(lMctSize); | |
| 8222 OPJ_INT32 * l_dc_shift = (OPJ_INT32 *)((OPJ_BYTE *) parameters->mct_data + | |
| 8223 lMctSize); | |
| 8224 | |
| 8225 if (!lTmpBuf) { | |
| 8226 opj_event_msg(p_manager, EVT_ERROR, | |
| 8227 "Not enough memory to allocate temp buffer\n"); | |
| 8228 return OPJ_FALSE; | |
| 8229 } | |
| 8230 | |
| 8231 tcp->mct = 2; | |
| 8232 tcp->m_mct_coding_matrix = (OPJ_FLOAT32*)opj_malloc(lMctSize); | |
| 8233 if (! tcp->m_mct_coding_matrix) { | |
| 8234 opj_free(lTmpBuf); | |
| 8235 lTmpBuf = NULL; | |
| 8236 opj_event_msg(p_manager, EVT_ERROR, | |
| 8237 "Not enough memory to allocate encoder MCT coding matrix \n"); | |
| 8238 return OPJ_FALSE; | |
| 8239 } | |
| 8240 memcpy(tcp->m_mct_coding_matrix, parameters->mct_data, lMctSize); | |
| 8241 memcpy(lTmpBuf, parameters->mct_data, lMctSize); | |
| 8242 | |
| 8243 tcp->m_mct_decoding_matrix = (OPJ_FLOAT32*)opj_malloc(lMctSize); | |
| 8244 if (! tcp->m_mct_decoding_matrix) { | |
| 8245 opj_free(lTmpBuf); | |
| 8246 lTmpBuf = NULL; | |
| 8247 opj_event_msg(p_manager, EVT_ERROR, | |
| 8248 "Not enough memory to allocate encoder MCT decoding matrix \n"); | |
| 8249 return OPJ_FALSE; | |
| 8250 } | |
| 8251 if (opj_matrix_inversion_f(lTmpBuf, (tcp->m_mct_decoding_matrix), | |
| 8252 image->numcomps) == OPJ_FALSE) { | |
| 8253 opj_free(lTmpBuf); | |
| 8254 lTmpBuf = NULL; | |
| 8255 opj_event_msg(p_manager, EVT_ERROR, | |
| 8256 "Failed to inverse encoder MCT decoding matrix \n"); | |
| 8257 return OPJ_FALSE; | |
| 8258 } | |
| 8259 | |
| 8260 tcp->mct_norms = (OPJ_FLOAT64*) | |
| 8261 opj_malloc(image->numcomps * sizeof(OPJ_FLOAT64)); | |
| 8262 if (! tcp->mct_norms) { | |
| 8263 opj_free(lTmpBuf); | |
| 8264 lTmpBuf = NULL; | |
| 8265 opj_event_msg(p_manager, EVT_ERROR, | |
| 8266 "Not enough memory to allocate encoder MCT norms \n"); | |
| 8267 return OPJ_FALSE; | |
| 8268 } | |
| 8269 opj_calculate_norms(tcp->mct_norms, image->numcomps, | |
| 8270 tcp->m_mct_decoding_matrix); | |
| 8271 opj_free(lTmpBuf); | |
| 8272 | |
| 8273 for (i = 0; i < image->numcomps; i++) { | |
| 8274 opj_tccp_t *tccp = &tcp->tccps[i]; | |
| 8275 tccp->m_dc_level_shift = l_dc_shift[i]; | |
| 8276 } | |
| 8277 | |
| 8278 if (opj_j2k_setup_mct_encoding(tcp, image) == OPJ_FALSE) { | |
| 8279 /* free will be handled by opj_j2k_destroy */ | |
| 8280 opj_event_msg(p_manager, EVT_ERROR, "Failed to setup j2k mct encoding\n"); | |
| 8281 return OPJ_FALSE; | |
| 8282 } | |
| 8283 } else { | |
| 8284 if (tcp->mct == 1 && image->numcomps >= 3) { /* RGB->YCC MCT is enabled */ | |
| 8285 if ((image->comps[0].dx != image->comps[1].dx) || | |
| 8286 (image->comps[0].dx != image->comps[2].dx) || | |
| 8287 (image->comps[0].dy != image->comps[1].dy) || | |
| 8288 (image->comps[0].dy != image->comps[2].dy)) { | |
| 8289 opj_event_msg(p_manager, EVT_WARNING, | |
| 8290 "Cannot perform MCT on components with different sizes. Disabling MCT.\n"); | |
| 8291 tcp->mct = 0; | |
| 8292 } | |
| 8293 } | |
| 8294 for (i = 0; i < image->numcomps; i++) { | |
| 8295 opj_tccp_t *tccp = &tcp->tccps[i]; | |
| 8296 opj_image_comp_t * l_comp = &(image->comps[i]); | |
| 8297 | |
| 8298 if (! l_comp->sgnd) { | |
| 8299 tccp->m_dc_level_shift = 1 << (l_comp->prec - 1); | |
| 8300 } | |
| 8301 } | |
| 8302 } | |
| 8303 | |
| 8304 for (i = 0; i < image->numcomps; i++) { | |
| 8305 opj_tccp_t *tccp = &tcp->tccps[i]; | |
| 8306 | |
| 8307 tccp->csty = parameters->csty & | |
| 8308 0x01; /* 0 => one precinct || 1 => custom precinct */ | |
| 8309 tccp->numresolutions = (OPJ_UINT32)parameters->numresolution; | |
| 8310 tccp->cblkw = (OPJ_UINT32)opj_int_floorlog2(parameters->cblockw_init); | |
| 8311 tccp->cblkh = (OPJ_UINT32)opj_int_floorlog2(parameters->cblockh_init); | |
| 8312 tccp->cblksty = (OPJ_UINT32)parameters->mode; | |
| 8313 tccp->qmfbid = parameters->irreversible ? 0 : 1; | |
| 8314 tccp->qntsty = parameters->irreversible ? J2K_CCP_QNTSTY_SEQNT : | |
| 8315 J2K_CCP_QNTSTY_NOQNT; | |
| 8316 | |
| 8317 if (OPJ_IS_CINEMA(parameters->rsiz) && | |
| 8318 parameters->rsiz == OPJ_PROFILE_CINEMA_2K) { | |
| 8319 /* From https://github.com/uclouvain/openjpeg/issues/1340 */ | |
| 8320 tccp->numgbits = 1; | |
| 8321 } else { | |
| 8322 tccp->numgbits = 2; | |
| 8323 } | |
| 8324 | |
| 8325 if ((OPJ_INT32)i == parameters->roi_compno) { | |
| 8326 tccp->roishift = parameters->roi_shift; | |
| 8327 } else { | |
| 8328 tccp->roishift = 0; | |
| 8329 } | |
| 8330 | |
| 8331 if (parameters->csty & J2K_CCP_CSTY_PRT) { | |
| 8332 OPJ_INT32 p = 0, it_res; | |
| 8333 assert(tccp->numresolutions > 0); | |
| 8334 for (it_res = (OPJ_INT32)tccp->numresolutions - 1; it_res >= 0; it_res--) { | |
| 8335 if (p < parameters->res_spec) { | |
| 8336 | |
| 8337 if (parameters->prcw_init[p] < 1) { | |
| 8338 tccp->prcw[it_res] = 1; | |
| 8339 } else { | |
| 8340 tccp->prcw[it_res] = (OPJ_UINT32)opj_int_floorlog2(parameters->prcw_init[p]); | |
| 8341 } | |
| 8342 | |
| 8343 if (parameters->prch_init[p] < 1) { | |
| 8344 tccp->prch[it_res] = 1; | |
| 8345 } else { | |
| 8346 tccp->prch[it_res] = (OPJ_UINT32)opj_int_floorlog2(parameters->prch_init[p]); | |
| 8347 } | |
| 8348 | |
| 8349 } else { | |
| 8350 OPJ_INT32 res_spec = parameters->res_spec; | |
| 8351 OPJ_INT32 size_prcw = 0; | |
| 8352 OPJ_INT32 size_prch = 0; | |
| 8353 | |
| 8354 assert(res_spec > 0); /* issue 189 */ | |
| 8355 size_prcw = parameters->prcw_init[res_spec - 1] >> (p - (res_spec - 1)); | |
| 8356 size_prch = parameters->prch_init[res_spec - 1] >> (p - (res_spec - 1)); | |
| 8357 | |
| 8358 | |
| 8359 if (size_prcw < 1) { | |
| 8360 tccp->prcw[it_res] = 1; | |
| 8361 } else { | |
| 8362 tccp->prcw[it_res] = (OPJ_UINT32)opj_int_floorlog2(size_prcw); | |
| 8363 } | |
| 8364 | |
| 8365 if (size_prch < 1) { | |
| 8366 tccp->prch[it_res] = 1; | |
| 8367 } else { | |
| 8368 tccp->prch[it_res] = (OPJ_UINT32)opj_int_floorlog2(size_prch); | |
| 8369 } | |
| 8370 } | |
| 8371 p++; | |
| 8372 /*printf("\nsize precinct for level %d : %d,%d\n", it_res,tccp->prcw[it_res], tccp->prch[it_res]); */ | |
| 8373 } /*end for*/ | |
| 8374 } else { | |
| 8375 for (j = 0; j < tccp->numresolutions; j++) { | |
| 8376 tccp->prcw[j] = 15; | |
| 8377 tccp->prch[j] = 15; | |
| 8378 } | |
| 8379 } | |
| 8380 | |
| 8381 opj_dwt_calc_explicit_stepsizes(tccp, image->comps[i].prec); | |
| 8382 } | |
| 8383 } | |
| 8384 | |
| 8385 if (parameters->mct_data) { | |
| 8386 opj_free(parameters->mct_data); | |
| 8387 parameters->mct_data = 00; | |
| 8388 } | |
| 8389 return OPJ_TRUE; | |
| 8390 } | |
| 8391 | |
| 8392 static OPJ_BOOL opj_j2k_add_mhmarker(opj_codestream_index_t *cstr_index, | |
| 8393 OPJ_UINT32 type, OPJ_OFF_T pos, OPJ_UINT32 len) | |
| 8394 { | |
| 8395 assert(cstr_index != 00); | |
| 8396 | |
| 8397 /* expand the list? */ | |
| 8398 if ((cstr_index->marknum + 1) > cstr_index->maxmarknum) { | |
| 8399 opj_marker_info_t *new_marker; | |
| 8400 cstr_index->maxmarknum = (OPJ_UINT32)(100 + (OPJ_FLOAT32) | |
| 8401 cstr_index->maxmarknum); | |
| 8402 new_marker = (opj_marker_info_t *) opj_realloc(cstr_index->marker, | |
| 8403 cstr_index->maxmarknum * sizeof(opj_marker_info_t)); | |
| 8404 if (! new_marker) { | |
| 8405 opj_free(cstr_index->marker); | |
| 8406 cstr_index->marker = NULL; | |
| 8407 cstr_index->maxmarknum = 0; | |
| 8408 cstr_index->marknum = 0; | |
| 8409 /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to add mh marker\n"); */ | |
| 8410 return OPJ_FALSE; | |
| 8411 } | |
| 8412 cstr_index->marker = new_marker; | |
| 8413 } | |
| 8414 | |
| 8415 /* add the marker */ | |
| 8416 cstr_index->marker[cstr_index->marknum].type = (OPJ_UINT16)type; | |
| 8417 cstr_index->marker[cstr_index->marknum].pos = (OPJ_INT32)pos; | |
| 8418 cstr_index->marker[cstr_index->marknum].len = (OPJ_INT32)len; | |
| 8419 cstr_index->marknum++; | |
| 8420 return OPJ_TRUE; | |
| 8421 } | |
| 8422 | |
| 8423 static OPJ_BOOL opj_j2k_add_tlmarker(OPJ_UINT32 tileno, | |
| 8424 opj_codestream_index_t *cstr_index, OPJ_UINT32 type, OPJ_OFF_T pos, | |
| 8425 OPJ_UINT32 len) | |
| 8426 { | |
| 8427 assert(cstr_index != 00); | |
| 8428 assert(cstr_index->tile_index != 00); | |
| 8429 | |
| 8430 /* expand the list? */ | |
| 8431 if ((cstr_index->tile_index[tileno].marknum + 1) > | |
| 8432 cstr_index->tile_index[tileno].maxmarknum) { | |
| 8433 opj_marker_info_t *new_marker; | |
| 8434 cstr_index->tile_index[tileno].maxmarknum = (OPJ_UINT32)(100 + | |
| 8435 (OPJ_FLOAT32) cstr_index->tile_index[tileno].maxmarknum); | |
| 8436 new_marker = (opj_marker_info_t *) opj_realloc( | |
| 8437 cstr_index->tile_index[tileno].marker, | |
| 8438 cstr_index->tile_index[tileno].maxmarknum * sizeof(opj_marker_info_t)); | |
| 8439 if (! new_marker) { | |
| 8440 opj_free(cstr_index->tile_index[tileno].marker); | |
| 8441 cstr_index->tile_index[tileno].marker = NULL; | |
| 8442 cstr_index->tile_index[tileno].maxmarknum = 0; | |
| 8443 cstr_index->tile_index[tileno].marknum = 0; | |
| 8444 /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to add tl marker\n"); */ | |
| 8445 return OPJ_FALSE; | |
| 8446 } | |
| 8447 cstr_index->tile_index[tileno].marker = new_marker; | |
| 8448 } | |
| 8449 | |
| 8450 /* add the marker */ | |
| 8451 cstr_index->tile_index[tileno].marker[cstr_index->tile_index[tileno].marknum].type | |
| 8452 = (OPJ_UINT16)type; | |
| 8453 cstr_index->tile_index[tileno].marker[cstr_index->tile_index[tileno].marknum].pos | |
| 8454 = (OPJ_INT32)pos; | |
| 8455 cstr_index->tile_index[tileno].marker[cstr_index->tile_index[tileno].marknum].len | |
| 8456 = (OPJ_INT32)len; | |
| 8457 cstr_index->tile_index[tileno].marknum++; | |
| 8458 | |
| 8459 if (type == J2K_MS_SOT) { | |
| 8460 OPJ_UINT32 l_current_tile_part = cstr_index->tile_index[tileno].current_tpsno; | |
| 8461 | |
| 8462 if (cstr_index->tile_index[tileno].tp_index && | |
| 8463 l_current_tile_part < cstr_index->tile_index[tileno].nb_tps) { | |
| 8464 cstr_index->tile_index[tileno].tp_index[l_current_tile_part].start_pos = pos; | |
| 8465 } | |
| 8466 | |
| 8467 } | |
| 8468 return OPJ_TRUE; | |
| 8469 } | |
| 8470 | |
| 8471 /* | |
| 8472 * ----------------------------------------------------------------------- | |
| 8473 * ----------------------------------------------------------------------- | |
| 8474 * ----------------------------------------------------------------------- | |
| 8475 */ | |
| 8476 | |
| 8477 OPJ_BOOL opj_j2k_end_decompress(opj_j2k_t *p_j2k, | |
| 8478 opj_stream_private_t *p_stream, | |
| 8479 opj_event_mgr_t * p_manager | |
| 8480 ) | |
| 8481 { | |
| 8482 (void)p_j2k; | |
| 8483 (void)p_stream; | |
| 8484 (void)p_manager; | |
| 8485 return OPJ_TRUE; | |
| 8486 } | |
| 8487 | |
| 8488 OPJ_BOOL opj_j2k_read_header(opj_stream_private_t *p_stream, | |
| 8489 opj_j2k_t* p_j2k, | |
| 8490 opj_image_t** p_image, | |
| 8491 opj_event_mgr_t* p_manager) | |
| 8492 { | |
| 8493 /* preconditions */ | |
| 8494 assert(p_j2k != 00); | |
| 8495 assert(p_stream != 00); | |
| 8496 assert(p_manager != 00); | |
| 8497 | |
| 8498 /* create an empty image header */ | |
| 8499 p_j2k->m_private_image = opj_image_create0(); | |
| 8500 if (! p_j2k->m_private_image) { | |
| 8501 return OPJ_FALSE; | |
| 8502 } | |
| 8503 | |
| 8504 /* customization of the validation */ | |
| 8505 if (! opj_j2k_setup_decoding_validation(p_j2k, p_manager)) { | |
| 8506 opj_image_destroy(p_j2k->m_private_image); | |
| 8507 p_j2k->m_private_image = NULL; | |
| 8508 return OPJ_FALSE; | |
| 8509 } | |
| 8510 | |
| 8511 /* validation of the parameters codec */ | |
| 8512 if (! opj_j2k_exec(p_j2k, p_j2k->m_validation_list, p_stream, p_manager)) { | |
| 8513 opj_image_destroy(p_j2k->m_private_image); | |
| 8514 p_j2k->m_private_image = NULL; | |
| 8515 return OPJ_FALSE; | |
| 8516 } | |
| 8517 | |
| 8518 /* customization of the encoding */ | |
| 8519 if (! opj_j2k_setup_header_reading(p_j2k, p_manager)) { | |
| 8520 opj_image_destroy(p_j2k->m_private_image); | |
| 8521 p_j2k->m_private_image = NULL; | |
| 8522 return OPJ_FALSE; | |
| 8523 } | |
| 8524 | |
| 8525 /* read header */ | |
| 8526 if (! opj_j2k_exec(p_j2k, p_j2k->m_procedure_list, p_stream, p_manager)) { | |
| 8527 opj_image_destroy(p_j2k->m_private_image); | |
| 8528 p_j2k->m_private_image = NULL; | |
| 8529 return OPJ_FALSE; | |
| 8530 } | |
| 8531 | |
| 8532 *p_image = opj_image_create0(); | |
| 8533 if (!(*p_image)) { | |
| 8534 return OPJ_FALSE; | |
| 8535 } | |
| 8536 | |
| 8537 /* Copy codestream image information to the output image */ | |
| 8538 opj_copy_image_header(p_j2k->m_private_image, *p_image); | |
| 8539 | |
| 8540 return OPJ_TRUE; | |
| 8541 } | |
| 8542 | |
| 8543 static OPJ_BOOL opj_j2k_setup_header_reading(opj_j2k_t *p_j2k, | |
| 8544 opj_event_mgr_t * p_manager) | |
| 8545 { | |
| 8546 /* preconditions*/ | |
| 8547 assert(p_j2k != 00); | |
| 8548 assert(p_manager != 00); | |
| 8549 | |
| 8550 if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list, | |
| 8551 (opj_procedure)opj_j2k_read_header_procedure, p_manager)) { | |
| 8552 return OPJ_FALSE; | |
| 8553 } | |
| 8554 | |
| 8555 /* DEVELOPER CORNER, add your custom procedures */ | |
| 8556 if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list, | |
| 8557 (opj_procedure)opj_j2k_copy_default_tcp_and_create_tcd, p_manager)) { | |
| 8558 return OPJ_FALSE; | |
| 8559 } | |
| 8560 | |
| 8561 return OPJ_TRUE; | |
| 8562 } | |
| 8563 | |
| 8564 static OPJ_BOOL opj_j2k_setup_decoding_validation(opj_j2k_t *p_j2k, | |
| 8565 opj_event_mgr_t * p_manager) | |
| 8566 { | |
| 8567 /* preconditions*/ | |
| 8568 assert(p_j2k != 00); | |
| 8569 assert(p_manager != 00); | |
| 8570 | |
| 8571 if (! opj_procedure_list_add_procedure(p_j2k->m_validation_list, | |
| 8572 (opj_procedure)opj_j2k_build_decoder, p_manager)) { | |
| 8573 return OPJ_FALSE; | |
| 8574 } | |
| 8575 if (! opj_procedure_list_add_procedure(p_j2k->m_validation_list, | |
| 8576 (opj_procedure)opj_j2k_decoding_validation, p_manager)) { | |
| 8577 return OPJ_FALSE; | |
| 8578 } | |
| 8579 | |
| 8580 /* DEVELOPER CORNER, add your custom validation procedure */ | |
| 8581 return OPJ_TRUE; | |
| 8582 } | |
| 8583 | |
| 8584 static OPJ_BOOL opj_j2k_mct_validation(opj_j2k_t * p_j2k, | |
| 8585 opj_stream_private_t *p_stream, | |
| 8586 opj_event_mgr_t * p_manager) | |
| 8587 { | |
| 8588 OPJ_BOOL l_is_valid = OPJ_TRUE; | |
| 8589 OPJ_UINT32 i, j; | |
| 8590 | |
| 8591 /* preconditions */ | |
| 8592 assert(p_j2k != 00); | |
| 8593 assert(p_stream != 00); | |
| 8594 assert(p_manager != 00); | |
| 8595 | |
| 8596 OPJ_UNUSED(p_stream); | |
| 8597 OPJ_UNUSED(p_manager); | |
| 8598 | |
| 8599 if ((p_j2k->m_cp.rsiz & 0x8200) == 0x8200) { | |
| 8600 OPJ_UINT32 l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw; | |
| 8601 opj_tcp_t * l_tcp = p_j2k->m_cp.tcps; | |
| 8602 | |
| 8603 for (i = 0; i < l_nb_tiles; ++i) { | |
| 8604 if (l_tcp->mct == 2) { | |
| 8605 opj_tccp_t * l_tccp = l_tcp->tccps; | |
| 8606 l_is_valid &= (l_tcp->m_mct_coding_matrix != 00); | |
| 8607 | |
| 8608 for (j = 0; j < p_j2k->m_private_image->numcomps; ++j) { | |
| 8609 l_is_valid &= !(l_tccp->qmfbid & 1); | |
| 8610 ++l_tccp; | |
| 8611 } | |
| 8612 } | |
| 8613 ++l_tcp; | |
| 8614 } | |
| 8615 } | |
| 8616 | |
| 8617 return l_is_valid; | |
| 8618 } | |
| 8619 | |
| 8620 OPJ_BOOL opj_j2k_setup_mct_encoding(opj_tcp_t * p_tcp, opj_image_t * p_image) | |
| 8621 { | |
| 8622 OPJ_UINT32 i; | |
| 8623 OPJ_UINT32 l_indix = 1; | |
| 8624 opj_mct_data_t * l_mct_deco_data = 00, * l_mct_offset_data = 00; | |
| 8625 opj_simple_mcc_decorrelation_data_t * l_mcc_data; | |
| 8626 OPJ_UINT32 l_mct_size, l_nb_elem; | |
| 8627 OPJ_FLOAT32 * l_data, * l_current_data; | |
| 8628 opj_tccp_t * l_tccp; | |
| 8629 | |
| 8630 /* preconditions */ | |
| 8631 assert(p_tcp != 00); | |
| 8632 | |
| 8633 if (p_tcp->mct != 2) { | |
| 8634 return OPJ_TRUE; | |
| 8635 } | |
| 8636 | |
| 8637 if (p_tcp->m_mct_decoding_matrix) { | |
| 8638 if (p_tcp->m_nb_mct_records == p_tcp->m_nb_max_mct_records) { | |
| 8639 opj_mct_data_t *new_mct_records; | |
| 8640 p_tcp->m_nb_max_mct_records += OPJ_J2K_MCT_DEFAULT_NB_RECORDS; | |
| 8641 | |
| 8642 new_mct_records = (opj_mct_data_t *) opj_realloc(p_tcp->m_mct_records, | |
| 8643 p_tcp->m_nb_max_mct_records * sizeof(opj_mct_data_t)); | |
| 8644 if (! new_mct_records) { | |
| 8645 opj_free(p_tcp->m_mct_records); | |
| 8646 p_tcp->m_mct_records = NULL; | |
| 8647 p_tcp->m_nb_max_mct_records = 0; | |
| 8648 p_tcp->m_nb_mct_records = 0; | |
| 8649 /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to setup mct encoding\n"); */ | |
| 8650 return OPJ_FALSE; | |
| 8651 } | |
| 8652 p_tcp->m_mct_records = new_mct_records; | |
| 8653 l_mct_deco_data = p_tcp->m_mct_records + p_tcp->m_nb_mct_records; | |
| 8654 | |
| 8655 memset(l_mct_deco_data, 0, | |
| 8656 (p_tcp->m_nb_max_mct_records - p_tcp->m_nb_mct_records) * sizeof( | |
| 8657 opj_mct_data_t)); | |
| 8658 } | |
| 8659 l_mct_deco_data = p_tcp->m_mct_records + p_tcp->m_nb_mct_records; | |
| 8660 | |
| 8661 if (l_mct_deco_data->m_data) { | |
| 8662 opj_free(l_mct_deco_data->m_data); | |
| 8663 l_mct_deco_data->m_data = 00; | |
| 8664 } | |
| 8665 | |
| 8666 l_mct_deco_data->m_index = l_indix++; | |
| 8667 l_mct_deco_data->m_array_type = MCT_TYPE_DECORRELATION; | |
| 8668 l_mct_deco_data->m_element_type = MCT_TYPE_FLOAT; | |
| 8669 l_nb_elem = p_image->numcomps * p_image->numcomps; | |
| 8670 l_mct_size = l_nb_elem * MCT_ELEMENT_SIZE[l_mct_deco_data->m_element_type]; | |
| 8671 l_mct_deco_data->m_data = (OPJ_BYTE*)opj_malloc(l_mct_size); | |
| 8672 | |
| 8673 if (! l_mct_deco_data->m_data) { | |
| 8674 return OPJ_FALSE; | |
| 8675 } | |
| 8676 | |
| 8677 j2k_mct_write_functions_from_float[l_mct_deco_data->m_element_type]( | |
| 8678 p_tcp->m_mct_decoding_matrix, l_mct_deco_data->m_data, l_nb_elem); | |
| 8679 | |
| 8680 l_mct_deco_data->m_data_size = l_mct_size; | |
| 8681 ++p_tcp->m_nb_mct_records; | |
| 8682 } | |
| 8683 | |
| 8684 if (p_tcp->m_nb_mct_records == p_tcp->m_nb_max_mct_records) { | |
| 8685 opj_mct_data_t *new_mct_records; | |
| 8686 p_tcp->m_nb_max_mct_records += OPJ_J2K_MCT_DEFAULT_NB_RECORDS; | |
| 8687 new_mct_records = (opj_mct_data_t *) opj_realloc(p_tcp->m_mct_records, | |
| 8688 p_tcp->m_nb_max_mct_records * sizeof(opj_mct_data_t)); | |
| 8689 if (! new_mct_records) { | |
| 8690 opj_free(p_tcp->m_mct_records); | |
| 8691 p_tcp->m_mct_records = NULL; | |
| 8692 p_tcp->m_nb_max_mct_records = 0; | |
| 8693 p_tcp->m_nb_mct_records = 0; | |
| 8694 /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to setup mct encoding\n"); */ | |
| 8695 return OPJ_FALSE; | |
| 8696 } | |
| 8697 p_tcp->m_mct_records = new_mct_records; | |
| 8698 l_mct_offset_data = p_tcp->m_mct_records + p_tcp->m_nb_mct_records; | |
| 8699 | |
| 8700 memset(l_mct_offset_data, 0, | |
| 8701 (p_tcp->m_nb_max_mct_records - p_tcp->m_nb_mct_records) * sizeof( | |
| 8702 opj_mct_data_t)); | |
| 8703 | |
| 8704 if (l_mct_deco_data) { | |
| 8705 l_mct_deco_data = l_mct_offset_data - 1; | |
| 8706 } | |
| 8707 } | |
| 8708 | |
| 8709 l_mct_offset_data = p_tcp->m_mct_records + p_tcp->m_nb_mct_records; | |
| 8710 | |
| 8711 if (l_mct_offset_data->m_data) { | |
| 8712 opj_free(l_mct_offset_data->m_data); | |
| 8713 l_mct_offset_data->m_data = 00; | |
| 8714 } | |
| 8715 | |
| 8716 l_mct_offset_data->m_index = l_indix++; | |
| 8717 l_mct_offset_data->m_array_type = MCT_TYPE_OFFSET; | |
| 8718 l_mct_offset_data->m_element_type = MCT_TYPE_FLOAT; | |
| 8719 l_nb_elem = p_image->numcomps; | |
| 8720 l_mct_size = l_nb_elem * MCT_ELEMENT_SIZE[l_mct_offset_data->m_element_type]; | |
| 8721 l_mct_offset_data->m_data = (OPJ_BYTE*)opj_malloc(l_mct_size); | |
| 8722 | |
| 8723 if (! l_mct_offset_data->m_data) { | |
| 8724 return OPJ_FALSE; | |
| 8725 } | |
| 8726 | |
| 8727 l_data = (OPJ_FLOAT32*)opj_malloc(l_nb_elem * sizeof(OPJ_FLOAT32)); | |
| 8728 if (! l_data) { | |
| 8729 opj_free(l_mct_offset_data->m_data); | |
| 8730 l_mct_offset_data->m_data = 00; | |
| 8731 return OPJ_FALSE; | |
| 8732 } | |
| 8733 | |
| 8734 l_tccp = p_tcp->tccps; | |
| 8735 l_current_data = l_data; | |
| 8736 | |
| 8737 for (i = 0; i < l_nb_elem; ++i) { | |
| 8738 *(l_current_data++) = (OPJ_FLOAT32)(l_tccp->m_dc_level_shift); | |
| 8739 ++l_tccp; | |
| 8740 } | |
| 8741 | |
| 8742 j2k_mct_write_functions_from_float[l_mct_offset_data->m_element_type](l_data, | |
| 8743 l_mct_offset_data->m_data, l_nb_elem); | |
| 8744 | |
| 8745 opj_free(l_data); | |
| 8746 | |
| 8747 l_mct_offset_data->m_data_size = l_mct_size; | |
| 8748 | |
| 8749 ++p_tcp->m_nb_mct_records; | |
| 8750 | |
| 8751 if (p_tcp->m_nb_mcc_records == p_tcp->m_nb_max_mcc_records) { | |
| 8752 opj_simple_mcc_decorrelation_data_t *new_mcc_records; | |
| 8753 p_tcp->m_nb_max_mcc_records += OPJ_J2K_MCT_DEFAULT_NB_RECORDS; | |
| 8754 new_mcc_records = (opj_simple_mcc_decorrelation_data_t *) opj_realloc( | |
| 8755 p_tcp->m_mcc_records, p_tcp->m_nb_max_mcc_records * sizeof( | |
| 8756 opj_simple_mcc_decorrelation_data_t)); | |
| 8757 if (! new_mcc_records) { | |
| 8758 opj_free(p_tcp->m_mcc_records); | |
| 8759 p_tcp->m_mcc_records = NULL; | |
| 8760 p_tcp->m_nb_max_mcc_records = 0; | |
| 8761 p_tcp->m_nb_mcc_records = 0; | |
| 8762 /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to setup mct encoding\n"); */ | |
| 8763 return OPJ_FALSE; | |
| 8764 } | |
| 8765 p_tcp->m_mcc_records = new_mcc_records; | |
| 8766 l_mcc_data = p_tcp->m_mcc_records + p_tcp->m_nb_mcc_records; | |
| 8767 memset(l_mcc_data, 0, (p_tcp->m_nb_max_mcc_records - p_tcp->m_nb_mcc_records) * | |
| 8768 sizeof(opj_simple_mcc_decorrelation_data_t)); | |
| 8769 | |
| 8770 } | |
| 8771 | |
| 8772 l_mcc_data = p_tcp->m_mcc_records + p_tcp->m_nb_mcc_records; | |
| 8773 l_mcc_data->m_decorrelation_array = l_mct_deco_data; | |
| 8774 l_mcc_data->m_is_irreversible = 1; | |
| 8775 l_mcc_data->m_nb_comps = p_image->numcomps; | |
| 8776 l_mcc_data->m_index = l_indix++; | |
| 8777 l_mcc_data->m_offset_array = l_mct_offset_data; | |
| 8778 ++p_tcp->m_nb_mcc_records; | |
| 8779 | |
| 8780 return OPJ_TRUE; | |
| 8781 } | |
| 8782 | |
| 8783 static OPJ_BOOL opj_j2k_build_decoder(opj_j2k_t * p_j2k, | |
| 8784 opj_stream_private_t *p_stream, | |
| 8785 opj_event_mgr_t * p_manager) | |
| 8786 { | |
| 8787 /* add here initialization of cp | |
| 8788 copy paste of setup_decoder */ | |
| 8789 (void)p_j2k; | |
| 8790 (void)p_stream; | |
| 8791 (void)p_manager; | |
| 8792 return OPJ_TRUE; | |
| 8793 } | |
| 8794 | |
| 8795 static OPJ_BOOL opj_j2k_build_encoder(opj_j2k_t * p_j2k, | |
| 8796 opj_stream_private_t *p_stream, | |
| 8797 opj_event_mgr_t * p_manager) | |
| 8798 { | |
| 8799 /* add here initialization of cp | |
| 8800 copy paste of setup_encoder */ | |
| 8801 (void)p_j2k; | |
| 8802 (void)p_stream; | |
| 8803 (void)p_manager; | |
| 8804 return OPJ_TRUE; | |
| 8805 } | |
| 8806 | |
| 8807 static OPJ_BOOL opj_j2k_encoding_validation(opj_j2k_t * p_j2k, | |
| 8808 opj_stream_private_t *p_stream, | |
| 8809 opj_event_mgr_t * p_manager) | |
| 8810 { | |
| 8811 OPJ_BOOL l_is_valid = OPJ_TRUE; | |
| 8812 | |
| 8813 /* preconditions */ | |
| 8814 assert(p_j2k != 00); | |
| 8815 assert(p_stream != 00); | |
| 8816 assert(p_manager != 00); | |
| 8817 | |
| 8818 OPJ_UNUSED(p_stream); | |
| 8819 | |
| 8820 /* STATE checking */ | |
| 8821 /* make sure the state is at 0 */ | |
| 8822 l_is_valid &= (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_NONE); | |
| 8823 | |
| 8824 /* POINTER validation */ | |
| 8825 /* make sure a p_j2k codec is present */ | |
| 8826 l_is_valid &= (p_j2k->m_procedure_list != 00); | |
| 8827 /* make sure a validation list is present */ | |
| 8828 l_is_valid &= (p_j2k->m_validation_list != 00); | |
| 8829 | |
| 8830 /* ISO 15444-1:2004 states between 1 & 33 (0 -> 32) */ | |
| 8831 /* 33 (32) would always fail the check below (if a cast to 64bits was done) */ | |
| 8832 /* FIXME Shall we change OPJ_J2K_MAXRLVLS to 32 ? */ | |
| 8833 if ((p_j2k->m_cp.tcps->tccps->numresolutions <= 0) || | |
| 8834 (p_j2k->m_cp.tcps->tccps->numresolutions > 32)) { | |
| 8835 opj_event_msg(p_manager, EVT_ERROR, | |
| 8836 "Number of resolutions is too high in comparison to the size of tiles\n"); | |
| 8837 return OPJ_FALSE; | |
| 8838 } | |
| 8839 | |
| 8840 if ((p_j2k->m_cp.tdx) < (OPJ_UINT32)(1 << | |
| 8841 (p_j2k->m_cp.tcps->tccps->numresolutions - 1U))) { | |
| 8842 opj_event_msg(p_manager, EVT_ERROR, | |
| 8843 "Number of resolutions is too high in comparison to the size of tiles\n"); | |
| 8844 return OPJ_FALSE; | |
| 8845 } | |
| 8846 | |
| 8847 if ((p_j2k->m_cp.tdy) < (OPJ_UINT32)(1 << | |
| 8848 (p_j2k->m_cp.tcps->tccps->numresolutions - 1U))) { | |
| 8849 opj_event_msg(p_manager, EVT_ERROR, | |
| 8850 "Number of resolutions is too high in comparison to the size of tiles\n"); | |
| 8851 return OPJ_FALSE; | |
| 8852 } | |
| 8853 | |
| 8854 /* PARAMETER VALIDATION */ | |
| 8855 return l_is_valid; | |
| 8856 } | |
| 8857 | |
| 8858 static OPJ_BOOL opj_j2k_decoding_validation(opj_j2k_t *p_j2k, | |
| 8859 opj_stream_private_t *p_stream, | |
| 8860 opj_event_mgr_t * p_manager | |
| 8861 ) | |
| 8862 { | |
| 8863 OPJ_BOOL l_is_valid = OPJ_TRUE; | |
| 8864 | |
| 8865 /* preconditions*/ | |
| 8866 assert(p_j2k != 00); | |
| 8867 assert(p_stream != 00); | |
| 8868 assert(p_manager != 00); | |
| 8869 | |
| 8870 OPJ_UNUSED(p_stream); | |
| 8871 OPJ_UNUSED(p_manager); | |
| 8872 | |
| 8873 /* STATE checking */ | |
| 8874 /* make sure the state is at 0 */ | |
| 8875 #ifdef TODO_MSD | |
| 8876 l_is_valid &= (p_j2k->m_specific_param.m_decoder.m_state == J2K_DEC_STATE_NONE); | |
| 8877 #endif | |
| 8878 l_is_valid &= (p_j2k->m_specific_param.m_decoder.m_state == 0x0000); | |
| 8879 | |
| 8880 /* POINTER validation */ | |
| 8881 /* make sure a p_j2k codec is present */ | |
| 8882 /* make sure a procedure list is present */ | |
| 8883 l_is_valid &= (p_j2k->m_procedure_list != 00); | |
| 8884 /* make sure a validation list is present */ | |
| 8885 l_is_valid &= (p_j2k->m_validation_list != 00); | |
| 8886 | |
| 8887 /* PARAMETER VALIDATION */ | |
| 8888 return l_is_valid; | |
| 8889 } | |
| 8890 | |
| 8891 /** Fill p_j2k->cstr_index->tp_index[].start_pos/end_pos fields from TLM marker segments */ | |
| 8892 static void opj_j2k_build_tp_index_from_tlm(opj_j2k_t* p_j2k, | |
| 8893 opj_event_mgr_t * p_manager) | |
| 8894 { | |
| 8895 opj_j2k_tlm_info_t* l_tlm; | |
| 8896 OPJ_UINT32 i; | |
| 8897 OPJ_OFF_T l_cur_offset; | |
| 8898 | |
| 8899 assert(p_j2k->cstr_index->main_head_end > 0); | |
| 8900 assert(p_j2k->cstr_index->nb_of_tiles > 0); | |
| 8901 assert(p_j2k->cstr_index->tile_index != NULL); | |
| 8902 | |
| 8903 l_tlm = &(p_j2k->m_specific_param.m_decoder.m_tlm); | |
| 8904 | |
| 8905 if (l_tlm->m_entries_count == 0) { | |
| 8906 l_tlm->m_is_invalid = OPJ_TRUE; | |
| 8907 return; | |
| 8908 } | |
| 8909 | |
| 8910 if (l_tlm->m_is_invalid) { | |
| 8911 return; | |
| 8912 } | |
| 8913 | |
| 8914 /* Initial pass to count the number of tile-parts per tile */ | |
| 8915 for (i = 0; i < l_tlm->m_entries_count; ++i) { | |
| 8916 OPJ_UINT32 l_tile_index_no = l_tlm->m_tile_part_infos[i].m_tile_index; | |
| 8917 assert(l_tile_index_no < p_j2k->cstr_index->nb_of_tiles); | |
| 8918 p_j2k->cstr_index->tile_index[l_tile_index_no].tileno = l_tile_index_no; | |
| 8919 ++p_j2k->cstr_index->tile_index[l_tile_index_no].current_nb_tps; | |
| 8920 } | |
| 8921 | |
| 8922 /* Now check that all tiles have at least one tile-part */ | |
| 8923 for (i = 0; i < p_j2k->cstr_index->nb_of_tiles; ++i) { | |
| 8924 if (p_j2k->cstr_index->tile_index[i].current_nb_tps == 0) { | |
| 8925 opj_event_msg(p_manager, EVT_ERROR, | |
| 8926 "opj_j2k_build_tp_index_from_tlm(): tile %d has no " | |
| 8927 "registered tile-part in TLM marker segments.\n", i); | |
| 8928 goto error; | |
| 8929 } | |
| 8930 } | |
| 8931 | |
| 8932 /* Final pass to fill p_j2k->cstr_index */ | |
| 8933 l_cur_offset = p_j2k->cstr_index->main_head_end; | |
| 8934 for (i = 0; i < l_tlm->m_entries_count; ++i) { | |
| 8935 OPJ_UINT32 l_tile_index_no = l_tlm->m_tile_part_infos[i].m_tile_index; | |
| 8936 opj_tile_index_t* l_tile_index = & | |
| 8937 (p_j2k->cstr_index->tile_index[l_tile_index_no]); | |
| 8938 if (!l_tile_index->tp_index) { | |
| 8939 l_tile_index->tp_index = (opj_tp_index_t *) opj_calloc( | |
| 8940 l_tile_index->current_nb_tps, sizeof(opj_tp_index_t)); | |
| 8941 if (! l_tile_index->tp_index) { | |
| 8942 opj_event_msg(p_manager, EVT_ERROR, | |
| 8943 "opj_j2k_build_tp_index_from_tlm(): tile index allocation failed\n"); | |
| 8944 goto error; | |
| 8945 } | |
| 8946 } | |
| 8947 | |
| 8948 assert(l_tile_index->nb_tps < l_tile_index->current_nb_tps); | |
| 8949 l_tile_index->tp_index[l_tile_index->nb_tps].start_pos = l_cur_offset; | |
| 8950 /* We don't know how to set the tp_index[].end_header field, but this is not really needed */ | |
| 8951 /* If there would be no markers between SOT and SOD, that would be : */ | |
| 8952 /* l_tile_index->tp_index[l_tile_index->nb_tps].end_header = l_cur_offset + 12; */ | |
| 8953 l_tile_index->tp_index[l_tile_index->nb_tps].end_pos = l_cur_offset + | |
| 8954 l_tlm->m_tile_part_infos[i].m_length; | |
| 8955 ++l_tile_index->nb_tps; | |
| 8956 | |
| 8957 l_cur_offset += l_tlm->m_tile_part_infos[i].m_length; | |
| 8958 } | |
| 8959 | |
| 8960 return; | |
| 8961 | |
| 8962 error: | |
| 8963 l_tlm->m_is_invalid = OPJ_TRUE; | |
| 8964 for (i = 0; i < l_tlm->m_entries_count; ++i) { | |
| 8965 OPJ_UINT32 l_tile_index = l_tlm->m_tile_part_infos[i].m_tile_index; | |
| 8966 p_j2k->cstr_index->tile_index[l_tile_index].current_nb_tps = 0; | |
| 8967 opj_free(p_j2k->cstr_index->tile_index[l_tile_index].tp_index); | |
| 8968 p_j2k->cstr_index->tile_index[l_tile_index].tp_index = NULL; | |
| 8969 } | |
| 8970 } | |
| 8971 | |
| 8972 static OPJ_BOOL opj_j2k_read_header_procedure(opj_j2k_t *p_j2k, | |
| 8973 opj_stream_private_t *p_stream, | |
| 8974 opj_event_mgr_t * p_manager) | |
| 8975 { | |
| 8976 OPJ_UINT32 l_current_marker; | |
| 8977 OPJ_UINT32 l_marker_size; | |
| 8978 const opj_dec_memory_marker_handler_t * l_marker_handler = 00; | |
| 8979 OPJ_BOOL l_has_siz = 0; | |
| 8980 OPJ_BOOL l_has_cod = 0; | |
| 8981 OPJ_BOOL l_has_qcd = 0; | |
| 8982 | |
| 8983 /* preconditions */ | |
| 8984 assert(p_stream != 00); | |
| 8985 assert(p_j2k != 00); | |
| 8986 assert(p_manager != 00); | |
| 8987 | |
| 8988 /* We enter in the main header */ | |
| 8989 p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_MHSOC; | |
| 8990 | |
| 8991 /* Try to read the SOC marker, the codestream must begin with SOC marker */ | |
| 8992 if (! opj_j2k_read_soc(p_j2k, p_stream, p_manager)) { | |
| 8993 opj_event_msg(p_manager, EVT_ERROR, "Expected a SOC marker \n"); | |
| 8994 return OPJ_FALSE; | |
| 8995 } | |
| 8996 | |
| 8997 /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer */ | |
| 8998 if (opj_stream_read_data(p_stream, | |
| 8999 p_j2k->m_specific_param.m_decoder.m_header_data, 2, p_manager) != 2) { | |
| 9000 opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); | |
| 9001 return OPJ_FALSE; | |
| 9002 } | |
| 9003 | |
| 9004 /* Read 2 bytes as the new marker ID */ | |
| 9005 opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data, | |
| 9006 &l_current_marker, 2); | |
| 9007 | |
| 9008 /* Try to read until the SOT is detected */ | |
| 9009 while (l_current_marker != J2K_MS_SOT) { | |
| 9010 | |
| 9011 /* Check if the current marker ID is valid */ | |
| 9012 if (l_current_marker < 0xff00) { | |
| 9013 opj_event_msg(p_manager, EVT_ERROR, | |
| 9014 "A marker ID was expected (0xff--) instead of %.8x\n", l_current_marker); | |
| 9015 return OPJ_FALSE; | |
| 9016 } | |
| 9017 | |
| 9018 /* Get the marker handler from the marker ID */ | |
| 9019 l_marker_handler = opj_j2k_get_marker_handler(l_current_marker); | |
| 9020 | |
| 9021 /* Manage case where marker is unknown */ | |
| 9022 if (l_marker_handler->id == J2K_MS_UNK) { | |
| 9023 if (! opj_j2k_read_unk(p_j2k, p_stream, &l_current_marker, p_manager)) { | |
| 9024 opj_event_msg(p_manager, EVT_ERROR, | |
| 9025 "Unknown marker has been detected and generated error.\n"); | |
| 9026 return OPJ_FALSE; | |
| 9027 } | |
| 9028 | |
| 9029 if (l_current_marker == J2K_MS_SOT) { | |
| 9030 break; /* SOT marker is detected main header is completely read */ | |
| 9031 } else { /* Get the marker handler from the marker ID */ | |
| 9032 l_marker_handler = opj_j2k_get_marker_handler(l_current_marker); | |
| 9033 } | |
| 9034 } | |
| 9035 | |
| 9036 if (l_marker_handler->id == J2K_MS_SIZ) { | |
| 9037 /* Mark required SIZ marker as found */ | |
| 9038 l_has_siz = 1; | |
| 9039 } | |
| 9040 if (l_marker_handler->id == J2K_MS_COD) { | |
| 9041 /* Mark required COD marker as found */ | |
| 9042 l_has_cod = 1; | |
| 9043 } | |
| 9044 if (l_marker_handler->id == J2K_MS_QCD) { | |
| 9045 /* Mark required QCD marker as found */ | |
| 9046 l_has_qcd = 1; | |
| 9047 } | |
| 9048 | |
| 9049 /* Check if the marker is known and if it is the right place to find it */ | |
| 9050 if (!(p_j2k->m_specific_param.m_decoder.m_state & l_marker_handler->states)) { | |
| 9051 opj_event_msg(p_manager, EVT_ERROR, | |
| 9052 "Marker is not compliant with its position\n"); | |
| 9053 return OPJ_FALSE; | |
| 9054 } | |
| 9055 | |
| 9056 /* Try to read 2 bytes (the marker size) from stream and copy them into the buffer */ | |
| 9057 if (opj_stream_read_data(p_stream, | |
| 9058 p_j2k->m_specific_param.m_decoder.m_header_data, 2, p_manager) != 2) { | |
| 9059 opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); | |
| 9060 return OPJ_FALSE; | |
| 9061 } | |
| 9062 | |
| 9063 /* read 2 bytes as the marker size */ | |
| 9064 opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data, &l_marker_size, | |
| 9065 2); | |
| 9066 if (l_marker_size < 2) { | |
| 9067 opj_event_msg(p_manager, EVT_ERROR, "Invalid marker size\n"); | |
| 9068 return OPJ_FALSE; | |
| 9069 } | |
| 9070 l_marker_size -= 2; /* Subtract the size of the marker ID already read */ | |
| 9071 | |
| 9072 /* Check if the marker size is compatible with the header data size */ | |
| 9073 if (l_marker_size > p_j2k->m_specific_param.m_decoder.m_header_data_size) { | |
| 9074 OPJ_BYTE *new_header_data = (OPJ_BYTE *) opj_realloc( | |
| 9075 p_j2k->m_specific_param.m_decoder.m_header_data, l_marker_size); | |
| 9076 if (! new_header_data) { | |
| 9077 opj_free(p_j2k->m_specific_param.m_decoder.m_header_data); | |
| 9078 p_j2k->m_specific_param.m_decoder.m_header_data = NULL; | |
| 9079 p_j2k->m_specific_param.m_decoder.m_header_data_size = 0; | |
| 9080 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read header\n"); | |
| 9081 return OPJ_FALSE; | |
| 9082 } | |
| 9083 p_j2k->m_specific_param.m_decoder.m_header_data = new_header_data; | |
| 9084 p_j2k->m_specific_param.m_decoder.m_header_data_size = l_marker_size; | |
| 9085 } | |
| 9086 | |
| 9087 /* Try to read the rest of the marker segment from stream and copy them into the buffer */ | |
| 9088 if (opj_stream_read_data(p_stream, | |
| 9089 p_j2k->m_specific_param.m_decoder.m_header_data, l_marker_size, | |
| 9090 p_manager) != l_marker_size) { | |
| 9091 opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); | |
| 9092 return OPJ_FALSE; | |
| 9093 } | |
| 9094 | |
| 9095 /* Read the marker segment with the correct marker handler */ | |
| 9096 if (!(*(l_marker_handler->handler))(p_j2k, | |
| 9097 p_j2k->m_specific_param.m_decoder.m_header_data, l_marker_size, p_manager)) { | |
| 9098 opj_event_msg(p_manager, EVT_ERROR, | |
| 9099 "Marker handler function failed to read the marker segment\n"); | |
| 9100 return OPJ_FALSE; | |
| 9101 } | |
| 9102 | |
| 9103 /* Add the marker to the codestream index*/ | |
| 9104 if (OPJ_FALSE == opj_j2k_add_mhmarker( | |
| 9105 p_j2k->cstr_index, | |
| 9106 l_marker_handler->id, | |
| 9107 (OPJ_UINT32) opj_stream_tell(p_stream) - l_marker_size - 4, | |
| 9108 l_marker_size + 4)) { | |
| 9109 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to add mh marker\n"); | |
| 9110 return OPJ_FALSE; | |
| 9111 } | |
| 9112 | |
| 9113 /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer */ | |
| 9114 if (opj_stream_read_data(p_stream, | |
| 9115 p_j2k->m_specific_param.m_decoder.m_header_data, 2, p_manager) != 2) { | |
| 9116 opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); | |
| 9117 return OPJ_FALSE; | |
| 9118 } | |
| 9119 | |
| 9120 /* read 2 bytes as the new marker ID */ | |
| 9121 opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data, | |
| 9122 &l_current_marker, 2); | |
| 9123 } | |
| 9124 | |
| 9125 if (l_has_siz == 0) { | |
| 9126 opj_event_msg(p_manager, EVT_ERROR, | |
| 9127 "required SIZ marker not found in main header\n"); | |
| 9128 return OPJ_FALSE; | |
| 9129 } | |
| 9130 if (l_has_cod == 0) { | |
| 9131 opj_event_msg(p_manager, EVT_ERROR, | |
| 9132 "required COD marker not found in main header\n"); | |
| 9133 return OPJ_FALSE; | |
| 9134 } | |
| 9135 if (l_has_qcd == 0) { | |
| 9136 opj_event_msg(p_manager, EVT_ERROR, | |
| 9137 "required QCD marker not found in main header\n"); | |
| 9138 return OPJ_FALSE; | |
| 9139 } | |
| 9140 | |
| 9141 if (! opj_j2k_merge_ppm(&(p_j2k->m_cp), p_manager)) { | |
| 9142 opj_event_msg(p_manager, EVT_ERROR, "Failed to merge PPM data\n"); | |
| 9143 return OPJ_FALSE; | |
| 9144 } | |
| 9145 | |
| 9146 opj_event_msg(p_manager, EVT_INFO, "Main header has been correctly decoded.\n"); | |
| 9147 | |
| 9148 /* Position of the last element if the main header */ | |
| 9149 p_j2k->cstr_index->main_head_end = (OPJ_UINT32) opj_stream_tell(p_stream) - 2; | |
| 9150 | |
| 9151 /* Build tile-part index from TLM information */ | |
| 9152 opj_j2k_build_tp_index_from_tlm(p_j2k, p_manager); | |
| 9153 | |
| 9154 /* Next step: read a tile-part header */ | |
| 9155 p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_TPHSOT; | |
| 9156 | |
| 9157 return OPJ_TRUE; | |
| 9158 } | |
| 9159 | |
| 9160 static OPJ_BOOL opj_j2k_exec(opj_j2k_t * p_j2k, | |
| 9161 opj_procedure_list_t * p_procedure_list, | |
| 9162 opj_stream_private_t *p_stream, | |
| 9163 opj_event_mgr_t * p_manager) | |
| 9164 { | |
| 9165 OPJ_BOOL(** l_procedure)(opj_j2k_t *, opj_stream_private_t *, | |
| 9166 opj_event_mgr_t *) = 00; | |
| 9167 OPJ_BOOL l_result = OPJ_TRUE; | |
| 9168 OPJ_UINT32 l_nb_proc, i; | |
| 9169 | |
| 9170 /* preconditions*/ | |
| 9171 assert(p_procedure_list != 00); | |
| 9172 assert(p_j2k != 00); | |
| 9173 assert(p_stream != 00); | |
| 9174 assert(p_manager != 00); | |
| 9175 | |
| 9176 l_nb_proc = opj_procedure_list_get_nb_procedures(p_procedure_list); | |
| 9177 l_procedure = (OPJ_BOOL(**)(opj_j2k_t *, opj_stream_private_t *, | |
| 9178 opj_event_mgr_t *)) opj_procedure_list_get_first_procedure(p_procedure_list); | |
| 9179 | |
| 9180 for (i = 0; i < l_nb_proc; ++i) { | |
| 9181 l_result = l_result && ((*l_procedure)(p_j2k, p_stream, p_manager)); | |
| 9182 ++l_procedure; | |
| 9183 } | |
| 9184 | |
| 9185 /* and clear the procedure list at the end.*/ | |
| 9186 opj_procedure_list_clear(p_procedure_list); | |
| 9187 return l_result; | |
| 9188 } | |
| 9189 | |
| 9190 /* FIXME DOC*/ | |
| 9191 static OPJ_BOOL opj_j2k_copy_default_tcp_and_create_tcd(opj_j2k_t * p_j2k, | |
| 9192 opj_stream_private_t *p_stream, | |
| 9193 opj_event_mgr_t * p_manager | |
| 9194 ) | |
| 9195 { | |
| 9196 opj_tcp_t * l_tcp = 00; | |
| 9197 opj_tcp_t * l_default_tcp = 00; | |
| 9198 OPJ_UINT32 l_nb_tiles; | |
| 9199 OPJ_UINT32 i, j; | |
| 9200 opj_tccp_t *l_current_tccp = 00; | |
| 9201 OPJ_UINT32 l_tccp_size; | |
| 9202 OPJ_UINT32 l_mct_size; | |
| 9203 opj_image_t * l_image; | |
| 9204 OPJ_UINT32 l_mcc_records_size, l_mct_records_size; | |
| 9205 opj_mct_data_t * l_src_mct_rec, *l_dest_mct_rec; | |
| 9206 opj_simple_mcc_decorrelation_data_t * l_src_mcc_rec, *l_dest_mcc_rec; | |
| 9207 OPJ_UINT32 l_offset; | |
| 9208 | |
| 9209 /* preconditions */ | |
| 9210 assert(p_j2k != 00); | |
| 9211 assert(p_stream != 00); | |
| 9212 assert(p_manager != 00); | |
| 9213 | |
| 9214 OPJ_UNUSED(p_stream); | |
| 9215 | |
| 9216 l_image = p_j2k->m_private_image; | |
| 9217 l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw; | |
| 9218 l_tcp = p_j2k->m_cp.tcps; | |
| 9219 l_tccp_size = l_image->numcomps * (OPJ_UINT32)sizeof(opj_tccp_t); | |
| 9220 l_default_tcp = p_j2k->m_specific_param.m_decoder.m_default_tcp; | |
| 9221 l_mct_size = l_image->numcomps * l_image->numcomps * (OPJ_UINT32)sizeof( | |
| 9222 OPJ_FLOAT32); | |
| 9223 | |
| 9224 /* For each tile */ | |
| 9225 for (i = 0; i < l_nb_tiles; ++i) { | |
| 9226 /* keep the tile-compo coding parameters pointer of the current tile coding parameters*/ | |
| 9227 l_current_tccp = l_tcp->tccps; | |
| 9228 /*Copy default coding parameters into the current tile coding parameters*/ | |
| 9229 memcpy(l_tcp, l_default_tcp, sizeof(opj_tcp_t)); | |
| 9230 /* Initialize some values of the current tile coding parameters*/ | |
| 9231 l_tcp->cod = 0; | |
| 9232 l_tcp->ppt = 0; | |
| 9233 l_tcp->ppt_data = 00; | |
| 9234 l_tcp->m_current_tile_part_number = -1; | |
| 9235 /* Remove memory not owned by this tile in case of early error return. */ | |
| 9236 l_tcp->m_mct_decoding_matrix = 00; | |
| 9237 l_tcp->m_nb_max_mct_records = 0; | |
| 9238 l_tcp->m_mct_records = 00; | |
| 9239 l_tcp->m_nb_max_mcc_records = 0; | |
| 9240 l_tcp->m_mcc_records = 00; | |
| 9241 /* Reconnect the tile-compo coding parameters pointer to the current tile coding parameters*/ | |
| 9242 l_tcp->tccps = l_current_tccp; | |
| 9243 | |
| 9244 /* Get the mct_decoding_matrix of the dflt_tile_cp and copy them into the current tile cp*/ | |
| 9245 if (l_default_tcp->m_mct_decoding_matrix) { | |
| 9246 l_tcp->m_mct_decoding_matrix = (OPJ_FLOAT32*)opj_malloc(l_mct_size); | |
| 9247 if (! l_tcp->m_mct_decoding_matrix) { | |
| 9248 return OPJ_FALSE; | |
| 9249 } | |
| 9250 memcpy(l_tcp->m_mct_decoding_matrix, l_default_tcp->m_mct_decoding_matrix, | |
| 9251 l_mct_size); | |
| 9252 } | |
| 9253 | |
| 9254 /* Get the mct_record of the dflt_tile_cp and copy them into the current tile cp*/ | |
| 9255 l_mct_records_size = l_default_tcp->m_nb_max_mct_records * (OPJ_UINT32)sizeof( | |
| 9256 opj_mct_data_t); | |
| 9257 l_tcp->m_mct_records = (opj_mct_data_t*)opj_malloc(l_mct_records_size); | |
| 9258 if (! l_tcp->m_mct_records) { | |
| 9259 return OPJ_FALSE; | |
| 9260 } | |
| 9261 memcpy(l_tcp->m_mct_records, l_default_tcp->m_mct_records, l_mct_records_size); | |
| 9262 | |
| 9263 /* Copy the mct record data from dflt_tile_cp to the current tile*/ | |
| 9264 l_src_mct_rec = l_default_tcp->m_mct_records; | |
| 9265 l_dest_mct_rec = l_tcp->m_mct_records; | |
| 9266 | |
| 9267 for (j = 0; j < l_default_tcp->m_nb_mct_records; ++j) { | |
| 9268 | |
| 9269 if (l_src_mct_rec->m_data) { | |
| 9270 | |
| 9271 l_dest_mct_rec->m_data = (OPJ_BYTE*) opj_malloc(l_src_mct_rec->m_data_size); | |
| 9272 if (! l_dest_mct_rec->m_data) { | |
| 9273 return OPJ_FALSE; | |
| 9274 } | |
| 9275 memcpy(l_dest_mct_rec->m_data, l_src_mct_rec->m_data, | |
| 9276 l_src_mct_rec->m_data_size); | |
| 9277 } | |
| 9278 | |
| 9279 ++l_src_mct_rec; | |
| 9280 ++l_dest_mct_rec; | |
| 9281 /* Update with each pass to free exactly what has been allocated on early return. */ | |
| 9282 l_tcp->m_nb_max_mct_records += 1; | |
| 9283 } | |
| 9284 | |
| 9285 /* Get the mcc_record of the dflt_tile_cp and copy them into the current tile cp*/ | |
| 9286 l_mcc_records_size = l_default_tcp->m_nb_max_mcc_records * (OPJ_UINT32)sizeof( | |
| 9287 opj_simple_mcc_decorrelation_data_t); | |
| 9288 l_tcp->m_mcc_records = (opj_simple_mcc_decorrelation_data_t*) opj_malloc( | |
| 9289 l_mcc_records_size); | |
| 9290 if (! l_tcp->m_mcc_records) { | |
| 9291 return OPJ_FALSE; | |
| 9292 } | |
| 9293 memcpy(l_tcp->m_mcc_records, l_default_tcp->m_mcc_records, l_mcc_records_size); | |
| 9294 l_tcp->m_nb_max_mcc_records = l_default_tcp->m_nb_max_mcc_records; | |
| 9295 | |
| 9296 /* Copy the mcc record data from dflt_tile_cp to the current tile*/ | |
| 9297 l_src_mcc_rec = l_default_tcp->m_mcc_records; | |
| 9298 l_dest_mcc_rec = l_tcp->m_mcc_records; | |
| 9299 | |
| 9300 for (j = 0; j < l_default_tcp->m_nb_max_mcc_records; ++j) { | |
| 9301 | |
| 9302 if (l_src_mcc_rec->m_decorrelation_array) { | |
| 9303 l_offset = (OPJ_UINT32)(l_src_mcc_rec->m_decorrelation_array - | |
| 9304 l_default_tcp->m_mct_records); | |
| 9305 l_dest_mcc_rec->m_decorrelation_array = l_tcp->m_mct_records + l_offset; | |
| 9306 } | |
| 9307 | |
| 9308 if (l_src_mcc_rec->m_offset_array) { | |
| 9309 l_offset = (OPJ_UINT32)(l_src_mcc_rec->m_offset_array - | |
| 9310 l_default_tcp->m_mct_records); | |
| 9311 l_dest_mcc_rec->m_offset_array = l_tcp->m_mct_records + l_offset; | |
| 9312 } | |
| 9313 | |
| 9314 ++l_src_mcc_rec; | |
| 9315 ++l_dest_mcc_rec; | |
| 9316 } | |
| 9317 | |
| 9318 /* Copy all the dflt_tile_compo_cp to the current tile cp */ | |
| 9319 memcpy(l_current_tccp, l_default_tcp->tccps, l_tccp_size); | |
| 9320 | |
| 9321 /* Move to next tile cp*/ | |
| 9322 ++l_tcp; | |
| 9323 } | |
| 9324 | |
| 9325 /* Create the current tile decoder*/ | |
| 9326 p_j2k->m_tcd = opj_tcd_create(OPJ_TRUE); | |
| 9327 if (! p_j2k->m_tcd) { | |
| 9328 return OPJ_FALSE; | |
| 9329 } | |
| 9330 | |
| 9331 if (!opj_tcd_init(p_j2k->m_tcd, l_image, &(p_j2k->m_cp), p_j2k->m_tp)) { | |
| 9332 opj_tcd_destroy(p_j2k->m_tcd); | |
| 9333 p_j2k->m_tcd = 00; | |
| 9334 opj_event_msg(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n"); | |
| 9335 return OPJ_FALSE; | |
| 9336 } | |
| 9337 | |
| 9338 return OPJ_TRUE; | |
| 9339 } | |
| 9340 | |
| 9341 static const opj_dec_memory_marker_handler_t * opj_j2k_get_marker_handler( | |
| 9342 OPJ_UINT32 p_id) | |
| 9343 { | |
| 9344 const opj_dec_memory_marker_handler_t *e; | |
| 9345 for (e = j2k_memory_marker_handler_tab; e->id != 0; ++e) { | |
| 9346 if (e->id == p_id) { | |
| 9347 break; /* we find a handler corresponding to the marker ID*/ | |
| 9348 } | |
| 9349 } | |
| 9350 return e; | |
| 9351 } | |
| 9352 | |
| 9353 void opj_j2k_destroy(opj_j2k_t *p_j2k) | |
| 9354 { | |
| 9355 if (p_j2k == 00) { | |
| 9356 return; | |
| 9357 } | |
| 9358 | |
| 9359 if (p_j2k->m_is_decoder) { | |
| 9360 | |
| 9361 if (p_j2k->m_specific_param.m_decoder.m_default_tcp != 00) { | |
| 9362 opj_j2k_tcp_destroy(p_j2k->m_specific_param.m_decoder.m_default_tcp); | |
| 9363 opj_free(p_j2k->m_specific_param.m_decoder.m_default_tcp); | |
| 9364 p_j2k->m_specific_param.m_decoder.m_default_tcp = 00; | |
| 9365 } | |
| 9366 | |
| 9367 if (p_j2k->m_specific_param.m_decoder.m_header_data != 00) { | |
| 9368 opj_free(p_j2k->m_specific_param.m_decoder.m_header_data); | |
| 9369 p_j2k->m_specific_param.m_decoder.m_header_data = 00; | |
| 9370 p_j2k->m_specific_param.m_decoder.m_header_data_size = 0; | |
| 9371 } | |
| 9372 | |
| 9373 opj_free(p_j2k->m_specific_param.m_decoder.m_comps_indices_to_decode); | |
| 9374 p_j2k->m_specific_param.m_decoder.m_comps_indices_to_decode = 00; | |
| 9375 p_j2k->m_specific_param.m_decoder.m_numcomps_to_decode = 0; | |
| 9376 | |
| 9377 opj_free(p_j2k->m_specific_param.m_decoder.m_tlm.m_tile_part_infos); | |
| 9378 p_j2k->m_specific_param.m_decoder.m_tlm.m_tile_part_infos = NULL; | |
| 9379 | |
| 9380 opj_free(p_j2k->m_specific_param.m_decoder.m_intersecting_tile_parts_offset); | |
| 9381 p_j2k->m_specific_param.m_decoder.m_intersecting_tile_parts_offset = NULL; | |
| 9382 | |
| 9383 } else { | |
| 9384 | |
| 9385 if (p_j2k->m_specific_param.m_encoder.m_encoded_tile_data) { | |
| 9386 opj_free(p_j2k->m_specific_param.m_encoder.m_encoded_tile_data); | |
| 9387 p_j2k->m_specific_param.m_encoder.m_encoded_tile_data = 00; | |
| 9388 } | |
| 9389 | |
| 9390 if (p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer) { | |
| 9391 opj_free(p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer); | |
| 9392 p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer = 00; | |
| 9393 p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current = 00; | |
| 9394 } | |
| 9395 | |
| 9396 if (p_j2k->m_specific_param.m_encoder.m_header_tile_data) { | |
| 9397 opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data); | |
| 9398 p_j2k->m_specific_param.m_encoder.m_header_tile_data = 00; | |
| 9399 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0; | |
| 9400 } | |
| 9401 } | |
| 9402 | |
| 9403 opj_tcd_destroy(p_j2k->m_tcd); | |
| 9404 | |
| 9405 opj_j2k_cp_destroy(&(p_j2k->m_cp)); | |
| 9406 memset(&(p_j2k->m_cp), 0, sizeof(opj_cp_t)); | |
| 9407 | |
| 9408 opj_procedure_list_destroy(p_j2k->m_procedure_list); | |
| 9409 p_j2k->m_procedure_list = 00; | |
| 9410 | |
| 9411 opj_procedure_list_destroy(p_j2k->m_validation_list); | |
| 9412 p_j2k->m_procedure_list = 00; | |
| 9413 | |
| 9414 j2k_destroy_cstr_index(p_j2k->cstr_index); | |
| 9415 p_j2k->cstr_index = NULL; | |
| 9416 | |
| 9417 opj_image_destroy(p_j2k->m_private_image); | |
| 9418 p_j2k->m_private_image = NULL; | |
| 9419 | |
| 9420 opj_image_destroy(p_j2k->m_output_image); | |
| 9421 p_j2k->m_output_image = NULL; | |
| 9422 | |
| 9423 opj_thread_pool_destroy(p_j2k->m_tp); | |
| 9424 p_j2k->m_tp = NULL; | |
| 9425 | |
| 9426 opj_free(p_j2k); | |
| 9427 } | |
| 9428 | |
| 9429 void j2k_destroy_cstr_index(opj_codestream_index_t *p_cstr_ind) | |
| 9430 { | |
| 9431 if (p_cstr_ind) { | |
| 9432 | |
| 9433 if (p_cstr_ind->marker) { | |
| 9434 opj_free(p_cstr_ind->marker); | |
| 9435 p_cstr_ind->marker = NULL; | |
| 9436 } | |
| 9437 | |
| 9438 if (p_cstr_ind->tile_index) { | |
| 9439 OPJ_UINT32 it_tile = 0; | |
| 9440 | |
| 9441 for (it_tile = 0; it_tile < p_cstr_ind->nb_of_tiles; it_tile++) { | |
| 9442 | |
| 9443 if (p_cstr_ind->tile_index[it_tile].packet_index) { | |
| 9444 opj_free(p_cstr_ind->tile_index[it_tile].packet_index); | |
| 9445 p_cstr_ind->tile_index[it_tile].packet_index = NULL; | |
| 9446 } | |
| 9447 | |
| 9448 if (p_cstr_ind->tile_index[it_tile].tp_index) { | |
| 9449 opj_free(p_cstr_ind->tile_index[it_tile].tp_index); | |
| 9450 p_cstr_ind->tile_index[it_tile].tp_index = NULL; | |
| 9451 } | |
| 9452 | |
| 9453 if (p_cstr_ind->tile_index[it_tile].marker) { | |
| 9454 opj_free(p_cstr_ind->tile_index[it_tile].marker); | |
| 9455 p_cstr_ind->tile_index[it_tile].marker = NULL; | |
| 9456 | |
| 9457 } | |
| 9458 } | |
| 9459 | |
| 9460 opj_free(p_cstr_ind->tile_index); | |
| 9461 p_cstr_ind->tile_index = NULL; | |
| 9462 } | |
| 9463 | |
| 9464 opj_free(p_cstr_ind); | |
| 9465 } | |
| 9466 } | |
| 9467 | |
| 9468 static void opj_j2k_tcp_destroy(opj_tcp_t *p_tcp) | |
| 9469 { | |
| 9470 if (p_tcp == 00) { | |
| 9471 return; | |
| 9472 } | |
| 9473 | |
| 9474 if (p_tcp->ppt_markers != 00) { | |
| 9475 OPJ_UINT32 i; | |
| 9476 for (i = 0U; i < p_tcp->ppt_markers_count; ++i) { | |
| 9477 if (p_tcp->ppt_markers[i].m_data != NULL) { | |
| 9478 opj_free(p_tcp->ppt_markers[i].m_data); | |
| 9479 } | |
| 9480 } | |
| 9481 p_tcp->ppt_markers_count = 0U; | |
| 9482 opj_free(p_tcp->ppt_markers); | |
| 9483 p_tcp->ppt_markers = NULL; | |
| 9484 } | |
| 9485 | |
| 9486 if (p_tcp->ppt_buffer != 00) { | |
| 9487 opj_free(p_tcp->ppt_buffer); | |
| 9488 p_tcp->ppt_buffer = 00; | |
| 9489 } | |
| 9490 | |
| 9491 if (p_tcp->tccps != 00) { | |
| 9492 opj_free(p_tcp->tccps); | |
| 9493 p_tcp->tccps = 00; | |
| 9494 } | |
| 9495 | |
| 9496 if (p_tcp->m_mct_coding_matrix != 00) { | |
| 9497 opj_free(p_tcp->m_mct_coding_matrix); | |
| 9498 p_tcp->m_mct_coding_matrix = 00; | |
| 9499 } | |
| 9500 | |
| 9501 if (p_tcp->m_mct_decoding_matrix != 00) { | |
| 9502 opj_free(p_tcp->m_mct_decoding_matrix); | |
| 9503 p_tcp->m_mct_decoding_matrix = 00; | |
| 9504 } | |
| 9505 | |
| 9506 if (p_tcp->m_mcc_records) { | |
| 9507 opj_free(p_tcp->m_mcc_records); | |
| 9508 p_tcp->m_mcc_records = 00; | |
| 9509 p_tcp->m_nb_max_mcc_records = 0; | |
| 9510 p_tcp->m_nb_mcc_records = 0; | |
| 9511 } | |
| 9512 | |
| 9513 if (p_tcp->m_mct_records) { | |
| 9514 opj_mct_data_t * l_mct_data = p_tcp->m_mct_records; | |
| 9515 OPJ_UINT32 i; | |
| 9516 | |
| 9517 for (i = 0; i < p_tcp->m_nb_mct_records; ++i) { | |
| 9518 if (l_mct_data->m_data) { | |
| 9519 opj_free(l_mct_data->m_data); | |
| 9520 l_mct_data->m_data = 00; | |
| 9521 } | |
| 9522 | |
| 9523 ++l_mct_data; | |
| 9524 } | |
| 9525 | |
| 9526 opj_free(p_tcp->m_mct_records); | |
| 9527 p_tcp->m_mct_records = 00; | |
| 9528 } | |
| 9529 | |
| 9530 if (p_tcp->mct_norms != 00) { | |
| 9531 opj_free(p_tcp->mct_norms); | |
| 9532 p_tcp->mct_norms = 00; | |
| 9533 } | |
| 9534 | |
| 9535 opj_j2k_tcp_data_destroy(p_tcp); | |
| 9536 | |
| 9537 } | |
| 9538 | |
| 9539 static void opj_j2k_tcp_data_destroy(opj_tcp_t *p_tcp) | |
| 9540 { | |
| 9541 if (p_tcp->m_data) { | |
| 9542 opj_free(p_tcp->m_data); | |
| 9543 p_tcp->m_data = NULL; | |
| 9544 p_tcp->m_data_size = 0; | |
| 9545 } | |
| 9546 } | |
| 9547 | |
| 9548 static void opj_j2k_cp_destroy(opj_cp_t *p_cp) | |
| 9549 { | |
| 9550 OPJ_UINT32 l_nb_tiles; | |
| 9551 opj_tcp_t * l_current_tile = 00; | |
| 9552 | |
| 9553 if (p_cp == 00) { | |
| 9554 return; | |
| 9555 } | |
| 9556 if (p_cp->tcps != 00) { | |
| 9557 OPJ_UINT32 i; | |
| 9558 l_current_tile = p_cp->tcps; | |
| 9559 l_nb_tiles = p_cp->th * p_cp->tw; | |
| 9560 | |
| 9561 for (i = 0U; i < l_nb_tiles; ++i) { | |
| 9562 opj_j2k_tcp_destroy(l_current_tile); | |
| 9563 ++l_current_tile; | |
| 9564 } | |
| 9565 opj_free(p_cp->tcps); | |
| 9566 p_cp->tcps = 00; | |
| 9567 } | |
| 9568 if (p_cp->ppm_markers != 00) { | |
| 9569 OPJ_UINT32 i; | |
| 9570 for (i = 0U; i < p_cp->ppm_markers_count; ++i) { | |
| 9571 if (p_cp->ppm_markers[i].m_data != NULL) { | |
| 9572 opj_free(p_cp->ppm_markers[i].m_data); | |
| 9573 } | |
| 9574 } | |
| 9575 p_cp->ppm_markers_count = 0U; | |
| 9576 opj_free(p_cp->ppm_markers); | |
| 9577 p_cp->ppm_markers = NULL; | |
| 9578 } | |
| 9579 opj_free(p_cp->ppm_buffer); | |
| 9580 p_cp->ppm_buffer = 00; | |
| 9581 p_cp->ppm_data = | |
| 9582 NULL; /* ppm_data belongs to the allocated buffer pointed by ppm_buffer */ | |
| 9583 opj_free(p_cp->comment); | |
| 9584 p_cp->comment = 00; | |
| 9585 if (! p_cp->m_is_decoder) { | |
| 9586 opj_free(p_cp->m_specific_param.m_enc.m_matrice); | |
| 9587 p_cp->m_specific_param.m_enc.m_matrice = 00; | |
| 9588 } | |
| 9589 } | |
| 9590 | |
| 9591 static OPJ_BOOL opj_j2k_need_nb_tile_parts_correction(opj_stream_private_t | |
| 9592 *p_stream, OPJ_UINT32 tile_no, OPJ_BOOL* p_correction_needed, | |
| 9593 opj_event_mgr_t * p_manager) | |
| 9594 { | |
| 9595 OPJ_BYTE l_header_data[10]; | |
| 9596 OPJ_OFF_T l_stream_pos_backup; | |
| 9597 OPJ_UINT32 l_current_marker; | |
| 9598 OPJ_UINT32 l_marker_size; | |
| 9599 OPJ_UINT32 l_tile_no, l_tot_len, l_current_part, l_num_parts; | |
| 9600 | |
| 9601 /* initialize to no correction needed */ | |
| 9602 *p_correction_needed = OPJ_FALSE; | |
| 9603 | |
| 9604 if (!opj_stream_has_seek(p_stream)) { | |
| 9605 /* We can't do much in this case, seek is needed */ | |
| 9606 return OPJ_TRUE; | |
| 9607 } | |
| 9608 | |
| 9609 l_stream_pos_backup = opj_stream_tell(p_stream); | |
| 9610 if (l_stream_pos_backup == -1) { | |
| 9611 /* let's do nothing */ | |
| 9612 return OPJ_TRUE; | |
| 9613 } | |
| 9614 | |
| 9615 for (;;) { | |
| 9616 /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer */ | |
| 9617 if (opj_stream_read_data(p_stream, l_header_data, 2, p_manager) != 2) { | |
| 9618 /* assume all is OK */ | |
| 9619 if (! opj_stream_seek(p_stream, l_stream_pos_backup, p_manager)) { | |
| 9620 return OPJ_FALSE; | |
| 9621 } | |
| 9622 return OPJ_TRUE; | |
| 9623 } | |
| 9624 | |
| 9625 /* Read 2 bytes from buffer as the new marker ID */ | |
| 9626 opj_read_bytes(l_header_data, &l_current_marker, 2); | |
| 9627 | |
| 9628 if (l_current_marker != J2K_MS_SOT) { | |
| 9629 /* assume all is OK */ | |
| 9630 if (! opj_stream_seek(p_stream, l_stream_pos_backup, p_manager)) { | |
| 9631 return OPJ_FALSE; | |
| 9632 } | |
| 9633 return OPJ_TRUE; | |
| 9634 } | |
| 9635 | |
| 9636 /* Try to read 2 bytes (the marker size) from stream and copy them into the buffer */ | |
| 9637 if (opj_stream_read_data(p_stream, l_header_data, 2, p_manager) != 2) { | |
| 9638 opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); | |
| 9639 return OPJ_FALSE; | |
| 9640 } | |
| 9641 | |
| 9642 /* Read 2 bytes from the buffer as the marker size */ | |
| 9643 opj_read_bytes(l_header_data, &l_marker_size, 2); | |
| 9644 | |
| 9645 /* Check marker size for SOT Marker */ | |
| 9646 if (l_marker_size != 10) { | |
| 9647 opj_event_msg(p_manager, EVT_ERROR, "Inconsistent marker size\n"); | |
| 9648 return OPJ_FALSE; | |
| 9649 } | |
| 9650 l_marker_size -= 2; | |
| 9651 | |
| 9652 if (opj_stream_read_data(p_stream, l_header_data, l_marker_size, | |
| 9653 p_manager) != l_marker_size) { | |
| 9654 opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); | |
| 9655 return OPJ_FALSE; | |
| 9656 } | |
| 9657 | |
| 9658 if (! opj_j2k_get_sot_values(l_header_data, l_marker_size, &l_tile_no, | |
| 9659 &l_tot_len, &l_current_part, &l_num_parts, p_manager)) { | |
| 9660 return OPJ_FALSE; | |
| 9661 } | |
| 9662 | |
| 9663 if (l_tile_no == tile_no) { | |
| 9664 /* we found what we were looking for */ | |
| 9665 break; | |
| 9666 } | |
| 9667 | |
| 9668 if (l_tot_len < 14U) { | |
| 9669 /* last SOT until EOC or invalid Psot value */ | |
| 9670 /* assume all is OK */ | |
| 9671 if (! opj_stream_seek(p_stream, l_stream_pos_backup, p_manager)) { | |
| 9672 return OPJ_FALSE; | |
| 9673 } | |
| 9674 return OPJ_TRUE; | |
| 9675 } | |
| 9676 l_tot_len -= 12U; | |
| 9677 /* look for next SOT marker */ | |
| 9678 if (opj_stream_skip(p_stream, (OPJ_OFF_T)(l_tot_len), | |
| 9679 p_manager) != (OPJ_OFF_T)(l_tot_len)) { | |
| 9680 /* assume all is OK */ | |
| 9681 if (! opj_stream_seek(p_stream, l_stream_pos_backup, p_manager)) { | |
| 9682 return OPJ_FALSE; | |
| 9683 } | |
| 9684 return OPJ_TRUE; | |
| 9685 } | |
| 9686 } | |
| 9687 | |
| 9688 /* check for correction */ | |
| 9689 if (l_current_part == l_num_parts) { | |
| 9690 *p_correction_needed = OPJ_TRUE; | |
| 9691 } | |
| 9692 | |
| 9693 if (! opj_stream_seek(p_stream, l_stream_pos_backup, p_manager)) { | |
| 9694 return OPJ_FALSE; | |
| 9695 } | |
| 9696 return OPJ_TRUE; | |
| 9697 } | |
| 9698 | |
| 9699 OPJ_BOOL opj_j2k_read_tile_header(opj_j2k_t * p_j2k, | |
| 9700 OPJ_UINT32 * p_tile_index, | |
| 9701 OPJ_UINT32 * p_data_size, | |
| 9702 OPJ_INT32 * p_tile_x0, OPJ_INT32 * p_tile_y0, | |
| 9703 OPJ_INT32 * p_tile_x1, OPJ_INT32 * p_tile_y1, | |
| 9704 OPJ_UINT32 * p_nb_comps, | |
| 9705 OPJ_BOOL * p_go_on, | |
| 9706 opj_stream_private_t *p_stream, | |
| 9707 opj_event_mgr_t * p_manager) | |
| 9708 { | |
| 9709 OPJ_UINT32 l_current_marker = J2K_MS_SOT; | |
| 9710 OPJ_UINT32 l_marker_size; | |
| 9711 const opj_dec_memory_marker_handler_t * l_marker_handler = 00; | |
| 9712 opj_tcp_t * l_tcp = NULL; | |
| 9713 const OPJ_UINT32 l_nb_tiles = p_j2k->m_cp.tw * p_j2k->m_cp.th; | |
| 9714 | |
| 9715 /* preconditions */ | |
| 9716 assert(p_stream != 00); | |
| 9717 assert(p_j2k != 00); | |
| 9718 assert(p_manager != 00); | |
| 9719 | |
| 9720 /* Reach the End Of Codestream ?*/ | |
| 9721 if (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_EOC) { | |
| 9722 l_current_marker = J2K_MS_EOC; | |
| 9723 } | |
| 9724 /* We need to encounter a SOT marker (a new tile-part header) */ | |
| 9725 else if (p_j2k->m_specific_param.m_decoder.m_state != J2K_STATE_TPHSOT) { | |
| 9726 return OPJ_FALSE; | |
| 9727 } | |
| 9728 | |
| 9729 /* Read into the codestream until reach the EOC or ! can_decode ??? FIXME */ | |
| 9730 while ((!p_j2k->m_specific_param.m_decoder.m_can_decode) && | |
| 9731 (l_current_marker != J2K_MS_EOC)) { | |
| 9732 | |
| 9733 if (p_j2k->m_specific_param.m_decoder.m_num_intersecting_tile_parts > 0 && | |
| 9734 p_j2k->m_specific_param.m_decoder.m_idx_intersecting_tile_parts < | |
| 9735 p_j2k->m_specific_param.m_decoder.m_num_intersecting_tile_parts) { | |
| 9736 OPJ_OFF_T next_tp_sot_pos; | |
| 9737 | |
| 9738 next_tp_sot_pos = | |
| 9739 p_j2k->m_specific_param.m_decoder.m_intersecting_tile_parts_offset[p_j2k->m_specific_param.m_decoder.m_idx_intersecting_tile_parts]; | |
| 9740 ++p_j2k->m_specific_param.m_decoder.m_idx_intersecting_tile_parts; | |
| 9741 if (!(opj_stream_read_seek(p_stream, | |
| 9742 next_tp_sot_pos, | |
| 9743 p_manager))) { | |
| 9744 opj_event_msg(p_manager, EVT_ERROR, "Problem with seek function\n"); | |
| 9745 return OPJ_FALSE; | |
| 9746 } | |
| 9747 | |
| 9748 /* Try to read 2 bytes (the marker ID) from stream and copy them into the buffer */ | |
| 9749 if (opj_stream_read_data(p_stream, | |
| 9750 p_j2k->m_specific_param.m_decoder.m_header_data, 2, p_manager) != 2) { | |
| 9751 opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); | |
| 9752 return OPJ_FALSE; | |
| 9753 } | |
| 9754 | |
| 9755 /* Read 2 bytes from the buffer as the marker ID */ | |
| 9756 opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data, | |
| 9757 &l_current_marker, | |
| 9758 2); | |
| 9759 | |
| 9760 if (l_current_marker != J2K_MS_SOT) { | |
| 9761 opj_event_msg(p_manager, EVT_ERROR, "Did not get expected SOT marker\n"); | |
| 9762 return OPJ_FALSE; | |
| 9763 } | |
| 9764 } | |
| 9765 | |
| 9766 /* Try to read until the Start Of Data is detected */ | |
| 9767 while (l_current_marker != J2K_MS_SOD) { | |
| 9768 | |
| 9769 if (opj_stream_get_number_byte_left(p_stream) == 0) { | |
| 9770 p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_NEOC; | |
| 9771 break; | |
| 9772 } | |
| 9773 | |
| 9774 /* Try to read 2 bytes (the marker size) from stream and copy them into the buffer */ | |
| 9775 if (opj_stream_read_data(p_stream, | |
| 9776 p_j2k->m_specific_param.m_decoder.m_header_data, 2, p_manager) != 2) { | |
| 9777 opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); | |
| 9778 return OPJ_FALSE; | |
| 9779 } | |
| 9780 | |
| 9781 /* Read 2 bytes from the buffer as the marker size */ | |
| 9782 opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data, &l_marker_size, | |
| 9783 2); | |
| 9784 | |
| 9785 /* Check marker size (does not include marker ID but includes marker size) */ | |
| 9786 if (l_marker_size < 2) { | |
| 9787 opj_event_msg(p_manager, EVT_ERROR, "Inconsistent marker size\n"); | |
| 9788 return OPJ_FALSE; | |
| 9789 } | |
| 9790 | |
| 9791 /* cf. https://code.google.com/p/openjpeg/issues/detail?id=226 */ | |
| 9792 if (l_current_marker == 0x8080 && | |
| 9793 opj_stream_get_number_byte_left(p_stream) == 0) { | |
| 9794 p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_NEOC; | |
| 9795 break; | |
| 9796 } | |
| 9797 | |
| 9798 /* Why this condition? FIXME */ | |
| 9799 if ((p_j2k->m_specific_param.m_decoder.m_state & J2K_STATE_TPH) && | |
| 9800 p_j2k->m_specific_param.m_decoder.m_sot_length != 0) { | |
| 9801 if (p_j2k->m_specific_param.m_decoder.m_sot_length < l_marker_size + 2) { | |
| 9802 opj_event_msg(p_manager, EVT_ERROR, | |
| 9803 "Sot length is less than marker size + marker ID\n"); | |
| 9804 return OPJ_FALSE; | |
| 9805 } | |
| 9806 p_j2k->m_specific_param.m_decoder.m_sot_length -= (l_marker_size + 2); | |
| 9807 } | |
| 9808 l_marker_size -= 2; /* Subtract the size of the marker ID already read */ | |
| 9809 | |
| 9810 /* Get the marker handler from the marker ID */ | |
| 9811 l_marker_handler = opj_j2k_get_marker_handler(l_current_marker); | |
| 9812 | |
| 9813 /* Check if the marker is known and if it is the right place to find it */ | |
| 9814 if (!(p_j2k->m_specific_param.m_decoder.m_state & l_marker_handler->states)) { | |
| 9815 opj_event_msg(p_manager, EVT_ERROR, | |
| 9816 "Marker is not compliant with its position\n"); | |
| 9817 return OPJ_FALSE; | |
| 9818 } | |
| 9819 /* FIXME manage case of unknown marker as in the main header ? */ | |
| 9820 | |
| 9821 /* Check if the marker size is compatible with the header data size */ | |
| 9822 if (l_marker_size > p_j2k->m_specific_param.m_decoder.m_header_data_size) { | |
| 9823 OPJ_BYTE *new_header_data = NULL; | |
| 9824 /* If we are here, this means we consider this marker as known & we will read it */ | |
| 9825 /* Check enough bytes left in stream before allocation */ | |
| 9826 if ((OPJ_OFF_T)l_marker_size > opj_stream_get_number_byte_left(p_stream)) { | |
| 9827 opj_event_msg(p_manager, EVT_ERROR, | |
| 9828 "Marker size inconsistent with stream length\n"); | |
| 9829 return OPJ_FALSE; | |
| 9830 } | |
| 9831 new_header_data = (OPJ_BYTE *) opj_realloc( | |
| 9832 p_j2k->m_specific_param.m_decoder.m_header_data, l_marker_size); | |
| 9833 if (! new_header_data) { | |
| 9834 opj_free(p_j2k->m_specific_param.m_decoder.m_header_data); | |
| 9835 p_j2k->m_specific_param.m_decoder.m_header_data = NULL; | |
| 9836 p_j2k->m_specific_param.m_decoder.m_header_data_size = 0; | |
| 9837 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read header\n"); | |
| 9838 return OPJ_FALSE; | |
| 9839 } | |
| 9840 p_j2k->m_specific_param.m_decoder.m_header_data = new_header_data; | |
| 9841 p_j2k->m_specific_param.m_decoder.m_header_data_size = l_marker_size; | |
| 9842 } | |
| 9843 | |
| 9844 /* Try to read the rest of the marker segment from stream and copy them into the buffer */ | |
| 9845 if (opj_stream_read_data(p_stream, | |
| 9846 p_j2k->m_specific_param.m_decoder.m_header_data, l_marker_size, | |
| 9847 p_manager) != l_marker_size) { | |
| 9848 opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); | |
| 9849 return OPJ_FALSE; | |
| 9850 } | |
| 9851 | |
| 9852 if (!l_marker_handler->handler) { | |
| 9853 /* See issue #175 */ | |
| 9854 opj_event_msg(p_manager, EVT_ERROR, "Not sure how that happened.\n"); | |
| 9855 return OPJ_FALSE; | |
| 9856 } | |
| 9857 /* Read the marker segment with the correct marker handler */ | |
| 9858 if (!(*(l_marker_handler->handler))(p_j2k, | |
| 9859 p_j2k->m_specific_param.m_decoder.m_header_data, l_marker_size, p_manager)) { | |
| 9860 opj_event_msg(p_manager, EVT_ERROR, | |
| 9861 "Fail to read the current marker segment (%#x)\n", l_current_marker); | |
| 9862 return OPJ_FALSE; | |
| 9863 } | |
| 9864 | |
| 9865 /* Add the marker to the codestream index*/ | |
| 9866 if (OPJ_FALSE == opj_j2k_add_tlmarker(p_j2k->m_current_tile_number, | |
| 9867 p_j2k->cstr_index, | |
| 9868 l_marker_handler->id, | |
| 9869 (OPJ_UINT32) opj_stream_tell(p_stream) - l_marker_size - 4, | |
| 9870 l_marker_size + 4)) { | |
| 9871 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to add tl marker\n"); | |
| 9872 return OPJ_FALSE; | |
| 9873 } | |
| 9874 | |
| 9875 /* Keep the position of the last SOT marker read */ | |
| 9876 if (l_marker_handler->id == J2K_MS_SOT) { | |
| 9877 OPJ_UINT32 sot_pos = (OPJ_UINT32) opj_stream_tell(p_stream) - l_marker_size - 4 | |
| 9878 ; | |
| 9879 if (sot_pos > p_j2k->m_specific_param.m_decoder.m_last_sot_read_pos) { | |
| 9880 p_j2k->m_specific_param.m_decoder.m_last_sot_read_pos = sot_pos; | |
| 9881 } | |
| 9882 } | |
| 9883 | |
| 9884 if (p_j2k->m_specific_param.m_decoder.m_skip_data) { | |
| 9885 /* Skip the rest of the tile part header*/ | |
| 9886 if (opj_stream_skip(p_stream, p_j2k->m_specific_param.m_decoder.m_sot_length, | |
| 9887 p_manager) != p_j2k->m_specific_param.m_decoder.m_sot_length) { | |
| 9888 opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); | |
| 9889 return OPJ_FALSE; | |
| 9890 } | |
| 9891 l_current_marker = J2K_MS_SOD; /* Normally we reached a SOD */ | |
| 9892 } else { | |
| 9893 /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer*/ | |
| 9894 if (opj_stream_read_data(p_stream, | |
| 9895 p_j2k->m_specific_param.m_decoder.m_header_data, 2, p_manager) != 2) { | |
| 9896 opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); | |
| 9897 return OPJ_FALSE; | |
| 9898 } | |
| 9899 /* Read 2 bytes from the buffer as the new marker ID */ | |
| 9900 opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data, | |
| 9901 &l_current_marker, 2); | |
| 9902 } | |
| 9903 } | |
| 9904 if (opj_stream_get_number_byte_left(p_stream) == 0 | |
| 9905 && p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_NEOC) { | |
| 9906 break; | |
| 9907 } | |
| 9908 | |
| 9909 /* If we didn't skip data before, we need to read the SOD marker*/ | |
| 9910 if (! p_j2k->m_specific_param.m_decoder.m_skip_data) { | |
| 9911 /* Try to read the SOD marker and skip data ? FIXME */ | |
| 9912 if (! opj_j2k_read_sod(p_j2k, p_stream, p_manager)) { | |
| 9913 return OPJ_FALSE; | |
| 9914 } | |
| 9915 | |
| 9916 /* Check if we can use the TLM index to access the next tile-part */ | |
| 9917 if (!p_j2k->m_specific_param.m_decoder.m_can_decode && | |
| 9918 p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec >= 0 && | |
| 9919 p_j2k->m_current_tile_number == (OPJ_UINT32) | |
| 9920 p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec && | |
| 9921 !p_j2k->m_specific_param.m_decoder.m_tlm.m_is_invalid && | |
| 9922 opj_stream_has_seek(p_stream)) { | |
| 9923 l_tcp = p_j2k->m_cp.tcps + p_j2k->m_current_tile_number; | |
| 9924 if (l_tcp->m_nb_tile_parts == | |
| 9925 p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].nb_tps && | |
| 9926 (OPJ_UINT32)l_tcp->m_current_tile_part_number + 1 < l_tcp->m_nb_tile_parts) { | |
| 9927 const OPJ_OFF_T next_tp_sot_pos = p_j2k->cstr_index->tile_index[ | |
| 9928 p_j2k->m_current_tile_number].tp_index[l_tcp->m_current_tile_part_number + | |
| 9929 1].start_pos; | |
| 9930 | |
| 9931 if (next_tp_sot_pos != opj_stream_tell(p_stream)) { | |
| 9932 #if 0 | |
| 9933 opj_event_msg(p_manager, EVT_INFO, | |
| 9934 "opj_j2k_read_tile_header(tile=%u): seek to tile part %u at %" PRId64 "\n", | |
| 9935 p_j2k->m_current_tile_number, | |
| 9936 l_tcp->m_current_tile_part_number + 1, | |
| 9937 next_tp_sot_pos); | |
| 9938 #endif | |
| 9939 | |
| 9940 if (!(opj_stream_read_seek(p_stream, | |
| 9941 next_tp_sot_pos, | |
| 9942 p_manager))) { | |
| 9943 opj_event_msg(p_manager, EVT_ERROR, "Problem with seek function\n"); | |
| 9944 return OPJ_FALSE; | |
| 9945 } | |
| 9946 } | |
| 9947 | |
| 9948 /* Try to read 2 bytes (the marker ID) from stream and copy them into the buffer */ | |
| 9949 if (opj_stream_read_data(p_stream, | |
| 9950 p_j2k->m_specific_param.m_decoder.m_header_data, 2, p_manager) != 2) { | |
| 9951 opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); | |
| 9952 return OPJ_FALSE; | |
| 9953 } | |
| 9954 | |
| 9955 /* Read 2 bytes from the buffer as the marker ID */ | |
| 9956 opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data, | |
| 9957 &l_current_marker, | |
| 9958 2); | |
| 9959 | |
| 9960 if (l_current_marker != J2K_MS_SOT) { | |
| 9961 opj_event_msg(p_manager, EVT_ERROR, "Did not get expected SOT marker\n"); | |
| 9962 return OPJ_FALSE; | |
| 9963 } | |
| 9964 | |
| 9965 continue; | |
| 9966 } | |
| 9967 } | |
| 9968 | |
| 9969 if (p_j2k->m_specific_param.m_decoder.m_can_decode && | |
| 9970 !p_j2k->m_specific_param.m_decoder.m_nb_tile_parts_correction_checked) { | |
| 9971 /* Issue 254 */ | |
| 9972 OPJ_BOOL l_correction_needed = OPJ_FALSE; | |
| 9973 | |
| 9974 p_j2k->m_specific_param.m_decoder.m_nb_tile_parts_correction_checked = 1; | |
| 9975 if (p_j2k->m_cp.tcps[p_j2k->m_current_tile_number].m_nb_tile_parts == 1) { | |
| 9976 /* Skip opj_j2k_need_nb_tile_parts_correction() if there is | |
| 9977 * only a single tile part declared. The | |
| 9978 * opj_j2k_need_nb_tile_parts_correction() hack was needed | |
| 9979 * for files with 5 declared tileparts (where they were | |
| 9980 * actually 6). | |
| 9981 * Doing it systematically hurts performance when reading | |
| 9982 * Sentinel2 L1C JPEG2000 files as explained in | |
| 9983 * https://lists.osgeo.org/pipermail/gdal-dev/2024-November/059805.html | |
| 9984 */ | |
| 9985 } else if (!opj_j2k_need_nb_tile_parts_correction(p_stream, | |
| 9986 p_j2k->m_current_tile_number, &l_correction_needed, p_manager)) { | |
| 9987 opj_event_msg(p_manager, EVT_ERROR, | |
| 9988 "opj_j2k_apply_nb_tile_parts_correction error\n"); | |
| 9989 return OPJ_FALSE; | |
| 9990 } | |
| 9991 if (l_correction_needed) { | |
| 9992 OPJ_UINT32 l_tile_no; | |
| 9993 | |
| 9994 p_j2k->m_specific_param.m_decoder.m_can_decode = 0; | |
| 9995 p_j2k->m_specific_param.m_decoder.m_nb_tile_parts_correction = 1; | |
| 9996 /* correct tiles */ | |
| 9997 for (l_tile_no = 0U; l_tile_no < l_nb_tiles; ++l_tile_no) { | |
| 9998 if (p_j2k->m_cp.tcps[l_tile_no].m_nb_tile_parts != 0U) { | |
| 9999 p_j2k->m_cp.tcps[l_tile_no].m_nb_tile_parts += 1; | |
| 10000 } | |
| 10001 } | |
| 10002 opj_event_msg(p_manager, EVT_WARNING, | |
| 10003 "Non conformant codestream TPsot==TNsot.\n"); | |
| 10004 } | |
| 10005 } | |
| 10006 } else { | |
| 10007 /* Indicate we will try to read a new tile-part header*/ | |
| 10008 p_j2k->m_specific_param.m_decoder.m_skip_data = 0; | |
| 10009 p_j2k->m_specific_param.m_decoder.m_can_decode = 0; | |
| 10010 p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_TPHSOT; | |
| 10011 } | |
| 10012 | |
| 10013 if (! p_j2k->m_specific_param.m_decoder.m_can_decode) { | |
| 10014 /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer */ | |
| 10015 if (opj_stream_read_data(p_stream, | |
| 10016 p_j2k->m_specific_param.m_decoder.m_header_data, 2, p_manager) != 2) { | |
| 10017 | |
| 10018 /* Deal with likely non conformant SPOT6 files, where the last */ | |
| 10019 /* row of tiles have TPsot == 0 and TNsot == 0, and missing EOC, */ | |
| 10020 /* but no other tile-parts were found. */ | |
| 10021 if (p_j2k->m_current_tile_number + 1 == l_nb_tiles) { | |
| 10022 OPJ_UINT32 l_tile_no; | |
| 10023 for (l_tile_no = 0U; l_tile_no < l_nb_tiles; ++l_tile_no) { | |
| 10024 if (p_j2k->m_cp.tcps[l_tile_no].m_current_tile_part_number == 0 && | |
| 10025 p_j2k->m_cp.tcps[l_tile_no].m_nb_tile_parts == 0) { | |
| 10026 break; | |
| 10027 } | |
| 10028 } | |
| 10029 if (l_tile_no < l_nb_tiles) { | |
| 10030 opj_event_msg(p_manager, EVT_INFO, | |
| 10031 "Tile %u has TPsot == 0 and TNsot == 0, " | |
| 10032 "but no other tile-parts were found. " | |
| 10033 "EOC is also missing.\n", | |
| 10034 l_tile_no); | |
| 10035 p_j2k->m_current_tile_number = l_tile_no; | |
| 10036 l_current_marker = J2K_MS_EOC; | |
| 10037 p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_EOC; | |
| 10038 break; | |
| 10039 } | |
| 10040 } | |
| 10041 | |
| 10042 opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); | |
| 10043 return OPJ_FALSE; | |
| 10044 } | |
| 10045 | |
| 10046 /* Read 2 bytes from buffer as the new marker ID */ | |
| 10047 opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data, | |
| 10048 &l_current_marker, 2); | |
| 10049 } | |
| 10050 } | |
| 10051 | |
| 10052 /* Current marker is the EOC marker ?*/ | |
| 10053 if (l_current_marker == J2K_MS_EOC) { | |
| 10054 if (p_j2k->m_specific_param.m_decoder.m_state != J2K_STATE_EOC) { | |
| 10055 p_j2k->m_current_tile_number = 0; | |
| 10056 p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_EOC; | |
| 10057 } | |
| 10058 } | |
| 10059 | |
| 10060 /* Deal with tiles that have a single tile-part with TPsot == 0 and TNsot == 0 */ | |
| 10061 if (! p_j2k->m_specific_param.m_decoder.m_can_decode) { | |
| 10062 l_tcp = p_j2k->m_cp.tcps + p_j2k->m_current_tile_number; | |
| 10063 | |
| 10064 while ((p_j2k->m_current_tile_number < l_nb_tiles) && (l_tcp->m_data == 00)) { | |
| 10065 ++p_j2k->m_current_tile_number; | |
| 10066 ++l_tcp; | |
| 10067 } | |
| 10068 | |
| 10069 if (p_j2k->m_current_tile_number == l_nb_tiles) { | |
| 10070 *p_go_on = OPJ_FALSE; | |
| 10071 return OPJ_TRUE; | |
| 10072 } | |
| 10073 } | |
| 10074 | |
| 10075 if (! opj_j2k_merge_ppt(p_j2k->m_cp.tcps + p_j2k->m_current_tile_number, | |
| 10076 p_manager)) { | |
| 10077 opj_event_msg(p_manager, EVT_ERROR, "Failed to merge PPT data\n"); | |
| 10078 return OPJ_FALSE; | |
| 10079 } | |
| 10080 /*FIXME ???*/ | |
| 10081 if (! opj_tcd_init_decode_tile(p_j2k->m_tcd, p_j2k->m_current_tile_number, | |
| 10082 p_manager)) { | |
| 10083 opj_event_msg(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n"); | |
| 10084 return OPJ_FALSE; | |
| 10085 } | |
| 10086 | |
| 10087 opj_event_msg(p_manager, EVT_INFO, "Header of tile %d / %d has been read.\n", | |
| 10088 p_j2k->m_current_tile_number + 1, (p_j2k->m_cp.th * p_j2k->m_cp.tw)); | |
| 10089 | |
| 10090 *p_tile_index = p_j2k->m_current_tile_number; | |
| 10091 *p_go_on = OPJ_TRUE; | |
| 10092 if (p_data_size) { | |
| 10093 /* For internal use in j2k.c, we don't need this */ | |
| 10094 /* This is just needed for folks using the opj_read_tile_header() / opj_decode_tile_data() combo */ | |
| 10095 *p_data_size = opj_tcd_get_decoded_tile_size(p_j2k->m_tcd, OPJ_FALSE); | |
| 10096 if (*p_data_size == UINT_MAX) { | |
| 10097 return OPJ_FALSE; | |
| 10098 } | |
| 10099 } | |
| 10100 *p_tile_x0 = p_j2k->m_tcd->tcd_image->tiles->x0; | |
| 10101 *p_tile_y0 = p_j2k->m_tcd->tcd_image->tiles->y0; | |
| 10102 *p_tile_x1 = p_j2k->m_tcd->tcd_image->tiles->x1; | |
| 10103 *p_tile_y1 = p_j2k->m_tcd->tcd_image->tiles->y1; | |
| 10104 *p_nb_comps = p_j2k->m_tcd->tcd_image->tiles->numcomps; | |
| 10105 | |
| 10106 p_j2k->m_specific_param.m_decoder.m_state |= J2K_STATE_DATA; | |
| 10107 | |
| 10108 return OPJ_TRUE; | |
| 10109 } | |
| 10110 | |
| 10111 OPJ_BOOL opj_j2k_decode_tile(opj_j2k_t * p_j2k, | |
| 10112 OPJ_UINT32 p_tile_index, | |
| 10113 OPJ_BYTE * p_data, | |
| 10114 OPJ_UINT32 p_data_size, | |
| 10115 opj_stream_private_t *p_stream, | |
| 10116 opj_event_mgr_t * p_manager) | |
| 10117 { | |
| 10118 OPJ_UINT32 l_current_marker; | |
| 10119 OPJ_BYTE l_data [2]; | |
| 10120 opj_tcp_t * l_tcp; | |
| 10121 opj_image_t* l_image_for_bounds; | |
| 10122 | |
| 10123 /* preconditions */ | |
| 10124 assert(p_stream != 00); | |
| 10125 assert(p_j2k != 00); | |
| 10126 assert(p_manager != 00); | |
| 10127 | |
| 10128 if (!(p_j2k->m_specific_param.m_decoder.m_state & J2K_STATE_DATA) | |
| 10129 || (p_tile_index != p_j2k->m_current_tile_number)) { | |
| 10130 return OPJ_FALSE; | |
| 10131 } | |
| 10132 | |
| 10133 l_tcp = &(p_j2k->m_cp.tcps[p_tile_index]); | |
| 10134 if (! l_tcp->m_data) { | |
| 10135 opj_j2k_tcp_destroy(l_tcp); | |
| 10136 return OPJ_FALSE; | |
| 10137 } | |
| 10138 | |
| 10139 /* When using the opj_read_tile_header / opj_decode_tile_data API */ | |
| 10140 /* such as in test_tile_decoder, m_output_image is NULL, so fall back */ | |
| 10141 /* to the full image dimension. This is a bit surprising that */ | |
| 10142 /* opj_set_decode_area() is only used to determine intersecting tiles, */ | |
| 10143 /* but full tile decoding is done */ | |
| 10144 l_image_for_bounds = p_j2k->m_output_image ? p_j2k->m_output_image : | |
| 10145 p_j2k->m_private_image; | |
| 10146 if (! opj_tcd_decode_tile(p_j2k->m_tcd, | |
| 10147 l_image_for_bounds->x0, | |
| 10148 l_image_for_bounds->y0, | |
| 10149 l_image_for_bounds->x1, | |
| 10150 l_image_for_bounds->y1, | |
| 10151 p_j2k->m_specific_param.m_decoder.m_numcomps_to_decode, | |
| 10152 p_j2k->m_specific_param.m_decoder.m_comps_indices_to_decode, | |
| 10153 l_tcp->m_data, | |
| 10154 l_tcp->m_data_size, | |
| 10155 p_tile_index, | |
| 10156 p_j2k->cstr_index, p_manager)) { | |
| 10157 opj_j2k_tcp_destroy(l_tcp); | |
| 10158 p_j2k->m_specific_param.m_decoder.m_state |= J2K_STATE_ERR; | |
| 10159 opj_event_msg(p_manager, EVT_ERROR, "Failed to decode.\n"); | |
| 10160 return OPJ_FALSE; | |
| 10161 } | |
| 10162 | |
| 10163 /* p_data can be set to NULL when the call will take care of using */ | |
| 10164 /* itself the TCD data. This is typically the case for whole single */ | |
| 10165 /* tile decoding optimization. */ | |
| 10166 if (p_data != NULL) { | |
| 10167 if (! opj_tcd_update_tile_data(p_j2k->m_tcd, p_data, p_data_size)) { | |
| 10168 return OPJ_FALSE; | |
| 10169 } | |
| 10170 | |
| 10171 /* To avoid to destroy the tcp which can be useful when we try to decode a tile decoded before (cf j2k_random_tile_access) | |
| 10172 * we destroy just the data which will be re-read in read_tile_header*/ | |
| 10173 /*opj_j2k_tcp_destroy(l_tcp); | |
| 10174 p_j2k->m_tcd->tcp = 0;*/ | |
| 10175 opj_j2k_tcp_data_destroy(l_tcp); | |
| 10176 } | |
| 10177 | |
| 10178 p_j2k->m_specific_param.m_decoder.m_can_decode = 0; | |
| 10179 p_j2k->m_specific_param.m_decoder.m_state &= (~(OPJ_UINT32)J2K_STATE_DATA); | |
| 10180 | |
| 10181 if (opj_stream_get_number_byte_left(p_stream) == 0 | |
| 10182 && p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_NEOC) { | |
| 10183 return OPJ_TRUE; | |
| 10184 } | |
| 10185 | |
| 10186 if (p_j2k->m_specific_param.m_decoder.m_state != J2K_STATE_EOC) { | |
| 10187 if (opj_stream_read_data(p_stream, l_data, 2, p_manager) != 2) { | |
| 10188 opj_event_msg(p_manager, p_j2k->m_cp.strict ? EVT_ERROR : EVT_WARNING, | |
| 10189 "Stream too short\n"); | |
| 10190 return p_j2k->m_cp.strict ? OPJ_FALSE : OPJ_TRUE; | |
| 10191 } | |
| 10192 opj_read_bytes(l_data, &l_current_marker, 2); | |
| 10193 | |
| 10194 if (l_current_marker == J2K_MS_EOC) { | |
| 10195 p_j2k->m_current_tile_number = 0; | |
| 10196 p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_EOC; | |
| 10197 } else if (l_current_marker != J2K_MS_SOT) { | |
| 10198 if (opj_stream_get_number_byte_left(p_stream) == 0) { | |
| 10199 p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_NEOC; | |
| 10200 opj_event_msg(p_manager, EVT_WARNING, "Stream does not end with EOC\n"); | |
| 10201 return OPJ_TRUE; | |
| 10202 } | |
| 10203 opj_event_msg(p_manager, EVT_ERROR, "Stream too short, expected SOT\n"); | |
| 10204 return OPJ_FALSE; | |
| 10205 } | |
| 10206 } | |
| 10207 | |
| 10208 return OPJ_TRUE; | |
| 10209 } | |
| 10210 | |
| 10211 static OPJ_BOOL opj_j2k_update_image_data(opj_tcd_t * p_tcd, | |
| 10212 opj_image_t* p_output_image) | |
| 10213 { | |
| 10214 OPJ_UINT32 i, j; | |
| 10215 OPJ_UINT32 l_width_src, l_height_src; | |
| 10216 OPJ_UINT32 l_width_dest, l_height_dest; | |
| 10217 OPJ_INT32 l_offset_x0_src, l_offset_y0_src, l_offset_x1_src, l_offset_y1_src; | |
| 10218 OPJ_SIZE_T l_start_offset_src; | |
| 10219 OPJ_UINT32 l_start_x_dest, l_start_y_dest; | |
| 10220 OPJ_UINT32 l_x0_dest, l_y0_dest, l_x1_dest, l_y1_dest; | |
| 10221 OPJ_SIZE_T l_start_offset_dest; | |
| 10222 | |
| 10223 opj_image_comp_t * l_img_comp_src = 00; | |
| 10224 opj_image_comp_t * l_img_comp_dest = 00; | |
| 10225 | |
| 10226 opj_tcd_tilecomp_t * l_tilec = 00; | |
| 10227 opj_image_t * l_image_src = 00; | |
| 10228 OPJ_INT32 * l_dest_ptr; | |
| 10229 | |
| 10230 l_tilec = p_tcd->tcd_image->tiles->comps; | |
| 10231 l_image_src = p_tcd->image; | |
| 10232 l_img_comp_src = l_image_src->comps; | |
| 10233 | |
| 10234 l_img_comp_dest = p_output_image->comps; | |
| 10235 | |
| 10236 for (i = 0; i < l_image_src->numcomps; | |
| 10237 i++, ++l_img_comp_dest, ++l_img_comp_src, ++l_tilec) { | |
| 10238 OPJ_INT32 res_x0, res_x1, res_y0, res_y1; | |
| 10239 OPJ_UINT32 src_data_stride; | |
| 10240 const OPJ_INT32* p_src_data; | |
| 10241 | |
| 10242 /* Copy info from decoded comp image to output image */ | |
| 10243 l_img_comp_dest->resno_decoded = l_img_comp_src->resno_decoded; | |
| 10244 | |
| 10245 if (p_tcd->whole_tile_decoding) { | |
| 10246 opj_tcd_resolution_t* l_res = l_tilec->resolutions + | |
| 10247 l_img_comp_src->resno_decoded; | |
| 10248 res_x0 = l_res->x0; | |
| 10249 res_y0 = l_res->y0; | |
| 10250 res_x1 = l_res->x1; | |
| 10251 res_y1 = l_res->y1; | |
| 10252 src_data_stride = (OPJ_UINT32)( | |
| 10253 l_tilec->resolutions[l_tilec->minimum_num_resolutions - 1].x1 - | |
| 10254 l_tilec->resolutions[l_tilec->minimum_num_resolutions - 1].x0); | |
| 10255 p_src_data = l_tilec->data; | |
| 10256 } else { | |
| 10257 opj_tcd_resolution_t* l_res = l_tilec->resolutions + | |
| 10258 l_img_comp_src->resno_decoded; | |
| 10259 res_x0 = (OPJ_INT32)l_res->win_x0; | |
| 10260 res_y0 = (OPJ_INT32)l_res->win_y0; | |
| 10261 res_x1 = (OPJ_INT32)l_res->win_x1; | |
| 10262 res_y1 = (OPJ_INT32)l_res->win_y1; | |
| 10263 src_data_stride = l_res->win_x1 - l_res->win_x0; | |
| 10264 p_src_data = l_tilec->data_win; | |
| 10265 } | |
| 10266 | |
| 10267 if (p_src_data == NULL) { | |
| 10268 /* Happens for partial component decoding */ | |
| 10269 continue; | |
| 10270 } | |
| 10271 | |
| 10272 l_width_src = (OPJ_UINT32)(res_x1 - res_x0); | |
| 10273 l_height_src = (OPJ_UINT32)(res_y1 - res_y0); | |
| 10274 | |
| 10275 | |
| 10276 /* Current tile component size*/ | |
| 10277 /*if (i == 0) { | |
| 10278 fprintf(stdout, "SRC: l_res_x0=%d, l_res_x1=%d, l_res_y0=%d, l_res_y1=%d\n", | |
| 10279 res_x0, res_x1, res_y0, res_y1); | |
| 10280 }*/ | |
| 10281 | |
| 10282 | |
| 10283 /* Border of the current output component*/ | |
| 10284 l_x0_dest = opj_uint_ceildivpow2(l_img_comp_dest->x0, l_img_comp_dest->factor); | |
| 10285 l_y0_dest = opj_uint_ceildivpow2(l_img_comp_dest->y0, l_img_comp_dest->factor); | |
| 10286 l_x1_dest = l_x0_dest + | |
| 10287 l_img_comp_dest->w; /* can't overflow given that image->x1 is uint32 */ | |
| 10288 l_y1_dest = l_y0_dest + l_img_comp_dest->h; | |
| 10289 | |
| 10290 /*if (i == 0) { | |
| 10291 fprintf(stdout, "DEST: l_x0_dest=%d, l_x1_dest=%d, l_y0_dest=%d, l_y1_dest=%d (%d)\n", | |
| 10292 l_x0_dest, l_x1_dest, l_y0_dest, l_y1_dest, l_img_comp_dest->factor ); | |
| 10293 }*/ | |
| 10294 | |
| 10295 /*-----*/ | |
| 10296 /* Compute the area (l_offset_x0_src, l_offset_y0_src, l_offset_x1_src, l_offset_y1_src) | |
| 10297 * of the input buffer (decoded tile component) which will be move | |
| 10298 * in the output buffer. Compute the area of the output buffer (l_start_x_dest, | |
| 10299 * l_start_y_dest, l_width_dest, l_height_dest) which will be modified | |
| 10300 * by this input area. | |
| 10301 * */ | |
| 10302 assert(res_x0 >= 0); | |
| 10303 assert(res_x1 >= 0); | |
| 10304 if (l_x0_dest < (OPJ_UINT32)res_x0) { | |
| 10305 l_start_x_dest = (OPJ_UINT32)res_x0 - l_x0_dest; | |
| 10306 l_offset_x0_src = 0; | |
| 10307 | |
| 10308 if (l_x1_dest >= (OPJ_UINT32)res_x1) { | |
| 10309 l_width_dest = l_width_src; | |
| 10310 l_offset_x1_src = 0; | |
| 10311 } else { | |
| 10312 l_width_dest = l_x1_dest - (OPJ_UINT32)res_x0 ; | |
| 10313 l_offset_x1_src = (OPJ_INT32)(l_width_src - l_width_dest); | |
| 10314 } | |
| 10315 } else { | |
| 10316 l_start_x_dest = 0U; | |
| 10317 l_offset_x0_src = (OPJ_INT32)l_x0_dest - res_x0; | |
| 10318 | |
| 10319 if (l_x1_dest >= (OPJ_UINT32)res_x1) { | |
| 10320 l_width_dest = l_width_src - (OPJ_UINT32)l_offset_x0_src; | |
| 10321 l_offset_x1_src = 0; | |
| 10322 } else { | |
| 10323 l_width_dest = l_img_comp_dest->w ; | |
| 10324 l_offset_x1_src = res_x1 - (OPJ_INT32)l_x1_dest; | |
| 10325 } | |
| 10326 } | |
| 10327 | |
| 10328 if (l_y0_dest < (OPJ_UINT32)res_y0) { | |
| 10329 l_start_y_dest = (OPJ_UINT32)res_y0 - l_y0_dest; | |
| 10330 l_offset_y0_src = 0; | |
| 10331 | |
| 10332 if (l_y1_dest >= (OPJ_UINT32)res_y1) { | |
| 10333 l_height_dest = l_height_src; | |
| 10334 l_offset_y1_src = 0; | |
| 10335 } else { | |
| 10336 l_height_dest = l_y1_dest - (OPJ_UINT32)res_y0 ; | |
| 10337 l_offset_y1_src = (OPJ_INT32)(l_height_src - l_height_dest); | |
| 10338 } | |
| 10339 } else { | |
| 10340 l_start_y_dest = 0U; | |
| 10341 l_offset_y0_src = (OPJ_INT32)l_y0_dest - res_y0; | |
| 10342 | |
| 10343 if (l_y1_dest >= (OPJ_UINT32)res_y1) { | |
| 10344 l_height_dest = l_height_src - (OPJ_UINT32)l_offset_y0_src; | |
| 10345 l_offset_y1_src = 0; | |
| 10346 } else { | |
| 10347 l_height_dest = l_img_comp_dest->h ; | |
| 10348 l_offset_y1_src = res_y1 - (OPJ_INT32)l_y1_dest; | |
| 10349 } | |
| 10350 } | |
| 10351 | |
| 10352 if ((l_offset_x0_src < 0) || (l_offset_y0_src < 0) || (l_offset_x1_src < 0) || | |
| 10353 (l_offset_y1_src < 0)) { | |
| 10354 return OPJ_FALSE; | |
| 10355 } | |
| 10356 /* testcase 2977.pdf.asan.67.2198 */ | |
| 10357 if ((OPJ_INT32)l_width_dest < 0 || (OPJ_INT32)l_height_dest < 0) { | |
| 10358 return OPJ_FALSE; | |
| 10359 } | |
| 10360 /*-----*/ | |
| 10361 | |
| 10362 /* Compute the input buffer offset */ | |
| 10363 l_start_offset_src = (OPJ_SIZE_T)l_offset_x0_src + (OPJ_SIZE_T)l_offset_y0_src | |
| 10364 * (OPJ_SIZE_T)src_data_stride; | |
| 10365 | |
| 10366 /* Compute the output buffer offset */ | |
| 10367 l_start_offset_dest = (OPJ_SIZE_T)l_start_x_dest + (OPJ_SIZE_T)l_start_y_dest | |
| 10368 * (OPJ_SIZE_T)l_img_comp_dest->w; | |
| 10369 | |
| 10370 /* Allocate output component buffer if necessary */ | |
| 10371 if (l_img_comp_dest->data == NULL && | |
| 10372 l_start_offset_src == 0 && l_start_offset_dest == 0 && | |
| 10373 src_data_stride == l_img_comp_dest->w && | |
| 10374 l_width_dest == l_img_comp_dest->w && | |
| 10375 l_height_dest == l_img_comp_dest->h) { | |
| 10376 /* If the final image matches the tile buffer, then borrow it */ | |
| 10377 /* directly to save a copy */ | |
| 10378 if (p_tcd->whole_tile_decoding) { | |
| 10379 l_img_comp_dest->data = l_tilec->data; | |
| 10380 l_tilec->data = NULL; | |
| 10381 } else { | |
| 10382 l_img_comp_dest->data = l_tilec->data_win; | |
| 10383 l_tilec->data_win = NULL; | |
| 10384 } | |
| 10385 continue; | |
| 10386 } else if (l_img_comp_dest->data == NULL) { | |
| 10387 OPJ_SIZE_T l_width = l_img_comp_dest->w; | |
| 10388 OPJ_SIZE_T l_height = l_img_comp_dest->h; | |
| 10389 | |
| 10390 if ((l_height == 0U) || (l_width > (SIZE_MAX / l_height)) || | |
| 10391 l_width * l_height > SIZE_MAX / sizeof(OPJ_INT32)) { | |
| 10392 /* would overflow */ | |
| 10393 return OPJ_FALSE; | |
| 10394 } | |
| 10395 l_img_comp_dest->data = (OPJ_INT32*) opj_image_data_alloc(l_width * l_height * | |
| 10396 sizeof(OPJ_INT32)); | |
| 10397 if (! l_img_comp_dest->data) { | |
| 10398 return OPJ_FALSE; | |
| 10399 } | |
| 10400 | |
| 10401 if (l_img_comp_dest->w != l_width_dest || | |
| 10402 l_img_comp_dest->h != l_height_dest) { | |
| 10403 memset(l_img_comp_dest->data, 0, | |
| 10404 (OPJ_SIZE_T)l_img_comp_dest->w * l_img_comp_dest->h * sizeof(OPJ_INT32)); | |
| 10405 } | |
| 10406 } | |
| 10407 | |
| 10408 /* Move the output buffer to the first place where we will write*/ | |
| 10409 l_dest_ptr = l_img_comp_dest->data + l_start_offset_dest; | |
| 10410 | |
| 10411 { | |
| 10412 const OPJ_INT32 * l_src_ptr = p_src_data; | |
| 10413 l_src_ptr += l_start_offset_src; | |
| 10414 | |
| 10415 for (j = 0; j < l_height_dest; ++j) { | |
| 10416 memcpy(l_dest_ptr, l_src_ptr, l_width_dest * sizeof(OPJ_INT32)); | |
| 10417 l_dest_ptr += l_img_comp_dest->w; | |
| 10418 l_src_ptr += src_data_stride; | |
| 10419 } | |
| 10420 } | |
| 10421 | |
| 10422 | |
| 10423 } | |
| 10424 | |
| 10425 return OPJ_TRUE; | |
| 10426 } | |
| 10427 | |
| 10428 static OPJ_BOOL opj_j2k_update_image_dimensions(opj_image_t* p_image, | |
| 10429 opj_event_mgr_t * p_manager) | |
| 10430 { | |
| 10431 OPJ_UINT32 it_comp; | |
| 10432 OPJ_INT32 l_comp_x1, l_comp_y1; | |
| 10433 opj_image_comp_t* l_img_comp = NULL; | |
| 10434 | |
| 10435 l_img_comp = p_image->comps; | |
| 10436 for (it_comp = 0; it_comp < p_image->numcomps; ++it_comp) { | |
| 10437 OPJ_INT32 l_h, l_w; | |
| 10438 if (p_image->x0 > (OPJ_UINT32)INT_MAX || | |
| 10439 p_image->y0 > (OPJ_UINT32)INT_MAX || | |
| 10440 p_image->x1 > (OPJ_UINT32)INT_MAX || | |
| 10441 p_image->y1 > (OPJ_UINT32)INT_MAX) { | |
| 10442 opj_event_msg(p_manager, EVT_ERROR, | |
| 10443 "Image coordinates above INT_MAX are not supported\n"); | |
| 10444 return OPJ_FALSE; | |
| 10445 } | |
| 10446 | |
| 10447 l_img_comp->x0 = opj_uint_ceildiv(p_image->x0, l_img_comp->dx); | |
| 10448 l_img_comp->y0 = opj_uint_ceildiv(p_image->y0, l_img_comp->dy); | |
| 10449 l_comp_x1 = opj_int_ceildiv((OPJ_INT32)p_image->x1, (OPJ_INT32)l_img_comp->dx); | |
| 10450 l_comp_y1 = opj_int_ceildiv((OPJ_INT32)p_image->y1, (OPJ_INT32)l_img_comp->dy); | |
| 10451 | |
| 10452 l_w = opj_int_ceildivpow2(l_comp_x1, (OPJ_INT32)l_img_comp->factor) | |
| 10453 - opj_int_ceildivpow2((OPJ_INT32)l_img_comp->x0, (OPJ_INT32)l_img_comp->factor); | |
| 10454 if (l_w < 0) { | |
| 10455 opj_event_msg(p_manager, EVT_ERROR, | |
| 10456 "Size x of the decoded component image is incorrect (comp[%d].w=%d).\n", | |
| 10457 it_comp, l_w); | |
| 10458 return OPJ_FALSE; | |
| 10459 } | |
| 10460 l_img_comp->w = (OPJ_UINT32)l_w; | |
| 10461 | |
| 10462 l_h = opj_int_ceildivpow2(l_comp_y1, (OPJ_INT32)l_img_comp->factor) | |
| 10463 - opj_int_ceildivpow2((OPJ_INT32)l_img_comp->y0, (OPJ_INT32)l_img_comp->factor); | |
| 10464 if (l_h < 0) { | |
| 10465 opj_event_msg(p_manager, EVT_ERROR, | |
| 10466 "Size y of the decoded component image is incorrect (comp[%d].h=%d).\n", | |
| 10467 it_comp, l_h); | |
| 10468 return OPJ_FALSE; | |
| 10469 } | |
| 10470 l_img_comp->h = (OPJ_UINT32)l_h; | |
| 10471 | |
| 10472 l_img_comp++; | |
| 10473 } | |
| 10474 | |
| 10475 return OPJ_TRUE; | |
| 10476 } | |
| 10477 | |
| 10478 OPJ_BOOL opj_j2k_set_decoded_components(opj_j2k_t *p_j2k, | |
| 10479 OPJ_UINT32 numcomps, | |
| 10480 const OPJ_UINT32* comps_indices, | |
| 10481 opj_event_mgr_t * p_manager) | |
| 10482 { | |
| 10483 OPJ_UINT32 i; | |
| 10484 OPJ_BOOL* already_mapped; | |
| 10485 | |
| 10486 if (p_j2k->m_private_image == NULL) { | |
| 10487 opj_event_msg(p_manager, EVT_ERROR, | |
| 10488 "opj_read_header() should be called before " | |
| 10489 "opj_set_decoded_components().\n"); | |
| 10490 return OPJ_FALSE; | |
| 10491 } | |
| 10492 | |
| 10493 already_mapped = (OPJ_BOOL*) opj_calloc(sizeof(OPJ_BOOL), | |
| 10494 p_j2k->m_private_image->numcomps); | |
| 10495 if (already_mapped == NULL) { | |
| 10496 return OPJ_FALSE; | |
| 10497 } | |
| 10498 | |
| 10499 for (i = 0; i < numcomps; i++) { | |
| 10500 if (comps_indices[i] >= p_j2k->m_private_image->numcomps) { | |
| 10501 opj_event_msg(p_manager, EVT_ERROR, | |
| 10502 "Invalid component index: %u\n", | |
| 10503 comps_indices[i]); | |
| 10504 opj_free(already_mapped); | |
| 10505 return OPJ_FALSE; | |
| 10506 } | |
| 10507 if (already_mapped[comps_indices[i]]) { | |
| 10508 opj_event_msg(p_manager, EVT_ERROR, | |
| 10509 "Component index %u used several times\n", | |
| 10510 comps_indices[i]); | |
| 10511 opj_free(already_mapped); | |
| 10512 return OPJ_FALSE; | |
| 10513 } | |
| 10514 already_mapped[comps_indices[i]] = OPJ_TRUE; | |
| 10515 } | |
| 10516 opj_free(already_mapped); | |
| 10517 | |
| 10518 opj_free(p_j2k->m_specific_param.m_decoder.m_comps_indices_to_decode); | |
| 10519 if (numcomps) { | |
| 10520 p_j2k->m_specific_param.m_decoder.m_comps_indices_to_decode = | |
| 10521 (OPJ_UINT32*) opj_malloc(numcomps * sizeof(OPJ_UINT32)); | |
| 10522 if (p_j2k->m_specific_param.m_decoder.m_comps_indices_to_decode == NULL) { | |
| 10523 p_j2k->m_specific_param.m_decoder.m_numcomps_to_decode = 0; | |
| 10524 return OPJ_FALSE; | |
| 10525 } | |
| 10526 memcpy(p_j2k->m_specific_param.m_decoder.m_comps_indices_to_decode, | |
| 10527 comps_indices, | |
| 10528 numcomps * sizeof(OPJ_UINT32)); | |
| 10529 } else { | |
| 10530 p_j2k->m_specific_param.m_decoder.m_comps_indices_to_decode = NULL; | |
| 10531 } | |
| 10532 p_j2k->m_specific_param.m_decoder.m_numcomps_to_decode = numcomps; | |
| 10533 | |
| 10534 return OPJ_TRUE; | |
| 10535 } | |
| 10536 | |
| 10537 | |
| 10538 OPJ_BOOL opj_j2k_set_decode_area(opj_j2k_t *p_j2k, | |
| 10539 opj_image_t* p_image, | |
| 10540 OPJ_INT32 p_start_x, OPJ_INT32 p_start_y, | |
| 10541 OPJ_INT32 p_end_x, OPJ_INT32 p_end_y, | |
| 10542 opj_event_mgr_t * p_manager) | |
| 10543 { | |
| 10544 opj_cp_t * l_cp = &(p_j2k->m_cp); | |
| 10545 opj_image_t * l_image = p_j2k->m_private_image; | |
| 10546 OPJ_BOOL ret; | |
| 10547 OPJ_UINT32 it_comp; | |
| 10548 | |
| 10549 if (p_j2k->m_cp.tw == 1 && p_j2k->m_cp.th == 1 && | |
| 10550 p_j2k->m_cp.tcps[0].m_data != NULL) { | |
| 10551 /* In the case of a single-tiled image whose codestream we have already */ | |
| 10552 /* ingested, go on */ | |
| 10553 } | |
| 10554 /* Check if we are read the main header */ | |
| 10555 else if (p_j2k->m_specific_param.m_decoder.m_state != J2K_STATE_TPHSOT) { | |
| 10556 opj_event_msg(p_manager, EVT_ERROR, | |
| 10557 "Need to decode the main header before begin to decode the remaining codestream.\n"); | |
| 10558 return OPJ_FALSE; | |
| 10559 } | |
| 10560 | |
| 10561 /* Update the comps[].factor member of the output image with the one */ | |
| 10562 /* of m_reduce */ | |
| 10563 for (it_comp = 0; it_comp < p_image->numcomps; ++it_comp) { | |
| 10564 p_image->comps[it_comp].factor = p_j2k->m_cp.m_specific_param.m_dec.m_reduce; | |
| 10565 } | |
| 10566 | |
| 10567 if (!p_start_x && !p_start_y && !p_end_x && !p_end_y) { | |
| 10568 opj_event_msg(p_manager, EVT_INFO, | |
| 10569 "No decoded area parameters, set the decoded area to the whole image\n"); | |
| 10570 | |
| 10571 p_j2k->m_specific_param.m_decoder.m_start_tile_x = 0; | |
| 10572 p_j2k->m_specific_param.m_decoder.m_start_tile_y = 0; | |
| 10573 p_j2k->m_specific_param.m_decoder.m_end_tile_x = l_cp->tw; | |
| 10574 p_j2k->m_specific_param.m_decoder.m_end_tile_y = l_cp->th; | |
| 10575 | |
| 10576 p_image->x0 = l_image->x0; | |
| 10577 p_image->y0 = l_image->y0; | |
| 10578 p_image->x1 = l_image->x1; | |
| 10579 p_image->y1 = l_image->y1; | |
| 10580 | |
| 10581 return opj_j2k_update_image_dimensions(p_image, p_manager); | |
| 10582 } | |
| 10583 | |
| 10584 /* ----- */ | |
| 10585 /* Check if the positions provided by the user are correct */ | |
| 10586 | |
| 10587 /* Left */ | |
| 10588 if (p_start_x < 0) { | |
| 10589 opj_event_msg(p_manager, EVT_ERROR, | |
| 10590 "Left position of the decoded area (region_x0=%d) should be >= 0.\n", | |
| 10591 p_start_x); | |
| 10592 return OPJ_FALSE; | |
| 10593 } else if ((OPJ_UINT32)p_start_x > l_image->x1) { | |
| 10594 opj_event_msg(p_manager, EVT_ERROR, | |
| 10595 "Left position of the decoded area (region_x0=%d) is outside the image area (Xsiz=%d).\n", | |
| 10596 p_start_x, l_image->x1); | |
| 10597 return OPJ_FALSE; | |
| 10598 } else if ((OPJ_UINT32)p_start_x < l_image->x0) { | |
| 10599 opj_event_msg(p_manager, EVT_WARNING, | |
| 10600 "Left position of the decoded area (region_x0=%d) is outside the image area (XOsiz=%d).\n", | |
| 10601 p_start_x, l_image->x0); | |
| 10602 p_j2k->m_specific_param.m_decoder.m_start_tile_x = 0; | |
| 10603 p_image->x0 = l_image->x0; | |
| 10604 } else { | |
| 10605 p_j2k->m_specific_param.m_decoder.m_start_tile_x = ((OPJ_UINT32)p_start_x - | |
| 10606 l_cp->tx0) / l_cp->tdx; | |
| 10607 p_image->x0 = (OPJ_UINT32)p_start_x; | |
| 10608 } | |
| 10609 | |
| 10610 /* Up */ | |
| 10611 if (p_start_y < 0) { | |
| 10612 opj_event_msg(p_manager, EVT_ERROR, | |
| 10613 "Up position of the decoded area (region_y0=%d) should be >= 0.\n", | |
| 10614 p_start_y); | |
| 10615 return OPJ_FALSE; | |
| 10616 } else if ((OPJ_UINT32)p_start_y > l_image->y1) { | |
| 10617 opj_event_msg(p_manager, EVT_ERROR, | |
| 10618 "Up position of the decoded area (region_y0=%d) is outside the image area (Ysiz=%d).\n", | |
| 10619 p_start_y, l_image->y1); | |
| 10620 return OPJ_FALSE; | |
| 10621 } else if ((OPJ_UINT32)p_start_y < l_image->y0) { | |
| 10622 opj_event_msg(p_manager, EVT_WARNING, | |
| 10623 "Up position of the decoded area (region_y0=%d) is outside the image area (YOsiz=%d).\n", | |
| 10624 p_start_y, l_image->y0); | |
| 10625 p_j2k->m_specific_param.m_decoder.m_start_tile_y = 0; | |
| 10626 p_image->y0 = l_image->y0; | |
| 10627 } else { | |
| 10628 p_j2k->m_specific_param.m_decoder.m_start_tile_y = ((OPJ_UINT32)p_start_y - | |
| 10629 l_cp->ty0) / l_cp->tdy; | |
| 10630 p_image->y0 = (OPJ_UINT32)p_start_y; | |
| 10631 } | |
| 10632 | |
| 10633 /* Right */ | |
| 10634 if (p_end_x <= 0) { | |
| 10635 opj_event_msg(p_manager, EVT_ERROR, | |
| 10636 "Right position of the decoded area (region_x1=%d) should be > 0.\n", | |
| 10637 p_end_x); | |
| 10638 return OPJ_FALSE; | |
| 10639 } else if ((OPJ_UINT32)p_end_x < l_image->x0) { | |
| 10640 opj_event_msg(p_manager, EVT_ERROR, | |
| 10641 "Right position of the decoded area (region_x1=%d) is outside the image area (XOsiz=%d).\n", | |
| 10642 p_end_x, l_image->x0); | |
| 10643 return OPJ_FALSE; | |
| 10644 } else if ((OPJ_UINT32)p_end_x > l_image->x1) { | |
| 10645 opj_event_msg(p_manager, EVT_WARNING, | |
| 10646 "Right position of the decoded area (region_x1=%d) is outside the image area (Xsiz=%d).\n", | |
| 10647 p_end_x, l_image->x1); | |
| 10648 p_j2k->m_specific_param.m_decoder.m_end_tile_x = l_cp->tw; | |
| 10649 p_image->x1 = l_image->x1; | |
| 10650 } else { | |
| 10651 p_j2k->m_specific_param.m_decoder.m_end_tile_x = opj_uint_ceildiv(( | |
| 10652 OPJ_UINT32)p_end_x - l_cp->tx0, l_cp->tdx); | |
| 10653 p_image->x1 = (OPJ_UINT32)p_end_x; | |
| 10654 } | |
| 10655 | |
| 10656 /* Bottom */ | |
| 10657 if (p_end_y <= 0) { | |
| 10658 opj_event_msg(p_manager, EVT_ERROR, | |
| 10659 "Bottom position of the decoded area (region_y1=%d) should be > 0.\n", | |
| 10660 p_end_y); | |
| 10661 return OPJ_FALSE; | |
| 10662 } else if ((OPJ_UINT32)p_end_y < l_image->y0) { | |
| 10663 opj_event_msg(p_manager, EVT_ERROR, | |
| 10664 "Bottom position of the decoded area (region_y1=%d) is outside the image area (YOsiz=%d).\n", | |
| 10665 p_end_y, l_image->y0); | |
| 10666 return OPJ_FALSE; | |
| 10667 } | |
| 10668 if ((OPJ_UINT32)p_end_y > l_image->y1) { | |
| 10669 opj_event_msg(p_manager, EVT_WARNING, | |
| 10670 "Bottom position of the decoded area (region_y1=%d) is outside the image area (Ysiz=%d).\n", | |
| 10671 p_end_y, l_image->y1); | |
| 10672 p_j2k->m_specific_param.m_decoder.m_end_tile_y = l_cp->th; | |
| 10673 p_image->y1 = l_image->y1; | |
| 10674 } else { | |
| 10675 p_j2k->m_specific_param.m_decoder.m_end_tile_y = opj_uint_ceildiv(( | |
| 10676 OPJ_UINT32)p_end_y - l_cp->ty0, l_cp->tdy); | |
| 10677 p_image->y1 = (OPJ_UINT32)p_end_y; | |
| 10678 } | |
| 10679 /* ----- */ | |
| 10680 | |
| 10681 p_j2k->m_specific_param.m_decoder.m_discard_tiles = 1; | |
| 10682 | |
| 10683 ret = opj_j2k_update_image_dimensions(p_image, p_manager); | |
| 10684 | |
| 10685 if (ret) { | |
| 10686 opj_event_msg(p_manager, EVT_INFO, "Setting decoding area to %d,%d,%d,%d\n", | |
| 10687 p_image->x0, p_image->y0, p_image->x1, p_image->y1); | |
| 10688 } | |
| 10689 | |
| 10690 return ret; | |
| 10691 } | |
| 10692 | |
| 10693 opj_j2k_t* opj_j2k_create_decompress(void) | |
| 10694 { | |
| 10695 opj_j2k_t *l_j2k = (opj_j2k_t*) opj_calloc(1, sizeof(opj_j2k_t)); | |
| 10696 if (!l_j2k) { | |
| 10697 return 00; | |
| 10698 } | |
| 10699 | |
| 10700 l_j2k->m_is_decoder = 1; | |
| 10701 l_j2k->m_cp.m_is_decoder = 1; | |
| 10702 /* in the absence of JP2 boxes, consider different bit depth / sign */ | |
| 10703 /* per component is allowed */ | |
| 10704 l_j2k->m_cp.allow_different_bit_depth_sign = 1; | |
| 10705 | |
| 10706 /* Default to using strict mode. */ | |
| 10707 l_j2k->m_cp.strict = OPJ_TRUE; | |
| 10708 | |
| 10709 #ifdef OPJ_DISABLE_TPSOT_FIX | |
| 10710 l_j2k->m_specific_param.m_decoder.m_nb_tile_parts_correction_checked = 1; | |
| 10711 #endif | |
| 10712 | |
| 10713 l_j2k->m_specific_param.m_decoder.m_default_tcp = (opj_tcp_t*) opj_calloc(1, | |
| 10714 sizeof(opj_tcp_t)); | |
| 10715 if (!l_j2k->m_specific_param.m_decoder.m_default_tcp) { | |
| 10716 opj_j2k_destroy(l_j2k); | |
| 10717 return 00; | |
| 10718 } | |
| 10719 | |
| 10720 l_j2k->m_specific_param.m_decoder.m_header_data = (OPJ_BYTE *) opj_calloc(1, | |
| 10721 OPJ_J2K_DEFAULT_HEADER_SIZE); | |
| 10722 if (! l_j2k->m_specific_param.m_decoder.m_header_data) { | |
| 10723 opj_j2k_destroy(l_j2k); | |
| 10724 return 00; | |
| 10725 } | |
| 10726 | |
| 10727 l_j2k->m_specific_param.m_decoder.m_header_data_size = | |
| 10728 OPJ_J2K_DEFAULT_HEADER_SIZE; | |
| 10729 | |
| 10730 l_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec = -1 ; | |
| 10731 | |
| 10732 l_j2k->m_specific_param.m_decoder.m_last_sot_read_pos = 0 ; | |
| 10733 | |
| 10734 /* codestream index creation */ | |
| 10735 l_j2k->cstr_index = opj_j2k_create_cstr_index(); | |
| 10736 if (!l_j2k->cstr_index) { | |
| 10737 opj_j2k_destroy(l_j2k); | |
| 10738 return 00; | |
| 10739 } | |
| 10740 | |
| 10741 /* validation list creation */ | |
| 10742 l_j2k->m_validation_list = opj_procedure_list_create(); | |
| 10743 if (! l_j2k->m_validation_list) { | |
| 10744 opj_j2k_destroy(l_j2k); | |
| 10745 return 00; | |
| 10746 } | |
| 10747 | |
| 10748 /* execution list creation */ | |
| 10749 l_j2k->m_procedure_list = opj_procedure_list_create(); | |
| 10750 if (! l_j2k->m_procedure_list) { | |
| 10751 opj_j2k_destroy(l_j2k); | |
| 10752 return 00; | |
| 10753 } | |
| 10754 | |
| 10755 l_j2k->m_tp = opj_thread_pool_create(opj_j2k_get_default_thread_count()); | |
| 10756 if (!l_j2k->m_tp) { | |
| 10757 l_j2k->m_tp = opj_thread_pool_create(0); | |
| 10758 } | |
| 10759 if (!l_j2k->m_tp) { | |
| 10760 opj_j2k_destroy(l_j2k); | |
| 10761 return NULL; | |
| 10762 } | |
| 10763 | |
| 10764 return l_j2k; | |
| 10765 } | |
| 10766 | |
| 10767 static opj_codestream_index_t* opj_j2k_create_cstr_index(void) | |
| 10768 { | |
| 10769 opj_codestream_index_t* cstr_index = (opj_codestream_index_t*) | |
| 10770 opj_calloc(1, sizeof(opj_codestream_index_t)); | |
| 10771 if (!cstr_index) { | |
| 10772 return NULL; | |
| 10773 } | |
| 10774 | |
| 10775 cstr_index->maxmarknum = 100; | |
| 10776 cstr_index->marknum = 0; | |
| 10777 cstr_index->marker = (opj_marker_info_t*) | |
| 10778 opj_calloc(cstr_index->maxmarknum, sizeof(opj_marker_info_t)); | |
| 10779 if (!cstr_index-> marker) { | |
| 10780 opj_free(cstr_index); | |
| 10781 return NULL; | |
| 10782 } | |
| 10783 | |
| 10784 cstr_index->tile_index = NULL; | |
| 10785 | |
| 10786 return cstr_index; | |
| 10787 } | |
| 10788 | |
| 10789 static OPJ_UINT32 opj_j2k_get_SPCod_SPCoc_size(opj_j2k_t *p_j2k, | |
| 10790 OPJ_UINT32 p_tile_no, | |
| 10791 OPJ_UINT32 p_comp_no) | |
| 10792 { | |
| 10793 opj_cp_t *l_cp = 00; | |
| 10794 opj_tcp_t *l_tcp = 00; | |
| 10795 opj_tccp_t *l_tccp = 00; | |
| 10796 | |
| 10797 /* preconditions */ | |
| 10798 assert(p_j2k != 00); | |
| 10799 | |
| 10800 l_cp = &(p_j2k->m_cp); | |
| 10801 l_tcp = &l_cp->tcps[p_tile_no]; | |
| 10802 l_tccp = &l_tcp->tccps[p_comp_no]; | |
| 10803 | |
| 10804 /* preconditions again */ | |
| 10805 assert(p_tile_no < (l_cp->tw * l_cp->th)); | |
| 10806 assert(p_comp_no < p_j2k->m_private_image->numcomps); | |
| 10807 | |
| 10808 if (l_tccp->csty & J2K_CCP_CSTY_PRT) { | |
| 10809 return 5 + l_tccp->numresolutions; | |
| 10810 } else { | |
| 10811 return 5; | |
| 10812 } | |
| 10813 } | |
| 10814 | |
| 10815 static OPJ_BOOL opj_j2k_compare_SPCod_SPCoc(opj_j2k_t *p_j2k, | |
| 10816 OPJ_UINT32 p_tile_no, OPJ_UINT32 p_first_comp_no, OPJ_UINT32 p_second_comp_no) | |
| 10817 { | |
| 10818 OPJ_UINT32 i; | |
| 10819 opj_cp_t *l_cp = NULL; | |
| 10820 opj_tcp_t *l_tcp = NULL; | |
| 10821 opj_tccp_t *l_tccp0 = NULL; | |
| 10822 opj_tccp_t *l_tccp1 = NULL; | |
| 10823 | |
| 10824 /* preconditions */ | |
| 10825 assert(p_j2k != 00); | |
| 10826 | |
| 10827 l_cp = &(p_j2k->m_cp); | |
| 10828 l_tcp = &l_cp->tcps[p_tile_no]; | |
| 10829 l_tccp0 = &l_tcp->tccps[p_first_comp_no]; | |
| 10830 l_tccp1 = &l_tcp->tccps[p_second_comp_no]; | |
| 10831 | |
| 10832 if (l_tccp0->numresolutions != l_tccp1->numresolutions) { | |
| 10833 return OPJ_FALSE; | |
| 10834 } | |
| 10835 if (l_tccp0->cblkw != l_tccp1->cblkw) { | |
| 10836 return OPJ_FALSE; | |
| 10837 } | |
| 10838 if (l_tccp0->cblkh != l_tccp1->cblkh) { | |
| 10839 return OPJ_FALSE; | |
| 10840 } | |
| 10841 if (l_tccp0->cblksty != l_tccp1->cblksty) { | |
| 10842 return OPJ_FALSE; | |
| 10843 } | |
| 10844 if (l_tccp0->qmfbid != l_tccp1->qmfbid) { | |
| 10845 return OPJ_FALSE; | |
| 10846 } | |
| 10847 if ((l_tccp0->csty & J2K_CCP_CSTY_PRT) != (l_tccp1->csty & J2K_CCP_CSTY_PRT)) { | |
| 10848 return OPJ_FALSE; | |
| 10849 } | |
| 10850 | |
| 10851 for (i = 0U; i < l_tccp0->numresolutions; ++i) { | |
| 10852 if (l_tccp0->prcw[i] != l_tccp1->prcw[i]) { | |
| 10853 return OPJ_FALSE; | |
| 10854 } | |
| 10855 if (l_tccp0->prch[i] != l_tccp1->prch[i]) { | |
| 10856 return OPJ_FALSE; | |
| 10857 } | |
| 10858 } | |
| 10859 return OPJ_TRUE; | |
| 10860 } | |
| 10861 | |
| 10862 static OPJ_BOOL opj_j2k_write_SPCod_SPCoc(opj_j2k_t *p_j2k, | |
| 10863 OPJ_UINT32 p_tile_no, | |
| 10864 OPJ_UINT32 p_comp_no, | |
| 10865 OPJ_BYTE * p_data, | |
| 10866 OPJ_UINT32 * p_header_size, | |
| 10867 struct opj_event_mgr * p_manager) | |
| 10868 { | |
| 10869 OPJ_UINT32 i; | |
| 10870 opj_cp_t *l_cp = 00; | |
| 10871 opj_tcp_t *l_tcp = 00; | |
| 10872 opj_tccp_t *l_tccp = 00; | |
| 10873 | |
| 10874 /* preconditions */ | |
| 10875 assert(p_j2k != 00); | |
| 10876 assert(p_header_size != 00); | |
| 10877 assert(p_manager != 00); | |
| 10878 assert(p_data != 00); | |
| 10879 | |
| 10880 l_cp = &(p_j2k->m_cp); | |
| 10881 l_tcp = &l_cp->tcps[p_tile_no]; | |
| 10882 l_tccp = &l_tcp->tccps[p_comp_no]; | |
| 10883 | |
| 10884 /* preconditions again */ | |
| 10885 assert(p_tile_no < (l_cp->tw * l_cp->th)); | |
| 10886 assert(p_comp_no < (p_j2k->m_private_image->numcomps)); | |
| 10887 | |
| 10888 if (*p_header_size < 5) { | |
| 10889 opj_event_msg(p_manager, EVT_ERROR, "Error writing SPCod SPCoc element\n"); | |
| 10890 return OPJ_FALSE; | |
| 10891 } | |
| 10892 | |
| 10893 opj_write_bytes(p_data, l_tccp->numresolutions - 1, 1); /* SPcoc (D) */ | |
| 10894 ++p_data; | |
| 10895 | |
| 10896 opj_write_bytes(p_data, l_tccp->cblkw - 2, 1); /* SPcoc (E) */ | |
| 10897 ++p_data; | |
| 10898 | |
| 10899 opj_write_bytes(p_data, l_tccp->cblkh - 2, 1); /* SPcoc (F) */ | |
| 10900 ++p_data; | |
| 10901 | |
| 10902 opj_write_bytes(p_data, l_tccp->cblksty, | |
| 10903 1); /* SPcoc (G) */ | |
| 10904 ++p_data; | |
| 10905 | |
| 10906 opj_write_bytes(p_data, l_tccp->qmfbid, | |
| 10907 1); /* SPcoc (H) */ | |
| 10908 ++p_data; | |
| 10909 | |
| 10910 *p_header_size = *p_header_size - 5; | |
| 10911 | |
| 10912 if (l_tccp->csty & J2K_CCP_CSTY_PRT) { | |
| 10913 | |
| 10914 if (*p_header_size < l_tccp->numresolutions) { | |
| 10915 opj_event_msg(p_manager, EVT_ERROR, "Error writing SPCod SPCoc element\n"); | |
| 10916 return OPJ_FALSE; | |
| 10917 } | |
| 10918 | |
| 10919 for (i = 0; i < l_tccp->numresolutions; ++i) { | |
| 10920 opj_write_bytes(p_data, l_tccp->prcw[i] + (l_tccp->prch[i] << 4), | |
| 10921 1); /* SPcoc (I_i) */ | |
| 10922 ++p_data; | |
| 10923 } | |
| 10924 | |
| 10925 *p_header_size = *p_header_size - l_tccp->numresolutions; | |
| 10926 } | |
| 10927 | |
| 10928 return OPJ_TRUE; | |
| 10929 } | |
| 10930 | |
| 10931 static OPJ_BOOL opj_j2k_read_SPCod_SPCoc(opj_j2k_t *p_j2k, | |
| 10932 OPJ_UINT32 compno, | |
| 10933 OPJ_BYTE * p_header_data, | |
| 10934 OPJ_UINT32 * p_header_size, | |
| 10935 opj_event_mgr_t * p_manager) | |
| 10936 { | |
| 10937 OPJ_UINT32 i, l_tmp; | |
| 10938 opj_cp_t *l_cp = NULL; | |
| 10939 opj_tcp_t *l_tcp = NULL; | |
| 10940 opj_tccp_t *l_tccp = NULL; | |
| 10941 OPJ_BYTE * l_current_ptr = NULL; | |
| 10942 | |
| 10943 /* preconditions */ | |
| 10944 assert(p_j2k != 00); | |
| 10945 assert(p_manager != 00); | |
| 10946 assert(p_header_data != 00); | |
| 10947 | |
| 10948 l_cp = &(p_j2k->m_cp); | |
| 10949 l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH) ? | |
| 10950 &l_cp->tcps[p_j2k->m_current_tile_number] : | |
| 10951 p_j2k->m_specific_param.m_decoder.m_default_tcp; | |
| 10952 | |
| 10953 /* precondition again */ | |
| 10954 assert(compno < p_j2k->m_private_image->numcomps); | |
| 10955 | |
| 10956 l_tccp = &l_tcp->tccps[compno]; | |
| 10957 l_current_ptr = p_header_data; | |
| 10958 | |
| 10959 /* make sure room is sufficient */ | |
| 10960 if (*p_header_size < 5) { | |
| 10961 opj_event_msg(p_manager, EVT_ERROR, "Error reading SPCod SPCoc element\n"); | |
| 10962 return OPJ_FALSE; | |
| 10963 } | |
| 10964 | |
| 10965 /* SPcod (D) / SPcoc (A) */ | |
| 10966 opj_read_bytes(l_current_ptr, &l_tccp->numresolutions, 1); | |
| 10967 ++l_tccp->numresolutions; /* tccp->numresolutions = read() + 1 */ | |
| 10968 if (l_tccp->numresolutions > OPJ_J2K_MAXRLVLS) { | |
| 10969 opj_event_msg(p_manager, EVT_ERROR, | |
| 10970 "Invalid value for numresolutions : %d, max value is set in openjpeg.h at %d\n", | |
| 10971 l_tccp->numresolutions, OPJ_J2K_MAXRLVLS); | |
| 10972 return OPJ_FALSE; | |
| 10973 } | |
| 10974 ++l_current_ptr; | |
| 10975 | |
| 10976 /* If user wants to remove more resolutions than the codestream contains, return error */ | |
| 10977 if (l_cp->m_specific_param.m_dec.m_reduce >= l_tccp->numresolutions) { | |
| 10978 opj_event_msg(p_manager, EVT_ERROR, | |
| 10979 "Error decoding component %d.\nThe number of resolutions " | |
| 10980 "to remove (%d) is greater or equal than the number " | |
| 10981 "of resolutions of this component (%d)\nModify the cp_reduce parameter.\n\n", | |
| 10982 compno, l_cp->m_specific_param.m_dec.m_reduce, l_tccp->numresolutions); | |
| 10983 p_j2k->m_specific_param.m_decoder.m_state |= | |
| 10984 0x8000;/* FIXME J2K_DEC_STATE_ERR;*/ | |
| 10985 return OPJ_FALSE; | |
| 10986 } | |
| 10987 | |
| 10988 /* SPcod (E) / SPcoc (B) */ | |
| 10989 opj_read_bytes(l_current_ptr, &l_tccp->cblkw, 1); | |
| 10990 ++l_current_ptr; | |
| 10991 l_tccp->cblkw += 2; | |
| 10992 | |
| 10993 /* SPcod (F) / SPcoc (C) */ | |
| 10994 opj_read_bytes(l_current_ptr, &l_tccp->cblkh, 1); | |
| 10995 ++l_current_ptr; | |
| 10996 l_tccp->cblkh += 2; | |
| 10997 | |
| 10998 if ((l_tccp->cblkw > 10) || (l_tccp->cblkh > 10) || | |
| 10999 ((l_tccp->cblkw + l_tccp->cblkh) > 12)) { | |
| 11000 opj_event_msg(p_manager, EVT_ERROR, | |
| 11001 "Error reading SPCod SPCoc element, Invalid cblkw/cblkh combination\n"); | |
| 11002 return OPJ_FALSE; | |
| 11003 } | |
| 11004 | |
| 11005 /* SPcod (G) / SPcoc (D) */ | |
| 11006 opj_read_bytes(l_current_ptr, &l_tccp->cblksty, 1); | |
| 11007 ++l_current_ptr; | |
| 11008 if ((l_tccp->cblksty & J2K_CCP_CBLKSTY_HTMIXED) != 0) { | |
| 11009 /* We do not support HT mixed mode yet. For conformance, it should be supported.*/ | |
| 11010 opj_event_msg(p_manager, EVT_ERROR, | |
| 11011 "Error reading SPCod SPCoc element. Unsupported Mixed HT code-block style found\n"); | |
| 11012 return OPJ_FALSE; | |
| 11013 } | |
| 11014 | |
| 11015 /* SPcod (H) / SPcoc (E) */ | |
| 11016 opj_read_bytes(l_current_ptr, &l_tccp->qmfbid, 1); | |
| 11017 ++l_current_ptr; | |
| 11018 | |
| 11019 if (l_tccp->qmfbid > 1) { | |
| 11020 opj_event_msg(p_manager, EVT_ERROR, | |
| 11021 "Error reading SPCod SPCoc element, Invalid transformation found\n"); | |
| 11022 return OPJ_FALSE; | |
| 11023 } | |
| 11024 | |
| 11025 *p_header_size = *p_header_size - 5; | |
| 11026 | |
| 11027 /* use custom precinct size ? */ | |
| 11028 if (l_tccp->csty & J2K_CCP_CSTY_PRT) { | |
| 11029 if (*p_header_size < l_tccp->numresolutions) { | |
| 11030 opj_event_msg(p_manager, EVT_ERROR, "Error reading SPCod SPCoc element\n"); | |
| 11031 return OPJ_FALSE; | |
| 11032 } | |
| 11033 | |
| 11034 /* SPcod (I_i) / SPcoc (F_i) */ | |
| 11035 for (i = 0; i < l_tccp->numresolutions; ++i) { | |
| 11036 opj_read_bytes(l_current_ptr, &l_tmp, 1); | |
| 11037 ++l_current_ptr; | |
| 11038 /* Precinct exponent 0 is only allowed for lowest resolution level (Table A.21) */ | |
| 11039 if ((i != 0) && (((l_tmp & 0xf) == 0) || ((l_tmp >> 4) == 0))) { | |
| 11040 opj_event_msg(p_manager, EVT_ERROR, "Invalid precinct size\n"); | |
| 11041 return OPJ_FALSE; | |
| 11042 } | |
| 11043 l_tccp->prcw[i] = l_tmp & 0xf; | |
| 11044 l_tccp->prch[i] = l_tmp >> 4; | |
| 11045 } | |
| 11046 | |
| 11047 *p_header_size = *p_header_size - l_tccp->numresolutions; | |
| 11048 } else { | |
| 11049 /* set default size for the precinct width and height */ | |
| 11050 for (i = 0; i < l_tccp->numresolutions; ++i) { | |
| 11051 l_tccp->prcw[i] = 15; | |
| 11052 l_tccp->prch[i] = 15; | |
| 11053 } | |
| 11054 } | |
| 11055 | |
| 11056 #ifdef WIP_REMOVE_MSD | |
| 11057 /* INDEX >> */ | |
| 11058 if (p_j2k->cstr_info && compno == 0) { | |
| 11059 OPJ_UINT32 l_data_size = l_tccp->numresolutions * sizeof(OPJ_UINT32); | |
| 11060 | |
| 11061 p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].tccp_info[compno].cblkh = | |
| 11062 l_tccp->cblkh; | |
| 11063 p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].tccp_info[compno].cblkw = | |
| 11064 l_tccp->cblkw; | |
| 11065 p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].tccp_info[compno].numresolutions | |
| 11066 = l_tccp->numresolutions; | |
| 11067 p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].tccp_info[compno].cblksty = | |
| 11068 l_tccp->cblksty; | |
| 11069 p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].tccp_info[compno].qmfbid = | |
| 11070 l_tccp->qmfbid; | |
| 11071 | |
| 11072 memcpy(p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].pdx, l_tccp->prcw, | |
| 11073 l_data_size); | |
| 11074 memcpy(p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].pdy, l_tccp->prch, | |
| 11075 l_data_size); | |
| 11076 } | |
| 11077 /* << INDEX */ | |
| 11078 #endif | |
| 11079 | |
| 11080 return OPJ_TRUE; | |
| 11081 } | |
| 11082 | |
| 11083 static void opj_j2k_copy_tile_component_parameters(opj_j2k_t *p_j2k) | |
| 11084 { | |
| 11085 /* loop */ | |
| 11086 OPJ_UINT32 i; | |
| 11087 opj_cp_t *l_cp = NULL; | |
| 11088 opj_tcp_t *l_tcp = NULL; | |
| 11089 opj_tccp_t *l_ref_tccp = NULL, *l_copied_tccp = NULL; | |
| 11090 OPJ_UINT32 l_prc_size; | |
| 11091 | |
| 11092 /* preconditions */ | |
| 11093 assert(p_j2k != 00); | |
| 11094 | |
| 11095 l_cp = &(p_j2k->m_cp); | |
| 11096 l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH) | |
| 11097 ? | |
| 11098 &l_cp->tcps[p_j2k->m_current_tile_number] : | |
| 11099 p_j2k->m_specific_param.m_decoder.m_default_tcp; | |
| 11100 | |
| 11101 l_ref_tccp = &l_tcp->tccps[0]; | |
| 11102 l_copied_tccp = l_ref_tccp + 1; | |
| 11103 l_prc_size = l_ref_tccp->numresolutions * (OPJ_UINT32)sizeof(OPJ_UINT32); | |
| 11104 | |
| 11105 for (i = 1; i < p_j2k->m_private_image->numcomps; ++i) { | |
| 11106 l_copied_tccp->numresolutions = l_ref_tccp->numresolutions; | |
| 11107 l_copied_tccp->cblkw = l_ref_tccp->cblkw; | |
| 11108 l_copied_tccp->cblkh = l_ref_tccp->cblkh; | |
| 11109 l_copied_tccp->cblksty = l_ref_tccp->cblksty; | |
| 11110 l_copied_tccp->qmfbid = l_ref_tccp->qmfbid; | |
| 11111 memcpy(l_copied_tccp->prcw, l_ref_tccp->prcw, l_prc_size); | |
| 11112 memcpy(l_copied_tccp->prch, l_ref_tccp->prch, l_prc_size); | |
| 11113 ++l_copied_tccp; | |
| 11114 } | |
| 11115 } | |
| 11116 | |
| 11117 static OPJ_UINT32 opj_j2k_get_SQcd_SQcc_size(opj_j2k_t *p_j2k, | |
| 11118 OPJ_UINT32 p_tile_no, | |
| 11119 OPJ_UINT32 p_comp_no) | |
| 11120 { | |
| 11121 OPJ_UINT32 l_num_bands; | |
| 11122 | |
| 11123 opj_cp_t *l_cp = 00; | |
| 11124 opj_tcp_t *l_tcp = 00; | |
| 11125 opj_tccp_t *l_tccp = 00; | |
| 11126 | |
| 11127 /* preconditions */ | |
| 11128 assert(p_j2k != 00); | |
| 11129 | |
| 11130 l_cp = &(p_j2k->m_cp); | |
| 11131 l_tcp = &l_cp->tcps[p_tile_no]; | |
| 11132 l_tccp = &l_tcp->tccps[p_comp_no]; | |
| 11133 | |
| 11134 /* preconditions again */ | |
| 11135 assert(p_tile_no < l_cp->tw * l_cp->th); | |
| 11136 assert(p_comp_no < p_j2k->m_private_image->numcomps); | |
| 11137 | |
| 11138 l_num_bands = (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? 1 : | |
| 11139 (l_tccp->numresolutions * 3 - 2); | |
| 11140 | |
| 11141 if (l_tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) { | |
| 11142 return 1 + l_num_bands; | |
| 11143 } else { | |
| 11144 return 1 + 2 * l_num_bands; | |
| 11145 } | |
| 11146 } | |
| 11147 | |
| 11148 static OPJ_BOOL opj_j2k_compare_SQcd_SQcc(opj_j2k_t *p_j2k, | |
| 11149 OPJ_UINT32 p_tile_no, OPJ_UINT32 p_first_comp_no, OPJ_UINT32 p_second_comp_no) | |
| 11150 { | |
| 11151 opj_cp_t *l_cp = NULL; | |
| 11152 opj_tcp_t *l_tcp = NULL; | |
| 11153 opj_tccp_t *l_tccp0 = NULL; | |
| 11154 opj_tccp_t *l_tccp1 = NULL; | |
| 11155 OPJ_UINT32 l_band_no, l_num_bands; | |
| 11156 | |
| 11157 /* preconditions */ | |
| 11158 assert(p_j2k != 00); | |
| 11159 | |
| 11160 l_cp = &(p_j2k->m_cp); | |
| 11161 l_tcp = &l_cp->tcps[p_tile_no]; | |
| 11162 l_tccp0 = &l_tcp->tccps[p_first_comp_no]; | |
| 11163 l_tccp1 = &l_tcp->tccps[p_second_comp_no]; | |
| 11164 | |
| 11165 if (l_tccp0->qntsty != l_tccp1->qntsty) { | |
| 11166 return OPJ_FALSE; | |
| 11167 } | |
| 11168 if (l_tccp0->numgbits != l_tccp1->numgbits) { | |
| 11169 return OPJ_FALSE; | |
| 11170 } | |
| 11171 if (l_tccp0->qntsty == J2K_CCP_QNTSTY_SIQNT) { | |
| 11172 l_num_bands = 1U; | |
| 11173 } else { | |
| 11174 l_num_bands = l_tccp0->numresolutions * 3U - 2U; | |
| 11175 if (l_num_bands != (l_tccp1->numresolutions * 3U - 2U)) { | |
| 11176 return OPJ_FALSE; | |
| 11177 } | |
| 11178 } | |
| 11179 | |
| 11180 for (l_band_no = 0; l_band_no < l_num_bands; ++l_band_no) { | |
| 11181 if (l_tccp0->stepsizes[l_band_no].expn != l_tccp1->stepsizes[l_band_no].expn) { | |
| 11182 return OPJ_FALSE; | |
| 11183 } | |
| 11184 } | |
| 11185 if (l_tccp0->qntsty != J2K_CCP_QNTSTY_NOQNT) { | |
| 11186 for (l_band_no = 0; l_band_no < l_num_bands; ++l_band_no) { | |
| 11187 if (l_tccp0->stepsizes[l_band_no].mant != l_tccp1->stepsizes[l_band_no].mant) { | |
| 11188 return OPJ_FALSE; | |
| 11189 } | |
| 11190 } | |
| 11191 } | |
| 11192 return OPJ_TRUE; | |
| 11193 } | |
| 11194 | |
| 11195 | |
| 11196 static OPJ_BOOL opj_j2k_write_SQcd_SQcc(opj_j2k_t *p_j2k, | |
| 11197 OPJ_UINT32 p_tile_no, | |
| 11198 OPJ_UINT32 p_comp_no, | |
| 11199 OPJ_BYTE * p_data, | |
| 11200 OPJ_UINT32 * p_header_size, | |
| 11201 struct opj_event_mgr * p_manager) | |
| 11202 { | |
| 11203 OPJ_UINT32 l_header_size; | |
| 11204 OPJ_UINT32 l_band_no, l_num_bands; | |
| 11205 OPJ_UINT32 l_expn, l_mant; | |
| 11206 | |
| 11207 opj_cp_t *l_cp = 00; | |
| 11208 opj_tcp_t *l_tcp = 00; | |
| 11209 opj_tccp_t *l_tccp = 00; | |
| 11210 | |
| 11211 /* preconditions */ | |
| 11212 assert(p_j2k != 00); | |
| 11213 assert(p_header_size != 00); | |
| 11214 assert(p_manager != 00); | |
| 11215 assert(p_data != 00); | |
| 11216 | |
| 11217 l_cp = &(p_j2k->m_cp); | |
| 11218 l_tcp = &l_cp->tcps[p_tile_no]; | |
| 11219 l_tccp = &l_tcp->tccps[p_comp_no]; | |
| 11220 | |
| 11221 /* preconditions again */ | |
| 11222 assert(p_tile_no < l_cp->tw * l_cp->th); | |
| 11223 assert(p_comp_no < p_j2k->m_private_image->numcomps); | |
| 11224 | |
| 11225 l_num_bands = (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? 1 : | |
| 11226 (l_tccp->numresolutions * 3 - 2); | |
| 11227 | |
| 11228 if (l_tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) { | |
| 11229 l_header_size = 1 + l_num_bands; | |
| 11230 | |
| 11231 if (*p_header_size < l_header_size) { | |
| 11232 opj_event_msg(p_manager, EVT_ERROR, "Error writing SQcd SQcc element\n"); | |
| 11233 return OPJ_FALSE; | |
| 11234 } | |
| 11235 | |
| 11236 opj_write_bytes(p_data, l_tccp->qntsty + (l_tccp->numgbits << 5), | |
| 11237 1); /* Sqcx */ | |
| 11238 ++p_data; | |
| 11239 | |
| 11240 for (l_band_no = 0; l_band_no < l_num_bands; ++l_band_no) { | |
| 11241 l_expn = (OPJ_UINT32)l_tccp->stepsizes[l_band_no].expn; | |
| 11242 opj_write_bytes(p_data, l_expn << 3, 1); /* SPqcx_i */ | |
| 11243 ++p_data; | |
| 11244 } | |
| 11245 } else { | |
| 11246 l_header_size = 1 + 2 * l_num_bands; | |
| 11247 | |
| 11248 if (*p_header_size < l_header_size) { | |
| 11249 opj_event_msg(p_manager, EVT_ERROR, "Error writing SQcd SQcc element\n"); | |
| 11250 return OPJ_FALSE; | |
| 11251 } | |
| 11252 | |
| 11253 opj_write_bytes(p_data, l_tccp->qntsty + (l_tccp->numgbits << 5), | |
| 11254 1); /* Sqcx */ | |
| 11255 ++p_data; | |
| 11256 | |
| 11257 for (l_band_no = 0; l_band_no < l_num_bands; ++l_band_no) { | |
| 11258 l_expn = (OPJ_UINT32)l_tccp->stepsizes[l_band_no].expn; | |
| 11259 l_mant = (OPJ_UINT32)l_tccp->stepsizes[l_band_no].mant; | |
| 11260 | |
| 11261 opj_write_bytes(p_data, (l_expn << 11) + l_mant, 2); /* SPqcx_i */ | |
| 11262 p_data += 2; | |
| 11263 } | |
| 11264 } | |
| 11265 | |
| 11266 *p_header_size = *p_header_size - l_header_size; | |
| 11267 | |
| 11268 return OPJ_TRUE; | |
| 11269 } | |
| 11270 | |
| 11271 static OPJ_BOOL opj_j2k_read_SQcd_SQcc(opj_j2k_t *p_j2k, | |
| 11272 OPJ_UINT32 p_comp_no, | |
| 11273 OPJ_BYTE* p_header_data, | |
| 11274 OPJ_UINT32 * p_header_size, | |
| 11275 opj_event_mgr_t * p_manager | |
| 11276 ) | |
| 11277 { | |
| 11278 /* loop*/ | |
| 11279 OPJ_UINT32 l_band_no; | |
| 11280 opj_cp_t *l_cp = 00; | |
| 11281 opj_tcp_t *l_tcp = 00; | |
| 11282 opj_tccp_t *l_tccp = 00; | |
| 11283 OPJ_BYTE * l_current_ptr = 00; | |
| 11284 OPJ_UINT32 l_tmp, l_num_band; | |
| 11285 | |
| 11286 /* preconditions*/ | |
| 11287 assert(p_j2k != 00); | |
| 11288 assert(p_manager != 00); | |
| 11289 assert(p_header_data != 00); | |
| 11290 | |
| 11291 l_cp = &(p_j2k->m_cp); | |
| 11292 /* come from tile part header or main header ?*/ | |
| 11293 l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH) | |
| 11294 ? | |
| 11295 &l_cp->tcps[p_j2k->m_current_tile_number] : | |
| 11296 p_j2k->m_specific_param.m_decoder.m_default_tcp; | |
| 11297 | |
| 11298 /* precondition again*/ | |
| 11299 assert(p_comp_no < p_j2k->m_private_image->numcomps); | |
| 11300 | |
| 11301 l_tccp = &l_tcp->tccps[p_comp_no]; | |
| 11302 l_current_ptr = p_header_data; | |
| 11303 | |
| 11304 if (*p_header_size < 1) { | |
| 11305 opj_event_msg(p_manager, EVT_ERROR, "Error reading SQcd or SQcc element\n"); | |
| 11306 return OPJ_FALSE; | |
| 11307 } | |
| 11308 *p_header_size -= 1; | |
| 11309 | |
| 11310 opj_read_bytes(l_current_ptr, &l_tmp, 1); /* Sqcx */ | |
| 11311 ++l_current_ptr; | |
| 11312 | |
| 11313 l_tccp->qntsty = l_tmp & 0x1f; | |
| 11314 l_tccp->numgbits = l_tmp >> 5; | |
| 11315 if (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) { | |
| 11316 l_num_band = 1; | |
| 11317 } else { | |
| 11318 l_num_band = (l_tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) ? | |
| 11319 (*p_header_size) : | |
| 11320 (*p_header_size) / 2; | |
| 11321 | |
| 11322 if (l_num_band > OPJ_J2K_MAXBANDS) { | |
| 11323 opj_event_msg(p_manager, EVT_WARNING, | |
| 11324 "While reading CCP_QNTSTY element inside QCD or QCC marker segment, " | |
| 11325 "number of subbands (%d) is greater to OPJ_J2K_MAXBANDS (%d). So we limit the number of elements stored to " | |
| 11326 "OPJ_J2K_MAXBANDS (%d) and skip the rest. \n", l_num_band, OPJ_J2K_MAXBANDS, | |
| 11327 OPJ_J2K_MAXBANDS); | |
| 11328 /*return OPJ_FALSE;*/ | |
| 11329 } | |
| 11330 } | |
| 11331 | |
| 11332 #ifdef USE_JPWL | |
| 11333 if (l_cp->correct) { | |
| 11334 | |
| 11335 /* if JPWL is on, we check whether there are too many subbands */ | |
| 11336 if (/*(l_num_band < 0) ||*/ (l_num_band >= OPJ_J2K_MAXBANDS)) { | |
| 11337 opj_event_msg(p_manager, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR, | |
| 11338 "JPWL: bad number of subbands in Sqcx (%d)\n", | |
| 11339 l_num_band); | |
| 11340 if (!JPWL_ASSUME) { | |
| 11341 opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n"); | |
| 11342 return OPJ_FALSE; | |
| 11343 } | |
| 11344 /* we try to correct */ | |
| 11345 l_num_band = 1; | |
| 11346 opj_event_msg(p_manager, EVT_WARNING, "- trying to adjust them\n" | |
| 11347 "- setting number of bands to %d => HYPOTHESIS!!!\n", | |
| 11348 l_num_band); | |
| 11349 }; | |
| 11350 | |
| 11351 }; | |
| 11352 #endif /* USE_JPWL */ | |
| 11353 | |
| 11354 if (l_tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) { | |
| 11355 for (l_band_no = 0; l_band_no < l_num_band; l_band_no++) { | |
| 11356 opj_read_bytes(l_current_ptr, &l_tmp, 1); /* SPqcx_i */ | |
| 11357 ++l_current_ptr; | |
| 11358 if (l_band_no < OPJ_J2K_MAXBANDS) { | |
| 11359 l_tccp->stepsizes[l_band_no].expn = (OPJ_INT32)(l_tmp >> 3); | |
| 11360 l_tccp->stepsizes[l_band_no].mant = 0; | |
| 11361 } | |
| 11362 } | |
| 11363 | |
| 11364 if (*p_header_size < l_num_band) { | |
| 11365 return OPJ_FALSE; | |
| 11366 } | |
| 11367 *p_header_size = *p_header_size - l_num_band; | |
| 11368 } else { | |
| 11369 for (l_band_no = 0; l_band_no < l_num_band; l_band_no++) { | |
| 11370 opj_read_bytes(l_current_ptr, &l_tmp, 2); /* SPqcx_i */ | |
| 11371 l_current_ptr += 2; | |
| 11372 if (l_band_no < OPJ_J2K_MAXBANDS) { | |
| 11373 l_tccp->stepsizes[l_band_no].expn = (OPJ_INT32)(l_tmp >> 11); | |
| 11374 l_tccp->stepsizes[l_band_no].mant = l_tmp & 0x7ff; | |
| 11375 } | |
| 11376 } | |
| 11377 | |
| 11378 if (*p_header_size < 2 * l_num_band) { | |
| 11379 return OPJ_FALSE; | |
| 11380 } | |
| 11381 *p_header_size = *p_header_size - 2 * l_num_band; | |
| 11382 } | |
| 11383 | |
| 11384 /* Add Antonin : if scalar_derived -> compute other stepsizes */ | |
| 11385 if (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) { | |
| 11386 for (l_band_no = 1; l_band_no < OPJ_J2K_MAXBANDS; l_band_no++) { | |
| 11387 l_tccp->stepsizes[l_band_no].expn = | |
| 11388 ((OPJ_INT32)(l_tccp->stepsizes[0].expn) - (OPJ_INT32)((l_band_no - 1) / 3) > 0) | |
| 11389 ? | |
| 11390 (OPJ_INT32)(l_tccp->stepsizes[0].expn) - (OPJ_INT32)((l_band_no - 1) / 3) : 0; | |
| 11391 l_tccp->stepsizes[l_band_no].mant = l_tccp->stepsizes[0].mant; | |
| 11392 } | |
| 11393 } | |
| 11394 | |
| 11395 return OPJ_TRUE; | |
| 11396 } | |
| 11397 | |
| 11398 static void opj_j2k_copy_tile_quantization_parameters(opj_j2k_t *p_j2k) | |
| 11399 { | |
| 11400 OPJ_UINT32 i; | |
| 11401 opj_cp_t *l_cp = NULL; | |
| 11402 opj_tcp_t *l_tcp = NULL; | |
| 11403 opj_tccp_t *l_ref_tccp = NULL; | |
| 11404 opj_tccp_t *l_copied_tccp = NULL; | |
| 11405 OPJ_UINT32 l_size; | |
| 11406 | |
| 11407 /* preconditions */ | |
| 11408 assert(p_j2k != 00); | |
| 11409 | |
| 11410 l_cp = &(p_j2k->m_cp); | |
| 11411 l_tcp = p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH ? | |
| 11412 &l_cp->tcps[p_j2k->m_current_tile_number] : | |
| 11413 p_j2k->m_specific_param.m_decoder.m_default_tcp; | |
| 11414 | |
| 11415 l_ref_tccp = &l_tcp->tccps[0]; | |
| 11416 l_copied_tccp = l_ref_tccp + 1; | |
| 11417 l_size = OPJ_J2K_MAXBANDS * sizeof(opj_stepsize_t); | |
| 11418 | |
| 11419 for (i = 1; i < p_j2k->m_private_image->numcomps; ++i) { | |
| 11420 l_copied_tccp->qntsty = l_ref_tccp->qntsty; | |
| 11421 l_copied_tccp->numgbits = l_ref_tccp->numgbits; | |
| 11422 memcpy(l_copied_tccp->stepsizes, l_ref_tccp->stepsizes, l_size); | |
| 11423 ++l_copied_tccp; | |
| 11424 } | |
| 11425 } | |
| 11426 | |
| 11427 static void opj_j2k_dump_tile_info(opj_tcp_t * l_default_tile, | |
| 11428 OPJ_INT32 numcomps, FILE* out_stream) | |
| 11429 { | |
| 11430 if (l_default_tile) { | |
| 11431 OPJ_INT32 compno; | |
| 11432 | |
| 11433 fprintf(out_stream, "\t default tile {\n"); | |
| 11434 fprintf(out_stream, "\t\t csty=%#x\n", l_default_tile->csty); | |
| 11435 fprintf(out_stream, "\t\t prg=%#x\n", l_default_tile->prg); | |
| 11436 fprintf(out_stream, "\t\t numlayers=%d\n", l_default_tile->numlayers); | |
| 11437 fprintf(out_stream, "\t\t mct=%x\n", l_default_tile->mct); | |
| 11438 | |
| 11439 for (compno = 0; compno < numcomps; compno++) { | |
| 11440 opj_tccp_t *l_tccp = &(l_default_tile->tccps[compno]); | |
| 11441 OPJ_UINT32 resno; | |
| 11442 OPJ_INT32 bandno, numbands; | |
| 11443 | |
| 11444 /* coding style*/ | |
| 11445 fprintf(out_stream, "\t\t comp %d {\n", compno); | |
| 11446 fprintf(out_stream, "\t\t\t csty=%#x\n", l_tccp->csty); | |
| 11447 fprintf(out_stream, "\t\t\t numresolutions=%d\n", l_tccp->numresolutions); | |
| 11448 fprintf(out_stream, "\t\t\t cblkw=2^%d\n", l_tccp->cblkw); | |
| 11449 fprintf(out_stream, "\t\t\t cblkh=2^%d\n", l_tccp->cblkh); | |
| 11450 fprintf(out_stream, "\t\t\t cblksty=%#x\n", l_tccp->cblksty); | |
| 11451 fprintf(out_stream, "\t\t\t qmfbid=%d\n", l_tccp->qmfbid); | |
| 11452 | |
| 11453 fprintf(out_stream, "\t\t\t preccintsize (w,h)="); | |
| 11454 for (resno = 0; resno < l_tccp->numresolutions; resno++) { | |
| 11455 fprintf(out_stream, "(%d,%d) ", l_tccp->prcw[resno], l_tccp->prch[resno]); | |
| 11456 } | |
| 11457 fprintf(out_stream, "\n"); | |
| 11458 | |
| 11459 /* quantization style*/ | |
| 11460 fprintf(out_stream, "\t\t\t qntsty=%d\n", l_tccp->qntsty); | |
| 11461 fprintf(out_stream, "\t\t\t numgbits=%d\n", l_tccp->numgbits); | |
| 11462 fprintf(out_stream, "\t\t\t stepsizes (m,e)="); | |
| 11463 numbands = (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? 1 : | |
| 11464 (OPJ_INT32)l_tccp->numresolutions * 3 - 2; | |
| 11465 for (bandno = 0; bandno < numbands; bandno++) { | |
| 11466 fprintf(out_stream, "(%d,%d) ", l_tccp->stepsizes[bandno].mant, | |
| 11467 l_tccp->stepsizes[bandno].expn); | |
| 11468 } | |
| 11469 fprintf(out_stream, "\n"); | |
| 11470 | |
| 11471 /* RGN value*/ | |
| 11472 fprintf(out_stream, "\t\t\t roishift=%d\n", l_tccp->roishift); | |
| 11473 | |
| 11474 fprintf(out_stream, "\t\t }\n"); | |
| 11475 } /*end of component of default tile*/ | |
| 11476 fprintf(out_stream, "\t }\n"); /*end of default tile*/ | |
| 11477 } | |
| 11478 } | |
| 11479 | |
| 11480 void j2k_dump(opj_j2k_t* p_j2k, OPJ_INT32 flag, FILE* out_stream) | |
| 11481 { | |
| 11482 /* Check if the flag is compatible with j2k file*/ | |
| 11483 if ((flag & OPJ_JP2_INFO) || (flag & OPJ_JP2_IND)) { | |
| 11484 fprintf(out_stream, "Wrong flag\n"); | |
| 11485 return; | |
| 11486 } | |
| 11487 | |
| 11488 /* Dump the image_header */ | |
| 11489 if (flag & OPJ_IMG_INFO) { | |
| 11490 if (p_j2k->m_private_image) { | |
| 11491 j2k_dump_image_header(p_j2k->m_private_image, 0, out_stream); | |
| 11492 } | |
| 11493 } | |
| 11494 | |
| 11495 /* Dump the codestream info from main header */ | |
| 11496 if (flag & OPJ_J2K_MH_INFO) { | |
| 11497 if (p_j2k->m_private_image) { | |
| 11498 opj_j2k_dump_MH_info(p_j2k, out_stream); | |
| 11499 } | |
| 11500 } | |
| 11501 /* Dump all tile/codestream info */ | |
| 11502 if (flag & OPJ_J2K_TCH_INFO) { | |
| 11503 OPJ_UINT32 l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw; | |
| 11504 OPJ_UINT32 i; | |
| 11505 opj_tcp_t * l_tcp = p_j2k->m_cp.tcps; | |
| 11506 if (p_j2k->m_private_image) { | |
| 11507 for (i = 0; i < l_nb_tiles; ++i) { | |
| 11508 opj_j2k_dump_tile_info(l_tcp, (OPJ_INT32)p_j2k->m_private_image->numcomps, | |
| 11509 out_stream); | |
| 11510 ++l_tcp; | |
| 11511 } | |
| 11512 } | |
| 11513 } | |
| 11514 | |
| 11515 /* Dump the codestream info of the current tile */ | |
| 11516 if (flag & OPJ_J2K_TH_INFO) { | |
| 11517 | |
| 11518 } | |
| 11519 | |
| 11520 /* Dump the codestream index from main header */ | |
| 11521 if (flag & OPJ_J2K_MH_IND) { | |
| 11522 opj_j2k_dump_MH_index(p_j2k, out_stream); | |
| 11523 } | |
| 11524 | |
| 11525 /* Dump the codestream index of the current tile */ | |
| 11526 if (flag & OPJ_J2K_TH_IND) { | |
| 11527 | |
| 11528 } | |
| 11529 | |
| 11530 } | |
| 11531 | |
| 11532 static void opj_j2k_dump_MH_index(opj_j2k_t* p_j2k, FILE* out_stream) | |
| 11533 { | |
| 11534 opj_codestream_index_t* cstr_index = p_j2k->cstr_index; | |
| 11535 OPJ_UINT32 it_marker, it_tile, it_tile_part; | |
| 11536 | |
| 11537 fprintf(out_stream, "Codestream index from main header: {\n"); | |
| 11538 | |
| 11539 fprintf(out_stream, "\t Main header start position=%" PRIi64 "\n" | |
| 11540 "\t Main header end position=%" PRIi64 "\n", | |
| 11541 cstr_index->main_head_start, cstr_index->main_head_end); | |
| 11542 | |
| 11543 fprintf(out_stream, "\t Marker list: {\n"); | |
| 11544 | |
| 11545 if (cstr_index->marker) { | |
| 11546 for (it_marker = 0; it_marker < cstr_index->marknum ; it_marker++) { | |
| 11547 fprintf(out_stream, "\t\t type=%#x, pos=%" PRIi64 ", len=%d\n", | |
| 11548 cstr_index->marker[it_marker].type, | |
| 11549 cstr_index->marker[it_marker].pos, | |
| 11550 cstr_index->marker[it_marker].len); | |
| 11551 } | |
| 11552 } | |
| 11553 | |
| 11554 fprintf(out_stream, "\t }\n"); | |
| 11555 | |
| 11556 if (cstr_index->tile_index) { | |
| 11557 | |
| 11558 /* Simple test to avoid to write empty information*/ | |
| 11559 OPJ_UINT32 l_acc_nb_of_tile_part = 0; | |
| 11560 for (it_tile = 0; it_tile < cstr_index->nb_of_tiles ; it_tile++) { | |
| 11561 l_acc_nb_of_tile_part += cstr_index->tile_index[it_tile].nb_tps; | |
| 11562 | |
| 11563 /* To avoid regenerating expected opj_dump results from the test */ | |
| 11564 /* suite when there is a TLM marker present */ | |
| 11565 if (cstr_index->tile_index[it_tile].nb_tps && | |
| 11566 cstr_index->tile_index[it_tile].tp_index && | |
| 11567 cstr_index->tile_index[it_tile].tp_index[0].start_pos > 0 && | |
| 11568 cstr_index->tile_index[it_tile].tp_index[0].end_header == 0 && | |
| 11569 getenv("OJP_DO_NOT_DISPLAY_TILE_INDEX_IF_TLM") != NULL) { | |
| 11570 l_acc_nb_of_tile_part = 0; | |
| 11571 break; | |
| 11572 } | |
| 11573 } | |
| 11574 | |
| 11575 if (l_acc_nb_of_tile_part) { | |
| 11576 fprintf(out_stream, "\t Tile index: {\n"); | |
| 11577 | |
| 11578 for (it_tile = 0; it_tile < cstr_index->nb_of_tiles ; it_tile++) { | |
| 11579 OPJ_UINT32 nb_of_tile_part = cstr_index->tile_index[it_tile].nb_tps; | |
| 11580 | |
| 11581 fprintf(out_stream, "\t\t nb of tile-part in tile [%d]=%d\n", it_tile, | |
| 11582 nb_of_tile_part); | |
| 11583 | |
| 11584 if (cstr_index->tile_index[it_tile].tp_index) { | |
| 11585 for (it_tile_part = 0; it_tile_part < nb_of_tile_part; it_tile_part++) { | |
| 11586 fprintf(out_stream, "\t\t\t tile-part[%d]: star_pos=%" PRIi64 ", end_header=%" | |
| 11587 PRIi64 ", end_pos=%" PRIi64 ".\n", | |
| 11588 it_tile_part, | |
| 11589 cstr_index->tile_index[it_tile].tp_index[it_tile_part].start_pos, | |
| 11590 cstr_index->tile_index[it_tile].tp_index[it_tile_part].end_header, | |
| 11591 cstr_index->tile_index[it_tile].tp_index[it_tile_part].end_pos); | |
| 11592 } | |
| 11593 } | |
| 11594 | |
| 11595 if (cstr_index->tile_index[it_tile].marker) { | |
| 11596 for (it_marker = 0; it_marker < cstr_index->tile_index[it_tile].marknum ; | |
| 11597 it_marker++) { | |
| 11598 fprintf(out_stream, "\t\t type=%#x, pos=%" PRIi64 ", len=%d\n", | |
| 11599 cstr_index->tile_index[it_tile].marker[it_marker].type, | |
| 11600 cstr_index->tile_index[it_tile].marker[it_marker].pos, | |
| 11601 cstr_index->tile_index[it_tile].marker[it_marker].len); | |
| 11602 } | |
| 11603 } | |
| 11604 } | |
| 11605 fprintf(out_stream, "\t }\n"); | |
| 11606 } | |
| 11607 } | |
| 11608 | |
| 11609 fprintf(out_stream, "}\n"); | |
| 11610 | |
| 11611 } | |
| 11612 | |
| 11613 | |
| 11614 static void opj_j2k_dump_MH_info(opj_j2k_t* p_j2k, FILE* out_stream) | |
| 11615 { | |
| 11616 | |
| 11617 fprintf(out_stream, "Codestream info from main header: {\n"); | |
| 11618 | |
| 11619 fprintf(out_stream, "\t tx0=%" PRIu32 ", ty0=%" PRIu32 "\n", p_j2k->m_cp.tx0, | |
| 11620 p_j2k->m_cp.ty0); | |
| 11621 fprintf(out_stream, "\t tdx=%" PRIu32 ", tdy=%" PRIu32 "\n", p_j2k->m_cp.tdx, | |
| 11622 p_j2k->m_cp.tdy); | |
| 11623 fprintf(out_stream, "\t tw=%" PRIu32 ", th=%" PRIu32 "\n", p_j2k->m_cp.tw, | |
| 11624 p_j2k->m_cp.th); | |
| 11625 opj_j2k_dump_tile_info(p_j2k->m_specific_param.m_decoder.m_default_tcp, | |
| 11626 (OPJ_INT32)p_j2k->m_private_image->numcomps, out_stream); | |
| 11627 fprintf(out_stream, "}\n"); | |
| 11628 } | |
| 11629 | |
| 11630 void j2k_dump_image_header(opj_image_t* img_header, OPJ_BOOL dev_dump_flag, | |
| 11631 FILE* out_stream) | |
| 11632 { | |
| 11633 char tab[2]; | |
| 11634 | |
| 11635 if (dev_dump_flag) { | |
| 11636 fprintf(stdout, "[DEV] Dump an image_header struct {\n"); | |
| 11637 tab[0] = '\0'; | |
| 11638 } else { | |
| 11639 fprintf(out_stream, "Image info {\n"); | |
| 11640 tab[0] = '\t'; | |
| 11641 tab[1] = '\0'; | |
| 11642 } | |
| 11643 | |
| 11644 fprintf(out_stream, "%s x0=%d, y0=%d\n", tab, img_header->x0, img_header->y0); | |
| 11645 fprintf(out_stream, "%s x1=%d, y1=%d\n", tab, img_header->x1, | |
| 11646 img_header->y1); | |
| 11647 fprintf(out_stream, "%s numcomps=%d\n", tab, img_header->numcomps); | |
| 11648 | |
| 11649 if (img_header->comps) { | |
| 11650 OPJ_UINT32 compno; | |
| 11651 for (compno = 0; compno < img_header->numcomps; compno++) { | |
| 11652 fprintf(out_stream, "%s\t component %d {\n", tab, compno); | |
| 11653 j2k_dump_image_comp_header(&(img_header->comps[compno]), dev_dump_flag, | |
| 11654 out_stream); | |
| 11655 fprintf(out_stream, "%s}\n", tab); | |
| 11656 } | |
| 11657 } | |
| 11658 | |
| 11659 fprintf(out_stream, "}\n"); | |
| 11660 } | |
| 11661 | |
| 11662 void j2k_dump_image_comp_header(opj_image_comp_t* comp_header, | |
| 11663 OPJ_BOOL dev_dump_flag, FILE* out_stream) | |
| 11664 { | |
| 11665 char tab[3]; | |
| 11666 | |
| 11667 if (dev_dump_flag) { | |
| 11668 fprintf(stdout, "[DEV] Dump an image_comp_header struct {\n"); | |
| 11669 tab[0] = '\0'; | |
| 11670 } else { | |
| 11671 tab[0] = '\t'; | |
| 11672 tab[1] = '\t'; | |
| 11673 tab[2] = '\0'; | |
| 11674 } | |
| 11675 | |
| 11676 fprintf(out_stream, "%s dx=%d, dy=%d\n", tab, comp_header->dx, comp_header->dy); | |
| 11677 fprintf(out_stream, "%s prec=%d\n", tab, comp_header->prec); | |
| 11678 fprintf(out_stream, "%s sgnd=%d\n", tab, comp_header->sgnd); | |
| 11679 | |
| 11680 if (dev_dump_flag) { | |
| 11681 fprintf(out_stream, "}\n"); | |
| 11682 } | |
| 11683 } | |
| 11684 | |
| 11685 opj_codestream_info_v2_t* j2k_get_cstr_info(opj_j2k_t* p_j2k) | |
| 11686 { | |
| 11687 OPJ_UINT32 compno; | |
| 11688 OPJ_UINT32 numcomps = p_j2k->m_private_image->numcomps; | |
| 11689 opj_tcp_t *l_default_tile; | |
| 11690 opj_codestream_info_v2_t* cstr_info = (opj_codestream_info_v2_t*) opj_calloc(1, | |
| 11691 sizeof(opj_codestream_info_v2_t)); | |
| 11692 if (!cstr_info) { | |
| 11693 return NULL; | |
| 11694 } | |
| 11695 | |
| 11696 cstr_info->nbcomps = p_j2k->m_private_image->numcomps; | |
| 11697 | |
| 11698 cstr_info->tx0 = p_j2k->m_cp.tx0; | |
| 11699 cstr_info->ty0 = p_j2k->m_cp.ty0; | |
| 11700 cstr_info->tdx = p_j2k->m_cp.tdx; | |
| 11701 cstr_info->tdy = p_j2k->m_cp.tdy; | |
| 11702 cstr_info->tw = p_j2k->m_cp.tw; | |
| 11703 cstr_info->th = p_j2k->m_cp.th; | |
| 11704 | |
| 11705 cstr_info->tile_info = NULL; /* Not fill from the main header*/ | |
| 11706 | |
| 11707 l_default_tile = p_j2k->m_specific_param.m_decoder.m_default_tcp; | |
| 11708 | |
| 11709 cstr_info->m_default_tile_info.csty = l_default_tile->csty; | |
| 11710 cstr_info->m_default_tile_info.prg = l_default_tile->prg; | |
| 11711 cstr_info->m_default_tile_info.numlayers = l_default_tile->numlayers; | |
| 11712 cstr_info->m_default_tile_info.mct = l_default_tile->mct; | |
| 11713 | |
| 11714 cstr_info->m_default_tile_info.tccp_info = (opj_tccp_info_t*) opj_calloc( | |
| 11715 cstr_info->nbcomps, sizeof(opj_tccp_info_t)); | |
| 11716 if (!cstr_info->m_default_tile_info.tccp_info) { | |
| 11717 opj_destroy_cstr_info(&cstr_info); | |
| 11718 return NULL; | |
| 11719 } | |
| 11720 | |
| 11721 for (compno = 0; compno < numcomps; compno++) { | |
| 11722 opj_tccp_t *l_tccp = &(l_default_tile->tccps[compno]); | |
| 11723 opj_tccp_info_t *l_tccp_info = & | |
| 11724 (cstr_info->m_default_tile_info.tccp_info[compno]); | |
| 11725 OPJ_INT32 bandno, numbands; | |
| 11726 | |
| 11727 /* coding style*/ | |
| 11728 l_tccp_info->csty = l_tccp->csty; | |
| 11729 l_tccp_info->numresolutions = l_tccp->numresolutions; | |
| 11730 l_tccp_info->cblkw = l_tccp->cblkw; | |
| 11731 l_tccp_info->cblkh = l_tccp->cblkh; | |
| 11732 l_tccp_info->cblksty = l_tccp->cblksty; | |
| 11733 l_tccp_info->qmfbid = l_tccp->qmfbid; | |
| 11734 if (l_tccp->numresolutions < OPJ_J2K_MAXRLVLS) { | |
| 11735 memcpy(l_tccp_info->prch, l_tccp->prch, l_tccp->numresolutions); | |
| 11736 memcpy(l_tccp_info->prcw, l_tccp->prcw, l_tccp->numresolutions); | |
| 11737 } | |
| 11738 | |
| 11739 /* quantization style*/ | |
| 11740 l_tccp_info->qntsty = l_tccp->qntsty; | |
| 11741 l_tccp_info->numgbits = l_tccp->numgbits; | |
| 11742 | |
| 11743 numbands = (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? 1 : | |
| 11744 (OPJ_INT32)l_tccp->numresolutions * 3 - 2; | |
| 11745 if (numbands < OPJ_J2K_MAXBANDS) { | |
| 11746 for (bandno = 0; bandno < numbands; bandno++) { | |
| 11747 l_tccp_info->stepsizes_mant[bandno] = (OPJ_UINT32) | |
| 11748 l_tccp->stepsizes[bandno].mant; | |
| 11749 l_tccp_info->stepsizes_expn[bandno] = (OPJ_UINT32) | |
| 11750 l_tccp->stepsizes[bandno].expn; | |
| 11751 } | |
| 11752 } | |
| 11753 | |
| 11754 /* RGN value*/ | |
| 11755 l_tccp_info->roishift = l_tccp->roishift; | |
| 11756 } | |
| 11757 | |
| 11758 return cstr_info; | |
| 11759 } | |
| 11760 | |
| 11761 opj_codestream_index_t* j2k_get_cstr_index(opj_j2k_t* p_j2k) | |
| 11762 { | |
| 11763 opj_codestream_index_t* l_cstr_index = (opj_codestream_index_t*) | |
| 11764 opj_calloc(1, sizeof(opj_codestream_index_t)); | |
| 11765 if (!l_cstr_index) { | |
| 11766 return NULL; | |
| 11767 } | |
| 11768 | |
| 11769 l_cstr_index->main_head_start = p_j2k->cstr_index->main_head_start; | |
| 11770 l_cstr_index->main_head_end = p_j2k->cstr_index->main_head_end; | |
| 11771 l_cstr_index->codestream_size = p_j2k->cstr_index->codestream_size; | |
| 11772 | |
| 11773 l_cstr_index->marknum = p_j2k->cstr_index->marknum; | |
| 11774 l_cstr_index->marker = (opj_marker_info_t*)opj_malloc(l_cstr_index->marknum * | |
| 11775 sizeof(opj_marker_info_t)); | |
| 11776 if (!l_cstr_index->marker) { | |
| 11777 opj_free(l_cstr_index); | |
| 11778 return NULL; | |
| 11779 } | |
| 11780 | |
| 11781 if (p_j2k->cstr_index->marker) { | |
| 11782 memcpy(l_cstr_index->marker, p_j2k->cstr_index->marker, | |
| 11783 l_cstr_index->marknum * sizeof(opj_marker_info_t)); | |
| 11784 } else { | |
| 11785 opj_free(l_cstr_index->marker); | |
| 11786 l_cstr_index->marker = NULL; | |
| 11787 } | |
| 11788 | |
| 11789 l_cstr_index->nb_of_tiles = p_j2k->cstr_index->nb_of_tiles; | |
| 11790 l_cstr_index->tile_index = (opj_tile_index_t*)opj_calloc( | |
| 11791 l_cstr_index->nb_of_tiles, sizeof(opj_tile_index_t)); | |
| 11792 if (!l_cstr_index->tile_index) { | |
| 11793 opj_free(l_cstr_index->marker); | |
| 11794 opj_free(l_cstr_index); | |
| 11795 return NULL; | |
| 11796 } | |
| 11797 | |
| 11798 if (!p_j2k->cstr_index->tile_index) { | |
| 11799 opj_free(l_cstr_index->tile_index); | |
| 11800 l_cstr_index->tile_index = NULL; | |
| 11801 } else { | |
| 11802 OPJ_UINT32 it_tile = 0; | |
| 11803 for (it_tile = 0; it_tile < l_cstr_index->nb_of_tiles; it_tile++) { | |
| 11804 | |
| 11805 /* Tile Marker*/ | |
| 11806 l_cstr_index->tile_index[it_tile].marknum = | |
| 11807 p_j2k->cstr_index->tile_index[it_tile].marknum; | |
| 11808 | |
| 11809 l_cstr_index->tile_index[it_tile].marker = | |
| 11810 (opj_marker_info_t*)opj_malloc(l_cstr_index->tile_index[it_tile].marknum * | |
| 11811 sizeof(opj_marker_info_t)); | |
| 11812 | |
| 11813 if (!l_cstr_index->tile_index[it_tile].marker) { | |
| 11814 OPJ_UINT32 it_tile_free; | |
| 11815 | |
| 11816 for (it_tile_free = 0; it_tile_free < it_tile; it_tile_free++) { | |
| 11817 opj_free(l_cstr_index->tile_index[it_tile_free].marker); | |
| 11818 } | |
| 11819 | |
| 11820 opj_free(l_cstr_index->tile_index); | |
| 11821 opj_free(l_cstr_index->marker); | |
| 11822 opj_free(l_cstr_index); | |
| 11823 return NULL; | |
| 11824 } | |
| 11825 | |
| 11826 if (p_j2k->cstr_index->tile_index[it_tile].marker) | |
| 11827 memcpy(l_cstr_index->tile_index[it_tile].marker, | |
| 11828 p_j2k->cstr_index->tile_index[it_tile].marker, | |
| 11829 l_cstr_index->tile_index[it_tile].marknum * sizeof(opj_marker_info_t)); | |
| 11830 else { | |
| 11831 opj_free(l_cstr_index->tile_index[it_tile].marker); | |
| 11832 l_cstr_index->tile_index[it_tile].marker = NULL; | |
| 11833 } | |
| 11834 | |
| 11835 /* Tile part index*/ | |
| 11836 l_cstr_index->tile_index[it_tile].nb_tps = | |
| 11837 p_j2k->cstr_index->tile_index[it_tile].nb_tps; | |
| 11838 | |
| 11839 l_cstr_index->tile_index[it_tile].tp_index = | |
| 11840 (opj_tp_index_t*)opj_malloc(l_cstr_index->tile_index[it_tile].nb_tps * sizeof( | |
| 11841 opj_tp_index_t)); | |
| 11842 | |
| 11843 if (!l_cstr_index->tile_index[it_tile].tp_index) { | |
| 11844 OPJ_UINT32 it_tile_free; | |
| 11845 | |
| 11846 for (it_tile_free = 0; it_tile_free < it_tile; it_tile_free++) { | |
| 11847 opj_free(l_cstr_index->tile_index[it_tile_free].marker); | |
| 11848 opj_free(l_cstr_index->tile_index[it_tile_free].tp_index); | |
| 11849 } | |
| 11850 | |
| 11851 opj_free(l_cstr_index->tile_index); | |
| 11852 opj_free(l_cstr_index->marker); | |
| 11853 opj_free(l_cstr_index); | |
| 11854 return NULL; | |
| 11855 } | |
| 11856 | |
| 11857 if (p_j2k->cstr_index->tile_index[it_tile].tp_index) { | |
| 11858 memcpy(l_cstr_index->tile_index[it_tile].tp_index, | |
| 11859 p_j2k->cstr_index->tile_index[it_tile].tp_index, | |
| 11860 l_cstr_index->tile_index[it_tile].nb_tps * sizeof(opj_tp_index_t)); | |
| 11861 } else { | |
| 11862 opj_free(l_cstr_index->tile_index[it_tile].tp_index); | |
| 11863 l_cstr_index->tile_index[it_tile].tp_index = NULL; | |
| 11864 } | |
| 11865 | |
| 11866 /* Packet index (NOT USED)*/ | |
| 11867 l_cstr_index->tile_index[it_tile].nb_packet = 0; | |
| 11868 l_cstr_index->tile_index[it_tile].packet_index = NULL; | |
| 11869 | |
| 11870 } | |
| 11871 } | |
| 11872 | |
| 11873 return l_cstr_index; | |
| 11874 } | |
| 11875 | |
| 11876 static OPJ_BOOL opj_j2k_allocate_tile_element_cstr_index(opj_j2k_t *p_j2k) | |
| 11877 { | |
| 11878 OPJ_UINT32 it_tile = 0; | |
| 11879 | |
| 11880 p_j2k->cstr_index->nb_of_tiles = p_j2k->m_cp.tw * p_j2k->m_cp.th; | |
| 11881 p_j2k->cstr_index->tile_index = (opj_tile_index_t*)opj_calloc( | |
| 11882 p_j2k->cstr_index->nb_of_tiles, sizeof(opj_tile_index_t)); | |
| 11883 if (!p_j2k->cstr_index->tile_index) { | |
| 11884 return OPJ_FALSE; | |
| 11885 } | |
| 11886 | |
| 11887 for (it_tile = 0; it_tile < p_j2k->cstr_index->nb_of_tiles; it_tile++) { | |
| 11888 p_j2k->cstr_index->tile_index[it_tile].maxmarknum = 100; | |
| 11889 p_j2k->cstr_index->tile_index[it_tile].marknum = 0; | |
| 11890 p_j2k->cstr_index->tile_index[it_tile].marker = (opj_marker_info_t*) | |
| 11891 opj_calloc(p_j2k->cstr_index->tile_index[it_tile].maxmarknum, | |
| 11892 sizeof(opj_marker_info_t)); | |
| 11893 if (!p_j2k->cstr_index->tile_index[it_tile].marker) { | |
| 11894 return OPJ_FALSE; | |
| 11895 } | |
| 11896 } | |
| 11897 | |
| 11898 return OPJ_TRUE; | |
| 11899 } | |
| 11900 | |
| 11901 static OPJ_BOOL opj_j2k_are_all_used_components_decoded(opj_j2k_t *p_j2k, | |
| 11902 opj_event_mgr_t * p_manager) | |
| 11903 { | |
| 11904 OPJ_UINT32 compno; | |
| 11905 OPJ_BOOL decoded_all_used_components = OPJ_TRUE; | |
| 11906 | |
| 11907 if (p_j2k->m_specific_param.m_decoder.m_numcomps_to_decode) { | |
| 11908 for (compno = 0; | |
| 11909 compno < p_j2k->m_specific_param.m_decoder.m_numcomps_to_decode; compno++) { | |
| 11910 OPJ_UINT32 dec_compno = | |
| 11911 p_j2k->m_specific_param.m_decoder.m_comps_indices_to_decode[compno]; | |
| 11912 if (p_j2k->m_output_image->comps[dec_compno].data == NULL) { | |
| 11913 opj_event_msg(p_manager, EVT_WARNING, "Failed to decode component %d\n", | |
| 11914 dec_compno); | |
| 11915 decoded_all_used_components = OPJ_FALSE; | |
| 11916 } | |
| 11917 } | |
| 11918 } else { | |
| 11919 for (compno = 0; compno < p_j2k->m_output_image->numcomps; compno++) { | |
| 11920 if (p_j2k->m_output_image->comps[compno].data == NULL) { | |
| 11921 opj_event_msg(p_manager, EVT_WARNING, "Failed to decode component %d\n", | |
| 11922 compno); | |
| 11923 decoded_all_used_components = OPJ_FALSE; | |
| 11924 } | |
| 11925 } | |
| 11926 } | |
| 11927 | |
| 11928 if (decoded_all_used_components == OPJ_FALSE) { | |
| 11929 opj_event_msg(p_manager, EVT_ERROR, "Failed to decode all used components\n"); | |
| 11930 return OPJ_FALSE; | |
| 11931 } | |
| 11932 | |
| 11933 return OPJ_TRUE; | |
| 11934 } | |
| 11935 | |
| 11936 static int CompareOffT(const void* a, const void* b) | |
| 11937 { | |
| 11938 const OPJ_OFF_T offA = *(const OPJ_OFF_T*)a; | |
| 11939 const OPJ_OFF_T offB = *(const OPJ_OFF_T*)b; | |
| 11940 if (offA < offB) { | |
| 11941 return -1; | |
| 11942 } | |
| 11943 if (offA == offB) { | |
| 11944 return 0; | |
| 11945 } | |
| 11946 return 1; | |
| 11947 } | |
| 11948 | |
| 11949 static OPJ_BOOL opj_j2k_decode_tiles(opj_j2k_t *p_j2k, | |
| 11950 opj_stream_private_t *p_stream, | |
| 11951 opj_event_mgr_t * p_manager) | |
| 11952 { | |
| 11953 OPJ_BOOL l_go_on = OPJ_TRUE; | |
| 11954 OPJ_UINT32 l_current_tile_no; | |
| 11955 OPJ_INT32 l_tile_x0, l_tile_y0, l_tile_x1, l_tile_y1; | |
| 11956 OPJ_UINT32 l_nb_comps; | |
| 11957 OPJ_UINT32 nr_tiles = 0; | |
| 11958 OPJ_OFF_T end_pos = 0; | |
| 11959 | |
| 11960 /* Particular case for whole single tile decoding */ | |
| 11961 /* We can avoid allocating intermediate tile buffers */ | |
| 11962 if (p_j2k->m_cp.tw == 1 && p_j2k->m_cp.th == 1 && | |
| 11963 p_j2k->m_cp.tx0 == 0 && p_j2k->m_cp.ty0 == 0 && | |
| 11964 p_j2k->m_output_image->x0 == 0 && | |
| 11965 p_j2k->m_output_image->y0 == 0 && | |
| 11966 p_j2k->m_output_image->x1 == p_j2k->m_cp.tdx && | |
| 11967 p_j2k->m_output_image->y1 == p_j2k->m_cp.tdy) { | |
| 11968 OPJ_UINT32 i; | |
| 11969 if (! opj_j2k_read_tile_header(p_j2k, | |
| 11970 &l_current_tile_no, | |
| 11971 NULL, | |
| 11972 &l_tile_x0, &l_tile_y0, | |
| 11973 &l_tile_x1, &l_tile_y1, | |
| 11974 &l_nb_comps, | |
| 11975 &l_go_on, | |
| 11976 p_stream, | |
| 11977 p_manager)) { | |
| 11978 return OPJ_FALSE; | |
| 11979 } | |
| 11980 | |
| 11981 if (!l_go_on || | |
| 11982 ! opj_j2k_decode_tile(p_j2k, l_current_tile_no, NULL, 0, | |
| 11983 p_stream, p_manager)) { | |
| 11984 opj_event_msg(p_manager, EVT_ERROR, "Failed to decode tile 1/1\n"); | |
| 11985 return OPJ_FALSE; | |
| 11986 } | |
| 11987 | |
| 11988 /* Transfer TCD data to output image data */ | |
| 11989 for (i = 0; i < p_j2k->m_output_image->numcomps; i++) { | |
| 11990 opj_image_data_free(p_j2k->m_output_image->comps[i].data); | |
| 11991 p_j2k->m_output_image->comps[i].data = | |
| 11992 p_j2k->m_tcd->tcd_image->tiles->comps[i].data; | |
| 11993 p_j2k->m_output_image->comps[i].resno_decoded = | |
| 11994 p_j2k->m_tcd->image->comps[i].resno_decoded; | |
| 11995 p_j2k->m_tcd->tcd_image->tiles->comps[i].data = NULL; | |
| 11996 } | |
| 11997 | |
| 11998 return OPJ_TRUE; | |
| 11999 } | |
| 12000 | |
| 12001 p_j2k->m_specific_param.m_decoder.m_num_intersecting_tile_parts = 0; | |
| 12002 p_j2k->m_specific_param.m_decoder.m_idx_intersecting_tile_parts = 0; | |
| 12003 opj_free(p_j2k->m_specific_param.m_decoder.m_intersecting_tile_parts_offset); | |
| 12004 p_j2k->m_specific_param.m_decoder.m_intersecting_tile_parts_offset = NULL; | |
| 12005 | |
| 12006 /* If the area to decode only intersects a subset of tiles, and we have | |
| 12007 * valid TLM information, then use it to plan the tilepart offsets to | |
| 12008 * seek to. | |
| 12009 */ | |
| 12010 if (!(p_j2k->m_specific_param.m_decoder.m_start_tile_x == 0 && | |
| 12011 p_j2k->m_specific_param.m_decoder.m_start_tile_y == 0 && | |
| 12012 p_j2k->m_specific_param.m_decoder.m_end_tile_x == p_j2k->m_cp.tw && | |
| 12013 p_j2k->m_specific_param.m_decoder.m_end_tile_y == p_j2k->m_cp.th) && | |
| 12014 !p_j2k->m_specific_param.m_decoder.m_tlm.m_is_invalid && | |
| 12015 opj_stream_has_seek(p_stream)) { | |
| 12016 OPJ_UINT32 m_num_intersecting_tile_parts = 0; | |
| 12017 | |
| 12018 OPJ_UINT32 j; | |
| 12019 for (j = 0; j < p_j2k->m_cp.tw * p_j2k->m_cp.th; ++j) { | |
| 12020 if (p_j2k->cstr_index->tile_index[j].nb_tps > 0 && | |
| 12021 p_j2k->cstr_index->tile_index[j].tp_index[ | |
| 12022 p_j2k->cstr_index->tile_index[j].nb_tps - 1].end_pos > end_pos) { | |
| 12023 end_pos = p_j2k->cstr_index->tile_index[j].tp_index[ | |
| 12024 p_j2k->cstr_index->tile_index[j].nb_tps - 1].end_pos; | |
| 12025 } | |
| 12026 } | |
| 12027 | |
| 12028 for (j = p_j2k->m_specific_param.m_decoder.m_start_tile_y; | |
| 12029 j < p_j2k->m_specific_param.m_decoder.m_end_tile_y; ++j) { | |
| 12030 OPJ_UINT32 i; | |
| 12031 for (i = p_j2k->m_specific_param.m_decoder.m_start_tile_x; | |
| 12032 i < p_j2k->m_specific_param.m_decoder.m_end_tile_x; ++i) { | |
| 12033 const OPJ_UINT32 tile_number = j * p_j2k->m_cp.tw + i; | |
| 12034 m_num_intersecting_tile_parts += | |
| 12035 p_j2k->cstr_index->tile_index[tile_number].nb_tps; | |
| 12036 } | |
| 12037 } | |
| 12038 | |
| 12039 p_j2k->m_specific_param.m_decoder.m_intersecting_tile_parts_offset = | |
| 12040 (OPJ_OFF_T*) | |
| 12041 opj_malloc(m_num_intersecting_tile_parts * sizeof(OPJ_OFF_T)); | |
| 12042 if (m_num_intersecting_tile_parts > 0 && | |
| 12043 p_j2k->m_specific_param.m_decoder.m_intersecting_tile_parts_offset) { | |
| 12044 OPJ_UINT32 idx = 0; | |
| 12045 for (j = p_j2k->m_specific_param.m_decoder.m_start_tile_y; | |
| 12046 j < p_j2k->m_specific_param.m_decoder.m_end_tile_y; ++j) { | |
| 12047 OPJ_UINT32 i; | |
| 12048 for (i = p_j2k->m_specific_param.m_decoder.m_start_tile_x; | |
| 12049 i < p_j2k->m_specific_param.m_decoder.m_end_tile_x; ++i) { | |
| 12050 const OPJ_UINT32 tile_number = j * p_j2k->m_cp.tw + i; | |
| 12051 OPJ_UINT32 k; | |
| 12052 for (k = 0; k < p_j2k->cstr_index->tile_index[tile_number].nb_tps; ++k) { | |
| 12053 const OPJ_OFF_T next_tp_sot_pos = | |
| 12054 p_j2k->cstr_index->tile_index[tile_number].tp_index[k].start_pos; | |
| 12055 p_j2k->m_specific_param.m_decoder.m_intersecting_tile_parts_offset[idx] = | |
| 12056 next_tp_sot_pos; | |
| 12057 ++idx; | |
| 12058 } | |
| 12059 } | |
| 12060 } | |
| 12061 | |
| 12062 p_j2k->m_specific_param.m_decoder.m_num_intersecting_tile_parts = idx; | |
| 12063 | |
| 12064 /* Sort by increasing offset */ | |
| 12065 qsort(p_j2k->m_specific_param.m_decoder.m_intersecting_tile_parts_offset, | |
| 12066 p_j2k->m_specific_param.m_decoder.m_num_intersecting_tile_parts, | |
| 12067 sizeof(OPJ_OFF_T), | |
| 12068 CompareOffT); | |
| 12069 } | |
| 12070 } | |
| 12071 | |
| 12072 for (;;) { | |
| 12073 if (p_j2k->m_cp.tw == 1 && p_j2k->m_cp.th == 1 && | |
| 12074 p_j2k->m_cp.tcps[0].m_data != NULL) { | |
| 12075 l_current_tile_no = 0; | |
| 12076 p_j2k->m_current_tile_number = 0; | |
| 12077 p_j2k->m_specific_param.m_decoder.m_state |= J2K_STATE_DATA; | |
| 12078 } else { | |
| 12079 if (! opj_j2k_read_tile_header(p_j2k, | |
| 12080 &l_current_tile_no, | |
| 12081 NULL, | |
| 12082 &l_tile_x0, &l_tile_y0, | |
| 12083 &l_tile_x1, &l_tile_y1, | |
| 12084 &l_nb_comps, | |
| 12085 &l_go_on, | |
| 12086 p_stream, | |
| 12087 p_manager)) { | |
| 12088 return OPJ_FALSE; | |
| 12089 } | |
| 12090 | |
| 12091 if (! l_go_on) { | |
| 12092 break; | |
| 12093 } | |
| 12094 } | |
| 12095 | |
| 12096 if (! opj_j2k_decode_tile(p_j2k, l_current_tile_no, NULL, 0, | |
| 12097 p_stream, p_manager)) { | |
| 12098 opj_event_msg(p_manager, EVT_ERROR, "Failed to decode tile %d/%d\n", | |
| 12099 l_current_tile_no + 1, p_j2k->m_cp.th * p_j2k->m_cp.tw); | |
| 12100 return OPJ_FALSE; | |
| 12101 } | |
| 12102 | |
| 12103 opj_event_msg(p_manager, EVT_INFO, "Tile %d/%d has been decoded.\n", | |
| 12104 l_current_tile_no + 1, p_j2k->m_cp.th * p_j2k->m_cp.tw); | |
| 12105 | |
| 12106 if (! opj_j2k_update_image_data(p_j2k->m_tcd, | |
| 12107 p_j2k->m_output_image)) { | |
| 12108 return OPJ_FALSE; | |
| 12109 } | |
| 12110 | |
| 12111 if (p_j2k->m_cp.tw == 1 && p_j2k->m_cp.th == 1 && | |
| 12112 !(p_j2k->m_output_image->x0 == p_j2k->m_private_image->x0 && | |
| 12113 p_j2k->m_output_image->y0 == p_j2k->m_private_image->y0 && | |
| 12114 p_j2k->m_output_image->x1 == p_j2k->m_private_image->x1 && | |
| 12115 p_j2k->m_output_image->y1 == p_j2k->m_private_image->y1)) { | |
| 12116 /* Keep current tcp data */ | |
| 12117 } else { | |
| 12118 opj_j2k_tcp_data_destroy(&p_j2k->m_cp.tcps[l_current_tile_no]); | |
| 12119 } | |
| 12120 | |
| 12121 opj_event_msg(p_manager, EVT_INFO, | |
| 12122 "Image data has been updated with tile %d.\n\n", l_current_tile_no + 1); | |
| 12123 | |
| 12124 if (opj_stream_get_number_byte_left(p_stream) == 0 | |
| 12125 && p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_NEOC) { | |
| 12126 break; | |
| 12127 } | |
| 12128 if (++nr_tiles == p_j2k->m_cp.th * p_j2k->m_cp.tw) { | |
| 12129 break; | |
| 12130 } | |
| 12131 if (p_j2k->m_specific_param.m_decoder.m_num_intersecting_tile_parts > 0 && | |
| 12132 p_j2k->m_specific_param.m_decoder.m_idx_intersecting_tile_parts == | |
| 12133 p_j2k->m_specific_param.m_decoder.m_num_intersecting_tile_parts) { | |
| 12134 opj_stream_seek(p_stream, end_pos + 2, p_manager); | |
| 12135 break; | |
| 12136 } | |
| 12137 } | |
| 12138 | |
| 12139 if (! opj_j2k_are_all_used_components_decoded(p_j2k, p_manager)) { | |
| 12140 return OPJ_FALSE; | |
| 12141 } | |
| 12142 | |
| 12143 return OPJ_TRUE; | |
| 12144 } | |
| 12145 | |
| 12146 /** | |
| 12147 * Sets up the procedures to do on decoding data. Developers wanting to extend the library can add their own reading procedures. | |
| 12148 */ | |
| 12149 static OPJ_BOOL opj_j2k_setup_decoding(opj_j2k_t *p_j2k, | |
| 12150 opj_event_mgr_t * p_manager) | |
| 12151 { | |
| 12152 /* preconditions*/ | |
| 12153 assert(p_j2k != 00); | |
| 12154 assert(p_manager != 00); | |
| 12155 | |
| 12156 if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list, | |
| 12157 (opj_procedure)opj_j2k_decode_tiles, p_manager)) { | |
| 12158 return OPJ_FALSE; | |
| 12159 } | |
| 12160 /* DEVELOPER CORNER, add your custom procedures */ | |
| 12161 | |
| 12162 return OPJ_TRUE; | |
| 12163 } | |
| 12164 | |
| 12165 /* | |
| 12166 * Read and decode one tile. | |
| 12167 */ | |
| 12168 static OPJ_BOOL opj_j2k_decode_one_tile(opj_j2k_t *p_j2k, | |
| 12169 opj_stream_private_t *p_stream, | |
| 12170 opj_event_mgr_t * p_manager) | |
| 12171 { | |
| 12172 OPJ_BOOL l_go_on = OPJ_TRUE; | |
| 12173 OPJ_UINT32 l_current_tile_no; | |
| 12174 OPJ_UINT32 l_tile_no_to_dec; | |
| 12175 OPJ_INT32 l_tile_x0, l_tile_y0, l_tile_x1, l_tile_y1; | |
| 12176 OPJ_UINT32 l_nb_comps; | |
| 12177 OPJ_UINT32 l_nb_tiles; | |
| 12178 OPJ_UINT32 i; | |
| 12179 | |
| 12180 /* Move into the codestream to the first SOT used to decode the desired tile */ | |
| 12181 l_tile_no_to_dec = (OPJ_UINT32) | |
| 12182 p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec; | |
| 12183 if (p_j2k->cstr_index->tile_index) | |
| 12184 if (p_j2k->cstr_index->tile_index->tp_index) { | |
| 12185 if (! p_j2k->cstr_index->tile_index[l_tile_no_to_dec].nb_tps) { | |
| 12186 /* the index for this tile has not been built, | |
| 12187 * so move to the last SOT read */ | |
| 12188 if (!(opj_stream_read_seek(p_stream, | |
| 12189 p_j2k->m_specific_param.m_decoder.m_last_sot_read_pos + 2, p_manager))) { | |
| 12190 opj_event_msg(p_manager, EVT_ERROR, "Problem with seek function\n"); | |
| 12191 return OPJ_FALSE; | |
| 12192 } | |
| 12193 } else { | |
| 12194 OPJ_OFF_T sot_pos = | |
| 12195 p_j2k->cstr_index->tile_index[l_tile_no_to_dec].tp_index[0].start_pos; | |
| 12196 OPJ_UINT32 l_marker; | |
| 12197 | |
| 12198 #if 0 | |
| 12199 opj_event_msg(p_manager, EVT_INFO, | |
| 12200 "opj_j2k_decode_one_tile(%u): seek to %" PRId64 "\n", | |
| 12201 l_tile_no_to_dec, | |
| 12202 sot_pos); | |
| 12203 #endif | |
| 12204 if (!(opj_stream_read_seek(p_stream, | |
| 12205 sot_pos, | |
| 12206 p_manager))) { | |
| 12207 opj_event_msg(p_manager, EVT_ERROR, "Problem with seek function\n"); | |
| 12208 return OPJ_FALSE; | |
| 12209 } | |
| 12210 | |
| 12211 /* Try to read 2 bytes (the marker ID) from stream and copy them into the buffer */ | |
| 12212 if (opj_stream_read_data(p_stream, | |
| 12213 p_j2k->m_specific_param.m_decoder.m_header_data, 2, p_manager) != 2) { | |
| 12214 opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); | |
| 12215 return OPJ_FALSE; | |
| 12216 } | |
| 12217 | |
| 12218 /* Read 2 bytes from the buffer as the marker ID */ | |
| 12219 opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data, &l_marker, | |
| 12220 2); | |
| 12221 | |
| 12222 if (l_marker != J2K_MS_SOT) { | |
| 12223 opj_event_msg(p_manager, EVT_ERROR, "Did not get expected SOT marker\n"); | |
| 12224 return OPJ_FALSE; | |
| 12225 } | |
| 12226 } | |
| 12227 /* Special case if we have previously read the EOC marker (if the previous tile getted is the last ) */ | |
| 12228 if (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_EOC) { | |
| 12229 p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_TPHSOT; | |
| 12230 } | |
| 12231 } | |
| 12232 | |
| 12233 /* Reset current tile part number for all tiles, and not only the one */ | |
| 12234 /* of interest. */ | |
| 12235 /* Not completely sure this is always correct but required for */ | |
| 12236 /* ./build/bin/j2k_random_tile_access ./build/tests/tte1.j2k */ | |
| 12237 l_nb_tiles = p_j2k->m_cp.tw * p_j2k->m_cp.th; | |
| 12238 for (i = 0; i < l_nb_tiles; ++i) { | |
| 12239 p_j2k->m_cp.tcps[i].m_current_tile_part_number = -1; | |
| 12240 } | |
| 12241 | |
| 12242 for (;;) { | |
| 12243 if (! opj_j2k_read_tile_header(p_j2k, | |
| 12244 &l_current_tile_no, | |
| 12245 NULL, | |
| 12246 &l_tile_x0, &l_tile_y0, | |
| 12247 &l_tile_x1, &l_tile_y1, | |
| 12248 &l_nb_comps, | |
| 12249 &l_go_on, | |
| 12250 p_stream, | |
| 12251 p_manager)) { | |
| 12252 return OPJ_FALSE; | |
| 12253 } | |
| 12254 | |
| 12255 if (! l_go_on) { | |
| 12256 break; | |
| 12257 } | |
| 12258 | |
| 12259 if (! opj_j2k_decode_tile(p_j2k, l_current_tile_no, NULL, 0, | |
| 12260 p_stream, p_manager)) { | |
| 12261 return OPJ_FALSE; | |
| 12262 } | |
| 12263 opj_event_msg(p_manager, EVT_INFO, "Tile %d/%d has been decoded.\n", | |
| 12264 l_current_tile_no + 1, p_j2k->m_cp.th * p_j2k->m_cp.tw); | |
| 12265 | |
| 12266 if (! opj_j2k_update_image_data(p_j2k->m_tcd, | |
| 12267 p_j2k->m_output_image)) { | |
| 12268 return OPJ_FALSE; | |
| 12269 } | |
| 12270 opj_j2k_tcp_data_destroy(&p_j2k->m_cp.tcps[l_current_tile_no]); | |
| 12271 | |
| 12272 opj_event_msg(p_manager, EVT_INFO, | |
| 12273 "Image data has been updated with tile %d.\n\n", l_current_tile_no + 1); | |
| 12274 | |
| 12275 if (l_current_tile_no == l_tile_no_to_dec) { | |
| 12276 /* move into the codestream to the first SOT (FIXME or not move?)*/ | |
| 12277 if (!(opj_stream_read_seek(p_stream, p_j2k->cstr_index->main_head_end + 2, | |
| 12278 p_manager))) { | |
| 12279 opj_event_msg(p_manager, EVT_ERROR, "Problem with seek function\n"); | |
| 12280 return OPJ_FALSE; | |
| 12281 } | |
| 12282 break; | |
| 12283 } else { | |
| 12284 opj_event_msg(p_manager, EVT_WARNING, | |
| 12285 "Tile read, decoded and updated is not the desired one (%d vs %d).\n", | |
| 12286 l_current_tile_no + 1, l_tile_no_to_dec + 1); | |
| 12287 } | |
| 12288 | |
| 12289 } | |
| 12290 | |
| 12291 if (! opj_j2k_are_all_used_components_decoded(p_j2k, p_manager)) { | |
| 12292 return OPJ_FALSE; | |
| 12293 } | |
| 12294 | |
| 12295 return OPJ_TRUE; | |
| 12296 } | |
| 12297 | |
| 12298 /** | |
| 12299 * Sets up the procedures to do on decoding one tile. Developers wanting to extend the library can add their own reading procedures. | |
| 12300 */ | |
| 12301 static OPJ_BOOL opj_j2k_setup_decoding_tile(opj_j2k_t *p_j2k, | |
| 12302 opj_event_mgr_t * p_manager) | |
| 12303 { | |
| 12304 /* preconditions*/ | |
| 12305 assert(p_j2k != 00); | |
| 12306 assert(p_manager != 00); | |
| 12307 | |
| 12308 if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list, | |
| 12309 (opj_procedure)opj_j2k_decode_one_tile, p_manager)) { | |
| 12310 return OPJ_FALSE; | |
| 12311 } | |
| 12312 /* DEVELOPER CORNER, add your custom procedures */ | |
| 12313 | |
| 12314 return OPJ_TRUE; | |
| 12315 } | |
| 12316 | |
| 12317 static OPJ_BOOL opj_j2k_move_data_from_codec_to_output_image(opj_j2k_t * p_j2k, | |
| 12318 opj_image_t * p_image) | |
| 12319 { | |
| 12320 OPJ_UINT32 compno; | |
| 12321 | |
| 12322 /* Move data and copy one information from codec to output image*/ | |
| 12323 if (p_j2k->m_specific_param.m_decoder.m_numcomps_to_decode > 0) { | |
| 12324 opj_image_comp_t* newcomps = | |
| 12325 (opj_image_comp_t*) opj_malloc( | |
| 12326 p_j2k->m_specific_param.m_decoder.m_numcomps_to_decode * | |
| 12327 sizeof(opj_image_comp_t)); | |
| 12328 if (newcomps == NULL) { | |
| 12329 opj_image_destroy(p_j2k->m_private_image); | |
| 12330 p_j2k->m_private_image = NULL; | |
| 12331 return OPJ_FALSE; | |
| 12332 } | |
| 12333 for (compno = 0; compno < p_image->numcomps; compno++) { | |
| 12334 opj_image_data_free(p_image->comps[compno].data); | |
| 12335 p_image->comps[compno].data = NULL; | |
| 12336 } | |
| 12337 for (compno = 0; | |
| 12338 compno < p_j2k->m_specific_param.m_decoder.m_numcomps_to_decode; compno++) { | |
| 12339 OPJ_UINT32 src_compno = | |
| 12340 p_j2k->m_specific_param.m_decoder.m_comps_indices_to_decode[compno]; | |
| 12341 memcpy(&(newcomps[compno]), | |
| 12342 &(p_j2k->m_output_image->comps[src_compno]), | |
| 12343 sizeof(opj_image_comp_t)); | |
| 12344 newcomps[compno].resno_decoded = | |
| 12345 p_j2k->m_output_image->comps[src_compno].resno_decoded; | |
| 12346 newcomps[compno].data = p_j2k->m_output_image->comps[src_compno].data; | |
| 12347 p_j2k->m_output_image->comps[src_compno].data = NULL; | |
| 12348 } | |
| 12349 for (compno = 0; compno < p_image->numcomps; compno++) { | |
| 12350 assert(p_j2k->m_output_image->comps[compno].data == NULL); | |
| 12351 opj_image_data_free(p_j2k->m_output_image->comps[compno].data); | |
| 12352 p_j2k->m_output_image->comps[compno].data = NULL; | |
| 12353 } | |
| 12354 p_image->numcomps = p_j2k->m_specific_param.m_decoder.m_numcomps_to_decode; | |
| 12355 opj_free(p_image->comps); | |
| 12356 p_image->comps = newcomps; | |
| 12357 } else { | |
| 12358 for (compno = 0; compno < p_image->numcomps; compno++) { | |
| 12359 p_image->comps[compno].resno_decoded = | |
| 12360 p_j2k->m_output_image->comps[compno].resno_decoded; | |
| 12361 opj_image_data_free(p_image->comps[compno].data); | |
| 12362 p_image->comps[compno].data = p_j2k->m_output_image->comps[compno].data; | |
| 12363 #if 0 | |
| 12364 char fn[256]; | |
| 12365 snprintf(fn, sizeof fn, "/tmp/%d.raw", compno); | |
| 12366 FILE *debug = fopen(fn, "wb"); | |
| 12367 fwrite(p_image->comps[compno].data, sizeof(OPJ_INT32), | |
| 12368 p_image->comps[compno].w * p_image->comps[compno].h, debug); | |
| 12369 fclose(debug); | |
| 12370 #endif | |
| 12371 p_j2k->m_output_image->comps[compno].data = NULL; | |
| 12372 } | |
| 12373 } | |
| 12374 return OPJ_TRUE; | |
| 12375 } | |
| 12376 | |
| 12377 OPJ_BOOL opj_j2k_decode(opj_j2k_t * p_j2k, | |
| 12378 opj_stream_private_t * p_stream, | |
| 12379 opj_image_t * p_image, | |
| 12380 opj_event_mgr_t * p_manager) | |
| 12381 { | |
| 12382 if (!p_image) { | |
| 12383 return OPJ_FALSE; | |
| 12384 } | |
| 12385 | |
| 12386 /* Heuristics to detect sequence opj_read_header(), opj_set_decoded_resolution_factor() */ | |
| 12387 /* and finally opj_decode_image() without manual setting of comps[].factor */ | |
| 12388 /* We could potentially always execute it, if we don't allow people to do */ | |
| 12389 /* opj_read_header(), modify x0,y0,x1,y1 of returned image an call opj_decode_image() */ | |
| 12390 if (p_j2k->m_cp.m_specific_param.m_dec.m_reduce > 0 && | |
| 12391 p_j2k->m_private_image != NULL && | |
| 12392 p_j2k->m_private_image->numcomps > 0 && | |
| 12393 p_j2k->m_private_image->comps[0].factor == | |
| 12394 p_j2k->m_cp.m_specific_param.m_dec.m_reduce && | |
| 12395 p_image->numcomps > 0 && | |
| 12396 p_image->comps[0].factor == 0 && | |
| 12397 /* Don't mess with image dimension if the user has allocated it */ | |
| 12398 p_image->comps[0].data == NULL) { | |
| 12399 OPJ_UINT32 it_comp; | |
| 12400 | |
| 12401 /* Update the comps[].factor member of the output image with the one */ | |
| 12402 /* of m_reduce */ | |
| 12403 for (it_comp = 0; it_comp < p_image->numcomps; ++it_comp) { | |
| 12404 p_image->comps[it_comp].factor = p_j2k->m_cp.m_specific_param.m_dec.m_reduce; | |
| 12405 } | |
| 12406 if (!opj_j2k_update_image_dimensions(p_image, p_manager)) { | |
| 12407 return OPJ_FALSE; | |
| 12408 } | |
| 12409 } | |
| 12410 | |
| 12411 if (p_j2k->m_output_image == NULL) { | |
| 12412 p_j2k->m_output_image = opj_image_create0(); | |
| 12413 if (!(p_j2k->m_output_image)) { | |
| 12414 return OPJ_FALSE; | |
| 12415 } | |
| 12416 } | |
| 12417 opj_copy_image_header(p_image, p_j2k->m_output_image); | |
| 12418 | |
| 12419 /* customization of the decoding */ | |
| 12420 if (!opj_j2k_setup_decoding(p_j2k, p_manager)) { | |
| 12421 return OPJ_FALSE; | |
| 12422 } | |
| 12423 | |
| 12424 /* Decode the codestream */ | |
| 12425 if (! opj_j2k_exec(p_j2k, p_j2k->m_procedure_list, p_stream, p_manager)) { | |
| 12426 opj_image_destroy(p_j2k->m_private_image); | |
| 12427 p_j2k->m_private_image = NULL; | |
| 12428 return OPJ_FALSE; | |
| 12429 } | |
| 12430 | |
| 12431 /* Move data and copy one information from codec to output image*/ | |
| 12432 return opj_j2k_move_data_from_codec_to_output_image(p_j2k, p_image); | |
| 12433 } | |
| 12434 | |
| 12435 OPJ_BOOL opj_j2k_get_tile(opj_j2k_t *p_j2k, | |
| 12436 opj_stream_private_t *p_stream, | |
| 12437 opj_image_t* p_image, | |
| 12438 opj_event_mgr_t * p_manager, | |
| 12439 OPJ_UINT32 tile_index) | |
| 12440 { | |
| 12441 OPJ_UINT32 compno; | |
| 12442 OPJ_UINT32 l_tile_x, l_tile_y; | |
| 12443 opj_image_comp_t* l_img_comp; | |
| 12444 | |
| 12445 if (!p_image) { | |
| 12446 opj_event_msg(p_manager, EVT_ERROR, "We need an image previously created.\n"); | |
| 12447 return OPJ_FALSE; | |
| 12448 } | |
| 12449 | |
| 12450 if (p_image->numcomps < p_j2k->m_private_image->numcomps) { | |
| 12451 opj_event_msg(p_manager, EVT_ERROR, | |
| 12452 "Image has less components than codestream.\n"); | |
| 12453 return OPJ_FALSE; | |
| 12454 } | |
| 12455 | |
| 12456 if (/*(tile_index < 0) &&*/ (tile_index >= p_j2k->m_cp.tw * p_j2k->m_cp.th)) { | |
| 12457 opj_event_msg(p_manager, EVT_ERROR, | |
| 12458 "Tile index provided by the user is incorrect %d (max = %d) \n", tile_index, | |
| 12459 (p_j2k->m_cp.tw * p_j2k->m_cp.th) - 1); | |
| 12460 return OPJ_FALSE; | |
| 12461 } | |
| 12462 | |
| 12463 /* Compute the dimension of the desired tile*/ | |
| 12464 l_tile_x = tile_index % p_j2k->m_cp.tw; | |
| 12465 l_tile_y = tile_index / p_j2k->m_cp.tw; | |
| 12466 | |
| 12467 p_image->x0 = l_tile_x * p_j2k->m_cp.tdx + p_j2k->m_cp.tx0; | |
| 12468 if (p_image->x0 < p_j2k->m_private_image->x0) { | |
| 12469 p_image->x0 = p_j2k->m_private_image->x0; | |
| 12470 } | |
| 12471 p_image->x1 = (l_tile_x + 1) * p_j2k->m_cp.tdx + p_j2k->m_cp.tx0; | |
| 12472 if (p_image->x1 > p_j2k->m_private_image->x1) { | |
| 12473 p_image->x1 = p_j2k->m_private_image->x1; | |
| 12474 } | |
| 12475 | |
| 12476 p_image->y0 = l_tile_y * p_j2k->m_cp.tdy + p_j2k->m_cp.ty0; | |
| 12477 if (p_image->y0 < p_j2k->m_private_image->y0) { | |
| 12478 p_image->y0 = p_j2k->m_private_image->y0; | |
| 12479 } | |
| 12480 p_image->y1 = (l_tile_y + 1) * p_j2k->m_cp.tdy + p_j2k->m_cp.ty0; | |
| 12481 if (p_image->y1 > p_j2k->m_private_image->y1) { | |
| 12482 p_image->y1 = p_j2k->m_private_image->y1; | |
| 12483 } | |
| 12484 | |
| 12485 l_img_comp = p_image->comps; | |
| 12486 for (compno = 0; compno < p_j2k->m_private_image->numcomps; ++compno) { | |
| 12487 OPJ_INT32 l_comp_x1, l_comp_y1; | |
| 12488 | |
| 12489 l_img_comp->factor = p_j2k->m_private_image->comps[compno].factor; | |
| 12490 | |
| 12491 l_img_comp->x0 = opj_uint_ceildiv(p_image->x0, l_img_comp->dx); | |
| 12492 l_img_comp->y0 = opj_uint_ceildiv(p_image->y0, l_img_comp->dy); | |
| 12493 l_comp_x1 = opj_int_ceildiv((OPJ_INT32)p_image->x1, (OPJ_INT32)l_img_comp->dx); | |
| 12494 l_comp_y1 = opj_int_ceildiv((OPJ_INT32)p_image->y1, (OPJ_INT32)l_img_comp->dy); | |
| 12495 | |
| 12496 l_img_comp->w = (OPJ_UINT32)(opj_int_ceildivpow2(l_comp_x1, | |
| 12497 (OPJ_INT32)l_img_comp->factor) - opj_int_ceildivpow2((OPJ_INT32)l_img_comp->x0, | |
| 12498 (OPJ_INT32)l_img_comp->factor)); | |
| 12499 l_img_comp->h = (OPJ_UINT32)(opj_int_ceildivpow2(l_comp_y1, | |
| 12500 (OPJ_INT32)l_img_comp->factor) - opj_int_ceildivpow2((OPJ_INT32)l_img_comp->y0, | |
| 12501 (OPJ_INT32)l_img_comp->factor)); | |
| 12502 | |
| 12503 l_img_comp++; | |
| 12504 } | |
| 12505 | |
| 12506 if (p_image->numcomps > p_j2k->m_private_image->numcomps) { | |
| 12507 /* Can happen when calling repeatdly opj_get_decoded_tile() on an | |
| 12508 * image with a color palette, where color palette expansion is done | |
| 12509 * later in jp2.c */ | |
| 12510 for (compno = p_j2k->m_private_image->numcomps; compno < p_image->numcomps; | |
| 12511 ++compno) { | |
| 12512 opj_image_data_free(p_image->comps[compno].data); | |
| 12513 p_image->comps[compno].data = NULL; | |
| 12514 } | |
| 12515 p_image->numcomps = p_j2k->m_private_image->numcomps; | |
| 12516 } | |
| 12517 | |
| 12518 /* Destroy the previous output image*/ | |
| 12519 if (p_j2k->m_output_image) { | |
| 12520 opj_image_destroy(p_j2k->m_output_image); | |
| 12521 } | |
| 12522 | |
| 12523 /* Create the output image from the information previously computed*/ | |
| 12524 p_j2k->m_output_image = opj_image_create0(); | |
| 12525 if (!(p_j2k->m_output_image)) { | |
| 12526 return OPJ_FALSE; | |
| 12527 } | |
| 12528 opj_copy_image_header(p_image, p_j2k->m_output_image); | |
| 12529 | |
| 12530 p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec = (OPJ_INT32)tile_index; | |
| 12531 | |
| 12532 /* customization of the decoding */ | |
| 12533 if (!opj_j2k_setup_decoding_tile(p_j2k, p_manager)) { | |
| 12534 return OPJ_FALSE; | |
| 12535 } | |
| 12536 | |
| 12537 /* Decode the codestream */ | |
| 12538 if (! opj_j2k_exec(p_j2k, p_j2k->m_procedure_list, p_stream, p_manager)) { | |
| 12539 opj_image_destroy(p_j2k->m_private_image); | |
| 12540 p_j2k->m_private_image = NULL; | |
| 12541 return OPJ_FALSE; | |
| 12542 } | |
| 12543 | |
| 12544 /* Move data and copy one information from codec to output image*/ | |
| 12545 return opj_j2k_move_data_from_codec_to_output_image(p_j2k, p_image); | |
| 12546 } | |
| 12547 | |
| 12548 OPJ_BOOL opj_j2k_set_decoded_resolution_factor(opj_j2k_t *p_j2k, | |
| 12549 OPJ_UINT32 res_factor, | |
| 12550 opj_event_mgr_t * p_manager) | |
| 12551 { | |
| 12552 OPJ_UINT32 it_comp; | |
| 12553 | |
| 12554 p_j2k->m_cp.m_specific_param.m_dec.m_reduce = res_factor; | |
| 12555 | |
| 12556 if (p_j2k->m_private_image) { | |
| 12557 if (p_j2k->m_private_image->comps) { | |
| 12558 if (p_j2k->m_specific_param.m_decoder.m_default_tcp) { | |
| 12559 if (p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps) { | |
| 12560 for (it_comp = 0 ; it_comp < p_j2k->m_private_image->numcomps; it_comp++) { | |
| 12561 OPJ_UINT32 max_res = | |
| 12562 p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps[it_comp].numresolutions; | |
| 12563 if (res_factor >= max_res) { | |
| 12564 opj_event_msg(p_manager, EVT_ERROR, | |
| 12565 "Resolution factor is greater than the maximum resolution in the component.\n"); | |
| 12566 return OPJ_FALSE; | |
| 12567 } | |
| 12568 p_j2k->m_private_image->comps[it_comp].factor = res_factor; | |
| 12569 } | |
| 12570 return OPJ_TRUE; | |
| 12571 } | |
| 12572 } | |
| 12573 } | |
| 12574 } | |
| 12575 | |
| 12576 return OPJ_FALSE; | |
| 12577 } | |
| 12578 | |
| 12579 /* ----------------------------------------------------------------------- */ | |
| 12580 | |
| 12581 OPJ_BOOL opj_j2k_encoder_set_extra_options( | |
| 12582 opj_j2k_t *p_j2k, | |
| 12583 const char* const* p_options, | |
| 12584 opj_event_mgr_t * p_manager) | |
| 12585 { | |
| 12586 const char* const* p_option_iter; | |
| 12587 | |
| 12588 if (p_options == NULL) { | |
| 12589 return OPJ_TRUE; | |
| 12590 } | |
| 12591 | |
| 12592 for (p_option_iter = p_options; *p_option_iter != NULL; ++p_option_iter) { | |
| 12593 if (strncmp(*p_option_iter, "PLT=", 4) == 0) { | |
| 12594 if (strcmp(*p_option_iter, "PLT=YES") == 0) { | |
| 12595 p_j2k->m_specific_param.m_encoder.m_PLT = OPJ_TRUE; | |
| 12596 } else if (strcmp(*p_option_iter, "PLT=NO") == 0) { | |
| 12597 p_j2k->m_specific_param.m_encoder.m_PLT = OPJ_FALSE; | |
| 12598 } else { | |
| 12599 opj_event_msg(p_manager, EVT_ERROR, | |
| 12600 "Invalid value for option: %s.\n", *p_option_iter); | |
| 12601 return OPJ_FALSE; | |
| 12602 } | |
| 12603 } else if (strncmp(*p_option_iter, "TLM=", 4) == 0) { | |
| 12604 if (strcmp(*p_option_iter, "TLM=YES") == 0) { | |
| 12605 p_j2k->m_specific_param.m_encoder.m_TLM = OPJ_TRUE; | |
| 12606 } else if (strcmp(*p_option_iter, "TLM=NO") == 0) { | |
| 12607 p_j2k->m_specific_param.m_encoder.m_TLM = OPJ_FALSE; | |
| 12608 } else { | |
| 12609 opj_event_msg(p_manager, EVT_ERROR, | |
| 12610 "Invalid value for option: %s.\n", *p_option_iter); | |
| 12611 return OPJ_FALSE; | |
| 12612 } | |
| 12613 } else if (strncmp(*p_option_iter, "GUARD_BITS=", strlen("GUARD_BITS=")) == 0) { | |
| 12614 OPJ_UINT32 tileno; | |
| 12615 opj_cp_t *cp = cp = &(p_j2k->m_cp); | |
| 12616 | |
| 12617 int numgbits = atoi(*p_option_iter + strlen("GUARD_BITS=")); | |
| 12618 if (numgbits < 0 || numgbits > 7) { | |
| 12619 opj_event_msg(p_manager, EVT_ERROR, | |
| 12620 "Invalid value for option: %s. Should be in [0,7]\n", *p_option_iter); | |
| 12621 return OPJ_FALSE; | |
| 12622 } | |
| 12623 | |
| 12624 for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { | |
| 12625 OPJ_UINT32 i; | |
| 12626 opj_tcp_t *tcp = &cp->tcps[tileno]; | |
| 12627 for (i = 0; i < p_j2k->m_specific_param.m_encoder.m_nb_comps; i++) { | |
| 12628 opj_tccp_t *tccp = &tcp->tccps[i]; | |
| 12629 tccp->numgbits = (OPJ_UINT32)numgbits; | |
| 12630 } | |
| 12631 } | |
| 12632 } else { | |
| 12633 opj_event_msg(p_manager, EVT_ERROR, | |
| 12634 "Invalid option: %s.\n", *p_option_iter); | |
| 12635 return OPJ_FALSE; | |
| 12636 } | |
| 12637 } | |
| 12638 | |
| 12639 return OPJ_TRUE; | |
| 12640 } | |
| 12641 | |
| 12642 /* ----------------------------------------------------------------------- */ | |
| 12643 | |
| 12644 OPJ_BOOL opj_j2k_encode(opj_j2k_t * p_j2k, | |
| 12645 opj_stream_private_t *p_stream, | |
| 12646 opj_event_mgr_t * p_manager) | |
| 12647 { | |
| 12648 OPJ_UINT32 i, j; | |
| 12649 OPJ_UINT32 l_nb_tiles; | |
| 12650 OPJ_SIZE_T l_max_tile_size = 0, l_current_tile_size; | |
| 12651 OPJ_BYTE * l_current_data = 00; | |
| 12652 OPJ_BOOL l_reuse_data = OPJ_FALSE; | |
| 12653 opj_tcd_t* p_tcd = 00; | |
| 12654 | |
| 12655 /* preconditions */ | |
| 12656 assert(p_j2k != 00); | |
| 12657 assert(p_stream != 00); | |
| 12658 assert(p_manager != 00); | |
| 12659 | |
| 12660 p_tcd = p_j2k->m_tcd; | |
| 12661 | |
| 12662 l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw; | |
| 12663 if (l_nb_tiles == 1) { | |
| 12664 l_reuse_data = OPJ_TRUE; | |
| 12665 #ifdef __SSE__ | |
| 12666 for (j = 0; j < p_j2k->m_tcd->image->numcomps; ++j) { | |
| 12667 opj_image_comp_t * l_img_comp = p_tcd->image->comps + j; | |
| 12668 if (((size_t)l_img_comp->data & 0xFU) != | |
| 12669 0U) { /* tile data shall be aligned on 16 bytes */ | |
| 12670 l_reuse_data = OPJ_FALSE; | |
| 12671 } | |
| 12672 } | |
| 12673 #endif | |
| 12674 } | |
| 12675 for (i = 0; i < l_nb_tiles; ++i) { | |
| 12676 if (! opj_j2k_pre_write_tile(p_j2k, i, p_stream, p_manager)) { | |
| 12677 if (l_current_data) { | |
| 12678 opj_free(l_current_data); | |
| 12679 } | |
| 12680 return OPJ_FALSE; | |
| 12681 } | |
| 12682 | |
| 12683 /* if we only have one tile, then simply set tile component data equal to image component data */ | |
| 12684 /* otherwise, allocate the data */ | |
| 12685 for (j = 0; j < p_j2k->m_tcd->image->numcomps; ++j) { | |
| 12686 opj_tcd_tilecomp_t* l_tilec = p_tcd->tcd_image->tiles->comps + j; | |
| 12687 if (l_reuse_data) { | |
| 12688 opj_image_comp_t * l_img_comp = p_tcd->image->comps + j; | |
| 12689 l_tilec->data = l_img_comp->data; | |
| 12690 l_tilec->ownsData = OPJ_FALSE; | |
| 12691 } else { | |
| 12692 if (! opj_alloc_tile_component_data(l_tilec)) { | |
| 12693 opj_event_msg(p_manager, EVT_ERROR, "Error allocating tile component data."); | |
| 12694 if (l_current_data) { | |
| 12695 opj_free(l_current_data); | |
| 12696 } | |
| 12697 return OPJ_FALSE; | |
| 12698 } | |
| 12699 } | |
| 12700 } | |
| 12701 l_current_tile_size = opj_tcd_get_encoder_input_buffer_size(p_j2k->m_tcd); | |
| 12702 if (!l_reuse_data) { | |
| 12703 if (l_current_tile_size > l_max_tile_size) { | |
| 12704 OPJ_BYTE *l_new_current_data = (OPJ_BYTE *) opj_realloc(l_current_data, | |
| 12705 l_current_tile_size); | |
| 12706 if (! l_new_current_data) { | |
| 12707 if (l_current_data) { | |
| 12708 opj_free(l_current_data); | |
| 12709 } | |
| 12710 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to encode all tiles\n"); | |
| 12711 return OPJ_FALSE; | |
| 12712 } | |
| 12713 l_current_data = l_new_current_data; | |
| 12714 l_max_tile_size = l_current_tile_size; | |
| 12715 } | |
| 12716 if (l_current_data == NULL) { | |
| 12717 /* Should not happen in practice, but will avoid Coverity to */ | |
| 12718 /* complain about a null pointer dereference */ | |
| 12719 assert(0); | |
| 12720 return OPJ_FALSE; | |
| 12721 } | |
| 12722 | |
| 12723 /* copy image data (32 bit) to l_current_data as contiguous, all-component, zero offset buffer */ | |
| 12724 /* 32 bit components @ 8 bit precision get converted to 8 bit */ | |
| 12725 /* 32 bit components @ 16 bit precision get converted to 16 bit */ | |
| 12726 opj_j2k_get_tile_data(p_j2k->m_tcd, l_current_data); | |
| 12727 | |
| 12728 /* now copy this data into the tile component */ | |
| 12729 if (! opj_tcd_copy_tile_data(p_j2k->m_tcd, l_current_data, | |
| 12730 l_current_tile_size)) { | |
| 12731 opj_event_msg(p_manager, EVT_ERROR, | |
| 12732 "Size mismatch between tile data and sent data."); | |
| 12733 opj_free(l_current_data); | |
| 12734 return OPJ_FALSE; | |
| 12735 } | |
| 12736 } | |
| 12737 | |
| 12738 if (! opj_j2k_post_write_tile(p_j2k, p_stream, p_manager)) { | |
| 12739 if (l_current_data) { | |
| 12740 opj_free(l_current_data); | |
| 12741 } | |
| 12742 return OPJ_FALSE; | |
| 12743 } | |
| 12744 } | |
| 12745 | |
| 12746 if (l_current_data) { | |
| 12747 opj_free(l_current_data); | |
| 12748 } | |
| 12749 return OPJ_TRUE; | |
| 12750 } | |
| 12751 | |
| 12752 OPJ_BOOL opj_j2k_end_compress(opj_j2k_t *p_j2k, | |
| 12753 opj_stream_private_t *p_stream, | |
| 12754 opj_event_mgr_t * p_manager) | |
| 12755 { | |
| 12756 /* customization of the encoding */ | |
| 12757 if (! opj_j2k_setup_end_compress(p_j2k, p_manager)) { | |
| 12758 return OPJ_FALSE; | |
| 12759 } | |
| 12760 | |
| 12761 if (! opj_j2k_exec(p_j2k, p_j2k->m_procedure_list, p_stream, p_manager)) { | |
| 12762 return OPJ_FALSE; | |
| 12763 } | |
| 12764 | |
| 12765 return OPJ_TRUE; | |
| 12766 } | |
| 12767 | |
| 12768 OPJ_BOOL opj_j2k_start_compress(opj_j2k_t *p_j2k, | |
| 12769 opj_stream_private_t *p_stream, | |
| 12770 opj_image_t * p_image, | |
| 12771 opj_event_mgr_t * p_manager) | |
| 12772 { | |
| 12773 /* preconditions */ | |
| 12774 assert(p_j2k != 00); | |
| 12775 assert(p_stream != 00); | |
| 12776 assert(p_manager != 00); | |
| 12777 | |
| 12778 p_j2k->m_private_image = opj_image_create0(); | |
| 12779 if (! p_j2k->m_private_image) { | |
| 12780 opj_event_msg(p_manager, EVT_ERROR, "Failed to allocate image header."); | |
| 12781 return OPJ_FALSE; | |
| 12782 } | |
| 12783 opj_copy_image_header(p_image, p_j2k->m_private_image); | |
| 12784 | |
| 12785 /* TODO_MSD: Find a better way */ | |
| 12786 if (p_image->comps) { | |
| 12787 OPJ_UINT32 it_comp; | |
| 12788 for (it_comp = 0 ; it_comp < p_image->numcomps; it_comp++) { | |
| 12789 if (p_image->comps[it_comp].data) { | |
| 12790 p_j2k->m_private_image->comps[it_comp].data = p_image->comps[it_comp].data; | |
| 12791 p_image->comps[it_comp].data = NULL; | |
| 12792 | |
| 12793 } | |
| 12794 } | |
| 12795 } | |
| 12796 | |
| 12797 /* customization of the validation */ | |
| 12798 if (! opj_j2k_setup_encoding_validation(p_j2k, p_manager)) { | |
| 12799 return OPJ_FALSE; | |
| 12800 } | |
| 12801 | |
| 12802 /* validation of the parameters codec */ | |
| 12803 if (! opj_j2k_exec(p_j2k, p_j2k->m_validation_list, p_stream, p_manager)) { | |
| 12804 return OPJ_FALSE; | |
| 12805 } | |
| 12806 | |
| 12807 /* customization of the encoding */ | |
| 12808 if (! opj_j2k_setup_header_writing(p_j2k, p_manager)) { | |
| 12809 return OPJ_FALSE; | |
| 12810 } | |
| 12811 | |
| 12812 /* write header */ | |
| 12813 if (! opj_j2k_exec(p_j2k, p_j2k->m_procedure_list, p_stream, p_manager)) { | |
| 12814 return OPJ_FALSE; | |
| 12815 } | |
| 12816 | |
| 12817 return OPJ_TRUE; | |
| 12818 } | |
| 12819 | |
| 12820 static OPJ_BOOL opj_j2k_pre_write_tile(opj_j2k_t * p_j2k, | |
| 12821 OPJ_UINT32 p_tile_index, | |
| 12822 opj_stream_private_t *p_stream, | |
| 12823 opj_event_mgr_t * p_manager) | |
| 12824 { | |
| 12825 (void)p_stream; | |
| 12826 if (p_tile_index != p_j2k->m_current_tile_number) { | |
| 12827 opj_event_msg(p_manager, EVT_ERROR, "The given tile index does not match."); | |
| 12828 return OPJ_FALSE; | |
| 12829 } | |
| 12830 | |
| 12831 opj_event_msg(p_manager, EVT_INFO, "tile number %d / %d\n", | |
| 12832 p_j2k->m_current_tile_number + 1, p_j2k->m_cp.tw * p_j2k->m_cp.th); | |
| 12833 | |
| 12834 p_j2k->m_specific_param.m_encoder.m_current_tile_part_number = 0; | |
| 12835 p_j2k->m_tcd->cur_totnum_tp = p_j2k->m_cp.tcps[p_tile_index].m_nb_tile_parts; | |
| 12836 p_j2k->m_specific_param.m_encoder.m_current_poc_tile_part_number = 0; | |
| 12837 | |
| 12838 /* initialisation before tile encoding */ | |
| 12839 if (! opj_tcd_init_encode_tile(p_j2k->m_tcd, p_j2k->m_current_tile_number, | |
| 12840 p_manager)) { | |
| 12841 return OPJ_FALSE; | |
| 12842 } | |
| 12843 | |
| 12844 return OPJ_TRUE; | |
| 12845 } | |
| 12846 | |
| 12847 static void opj_get_tile_dimensions(opj_image_t * l_image, | |
| 12848 opj_tcd_tilecomp_t * l_tilec, | |
| 12849 opj_image_comp_t * l_img_comp, | |
| 12850 OPJ_UINT32* l_size_comp, | |
| 12851 OPJ_UINT32* l_width, | |
| 12852 OPJ_UINT32* l_height, | |
| 12853 OPJ_UINT32* l_offset_x, | |
| 12854 OPJ_UINT32* l_offset_y, | |
| 12855 OPJ_UINT32* l_image_width, | |
| 12856 OPJ_UINT32* l_stride, | |
| 12857 OPJ_UINT32* l_tile_offset) | |
| 12858 { | |
| 12859 OPJ_UINT32 l_remaining; | |
| 12860 *l_size_comp = l_img_comp->prec >> 3; /* (/8) */ | |
| 12861 l_remaining = l_img_comp->prec & 7; /* (%8) */ | |
| 12862 if (l_remaining) { | |
| 12863 *l_size_comp += 1; | |
| 12864 } | |
| 12865 | |
| 12866 if (*l_size_comp == 3) { | |
| 12867 *l_size_comp = 4; | |
| 12868 } | |
| 12869 | |
| 12870 *l_width = (OPJ_UINT32)(l_tilec->x1 - l_tilec->x0); | |
| 12871 *l_height = (OPJ_UINT32)(l_tilec->y1 - l_tilec->y0); | |
| 12872 *l_offset_x = opj_uint_ceildiv(l_image->x0, l_img_comp->dx); | |
| 12873 *l_offset_y = opj_uint_ceildiv(l_image->y0, l_img_comp->dy); | |
| 12874 *l_image_width = opj_uint_ceildiv(l_image->x1 - l_image->x0, l_img_comp->dx); | |
| 12875 *l_stride = *l_image_width - *l_width; | |
| 12876 *l_tile_offset = ((OPJ_UINT32)l_tilec->x0 - *l_offset_x) + (( | |
| 12877 OPJ_UINT32)l_tilec->y0 - *l_offset_y) * *l_image_width; | |
| 12878 } | |
| 12879 | |
| 12880 static void opj_j2k_get_tile_data(opj_tcd_t * p_tcd, OPJ_BYTE * p_data) | |
| 12881 { | |
| 12882 OPJ_UINT32 i, j, k = 0; | |
| 12883 | |
| 12884 for (i = 0; i < p_tcd->image->numcomps; ++i) { | |
| 12885 opj_image_t * l_image = p_tcd->image; | |
| 12886 OPJ_INT32 * l_src_ptr; | |
| 12887 opj_tcd_tilecomp_t * l_tilec = p_tcd->tcd_image->tiles->comps + i; | |
| 12888 opj_image_comp_t * l_img_comp = l_image->comps + i; | |
| 12889 OPJ_UINT32 l_size_comp, l_width, l_height, l_offset_x, l_offset_y, | |
| 12890 l_image_width, l_stride, l_tile_offset; | |
| 12891 | |
| 12892 opj_get_tile_dimensions(l_image, | |
| 12893 l_tilec, | |
| 12894 l_img_comp, | |
| 12895 &l_size_comp, | |
| 12896 &l_width, | |
| 12897 &l_height, | |
| 12898 &l_offset_x, | |
| 12899 &l_offset_y, | |
| 12900 &l_image_width, | |
| 12901 &l_stride, | |
| 12902 &l_tile_offset); | |
| 12903 | |
| 12904 l_src_ptr = l_img_comp->data + l_tile_offset; | |
| 12905 | |
| 12906 switch (l_size_comp) { | |
| 12907 case 1: { | |
| 12908 OPJ_CHAR * l_dest_ptr = (OPJ_CHAR*) p_data; | |
| 12909 if (l_img_comp->sgnd) { | |
| 12910 for (j = 0; j < l_height; ++j) { | |
| 12911 for (k = 0; k < l_width; ++k) { | |
| 12912 *(l_dest_ptr) = (OPJ_CHAR)(*l_src_ptr); | |
| 12913 ++l_dest_ptr; | |
| 12914 ++l_src_ptr; | |
| 12915 } | |
| 12916 l_src_ptr += l_stride; | |
| 12917 } | |
| 12918 } else { | |
| 12919 for (j = 0; j < l_height; ++j) { | |
| 12920 for (k = 0; k < l_width; ++k) { | |
| 12921 *(l_dest_ptr) = (OPJ_CHAR)((*l_src_ptr) & 0xff); | |
| 12922 ++l_dest_ptr; | |
| 12923 ++l_src_ptr; | |
| 12924 } | |
| 12925 l_src_ptr += l_stride; | |
| 12926 } | |
| 12927 } | |
| 12928 | |
| 12929 p_data = (OPJ_BYTE*) l_dest_ptr; | |
| 12930 } | |
| 12931 break; | |
| 12932 case 2: { | |
| 12933 OPJ_INT16 * l_dest_ptr = (OPJ_INT16 *) p_data; | |
| 12934 if (l_img_comp->sgnd) { | |
| 12935 for (j = 0; j < l_height; ++j) { | |
| 12936 for (k = 0; k < l_width; ++k) { | |
| 12937 *(l_dest_ptr++) = (OPJ_INT16)(*(l_src_ptr++)); | |
| 12938 } | |
| 12939 l_src_ptr += l_stride; | |
| 12940 } | |
| 12941 } else { | |
| 12942 for (j = 0; j < l_height; ++j) { | |
| 12943 for (k = 0; k < l_width; ++k) { | |
| 12944 *(l_dest_ptr++) = (OPJ_INT16)((*(l_src_ptr++)) & 0xffff); | |
| 12945 } | |
| 12946 l_src_ptr += l_stride; | |
| 12947 } | |
| 12948 } | |
| 12949 | |
| 12950 p_data = (OPJ_BYTE*) l_dest_ptr; | |
| 12951 } | |
| 12952 break; | |
| 12953 case 4: { | |
| 12954 OPJ_INT32 * l_dest_ptr = (OPJ_INT32 *) p_data; | |
| 12955 for (j = 0; j < l_height; ++j) { | |
| 12956 for (k = 0; k < l_width; ++k) { | |
| 12957 *(l_dest_ptr++) = *(l_src_ptr++); | |
| 12958 } | |
| 12959 l_src_ptr += l_stride; | |
| 12960 } | |
| 12961 | |
| 12962 p_data = (OPJ_BYTE*) l_dest_ptr; | |
| 12963 } | |
| 12964 break; | |
| 12965 } | |
| 12966 } | |
| 12967 } | |
| 12968 | |
| 12969 static OPJ_BOOL opj_j2k_post_write_tile(opj_j2k_t * p_j2k, | |
| 12970 opj_stream_private_t *p_stream, | |
| 12971 opj_event_mgr_t * p_manager) | |
| 12972 { | |
| 12973 OPJ_UINT32 l_nb_bytes_written; | |
| 12974 OPJ_BYTE * l_current_data = 00; | |
| 12975 OPJ_UINT32 l_tile_size = 0; | |
| 12976 OPJ_UINT32 l_available_data; | |
| 12977 | |
| 12978 /* preconditions */ | |
| 12979 assert(p_j2k->m_specific_param.m_encoder.m_encoded_tile_data); | |
| 12980 | |
| 12981 l_tile_size = p_j2k->m_specific_param.m_encoder.m_encoded_tile_size; | |
| 12982 l_available_data = l_tile_size; | |
| 12983 l_current_data = p_j2k->m_specific_param.m_encoder.m_encoded_tile_data; | |
| 12984 | |
| 12985 l_nb_bytes_written = 0; | |
| 12986 if (! opj_j2k_write_first_tile_part(p_j2k, l_current_data, &l_nb_bytes_written, | |
| 12987 l_available_data, p_stream, p_manager)) { | |
| 12988 return OPJ_FALSE; | |
| 12989 } | |
| 12990 l_current_data += l_nb_bytes_written; | |
| 12991 l_available_data -= l_nb_bytes_written; | |
| 12992 | |
| 12993 l_nb_bytes_written = 0; | |
| 12994 if (! opj_j2k_write_all_tile_parts(p_j2k, l_current_data, &l_nb_bytes_written, | |
| 12995 l_available_data, p_stream, p_manager)) { | |
| 12996 return OPJ_FALSE; | |
| 12997 } | |
| 12998 | |
| 12999 l_available_data -= l_nb_bytes_written; | |
| 13000 l_nb_bytes_written = l_tile_size - l_available_data; | |
| 13001 | |
| 13002 if (opj_stream_write_data(p_stream, | |
| 13003 p_j2k->m_specific_param.m_encoder.m_encoded_tile_data, | |
| 13004 l_nb_bytes_written, p_manager) != l_nb_bytes_written) { | |
| 13005 return OPJ_FALSE; | |
| 13006 } | |
| 13007 | |
| 13008 ++p_j2k->m_current_tile_number; | |
| 13009 | |
| 13010 return OPJ_TRUE; | |
| 13011 } | |
| 13012 | |
| 13013 static OPJ_BOOL opj_j2k_setup_end_compress(opj_j2k_t *p_j2k, | |
| 13014 opj_event_mgr_t * p_manager) | |
| 13015 { | |
| 13016 /* preconditions */ | |
| 13017 assert(p_j2k != 00); | |
| 13018 assert(p_manager != 00); | |
| 13019 | |
| 13020 /* DEVELOPER CORNER, insert your custom procedures */ | |
| 13021 if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list, | |
| 13022 (opj_procedure)opj_j2k_write_eoc, p_manager)) { | |
| 13023 return OPJ_FALSE; | |
| 13024 } | |
| 13025 | |
| 13026 if (p_j2k->m_specific_param.m_encoder.m_TLM) { | |
| 13027 if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list, | |
| 13028 (opj_procedure)opj_j2k_write_updated_tlm, p_manager)) { | |
| 13029 return OPJ_FALSE; | |
| 13030 } | |
| 13031 } | |
| 13032 | |
| 13033 if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list, | |
| 13034 (opj_procedure)opj_j2k_write_epc, p_manager)) { | |
| 13035 return OPJ_FALSE; | |
| 13036 } | |
| 13037 if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list, | |
| 13038 (opj_procedure)opj_j2k_end_encoding, p_manager)) { | |
| 13039 return OPJ_FALSE; | |
| 13040 } | |
| 13041 if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list, | |
| 13042 (opj_procedure)opj_j2k_destroy_header_memory, p_manager)) { | |
| 13043 return OPJ_FALSE; | |
| 13044 } | |
| 13045 return OPJ_TRUE; | |
| 13046 } | |
| 13047 | |
| 13048 static OPJ_BOOL opj_j2k_setup_encoding_validation(opj_j2k_t *p_j2k, | |
| 13049 opj_event_mgr_t * p_manager) | |
| 13050 { | |
| 13051 /* preconditions */ | |
| 13052 assert(p_j2k != 00); | |
| 13053 assert(p_manager != 00); | |
| 13054 | |
| 13055 if (! opj_procedure_list_add_procedure(p_j2k->m_validation_list, | |
| 13056 (opj_procedure)opj_j2k_build_encoder, p_manager)) { | |
| 13057 return OPJ_FALSE; | |
| 13058 } | |
| 13059 if (! opj_procedure_list_add_procedure(p_j2k->m_validation_list, | |
| 13060 (opj_procedure)opj_j2k_encoding_validation, p_manager)) { | |
| 13061 return OPJ_FALSE; | |
| 13062 } | |
| 13063 | |
| 13064 /* DEVELOPER CORNER, add your custom validation procedure */ | |
| 13065 if (! opj_procedure_list_add_procedure(p_j2k->m_validation_list, | |
| 13066 (opj_procedure)opj_j2k_mct_validation, p_manager)) { | |
| 13067 return OPJ_FALSE; | |
| 13068 } | |
| 13069 | |
| 13070 return OPJ_TRUE; | |
| 13071 } | |
| 13072 | |
| 13073 static OPJ_BOOL opj_j2k_setup_header_writing(opj_j2k_t *p_j2k, | |
| 13074 opj_event_mgr_t * p_manager) | |
| 13075 { | |
| 13076 /* preconditions */ | |
| 13077 assert(p_j2k != 00); | |
| 13078 assert(p_manager != 00); | |
| 13079 | |
| 13080 if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list, | |
| 13081 (opj_procedure)opj_j2k_init_info, p_manager)) { | |
| 13082 return OPJ_FALSE; | |
| 13083 } | |
| 13084 if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list, | |
| 13085 (opj_procedure)opj_j2k_write_soc, p_manager)) { | |
| 13086 return OPJ_FALSE; | |
| 13087 } | |
| 13088 if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list, | |
| 13089 (opj_procedure)opj_j2k_write_siz, p_manager)) { | |
| 13090 return OPJ_FALSE; | |
| 13091 } | |
| 13092 if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list, | |
| 13093 (opj_procedure)opj_j2k_write_cod, p_manager)) { | |
| 13094 return OPJ_FALSE; | |
| 13095 } | |
| 13096 if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list, | |
| 13097 (opj_procedure)opj_j2k_write_qcd, p_manager)) { | |
| 13098 return OPJ_FALSE; | |
| 13099 } | |
| 13100 if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list, | |
| 13101 (opj_procedure)opj_j2k_write_all_coc, p_manager)) { | |
| 13102 return OPJ_FALSE; | |
| 13103 } | |
| 13104 if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list, | |
| 13105 (opj_procedure)opj_j2k_write_all_qcc, p_manager)) { | |
| 13106 return OPJ_FALSE; | |
| 13107 } | |
| 13108 | |
| 13109 if (p_j2k->m_specific_param.m_encoder.m_TLM) { | |
| 13110 if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list, | |
| 13111 (opj_procedure)opj_j2k_write_tlm, p_manager)) { | |
| 13112 return OPJ_FALSE; | |
| 13113 } | |
| 13114 | |
| 13115 if (p_j2k->m_cp.rsiz == OPJ_PROFILE_CINEMA_4K) { | |
| 13116 if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list, | |
| 13117 (opj_procedure)opj_j2k_write_poc, p_manager)) { | |
| 13118 return OPJ_FALSE; | |
| 13119 } | |
| 13120 } | |
| 13121 } | |
| 13122 | |
| 13123 if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list, | |
| 13124 (opj_procedure)opj_j2k_write_regions, p_manager)) { | |
| 13125 return OPJ_FALSE; | |
| 13126 } | |
| 13127 | |
| 13128 if (p_j2k->m_cp.comment != 00) { | |
| 13129 if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list, | |
| 13130 (opj_procedure)opj_j2k_write_com, p_manager)) { | |
| 13131 return OPJ_FALSE; | |
| 13132 } | |
| 13133 } | |
| 13134 | |
| 13135 /* DEVELOPER CORNER, insert your custom procedures */ | |
| 13136 if ((p_j2k->m_cp.rsiz & (OPJ_PROFILE_PART2 | OPJ_EXTENSION_MCT)) == | |
| 13137 (OPJ_PROFILE_PART2 | OPJ_EXTENSION_MCT)) { | |
| 13138 if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list, | |
| 13139 (opj_procedure)opj_j2k_write_mct_data_group, p_manager)) { | |
| 13140 return OPJ_FALSE; | |
| 13141 } | |
| 13142 } | |
| 13143 /* End of Developer Corner */ | |
| 13144 | |
| 13145 if (p_j2k->cstr_index) { | |
| 13146 if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list, | |
| 13147 (opj_procedure)opj_j2k_get_end_header, p_manager)) { | |
| 13148 return OPJ_FALSE; | |
| 13149 } | |
| 13150 } | |
| 13151 | |
| 13152 if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list, | |
| 13153 (opj_procedure)opj_j2k_create_tcd, p_manager)) { | |
| 13154 return OPJ_FALSE; | |
| 13155 } | |
| 13156 if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list, | |
| 13157 (opj_procedure)opj_j2k_update_rates, p_manager)) { | |
| 13158 return OPJ_FALSE; | |
| 13159 } | |
| 13160 | |
| 13161 return OPJ_TRUE; | |
| 13162 } | |
| 13163 | |
| 13164 static OPJ_BOOL opj_j2k_write_first_tile_part(opj_j2k_t *p_j2k, | |
| 13165 OPJ_BYTE * p_data, | |
| 13166 OPJ_UINT32 * p_data_written, | |
| 13167 OPJ_UINT32 total_data_size, | |
| 13168 opj_stream_private_t *p_stream, | |
| 13169 struct opj_event_mgr * p_manager) | |
| 13170 { | |
| 13171 OPJ_UINT32 l_nb_bytes_written = 0; | |
| 13172 OPJ_UINT32 l_current_nb_bytes_written; | |
| 13173 OPJ_BYTE * l_begin_data = 00; | |
| 13174 | |
| 13175 opj_tcd_t * l_tcd = 00; | |
| 13176 opj_cp_t * l_cp = 00; | |
| 13177 | |
| 13178 l_tcd = p_j2k->m_tcd; | |
| 13179 l_cp = &(p_j2k->m_cp); | |
| 13180 | |
| 13181 l_tcd->cur_pino = 0; | |
| 13182 | |
| 13183 /*Get number of tile parts*/ | |
| 13184 p_j2k->m_specific_param.m_encoder.m_current_poc_tile_part_number = 0; | |
| 13185 | |
| 13186 /* INDEX >> */ | |
| 13187 /* << INDEX */ | |
| 13188 | |
| 13189 l_current_nb_bytes_written = 0; | |
| 13190 l_begin_data = p_data; | |
| 13191 if (! opj_j2k_write_sot(p_j2k, p_data, total_data_size, | |
| 13192 &l_current_nb_bytes_written, p_stream, | |
| 13193 p_manager)) { | |
| 13194 return OPJ_FALSE; | |
| 13195 } | |
| 13196 | |
| 13197 l_nb_bytes_written += l_current_nb_bytes_written; | |
| 13198 p_data += l_current_nb_bytes_written; | |
| 13199 total_data_size -= l_current_nb_bytes_written; | |
| 13200 | |
| 13201 if (!OPJ_IS_CINEMA(l_cp->rsiz)) { | |
| 13202 #if 0 | |
| 13203 for (compno = 1; compno < p_j2k->m_private_image->numcomps; compno++) { | |
| 13204 l_current_nb_bytes_written = 0; | |
| 13205 opj_j2k_write_coc_in_memory(p_j2k, compno, p_data, &l_current_nb_bytes_written, | |
| 13206 p_manager); | |
| 13207 l_nb_bytes_written += l_current_nb_bytes_written; | |
| 13208 p_data += l_current_nb_bytes_written; | |
| 13209 total_data_size -= l_current_nb_bytes_written; | |
| 13210 | |
| 13211 l_current_nb_bytes_written = 0; | |
| 13212 opj_j2k_write_qcc_in_memory(p_j2k, compno, p_data, &l_current_nb_bytes_written, | |
| 13213 p_manager); | |
| 13214 l_nb_bytes_written += l_current_nb_bytes_written; | |
| 13215 p_data += l_current_nb_bytes_written; | |
| 13216 total_data_size -= l_current_nb_bytes_written; | |
| 13217 } | |
| 13218 #endif | |
| 13219 if (l_cp->tcps[p_j2k->m_current_tile_number].POC) { | |
| 13220 l_current_nb_bytes_written = 0; | |
| 13221 opj_j2k_write_poc_in_memory(p_j2k, p_data, &l_current_nb_bytes_written, | |
| 13222 p_manager); | |
| 13223 l_nb_bytes_written += l_current_nb_bytes_written; | |
| 13224 p_data += l_current_nb_bytes_written; | |
| 13225 total_data_size -= l_current_nb_bytes_written; | |
| 13226 } | |
| 13227 } | |
| 13228 | |
| 13229 l_current_nb_bytes_written = 0; | |
| 13230 if (! opj_j2k_write_sod(p_j2k, l_tcd, p_data, &l_current_nb_bytes_written, | |
| 13231 total_data_size, p_stream, p_manager)) { | |
| 13232 return OPJ_FALSE; | |
| 13233 } | |
| 13234 | |
| 13235 l_nb_bytes_written += l_current_nb_bytes_written; | |
| 13236 * p_data_written = l_nb_bytes_written; | |
| 13237 | |
| 13238 /* Writing Psot in SOT marker */ | |
| 13239 opj_write_bytes(l_begin_data + 6, l_nb_bytes_written, | |
| 13240 4); /* PSOT */ | |
| 13241 | |
| 13242 if (p_j2k->m_specific_param.m_encoder.m_TLM) { | |
| 13243 opj_j2k_update_tlm(p_j2k, l_nb_bytes_written); | |
| 13244 } | |
| 13245 | |
| 13246 return OPJ_TRUE; | |
| 13247 } | |
| 13248 | |
| 13249 static OPJ_BOOL opj_j2k_write_all_tile_parts(opj_j2k_t *p_j2k, | |
| 13250 OPJ_BYTE * p_data, | |
| 13251 OPJ_UINT32 * p_data_written, | |
| 13252 OPJ_UINT32 total_data_size, | |
| 13253 opj_stream_private_t *p_stream, | |
| 13254 struct opj_event_mgr * p_manager | |
| 13255 ) | |
| 13256 { | |
| 13257 OPJ_UINT32 tilepartno = 0; | |
| 13258 OPJ_UINT32 l_nb_bytes_written = 0; | |
| 13259 OPJ_UINT32 l_current_nb_bytes_written; | |
| 13260 OPJ_UINT32 l_part_tile_size; | |
| 13261 OPJ_UINT32 tot_num_tp; | |
| 13262 OPJ_UINT32 pino; | |
| 13263 | |
| 13264 OPJ_BYTE * l_begin_data; | |
| 13265 opj_tcp_t *l_tcp = 00; | |
| 13266 opj_tcd_t * l_tcd = 00; | |
| 13267 opj_cp_t * l_cp = 00; | |
| 13268 | |
| 13269 l_tcd = p_j2k->m_tcd; | |
| 13270 l_cp = &(p_j2k->m_cp); | |
| 13271 l_tcp = l_cp->tcps + p_j2k->m_current_tile_number; | |
| 13272 | |
| 13273 /*Get number of tile parts*/ | |
| 13274 tot_num_tp = opj_j2k_get_num_tp(l_cp, 0, p_j2k->m_current_tile_number); | |
| 13275 | |
| 13276 /* start writing remaining tile parts */ | |
| 13277 ++p_j2k->m_specific_param.m_encoder.m_current_tile_part_number; | |
| 13278 for (tilepartno = 1; tilepartno < tot_num_tp ; ++tilepartno) { | |
| 13279 p_j2k->m_specific_param.m_encoder.m_current_poc_tile_part_number = tilepartno; | |
| 13280 l_current_nb_bytes_written = 0; | |
| 13281 l_part_tile_size = 0; | |
| 13282 l_begin_data = p_data; | |
| 13283 | |
| 13284 if (! opj_j2k_write_sot(p_j2k, p_data, | |
| 13285 total_data_size, | |
| 13286 &l_current_nb_bytes_written, | |
| 13287 p_stream, | |
| 13288 p_manager)) { | |
| 13289 return OPJ_FALSE; | |
| 13290 } | |
| 13291 | |
| 13292 l_nb_bytes_written += l_current_nb_bytes_written; | |
| 13293 p_data += l_current_nb_bytes_written; | |
| 13294 total_data_size -= l_current_nb_bytes_written; | |
| 13295 l_part_tile_size += l_current_nb_bytes_written; | |
| 13296 | |
| 13297 l_current_nb_bytes_written = 0; | |
| 13298 if (! opj_j2k_write_sod(p_j2k, l_tcd, p_data, &l_current_nb_bytes_written, | |
| 13299 total_data_size, p_stream, p_manager)) { | |
| 13300 return OPJ_FALSE; | |
| 13301 } | |
| 13302 | |
| 13303 p_data += l_current_nb_bytes_written; | |
| 13304 l_nb_bytes_written += l_current_nb_bytes_written; | |
| 13305 total_data_size -= l_current_nb_bytes_written; | |
| 13306 l_part_tile_size += l_current_nb_bytes_written; | |
| 13307 | |
| 13308 /* Writing Psot in SOT marker */ | |
| 13309 opj_write_bytes(l_begin_data + 6, l_part_tile_size, | |
| 13310 4); /* PSOT */ | |
| 13311 | |
| 13312 if (p_j2k->m_specific_param.m_encoder.m_TLM) { | |
| 13313 opj_j2k_update_tlm(p_j2k, l_part_tile_size); | |
| 13314 } | |
| 13315 | |
| 13316 ++p_j2k->m_specific_param.m_encoder.m_current_tile_part_number; | |
| 13317 } | |
| 13318 | |
| 13319 for (pino = 1; pino <= l_tcp->numpocs; ++pino) { | |
| 13320 l_tcd->cur_pino = pino; | |
| 13321 | |
| 13322 /*Get number of tile parts*/ | |
| 13323 tot_num_tp = opj_j2k_get_num_tp(l_cp, pino, p_j2k->m_current_tile_number); | |
| 13324 for (tilepartno = 0; tilepartno < tot_num_tp ; ++tilepartno) { | |
| 13325 p_j2k->m_specific_param.m_encoder.m_current_poc_tile_part_number = tilepartno; | |
| 13326 l_current_nb_bytes_written = 0; | |
| 13327 l_part_tile_size = 0; | |
| 13328 l_begin_data = p_data; | |
| 13329 | |
| 13330 if (! opj_j2k_write_sot(p_j2k, p_data, | |
| 13331 total_data_size, | |
| 13332 &l_current_nb_bytes_written, p_stream, | |
| 13333 p_manager)) { | |
| 13334 return OPJ_FALSE; | |
| 13335 } | |
| 13336 | |
| 13337 l_nb_bytes_written += l_current_nb_bytes_written; | |
| 13338 p_data += l_current_nb_bytes_written; | |
| 13339 total_data_size -= l_current_nb_bytes_written; | |
| 13340 l_part_tile_size += l_current_nb_bytes_written; | |
| 13341 | |
| 13342 l_current_nb_bytes_written = 0; | |
| 13343 | |
| 13344 if (! opj_j2k_write_sod(p_j2k, l_tcd, p_data, &l_current_nb_bytes_written, | |
| 13345 total_data_size, p_stream, p_manager)) { | |
| 13346 return OPJ_FALSE; | |
| 13347 } | |
| 13348 | |
| 13349 l_nb_bytes_written += l_current_nb_bytes_written; | |
| 13350 p_data += l_current_nb_bytes_written; | |
| 13351 total_data_size -= l_current_nb_bytes_written; | |
| 13352 l_part_tile_size += l_current_nb_bytes_written; | |
| 13353 | |
| 13354 /* Writing Psot in SOT marker */ | |
| 13355 opj_write_bytes(l_begin_data + 6, l_part_tile_size, | |
| 13356 4); /* PSOT */ | |
| 13357 | |
| 13358 if (p_j2k->m_specific_param.m_encoder.m_TLM) { | |
| 13359 opj_j2k_update_tlm(p_j2k, l_part_tile_size); | |
| 13360 } | |
| 13361 | |
| 13362 ++p_j2k->m_specific_param.m_encoder.m_current_tile_part_number; | |
| 13363 } | |
| 13364 } | |
| 13365 | |
| 13366 *p_data_written = l_nb_bytes_written; | |
| 13367 | |
| 13368 return OPJ_TRUE; | |
| 13369 } | |
| 13370 | |
| 13371 static OPJ_BOOL opj_j2k_write_updated_tlm(opj_j2k_t *p_j2k, | |
| 13372 struct opj_stream_private *p_stream, | |
| 13373 struct opj_event_mgr * p_manager) | |
| 13374 { | |
| 13375 OPJ_UINT32 l_tlm_size; | |
| 13376 OPJ_OFF_T l_tlm_position, l_current_position; | |
| 13377 OPJ_UINT32 size_per_tile_part; | |
| 13378 | |
| 13379 /* preconditions */ | |
| 13380 assert(p_j2k != 00); | |
| 13381 assert(p_manager != 00); | |
| 13382 assert(p_stream != 00); | |
| 13383 | |
| 13384 size_per_tile_part = p_j2k->m_specific_param.m_encoder.m_Ttlmi_is_byte ? 5 : 6; | |
| 13385 l_tlm_size = size_per_tile_part * | |
| 13386 p_j2k->m_specific_param.m_encoder.m_total_tile_parts; | |
| 13387 l_tlm_position = 6 + p_j2k->m_specific_param.m_encoder.m_tlm_start; | |
| 13388 l_current_position = opj_stream_tell(p_stream); | |
| 13389 | |
| 13390 if (! opj_stream_seek(p_stream, l_tlm_position, p_manager)) { | |
| 13391 return OPJ_FALSE; | |
| 13392 } | |
| 13393 | |
| 13394 if (opj_stream_write_data(p_stream, | |
| 13395 p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer, l_tlm_size, | |
| 13396 p_manager) != l_tlm_size) { | |
| 13397 return OPJ_FALSE; | |
| 13398 } | |
| 13399 | |
| 13400 if (! opj_stream_seek(p_stream, l_current_position, p_manager)) { | |
| 13401 return OPJ_FALSE; | |
| 13402 } | |
| 13403 | |
| 13404 return OPJ_TRUE; | |
| 13405 } | |
| 13406 | |
| 13407 static OPJ_BOOL opj_j2k_end_encoding(opj_j2k_t *p_j2k, | |
| 13408 struct opj_stream_private *p_stream, | |
| 13409 struct opj_event_mgr * p_manager) | |
| 13410 { | |
| 13411 /* preconditions */ | |
| 13412 assert(p_j2k != 00); | |
| 13413 assert(p_manager != 00); | |
| 13414 assert(p_stream != 00); | |
| 13415 | |
| 13416 OPJ_UNUSED(p_stream); | |
| 13417 OPJ_UNUSED(p_manager); | |
| 13418 | |
| 13419 opj_tcd_destroy(p_j2k->m_tcd); | |
| 13420 p_j2k->m_tcd = 00; | |
| 13421 | |
| 13422 if (p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer) { | |
| 13423 opj_free(p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer); | |
| 13424 p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer = 0; | |
| 13425 p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current = 0; | |
| 13426 } | |
| 13427 | |
| 13428 if (p_j2k->m_specific_param.m_encoder.m_encoded_tile_data) { | |
| 13429 opj_free(p_j2k->m_specific_param.m_encoder.m_encoded_tile_data); | |
| 13430 p_j2k->m_specific_param.m_encoder.m_encoded_tile_data = 0; | |
| 13431 } | |
| 13432 | |
| 13433 p_j2k->m_specific_param.m_encoder.m_encoded_tile_size = 0; | |
| 13434 | |
| 13435 return OPJ_TRUE; | |
| 13436 } | |
| 13437 | |
| 13438 /** | |
| 13439 * Destroys the memory associated with the decoding of headers. | |
| 13440 */ | |
| 13441 static OPJ_BOOL opj_j2k_destroy_header_memory(opj_j2k_t * p_j2k, | |
| 13442 opj_stream_private_t *p_stream, | |
| 13443 opj_event_mgr_t * p_manager | |
| 13444 ) | |
| 13445 { | |
| 13446 /* preconditions */ | |
| 13447 assert(p_j2k != 00); | |
| 13448 assert(p_stream != 00); | |
| 13449 assert(p_manager != 00); | |
| 13450 | |
| 13451 OPJ_UNUSED(p_stream); | |
| 13452 OPJ_UNUSED(p_manager); | |
| 13453 | |
| 13454 if (p_j2k->m_specific_param.m_encoder.m_header_tile_data) { | |
| 13455 opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data); | |
| 13456 p_j2k->m_specific_param.m_encoder.m_header_tile_data = 0; | |
| 13457 } | |
| 13458 | |
| 13459 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0; | |
| 13460 | |
| 13461 return OPJ_TRUE; | |
| 13462 } | |
| 13463 | |
| 13464 static OPJ_BOOL opj_j2k_init_info(opj_j2k_t *p_j2k, | |
| 13465 struct opj_stream_private *p_stream, | |
| 13466 struct opj_event_mgr * p_manager) | |
| 13467 { | |
| 13468 opj_codestream_info_t * l_cstr_info = 00; | |
| 13469 | |
| 13470 /* preconditions */ | |
| 13471 assert(p_j2k != 00); | |
| 13472 assert(p_manager != 00); | |
| 13473 assert(p_stream != 00); | |
| 13474 (void)l_cstr_info; | |
| 13475 | |
| 13476 OPJ_UNUSED(p_stream); | |
| 13477 | |
| 13478 /* TODO mergeV2: check this part which use cstr_info */ | |
| 13479 /*l_cstr_info = p_j2k->cstr_info; | |
| 13480 | |
| 13481 if (l_cstr_info) { | |
| 13482 OPJ_UINT32 compno; | |
| 13483 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)); | |
| 13484 | |
| 13485 l_cstr_info->image_w = p_j2k->m_image->x1 - p_j2k->m_image->x0; | |
| 13486 l_cstr_info->image_h = p_j2k->m_image->y1 - p_j2k->m_image->y0; | |
| 13487 | |
| 13488 l_cstr_info->prog = (&p_j2k->m_cp.tcps[0])->prg; | |
| 13489 | |
| 13490 l_cstr_info->tw = p_j2k->m_cp.tw; | |
| 13491 l_cstr_info->th = p_j2k->m_cp.th; | |
| 13492 | |
| 13493 l_cstr_info->tile_x = p_j2k->m_cp.tdx;*/ /* new version parser */ | |
| 13494 /*l_cstr_info->tile_y = p_j2k->m_cp.tdy;*/ /* new version parser */ | |
| 13495 /*l_cstr_info->tile_Ox = p_j2k->m_cp.tx0;*/ /* new version parser */ | |
| 13496 /*l_cstr_info->tile_Oy = p_j2k->m_cp.ty0;*/ /* new version parser */ | |
| 13497 | |
| 13498 /*l_cstr_info->numcomps = p_j2k->m_image->numcomps; | |
| 13499 | |
| 13500 l_cstr_info->numlayers = (&p_j2k->m_cp.tcps[0])->numlayers; | |
| 13501 | |
| 13502 l_cstr_info->numdecompos = (OPJ_INT32*) opj_malloc(p_j2k->m_image->numcomps * sizeof(OPJ_INT32)); | |
| 13503 | |
| 13504 for (compno=0; compno < p_j2k->m_image->numcomps; compno++) { | |
| 13505 l_cstr_info->numdecompos[compno] = (&p_j2k->m_cp.tcps[0])->tccps->numresolutions - 1; | |
| 13506 } | |
| 13507 | |
| 13508 l_cstr_info->D_max = 0.0; */ /* ADD Marcela */ | |
| 13509 | |
| 13510 /*l_cstr_info->main_head_start = opj_stream_tell(p_stream);*/ /* position of SOC */ | |
| 13511 | |
| 13512 /*l_cstr_info->maxmarknum = 100; | |
| 13513 l_cstr_info->marker = (opj_marker_info_t *) opj_malloc(l_cstr_info->maxmarknum * sizeof(opj_marker_info_t)); | |
| 13514 l_cstr_info->marknum = 0; | |
| 13515 }*/ | |
| 13516 | |
| 13517 return opj_j2k_calculate_tp(p_j2k, &(p_j2k->m_cp), | |
| 13518 &p_j2k->m_specific_param.m_encoder.m_total_tile_parts, p_j2k->m_private_image, | |
| 13519 p_manager); | |
| 13520 } | |
| 13521 | |
| 13522 /** | |
| 13523 * Creates a tile-coder encoder. | |
| 13524 * | |
| 13525 * @param p_stream the stream to write data to. | |
| 13526 * @param p_j2k J2K codec. | |
| 13527 * @param p_manager the user event manager. | |
| 13528 */ | |
| 13529 static OPJ_BOOL opj_j2k_create_tcd(opj_j2k_t *p_j2k, | |
| 13530 opj_stream_private_t *p_stream, | |
| 13531 opj_event_mgr_t * p_manager | |
| 13532 ) | |
| 13533 { | |
| 13534 /* preconditions */ | |
| 13535 assert(p_j2k != 00); | |
| 13536 assert(p_manager != 00); | |
| 13537 assert(p_stream != 00); | |
| 13538 | |
| 13539 OPJ_UNUSED(p_stream); | |
| 13540 | |
| 13541 p_j2k->m_tcd = opj_tcd_create(OPJ_FALSE); | |
| 13542 | |
| 13543 if (! p_j2k->m_tcd) { | |
| 13544 opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to create Tile Coder\n"); | |
| 13545 return OPJ_FALSE; | |
| 13546 } | |
| 13547 | |
| 13548 if (!opj_tcd_init(p_j2k->m_tcd, p_j2k->m_private_image, &p_j2k->m_cp, | |
| 13549 p_j2k->m_tp)) { | |
| 13550 opj_tcd_destroy(p_j2k->m_tcd); | |
| 13551 p_j2k->m_tcd = 00; | |
| 13552 return OPJ_FALSE; | |
| 13553 } | |
| 13554 | |
| 13555 return OPJ_TRUE; | |
| 13556 } | |
| 13557 | |
| 13558 OPJ_BOOL opj_j2k_write_tile(opj_j2k_t * p_j2k, | |
| 13559 OPJ_UINT32 p_tile_index, | |
| 13560 OPJ_BYTE * p_data, | |
| 13561 OPJ_UINT32 p_data_size, | |
| 13562 opj_stream_private_t *p_stream, | |
| 13563 opj_event_mgr_t * p_manager) | |
| 13564 { | |
| 13565 if (! opj_j2k_pre_write_tile(p_j2k, p_tile_index, p_stream, p_manager)) { | |
| 13566 opj_event_msg(p_manager, EVT_ERROR, | |
| 13567 "Error while opj_j2k_pre_write_tile with tile index = %d\n", p_tile_index); | |
| 13568 return OPJ_FALSE; | |
| 13569 } else { | |
| 13570 OPJ_UINT32 j; | |
| 13571 /* Allocate data */ | |
| 13572 for (j = 0; j < p_j2k->m_tcd->image->numcomps; ++j) { | |
| 13573 opj_tcd_tilecomp_t* l_tilec = p_j2k->m_tcd->tcd_image->tiles->comps + j; | |
| 13574 | |
| 13575 if (! opj_alloc_tile_component_data(l_tilec)) { | |
| 13576 opj_event_msg(p_manager, EVT_ERROR, "Error allocating tile component data."); | |
| 13577 return OPJ_FALSE; | |
| 13578 } | |
| 13579 } | |
| 13580 | |
| 13581 /* now copy data into the tile component */ | |
| 13582 if (! opj_tcd_copy_tile_data(p_j2k->m_tcd, p_data, p_data_size)) { | |
| 13583 opj_event_msg(p_manager, EVT_ERROR, | |
| 13584 "Size mismatch between tile data and sent data."); | |
| 13585 return OPJ_FALSE; | |
| 13586 } | |
| 13587 if (! opj_j2k_post_write_tile(p_j2k, p_stream, p_manager)) { | |
| 13588 opj_event_msg(p_manager, EVT_ERROR, | |
| 13589 "Error while opj_j2k_post_write_tile with tile index = %d\n", p_tile_index); | |
| 13590 return OPJ_FALSE; | |
| 13591 } | |
| 13592 } | |
| 13593 | |
| 13594 return OPJ_TRUE; | |
| 13595 } |
