John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 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, 2011-2012, Centre National d'Etudes Spatiales (CNES), FR |
| 15 | * Copyright (c) 2012, CS Systemes d'Information, France |
| 16 | * All rights reserved. |
| 17 | * |
| 18 | * Redistribution and use in source and binary forms, with or without |
| 19 | * modification, are permitted provided that the following conditions |
| 20 | * are met: |
| 21 | * 1. Redistributions of source code must retain the above copyright |
| 22 | * notice, this list of conditions and the following disclaimer. |
| 23 | * 2. Redistributions in binary form must reproduce the above copyright |
| 24 | * notice, this list of conditions and the following disclaimer in the |
| 25 | * documentation and/or other materials provided with the distribution. |
| 26 | * |
| 27 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' |
| 28 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 29 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 30 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
| 31 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 32 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 33 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 34 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 35 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 36 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 37 | * POSSIBILITY OF SUCH DAMAGE. |
| 38 | */ |
| 39 | |
| 40 | #include "opj_includes.h" |
| 41 | |
| 42 | /** @defgroup T2 T2 - Implementation of a tier-2 coding */ |
| 43 | /*@{*/ |
| 44 | |
| 45 | /** @name Local static functions */ |
| 46 | /*@{*/ |
| 47 | |
| 48 | static void opj_t2_putcommacode(opj_bio_t *bio, OPJ_INT32 n); |
| 49 | |
| 50 | static OPJ_UINT32 opj_t2_getcommacode(opj_bio_t *bio); |
| 51 | /** |
| 52 | Variable length code for signalling delta Zil (truncation point) |
| 53 | @param bio Bit Input/Output component |
| 54 | @param n delta Zil |
| 55 | */ |
| 56 | static void opj_t2_putnumpasses(opj_bio_t *bio, OPJ_UINT32 n); |
| 57 | static OPJ_UINT32 opj_t2_getnumpasses(opj_bio_t *bio); |
| 58 | |
| 59 | /** |
| 60 | Encode a packet of a tile to a destination buffer |
| 61 | @param tileno Number of the tile encoded |
| 62 | @param tile Tile for which to write the packets |
| 63 | @param tcp Tile coding parameters |
| 64 | @param pi Packet identity |
| 65 | @param dest Destination buffer |
| 66 | @param p_data_written FIXME DOC |
| 67 | @param len Length of the destination buffer |
| 68 | @param cstr_info Codestream information structure |
| 69 | @return |
| 70 | */ |
| 71 | static OPJ_BOOL opj_t2_encode_packet( OPJ_UINT32 tileno, |
| 72 | opj_tcd_tile_t *tile, |
| 73 | opj_tcp_t *tcp, |
| 74 | opj_pi_iterator_t *pi, |
| 75 | OPJ_BYTE *dest, |
| 76 | OPJ_UINT32 * p_data_written, |
| 77 | OPJ_UINT32 len, |
| 78 | opj_codestream_info_t *cstr_info); |
| 79 | |
| 80 | /** |
| 81 | Decode a packet of a tile from a source buffer |
| 82 | @param t2 T2 handle |
| 83 | @param tile Tile for which to write the packets |
| 84 | @param tcp Tile coding parameters |
| 85 | @param pi Packet identity |
| 86 | @param src Source buffer |
| 87 | @param data_read FIXME DOC |
| 88 | @param max_length FIXME DOC |
| 89 | @param pack_info Packet information |
| 90 | |
| 91 | @return FIXME DOC |
| 92 | */ |
| 93 | static OPJ_BOOL opj_t2_decode_packet( opj_t2_t* t2, |
| 94 | opj_tcd_tile_t *tile, |
| 95 | opj_tcp_t *tcp, |
| 96 | opj_pi_iterator_t *pi, |
| 97 | OPJ_BYTE *src, |
| 98 | OPJ_UINT32 * data_read, |
| 99 | OPJ_UINT32 max_length, |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 100 | opj_packet_info_t *pack_info, |
| 101 | opj_event_mgr_t *p_manager); |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 102 | |
| 103 | static OPJ_BOOL opj_t2_skip_packet( opj_t2_t* p_t2, |
| 104 | opj_tcd_tile_t *p_tile, |
| 105 | opj_tcp_t *p_tcp, |
| 106 | opj_pi_iterator_t *p_pi, |
| 107 | OPJ_BYTE *p_src, |
| 108 | OPJ_UINT32 * p_data_read, |
| 109 | OPJ_UINT32 p_max_length, |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 110 | opj_packet_info_t *p_pack_info, |
| 111 | opj_event_mgr_t *p_manager); |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 112 | |
| 113 | static OPJ_BOOL opj_t2_read_packet_header( opj_t2_t* p_t2, |
| 114 | opj_tcd_tile_t *p_tile, |
| 115 | opj_tcp_t *p_tcp, |
| 116 | opj_pi_iterator_t *p_pi, |
| 117 | OPJ_BOOL * p_is_data_present, |
| 118 | OPJ_BYTE *p_src_data, |
| 119 | OPJ_UINT32 * p_data_read, |
| 120 | OPJ_UINT32 p_max_length, |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 121 | opj_packet_info_t *p_pack_info, |
| 122 | opj_event_mgr_t *p_manager); |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 123 | |
| 124 | static OPJ_BOOL opj_t2_read_packet_data(opj_t2_t* p_t2, |
| 125 | opj_tcd_tile_t *p_tile, |
| 126 | opj_pi_iterator_t *p_pi, |
| 127 | OPJ_BYTE *p_src_data, |
| 128 | OPJ_UINT32 * p_data_read, |
| 129 | OPJ_UINT32 p_max_length, |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 130 | opj_packet_info_t *pack_info, |
| 131 | opj_event_mgr_t *p_manager); |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 132 | |
| 133 | static OPJ_BOOL opj_t2_skip_packet_data(opj_t2_t* p_t2, |
| 134 | opj_tcd_tile_t *p_tile, |
| 135 | opj_pi_iterator_t *p_pi, |
| 136 | OPJ_UINT32 * p_data_read, |
| 137 | OPJ_UINT32 p_max_length, |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 138 | opj_packet_info_t *pack_info, |
| 139 | opj_event_mgr_t *p_manager); |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 140 | |
| 141 | /** |
| 142 | @param cblk |
| 143 | @param index |
| 144 | @param cblksty |
| 145 | @param first |
| 146 | */ |
| 147 | static OPJ_BOOL opj_t2_init_seg( opj_tcd_cblk_dec_t* cblk, |
| 148 | OPJ_UINT32 index, |
| 149 | OPJ_UINT32 cblksty, |
| 150 | OPJ_UINT32 first); |
| 151 | |
| 152 | /*@}*/ |
| 153 | |
| 154 | /*@}*/ |
| 155 | |
| 156 | /* ----------------------------------------------------------------------- */ |
| 157 | |
| 158 | /* #define RESTART 0x04 */ |
| 159 | static void opj_t2_putcommacode(opj_bio_t *bio, OPJ_INT32 n) { |
| 160 | while (--n >= 0) { |
| 161 | opj_bio_write(bio, 1, 1); |
| 162 | } |
| 163 | opj_bio_write(bio, 0, 1); |
| 164 | } |
| 165 | |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 166 | static OPJ_UINT32 opj_t2_getcommacode(opj_bio_t *bio) |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 167 | { |
| 168 | OPJ_UINT32 n = 0; |
| 169 | while (opj_bio_read(bio, 1)) { |
| 170 | ++n; |
| 171 | } |
| 172 | return n; |
| 173 | } |
| 174 | |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 175 | static void opj_t2_putnumpasses(opj_bio_t *bio, OPJ_UINT32 n) { |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 176 | if (n == 1) { |
| 177 | opj_bio_write(bio, 0, 1); |
| 178 | } else if (n == 2) { |
| 179 | opj_bio_write(bio, 2, 2); |
| 180 | } else if (n <= 5) { |
| 181 | opj_bio_write(bio, 0xc | (n - 3), 4); |
| 182 | } else if (n <= 36) { |
| 183 | opj_bio_write(bio, 0x1e0 | (n - 6), 9); |
| 184 | } else if (n <= 164) { |
| 185 | opj_bio_write(bio, 0xff80 | (n - 37), 16); |
| 186 | } |
| 187 | } |
| 188 | |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 189 | static OPJ_UINT32 opj_t2_getnumpasses(opj_bio_t *bio) { |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 190 | OPJ_UINT32 n; |
| 191 | if (!opj_bio_read(bio, 1)) |
| 192 | return 1; |
| 193 | if (!opj_bio_read(bio, 1)) |
| 194 | return 2; |
| 195 | if ((n = opj_bio_read(bio, 2)) != 3) |
| 196 | return (3 + n); |
| 197 | if ((n = opj_bio_read(bio, 5)) != 31) |
| 198 | return (6 + n); |
| 199 | return (37 + opj_bio_read(bio, 7)); |
| 200 | } |
| 201 | |
| 202 | /* ----------------------------------------------------------------------- */ |
| 203 | |
| 204 | OPJ_BOOL opj_t2_encode_packets( opj_t2_t* p_t2, |
| 205 | OPJ_UINT32 p_tile_no, |
| 206 | opj_tcd_tile_t *p_tile, |
| 207 | OPJ_UINT32 p_maxlayers, |
| 208 | OPJ_BYTE *p_dest, |
| 209 | OPJ_UINT32 * p_data_written, |
| 210 | OPJ_UINT32 p_max_len, |
| 211 | opj_codestream_info_t *cstr_info, |
| 212 | OPJ_UINT32 p_tp_num, |
| 213 | OPJ_INT32 p_tp_pos, |
| 214 | OPJ_UINT32 p_pino, |
| 215 | J2K_T2_MODE p_t2_mode) |
| 216 | { |
| 217 | OPJ_BYTE *l_current_data = p_dest; |
| 218 | OPJ_UINT32 l_nb_bytes = 0; |
| 219 | OPJ_UINT32 compno; |
| 220 | OPJ_UINT32 poc; |
| 221 | opj_pi_iterator_t *l_pi = 00; |
| 222 | opj_pi_iterator_t *l_current_pi = 00; |
| 223 | opj_image_t *l_image = p_t2->image; |
| 224 | opj_cp_t *l_cp = p_t2->cp; |
| 225 | opj_tcp_t *l_tcp = &l_cp->tcps[p_tile_no]; |
Bo Xu | d53e6fd | 2014-09-30 11:12:05 -0700 | [diff] [blame] | 226 | OPJ_UINT32 pocno = (l_cp->rsiz == OPJ_PROFILE_CINEMA_4K)? 2: 1; |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 227 | OPJ_UINT32 l_max_comp = l_cp->m_specific_param.m_enc.m_max_comp_size > 0 ? l_image->numcomps : 1; |
| 228 | OPJ_UINT32 l_nb_pocs = l_tcp->numpocs + 1; |
| 229 | |
| 230 | l_pi = opj_pi_initialise_encode(l_image, l_cp, p_tile_no, p_t2_mode); |
| 231 | if (!l_pi) { |
| 232 | return OPJ_FALSE; |
| 233 | } |
| 234 | |
| 235 | * p_data_written = 0; |
| 236 | |
| 237 | if (p_t2_mode == THRESH_CALC ){ /* Calculating threshold */ |
| 238 | l_current_pi = l_pi; |
| 239 | |
| 240 | for (compno = 0; compno < l_max_comp; ++compno) { |
| 241 | OPJ_UINT32 l_comp_len = 0; |
| 242 | l_current_pi = l_pi; |
| 243 | |
| 244 | for (poc = 0; poc < pocno ; ++poc) { |
| 245 | OPJ_UINT32 l_tp_num = compno; |
| 246 | |
| 247 | /* TODO MSD : check why this function cannot fail (cf. v1) */ |
| 248 | opj_pi_create_encode(l_pi, l_cp,p_tile_no,poc,l_tp_num,p_tp_pos,p_t2_mode); |
| 249 | |
Bo Xu | 767aebb | 2014-10-21 13:05:17 -0700 | [diff] [blame] | 250 | if (l_current_pi->poc.prg == OPJ_PROG_UNKNOWN) { |
| 251 | /* TODO ADE : add an error */ |
| 252 | opj_pi_destroy(l_pi, l_nb_pocs); |
| 253 | return OPJ_FALSE; |
| 254 | } |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 255 | while (opj_pi_next(l_current_pi)) { |
| 256 | if (l_current_pi->layno < p_maxlayers) { |
| 257 | l_nb_bytes = 0; |
| 258 | |
| 259 | if (! opj_t2_encode_packet(p_tile_no,p_tile, l_tcp, l_current_pi, l_current_data, &l_nb_bytes, p_max_len, cstr_info)) { |
| 260 | opj_pi_destroy(l_pi, l_nb_pocs); |
| 261 | return OPJ_FALSE; |
| 262 | } |
| 263 | |
| 264 | l_comp_len += l_nb_bytes; |
| 265 | l_current_data += l_nb_bytes; |
| 266 | p_max_len -= l_nb_bytes; |
| 267 | |
| 268 | * p_data_written += l_nb_bytes; |
| 269 | } |
| 270 | } |
| 271 | |
| 272 | if (l_cp->m_specific_param.m_enc.m_max_comp_size) { |
| 273 | if (l_comp_len > l_cp->m_specific_param.m_enc.m_max_comp_size) { |
| 274 | opj_pi_destroy(l_pi, l_nb_pocs); |
| 275 | return OPJ_FALSE; |
| 276 | } |
| 277 | } |
| 278 | |
| 279 | ++l_current_pi; |
| 280 | } |
| 281 | } |
| 282 | } |
| 283 | else { /* t2_mode == FINAL_PASS */ |
| 284 | opj_pi_create_encode(l_pi, l_cp,p_tile_no,p_pino,p_tp_num,p_tp_pos,p_t2_mode); |
| 285 | |
| 286 | l_current_pi = &l_pi[p_pino]; |
Bo Xu | 767aebb | 2014-10-21 13:05:17 -0700 | [diff] [blame] | 287 | if (l_current_pi->poc.prg == OPJ_PROG_UNKNOWN) { |
| 288 | /* TODO ADE : add an error */ |
| 289 | opj_pi_destroy(l_pi, l_nb_pocs); |
| 290 | return OPJ_FALSE; |
| 291 | } |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 292 | while (opj_pi_next(l_current_pi)) { |
| 293 | if (l_current_pi->layno < p_maxlayers) { |
| 294 | l_nb_bytes=0; |
| 295 | |
| 296 | if (! opj_t2_encode_packet(p_tile_no,p_tile, l_tcp, l_current_pi, l_current_data, &l_nb_bytes, p_max_len, cstr_info)) { |
| 297 | opj_pi_destroy(l_pi, l_nb_pocs); |
| 298 | return OPJ_FALSE; |
| 299 | } |
| 300 | |
| 301 | l_current_data += l_nb_bytes; |
| 302 | p_max_len -= l_nb_bytes; |
| 303 | |
| 304 | * p_data_written += l_nb_bytes; |
| 305 | |
| 306 | /* INDEX >> */ |
| 307 | if(cstr_info) { |
| 308 | if(cstr_info->index_write) { |
| 309 | opj_tile_info_t *info_TL = &cstr_info->tile[p_tile_no]; |
| 310 | opj_packet_info_t *info_PK = &info_TL->packet[cstr_info->packno]; |
| 311 | if (!cstr_info->packno) { |
| 312 | info_PK->start_pos = info_TL->end_header + 1; |
| 313 | } else { |
| 314 | info_PK->start_pos = ((l_cp->m_specific_param.m_enc.m_tp_on | l_tcp->POC)&& info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[cstr_info->packno - 1].end_pos + 1; |
| 315 | } |
| 316 | info_PK->end_pos = info_PK->start_pos + l_nb_bytes - 1; |
| 317 | info_PK->end_ph_pos += info_PK->start_pos - 1; /* End of packet header which now only represents the distance |
| 318 | to start of packet is incremented by value of start of packet*/ |
| 319 | } |
| 320 | |
| 321 | cstr_info->packno++; |
| 322 | } |
| 323 | /* << INDEX */ |
| 324 | ++p_tile->packno; |
| 325 | } |
| 326 | } |
| 327 | } |
| 328 | |
| 329 | opj_pi_destroy(l_pi, l_nb_pocs); |
| 330 | |
| 331 | return OPJ_TRUE; |
| 332 | } |
| 333 | |
| 334 | /* see issue 80 */ |
| 335 | #if 0 |
| 336 | #define JAS_FPRINTF fprintf |
| 337 | #else |
| 338 | /* issue 290 */ |
| 339 | static void opj_null_jas_fprintf(FILE* file, const char * format, ...) |
| 340 | { |
| 341 | (void)file; |
| 342 | (void)format; |
| 343 | } |
| 344 | #define JAS_FPRINTF opj_null_jas_fprintf |
| 345 | #endif |
| 346 | |
| 347 | OPJ_BOOL opj_t2_decode_packets( opj_t2_t *p_t2, |
| 348 | OPJ_UINT32 p_tile_no, |
| 349 | opj_tcd_tile_t *p_tile, |
| 350 | OPJ_BYTE *p_src, |
| 351 | OPJ_UINT32 * p_data_read, |
| 352 | OPJ_UINT32 p_max_len, |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 353 | opj_codestream_index_t *p_cstr_index, |
| 354 | opj_event_mgr_t *p_manager) |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 355 | { |
| 356 | OPJ_BYTE *l_current_data = p_src; |
| 357 | opj_pi_iterator_t *l_pi = 00; |
| 358 | OPJ_UINT32 pino; |
| 359 | opj_image_t *l_image = p_t2->image; |
| 360 | opj_cp_t *l_cp = p_t2->cp; |
| 361 | opj_tcp_t *l_tcp = &(p_t2->cp->tcps[p_tile_no]); |
| 362 | OPJ_UINT32 l_nb_bytes_read; |
| 363 | OPJ_UINT32 l_nb_pocs = l_tcp->numpocs + 1; |
| 364 | opj_pi_iterator_t *l_current_pi = 00; |
| 365 | #ifdef TODO_MSD |
| 366 | OPJ_UINT32 curtp = 0; |
| 367 | OPJ_UINT32 tp_start_packno; |
| 368 | #endif |
| 369 | opj_packet_info_t *l_pack_info = 00; |
| 370 | opj_image_comp_t* l_img_comp = 00; |
| 371 | |
| 372 | OPJ_ARG_NOT_USED(p_cstr_index); |
| 373 | |
| 374 | #ifdef TODO_MSD |
| 375 | if (p_cstr_index) { |
| 376 | l_pack_info = p_cstr_index->tile_index[p_tile_no].packet; |
| 377 | } |
| 378 | #endif |
| 379 | |
| 380 | /* create a packet iterator */ |
| 381 | l_pi = opj_pi_create_decode(l_image, l_cp, p_tile_no); |
| 382 | if (!l_pi) { |
| 383 | return OPJ_FALSE; |
| 384 | } |
| 385 | |
| 386 | |
| 387 | l_current_pi = l_pi; |
| 388 | |
| 389 | for (pino = 0; pino <= l_tcp->numpocs; ++pino) { |
| 390 | |
| 391 | /* if the resolution needed is too low, one dim of the tilec could be equal to zero |
| 392 | * and no packets are used to decode this resolution and |
| 393 | * l_current_pi->resno is always >= p_tile->comps[l_current_pi->compno].minimum_num_resolutions |
| 394 | * and no l_img_comp->resno_decoded are computed |
| 395 | */ |
Bo Xu | 66d6538 | 2014-11-24 13:58:10 -0800 | [diff] [blame] | 396 | OPJ_BOOL* first_pass_failed = NULL; |
JUN FANG | 7dba986 | 2015-02-27 10:00:00 -0800 | [diff] [blame] | 397 | |
Bo Xu | 66d6538 | 2014-11-24 13:58:10 -0800 | [diff] [blame] | 398 | if (l_current_pi->poc.prg == OPJ_PROG_UNKNOWN) { |
| 399 | /* TODO ADE : add an error */ |
| 400 | opj_pi_destroy(l_pi, l_nb_pocs); |
| 401 | return OPJ_FALSE; |
| 402 | } |
JUN FANG | 7dba986 | 2015-02-27 10:00:00 -0800 | [diff] [blame] | 403 | |
Bo Xu | 66d6538 | 2014-11-24 13:58:10 -0800 | [diff] [blame] | 404 | first_pass_failed = (OPJ_BOOL*)opj_malloc(l_image->numcomps * sizeof(OPJ_BOOL)); |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 405 | if (!first_pass_failed) |
| 406 | { |
| 407 | opj_pi_destroy(l_pi,l_nb_pocs); |
| 408 | return OPJ_FALSE; |
| 409 | } |
| 410 | memset(first_pass_failed, OPJ_TRUE, l_image->numcomps * sizeof(OPJ_BOOL)); |
| 411 | |
| 412 | while (opj_pi_next(l_current_pi)) { |
| 413 | JAS_FPRINTF( stderr, "packet offset=00000166 prg=%d cmptno=%02d rlvlno=%02d prcno=%03d lyrno=%02d\n\n", |
| 414 | l_current_pi->poc.prg1, l_current_pi->compno, l_current_pi->resno, l_current_pi->precno, l_current_pi->layno ); |
| 415 | |
| 416 | if (l_tcp->num_layers_to_decode > l_current_pi->layno |
| 417 | && l_current_pi->resno < p_tile->comps[l_current_pi->compno].minimum_num_resolutions) { |
| 418 | l_nb_bytes_read = 0; |
| 419 | |
| 420 | first_pass_failed[l_current_pi->compno] = OPJ_FALSE; |
| 421 | |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 422 | if (! opj_t2_decode_packet(p_t2,p_tile,l_tcp,l_current_pi,l_current_data,&l_nb_bytes_read,p_max_len,l_pack_info, p_manager)) { |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 423 | opj_pi_destroy(l_pi,l_nb_pocs); |
| 424 | opj_free(first_pass_failed); |
| 425 | return OPJ_FALSE; |
| 426 | } |
| 427 | |
| 428 | l_img_comp = &(l_image->comps[l_current_pi->compno]); |
| 429 | l_img_comp->resno_decoded = opj_uint_max(l_current_pi->resno, l_img_comp->resno_decoded); |
| 430 | } |
| 431 | else { |
| 432 | l_nb_bytes_read = 0; |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 433 | if (! opj_t2_skip_packet(p_t2,p_tile,l_tcp,l_current_pi,l_current_data,&l_nb_bytes_read,p_max_len,l_pack_info, p_manager)) { |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 434 | opj_pi_destroy(l_pi,l_nb_pocs); |
| 435 | opj_free(first_pass_failed); |
| 436 | return OPJ_FALSE; |
| 437 | } |
| 438 | } |
| 439 | |
| 440 | if (first_pass_failed[l_current_pi->compno]) { |
| 441 | l_img_comp = &(l_image->comps[l_current_pi->compno]); |
| 442 | if (l_img_comp->resno_decoded == 0) |
| 443 | l_img_comp->resno_decoded = p_tile->comps[l_current_pi->compno].minimum_num_resolutions - 1; |
| 444 | } |
| 445 | |
| 446 | l_current_data += l_nb_bytes_read; |
| 447 | p_max_len -= l_nb_bytes_read; |
| 448 | |
| 449 | /* INDEX >> */ |
| 450 | #ifdef TODO_MSD |
| 451 | if(p_cstr_info) { |
| 452 | opj_tile_info_v2_t *info_TL = &p_cstr_info->tile[p_tile_no]; |
| 453 | opj_packet_info_t *info_PK = &info_TL->packet[p_cstr_info->packno]; |
| 454 | tp_start_packno = 0; |
| 455 | if (!p_cstr_info->packno) { |
| 456 | info_PK->start_pos = info_TL->end_header + 1; |
| 457 | } else if (info_TL->packet[p_cstr_info->packno-1].end_pos >= (OPJ_INT32)p_cstr_info->tile[p_tile_no].tp[curtp].tp_end_pos){ /* New tile part */ |
| 458 | info_TL->tp[curtp].tp_numpacks = p_cstr_info->packno - tp_start_packno; /* Number of packets in previous tile-part */ |
| 459 | tp_start_packno = p_cstr_info->packno; |
| 460 | curtp++; |
| 461 | info_PK->start_pos = p_cstr_info->tile[p_tile_no].tp[curtp].tp_end_header+1; |
| 462 | } else { |
| 463 | info_PK->start_pos = (l_cp->m_specific_param.m_enc.m_tp_on && info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[p_cstr_info->packno - 1].end_pos + 1; |
| 464 | } |
| 465 | info_PK->end_pos = info_PK->start_pos + l_nb_bytes_read - 1; |
| 466 | info_PK->end_ph_pos += info_PK->start_pos - 1; /* End of packet header which now only represents the distance */ |
| 467 | ++p_cstr_info->packno; |
| 468 | } |
| 469 | #endif |
| 470 | /* << INDEX */ |
| 471 | } |
| 472 | ++l_current_pi; |
| 473 | |
| 474 | opj_free(first_pass_failed); |
| 475 | } |
| 476 | /* INDEX >> */ |
| 477 | #ifdef TODO_MSD |
| 478 | if |
| 479 | (p_cstr_info) { |
| 480 | p_cstr_info->tile[p_tile_no].tp[curtp].tp_numpacks = p_cstr_info->packno - tp_start_packno; /* Number of packets in last tile-part */ |
| 481 | } |
| 482 | #endif |
| 483 | /* << INDEX */ |
| 484 | |
| 485 | /* don't forget to release pi */ |
| 486 | opj_pi_destroy(l_pi,l_nb_pocs); |
| 487 | *p_data_read = (OPJ_UINT32)(l_current_data - p_src); |
| 488 | return OPJ_TRUE; |
| 489 | } |
| 490 | |
| 491 | /* ----------------------------------------------------------------------- */ |
| 492 | |
| 493 | /** |
| 494 | * Creates a Tier 2 handle |
| 495 | * |
| 496 | * @param p_image Source or destination image |
| 497 | * @param p_cp Image coding parameters. |
| 498 | * @return a new T2 handle if successful, NULL otherwise. |
| 499 | */ |
| 500 | opj_t2_t* opj_t2_create(opj_image_t *p_image, opj_cp_t *p_cp) |
| 501 | { |
| 502 | /* create the t2 structure */ |
Bo Xu | d53e6fd | 2014-09-30 11:12:05 -0700 | [diff] [blame] | 503 | opj_t2_t *l_t2 = (opj_t2_t*)opj_calloc(1,sizeof(opj_t2_t)); |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 504 | if (!l_t2) { |
| 505 | return NULL; |
| 506 | } |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 507 | |
| 508 | l_t2->image = p_image; |
| 509 | l_t2->cp = p_cp; |
| 510 | |
| 511 | return l_t2; |
| 512 | } |
| 513 | |
| 514 | void opj_t2_destroy(opj_t2_t *t2) { |
| 515 | if(t2) { |
| 516 | opj_free(t2); |
| 517 | } |
| 518 | } |
| 519 | |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 520 | static OPJ_BOOL opj_t2_decode_packet( opj_t2_t* p_t2, |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 521 | opj_tcd_tile_t *p_tile, |
| 522 | opj_tcp_t *p_tcp, |
| 523 | opj_pi_iterator_t *p_pi, |
| 524 | OPJ_BYTE *p_src, |
| 525 | OPJ_UINT32 * p_data_read, |
| 526 | OPJ_UINT32 p_max_length, |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 527 | opj_packet_info_t *p_pack_info, |
| 528 | opj_event_mgr_t *p_manager) |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 529 | { |
| 530 | OPJ_BOOL l_read_data; |
| 531 | OPJ_UINT32 l_nb_bytes_read = 0; |
| 532 | OPJ_UINT32 l_nb_total_bytes_read = 0; |
| 533 | |
| 534 | *p_data_read = 0; |
| 535 | |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 536 | if (! opj_t2_read_packet_header(p_t2,p_tile,p_tcp,p_pi,&l_read_data,p_src,&l_nb_bytes_read,p_max_length,p_pack_info, p_manager)) { |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 537 | return OPJ_FALSE; |
| 538 | } |
| 539 | |
| 540 | p_src += l_nb_bytes_read; |
| 541 | l_nb_total_bytes_read += l_nb_bytes_read; |
| 542 | p_max_length -= l_nb_bytes_read; |
| 543 | |
| 544 | /* we should read data for the packet */ |
| 545 | if (l_read_data) { |
| 546 | l_nb_bytes_read = 0; |
| 547 | |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 548 | if (! opj_t2_read_packet_data(p_t2,p_tile,p_pi,p_src,&l_nb_bytes_read,p_max_length,p_pack_info, p_manager)) { |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 549 | return OPJ_FALSE; |
| 550 | } |
| 551 | |
| 552 | l_nb_total_bytes_read += l_nb_bytes_read; |
| 553 | } |
| 554 | |
| 555 | *p_data_read = l_nb_total_bytes_read; |
| 556 | |
| 557 | return OPJ_TRUE; |
| 558 | } |
| 559 | |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 560 | static OPJ_BOOL opj_t2_encode_packet( OPJ_UINT32 tileno, |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 561 | opj_tcd_tile_t * tile, |
| 562 | opj_tcp_t * tcp, |
| 563 | opj_pi_iterator_t *pi, |
| 564 | OPJ_BYTE *dest, |
| 565 | OPJ_UINT32 * p_data_written, |
| 566 | OPJ_UINT32 length, |
| 567 | opj_codestream_info_t *cstr_info) |
| 568 | { |
| 569 | OPJ_UINT32 bandno, cblkno; |
| 570 | OPJ_BYTE* c = dest; |
| 571 | OPJ_UINT32 l_nb_bytes; |
| 572 | OPJ_UINT32 compno = pi->compno; /* component value */ |
| 573 | OPJ_UINT32 resno = pi->resno; /* resolution level value */ |
| 574 | OPJ_UINT32 precno = pi->precno; /* precinct value */ |
| 575 | OPJ_UINT32 layno = pi->layno; /* quality layer value */ |
| 576 | OPJ_UINT32 l_nb_blocks; |
| 577 | opj_tcd_band_t *band = 00; |
| 578 | opj_tcd_cblk_enc_t* cblk = 00; |
| 579 | opj_tcd_pass_t *pass = 00; |
| 580 | |
| 581 | opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; |
| 582 | opj_tcd_resolution_t *res = &tilec->resolutions[resno]; |
| 583 | |
| 584 | opj_bio_t *bio = 00; /* BIO component */ |
| 585 | |
| 586 | /* <SOP 0xff91> */ |
| 587 | if (tcp->csty & J2K_CP_CSTY_SOP) { |
| 588 | c[0] = 255; |
| 589 | c[1] = 145; |
| 590 | c[2] = 0; |
| 591 | c[3] = 4; |
| 592 | #if 0 |
| 593 | c[4] = (tile->packno % 65536) / 256; |
| 594 | c[5] = (tile->packno % 65536) % 256; |
| 595 | #else |
| 596 | c[4] = (tile->packno >> 8) & 0xff; /* packno is uint32_t */ |
| 597 | c[5] = tile->packno & 0xff; |
| 598 | #endif |
| 599 | c += 6; |
| 600 | length -= 6; |
| 601 | } |
| 602 | /* </SOP> */ |
| 603 | |
| 604 | if (!layno) { |
| 605 | band = res->bands; |
| 606 | |
| 607 | for(bandno = 0; bandno < res->numbands; ++bandno) { |
| 608 | opj_tcd_precinct_t *prc = &band->precincts[precno]; |
| 609 | |
| 610 | opj_tgt_reset(prc->incltree); |
| 611 | opj_tgt_reset(prc->imsbtree); |
| 612 | |
| 613 | l_nb_blocks = prc->cw * prc->ch; |
| 614 | for (cblkno = 0; cblkno < l_nb_blocks; ++cblkno) { |
| 615 | cblk = &prc->cblks.enc[cblkno]; |
| 616 | |
| 617 | cblk->numpasses = 0; |
| 618 | opj_tgt_setvalue(prc->imsbtree, cblkno, band->numbps - (OPJ_INT32)cblk->numbps); |
| 619 | } |
| 620 | ++band; |
| 621 | } |
| 622 | } |
| 623 | |
| 624 | bio = opj_bio_create(); |
Bo Xu | d53e6fd | 2014-09-30 11:12:05 -0700 | [diff] [blame] | 625 | if (!bio) { |
| 626 | /* FIXME event manager error callback */ |
| 627 | return OPJ_FALSE; |
| 628 | } |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 629 | opj_bio_init_enc(bio, c, length); |
| 630 | opj_bio_write(bio, 1, 1); /* Empty header bit */ |
| 631 | |
| 632 | /* Writing Packet header */ |
| 633 | band = res->bands; |
| 634 | for (bandno = 0; bandno < res->numbands; ++bandno) { |
| 635 | opj_tcd_precinct_t *prc = &band->precincts[precno]; |
| 636 | |
| 637 | l_nb_blocks = prc->cw * prc->ch; |
| 638 | cblk = prc->cblks.enc; |
| 639 | |
| 640 | for (cblkno = 0; cblkno < l_nb_blocks; ++cblkno) { |
| 641 | opj_tcd_layer_t *layer = &cblk->layers[layno]; |
| 642 | |
| 643 | if (!cblk->numpasses && layer->numpasses) { |
| 644 | opj_tgt_setvalue(prc->incltree, cblkno, (OPJ_INT32)layno); |
| 645 | } |
| 646 | |
| 647 | ++cblk; |
| 648 | } |
| 649 | |
| 650 | cblk = prc->cblks.enc; |
| 651 | for (cblkno = 0; cblkno < l_nb_blocks; cblkno++) { |
| 652 | opj_tcd_layer_t *layer = &cblk->layers[layno]; |
| 653 | OPJ_UINT32 increment = 0; |
| 654 | OPJ_UINT32 nump = 0; |
| 655 | OPJ_UINT32 len = 0, passno; |
| 656 | OPJ_UINT32 l_nb_passes; |
| 657 | |
| 658 | /* cblk inclusion bits */ |
| 659 | if (!cblk->numpasses) { |
| 660 | opj_tgt_encode(bio, prc->incltree, cblkno, (OPJ_INT32)(layno + 1)); |
| 661 | } else { |
| 662 | opj_bio_write(bio, layer->numpasses != 0, 1); |
| 663 | } |
| 664 | |
| 665 | /* if cblk not included, go to the next cblk */ |
| 666 | if (!layer->numpasses) { |
| 667 | ++cblk; |
| 668 | continue; |
| 669 | } |
| 670 | |
| 671 | /* if first instance of cblk --> zero bit-planes information */ |
| 672 | if (!cblk->numpasses) { |
| 673 | cblk->numlenbits = 3; |
| 674 | opj_tgt_encode(bio, prc->imsbtree, cblkno, 999); |
| 675 | } |
| 676 | |
| 677 | /* number of coding passes included */ |
| 678 | opj_t2_putnumpasses(bio, layer->numpasses); |
| 679 | l_nb_passes = cblk->numpasses + layer->numpasses; |
| 680 | pass = cblk->passes + cblk->numpasses; |
| 681 | |
| 682 | /* computation of the increase of the length indicator and insertion in the header */ |
| 683 | for (passno = cblk->numpasses; passno < l_nb_passes; ++passno) { |
| 684 | ++nump; |
| 685 | len += pass->len; |
| 686 | |
| 687 | if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) { |
| 688 | increment = (OPJ_UINT32)opj_int_max((OPJ_INT32)increment, opj_int_floorlog2((OPJ_INT32)len) + 1 |
| 689 | - ((OPJ_INT32)cblk->numlenbits + opj_int_floorlog2((OPJ_INT32)nump))); |
| 690 | len = 0; |
| 691 | nump = 0; |
| 692 | } |
| 693 | |
| 694 | ++pass; |
| 695 | } |
| 696 | opj_t2_putcommacode(bio, (OPJ_INT32)increment); |
| 697 | |
| 698 | /* computation of the new Length indicator */ |
| 699 | cblk->numlenbits += increment; |
| 700 | |
| 701 | pass = cblk->passes + cblk->numpasses; |
| 702 | /* insertion of the codeword segment length */ |
| 703 | for (passno = cblk->numpasses; passno < l_nb_passes; ++passno) { |
| 704 | nump++; |
| 705 | len += pass->len; |
| 706 | |
| 707 | if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) { |
| 708 | opj_bio_write(bio, (OPJ_UINT32)len, cblk->numlenbits + (OPJ_UINT32)opj_int_floorlog2((OPJ_INT32)nump)); |
| 709 | len = 0; |
| 710 | nump = 0; |
| 711 | } |
| 712 | ++pass; |
| 713 | } |
| 714 | |
| 715 | ++cblk; |
| 716 | } |
| 717 | |
| 718 | ++band; |
| 719 | } |
| 720 | |
| 721 | if (!opj_bio_flush(bio)) { |
| 722 | opj_bio_destroy(bio); |
| 723 | return OPJ_FALSE; /* modified to eliminate longjmp !! */ |
| 724 | } |
| 725 | |
| 726 | l_nb_bytes = (OPJ_UINT32)opj_bio_numbytes(bio); |
| 727 | c += l_nb_bytes; |
| 728 | length -= l_nb_bytes; |
| 729 | |
| 730 | opj_bio_destroy(bio); |
| 731 | |
| 732 | /* <EPH 0xff92> */ |
| 733 | if (tcp->csty & J2K_CP_CSTY_EPH) { |
| 734 | c[0] = 255; |
| 735 | c[1] = 146; |
| 736 | c += 2; |
| 737 | length -= 2; |
| 738 | } |
| 739 | /* </EPH> */ |
| 740 | |
| 741 | /* << INDEX */ |
| 742 | /* End of packet header position. Currently only represents the distance to start of packet |
| 743 | Will be updated later by incrementing with packet start value*/ |
| 744 | if(cstr_info && cstr_info->index_write) { |
| 745 | opj_packet_info_t *info_PK = &cstr_info->tile[tileno].packet[cstr_info->packno]; |
| 746 | info_PK->end_ph_pos = (OPJ_INT32)(c - dest); |
| 747 | } |
| 748 | /* INDEX >> */ |
| 749 | |
| 750 | /* Writing the packet body */ |
| 751 | band = res->bands; |
| 752 | for (bandno = 0; bandno < res->numbands; bandno++) { |
| 753 | opj_tcd_precinct_t *prc = &band->precincts[precno]; |
| 754 | |
| 755 | l_nb_blocks = prc->cw * prc->ch; |
| 756 | cblk = prc->cblks.enc; |
| 757 | |
| 758 | for (cblkno = 0; cblkno < l_nb_blocks; ++cblkno) { |
| 759 | opj_tcd_layer_t *layer = &cblk->layers[layno]; |
| 760 | |
| 761 | if (!layer->numpasses) { |
| 762 | ++cblk; |
| 763 | continue; |
| 764 | } |
| 765 | |
| 766 | if (layer->len > length) { |
| 767 | return OPJ_FALSE; |
| 768 | } |
| 769 | |
| 770 | memcpy(c, layer->data, layer->len); |
| 771 | cblk->numpasses += layer->numpasses; |
| 772 | c += layer->len; |
| 773 | length -= layer->len; |
| 774 | |
| 775 | /* << INDEX */ |
| 776 | if(cstr_info && cstr_info->index_write) { |
| 777 | opj_packet_info_t *info_PK = &cstr_info->tile[tileno].packet[cstr_info->packno]; |
| 778 | info_PK->disto += layer->disto; |
| 779 | if (cstr_info->D_max < info_PK->disto) { |
| 780 | cstr_info->D_max = info_PK->disto; |
| 781 | } |
| 782 | } |
| 783 | |
| 784 | ++cblk; |
| 785 | /* INDEX >> */ |
| 786 | } |
| 787 | ++band; |
| 788 | } |
| 789 | |
| 790 | assert( c >= dest ); |
| 791 | * p_data_written += (OPJ_UINT32)(c - dest); |
| 792 | |
| 793 | return OPJ_TRUE; |
| 794 | } |
| 795 | |
| 796 | static OPJ_BOOL opj_t2_skip_packet( opj_t2_t* p_t2, |
| 797 | opj_tcd_tile_t *p_tile, |
| 798 | opj_tcp_t *p_tcp, |
| 799 | opj_pi_iterator_t *p_pi, |
| 800 | OPJ_BYTE *p_src, |
| 801 | OPJ_UINT32 * p_data_read, |
| 802 | OPJ_UINT32 p_max_length, |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 803 | opj_packet_info_t *p_pack_info, |
| 804 | opj_event_mgr_t *p_manager) |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 805 | { |
| 806 | OPJ_BOOL l_read_data; |
| 807 | OPJ_UINT32 l_nb_bytes_read = 0; |
| 808 | OPJ_UINT32 l_nb_total_bytes_read = 0; |
| 809 | |
| 810 | *p_data_read = 0; |
| 811 | |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 812 | if (! opj_t2_read_packet_header(p_t2,p_tile,p_tcp,p_pi,&l_read_data,p_src,&l_nb_bytes_read,p_max_length,p_pack_info, p_manager)) { |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 813 | return OPJ_FALSE; |
| 814 | } |
| 815 | |
| 816 | p_src += l_nb_bytes_read; |
| 817 | l_nb_total_bytes_read += l_nb_bytes_read; |
| 818 | p_max_length -= l_nb_bytes_read; |
| 819 | |
| 820 | /* we should read data for the packet */ |
| 821 | if (l_read_data) { |
| 822 | l_nb_bytes_read = 0; |
| 823 | |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 824 | if (! opj_t2_skip_packet_data(p_t2,p_tile,p_pi,&l_nb_bytes_read,p_max_length,p_pack_info, p_manager)) { |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 825 | return OPJ_FALSE; |
| 826 | } |
| 827 | |
| 828 | l_nb_total_bytes_read += l_nb_bytes_read; |
| 829 | } |
| 830 | *p_data_read = l_nb_total_bytes_read; |
| 831 | |
| 832 | return OPJ_TRUE; |
| 833 | } |
| 834 | |
| 835 | |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 836 | static OPJ_BOOL opj_t2_read_packet_header( opj_t2_t* p_t2, |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 837 | opj_tcd_tile_t *p_tile, |
| 838 | opj_tcp_t *p_tcp, |
| 839 | opj_pi_iterator_t *p_pi, |
| 840 | OPJ_BOOL * p_is_data_present, |
| 841 | OPJ_BYTE *p_src_data, |
| 842 | OPJ_UINT32 * p_data_read, |
| 843 | OPJ_UINT32 p_max_length, |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 844 | opj_packet_info_t *p_pack_info, |
| 845 | opj_event_mgr_t *p_manager) |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 846 | |
| 847 | { |
| 848 | /* loop */ |
| 849 | OPJ_UINT32 bandno, cblkno; |
| 850 | OPJ_UINT32 l_nb_code_blocks; |
| 851 | OPJ_UINT32 l_remaining_length; |
| 852 | OPJ_UINT32 l_header_length; |
| 853 | OPJ_UINT32 * l_modified_length_ptr = 00; |
| 854 | OPJ_BYTE *l_current_data = p_src_data; |
| 855 | opj_cp_t *l_cp = p_t2->cp; |
| 856 | opj_bio_t *l_bio = 00; /* BIO component */ |
| 857 | opj_tcd_band_t *l_band = 00; |
| 858 | opj_tcd_cblk_dec_t* l_cblk = 00; |
| 859 | opj_tcd_resolution_t* l_res = &p_tile->comps[p_pi->compno].resolutions[p_pi->resno]; |
| 860 | |
| 861 | OPJ_BYTE *l_header_data = 00; |
| 862 | OPJ_BYTE **l_header_data_start = 00; |
| 863 | |
| 864 | OPJ_UINT32 l_present; |
| 865 | |
| 866 | if (p_pi->layno == 0) { |
| 867 | l_band = l_res->bands; |
| 868 | |
| 869 | /* reset tagtrees */ |
| 870 | for (bandno = 0; bandno < l_res->numbands; ++bandno) { |
| 871 | opj_tcd_precinct_t *l_prc = &l_band->precincts[p_pi->precno]; |
| 872 | |
| 873 | if ( ! ((l_band->x1-l_band->x0 == 0)||(l_band->y1-l_band->y0 == 0)) ) { |
| 874 | opj_tgt_reset(l_prc->incltree); |
| 875 | opj_tgt_reset(l_prc->imsbtree); |
| 876 | l_cblk = l_prc->cblks.dec; |
| 877 | |
| 878 | l_nb_code_blocks = l_prc->cw * l_prc->ch; |
| 879 | for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) { |
| 880 | l_cblk->numsegs = 0; |
| 881 | l_cblk->real_num_segs = 0; |
| 882 | ++l_cblk; |
| 883 | } |
| 884 | } |
| 885 | |
| 886 | ++l_band; |
| 887 | } |
| 888 | } |
| 889 | |
| 890 | /* SOP markers */ |
| 891 | |
| 892 | if (p_tcp->csty & J2K_CP_CSTY_SOP) { |
| 893 | if (p_max_length < 6) { |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 894 | opj_event_msg(p_manager, EVT_WARNING, "Not enough space for expected SOP marker\n"); |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 895 | } else if ((*l_current_data) != 0xff || (*(l_current_data + 1) != 0x91)) { |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 896 | opj_event_msg(p_manager, EVT_WARNING, "Expected SOP marker\n"); |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 897 | } else { |
| 898 | l_current_data += 6; |
| 899 | } |
| 900 | |
| 901 | /** TODO : check the Nsop value */ |
| 902 | } |
| 903 | |
| 904 | /* |
| 905 | When the marker PPT/PPM is used the packet header are store in PPT/PPM marker |
| 906 | This part deal with this caracteristic |
| 907 | step 1: Read packet header in the saved structure |
| 908 | step 2: Return to codestream for decoding |
| 909 | */ |
| 910 | |
| 911 | l_bio = opj_bio_create(); |
| 912 | if (! l_bio) { |
| 913 | return OPJ_FALSE; |
| 914 | } |
| 915 | |
| 916 | if (l_cp->ppm == 1) { /* PPM */ |
| 917 | l_header_data_start = &l_cp->ppm_data; |
| 918 | l_header_data = *l_header_data_start; |
| 919 | l_modified_length_ptr = &(l_cp->ppm_len); |
| 920 | |
| 921 | } |
| 922 | else if (p_tcp->ppt == 1) { /* PPT */ |
| 923 | l_header_data_start = &(p_tcp->ppt_data); |
| 924 | l_header_data = *l_header_data_start; |
| 925 | l_modified_length_ptr = &(p_tcp->ppt_len); |
| 926 | } |
| 927 | else { /* Normal Case */ |
| 928 | l_header_data_start = &(l_current_data); |
| 929 | l_header_data = *l_header_data_start; |
| 930 | l_remaining_length = (OPJ_UINT32)(p_src_data+p_max_length-l_header_data); |
| 931 | l_modified_length_ptr = &(l_remaining_length); |
| 932 | } |
| 933 | |
| 934 | opj_bio_init_dec(l_bio, l_header_data,*l_modified_length_ptr); |
| 935 | |
| 936 | l_present = opj_bio_read(l_bio, 1); |
| 937 | JAS_FPRINTF(stderr, "present=%d \n", l_present ); |
| 938 | if (!l_present) { |
| 939 | /* TODO MSD: no test to control the output of this function*/ |
| 940 | opj_bio_inalign(l_bio); |
| 941 | l_header_data += opj_bio_numbytes(l_bio); |
| 942 | opj_bio_destroy(l_bio); |
| 943 | |
| 944 | /* EPH markers */ |
| 945 | if (p_tcp->csty & J2K_CP_CSTY_EPH) { |
Bo Xu | d53e6fd | 2014-09-30 11:12:05 -0700 | [diff] [blame] | 946 | if ((*l_modified_length_ptr - (OPJ_UINT32)(l_header_data - *l_header_data_start)) < 2U) { |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 947 | opj_event_msg(p_manager, EVT_WARNING, "Not enough space for expected EPH marker\n"); |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 948 | } else if ((*l_header_data) != 0xff || (*(l_header_data + 1) != 0x92)) { |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 949 | opj_event_msg(p_manager, EVT_WARNING, "Expected EPH marker\n"); |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 950 | } else { |
| 951 | l_header_data += 2; |
| 952 | } |
| 953 | } |
| 954 | |
| 955 | l_header_length = (OPJ_UINT32)(l_header_data - *l_header_data_start); |
| 956 | *l_modified_length_ptr -= l_header_length; |
| 957 | *l_header_data_start += l_header_length; |
| 958 | |
| 959 | /* << INDEX */ |
| 960 | /* End of packet header position. Currently only represents the distance to start of packet |
| 961 | Will be updated later by incrementing with packet start value */ |
| 962 | if (p_pack_info) { |
| 963 | p_pack_info->end_ph_pos = (OPJ_INT32)(l_current_data - p_src_data); |
| 964 | } |
| 965 | /* INDEX >> */ |
| 966 | |
| 967 | * p_is_data_present = OPJ_FALSE; |
| 968 | *p_data_read = (OPJ_UINT32)(l_current_data - p_src_data); |
| 969 | return OPJ_TRUE; |
| 970 | } |
| 971 | |
| 972 | l_band = l_res->bands; |
| 973 | for (bandno = 0; bandno < l_res->numbands; ++bandno) { |
| 974 | opj_tcd_precinct_t *l_prc = &(l_band->precincts[p_pi->precno]); |
| 975 | |
| 976 | if ((l_band->x1-l_band->x0 == 0)||(l_band->y1-l_band->y0 == 0)) { |
| 977 | ++l_band; |
| 978 | continue; |
| 979 | } |
| 980 | |
| 981 | l_nb_code_blocks = l_prc->cw * l_prc->ch; |
| 982 | l_cblk = l_prc->cblks.dec; |
| 983 | for (cblkno = 0; cblkno < l_nb_code_blocks; cblkno++) { |
| 984 | OPJ_UINT32 l_included,l_increment, l_segno; |
| 985 | OPJ_INT32 n; |
| 986 | |
| 987 | /* if cblk not yet included before --> inclusion tagtree */ |
| 988 | if (!l_cblk->numsegs) { |
| 989 | l_included = opj_tgt_decode(l_bio, l_prc->incltree, cblkno, (OPJ_INT32)(p_pi->layno + 1)); |
| 990 | /* else one bit */ |
| 991 | } |
| 992 | else { |
| 993 | l_included = opj_bio_read(l_bio, 1); |
| 994 | } |
| 995 | |
| 996 | /* if cblk not included */ |
| 997 | if (!l_included) { |
| 998 | l_cblk->numnewpasses = 0; |
| 999 | ++l_cblk; |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 1000 | JAS_FPRINTF(stderr, "included=%d \n", l_included); |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 1001 | continue; |
| 1002 | } |
| 1003 | |
| 1004 | /* if cblk not yet included --> zero-bitplane tagtree */ |
| 1005 | if (!l_cblk->numsegs) { |
| 1006 | OPJ_UINT32 i = 0; |
| 1007 | |
| 1008 | while (!opj_tgt_decode(l_bio, l_prc->imsbtree, cblkno, (OPJ_INT32)i)) { |
| 1009 | ++i; |
| 1010 | } |
| 1011 | |
| 1012 | l_cblk->numbps = (OPJ_UINT32)l_band->numbps + 1 - i; |
| 1013 | l_cblk->numlenbits = 3; |
| 1014 | } |
| 1015 | |
| 1016 | /* number of coding passes */ |
| 1017 | l_cblk->numnewpasses = opj_t2_getnumpasses(l_bio); |
| 1018 | l_increment = opj_t2_getcommacode(l_bio); |
| 1019 | |
| 1020 | /* length indicator increment */ |
| 1021 | l_cblk->numlenbits += l_increment; |
| 1022 | l_segno = 0; |
| 1023 | |
| 1024 | if (!l_cblk->numsegs) { |
| 1025 | if (! opj_t2_init_seg(l_cblk, l_segno, p_tcp->tccps[p_pi->compno].cblksty, 1)) { |
| 1026 | opj_bio_destroy(l_bio); |
| 1027 | return OPJ_FALSE; |
| 1028 | } |
| 1029 | } |
| 1030 | else { |
| 1031 | l_segno = l_cblk->numsegs - 1; |
| 1032 | if (l_cblk->segs[l_segno].numpasses == l_cblk->segs[l_segno].maxpasses) { |
| 1033 | ++l_segno; |
| 1034 | if (! opj_t2_init_seg(l_cblk, l_segno, p_tcp->tccps[p_pi->compno].cblksty, 0)) { |
| 1035 | opj_bio_destroy(l_bio); |
| 1036 | return OPJ_FALSE; |
| 1037 | } |
| 1038 | } |
| 1039 | } |
| 1040 | n = (OPJ_INT32)l_cblk->numnewpasses; |
| 1041 | |
| 1042 | do { |
| 1043 | l_cblk->segs[l_segno].numnewpasses = (OPJ_UINT32)opj_int_min((OPJ_INT32)(l_cblk->segs[l_segno].maxpasses - l_cblk->segs[l_segno].numpasses), n); |
| 1044 | l_cblk->segs[l_segno].newlen = opj_bio_read(l_bio, l_cblk->numlenbits + opj_uint_floorlog2(l_cblk->segs[l_segno].numnewpasses)); |
| 1045 | JAS_FPRINTF(stderr, "included=%d numnewpasses=%d increment=%d len=%d \n", l_included, l_cblk->segs[l_segno].numnewpasses, l_increment, l_cblk->segs[l_segno].newlen ); |
| 1046 | |
| 1047 | n -= (OPJ_INT32)l_cblk->segs[l_segno].numnewpasses; |
| 1048 | if (n > 0) { |
| 1049 | ++l_segno; |
| 1050 | |
| 1051 | if (! opj_t2_init_seg(l_cblk, l_segno, p_tcp->tccps[p_pi->compno].cblksty, 0)) { |
| 1052 | opj_bio_destroy(l_bio); |
| 1053 | return OPJ_FALSE; |
| 1054 | } |
| 1055 | } |
| 1056 | } while (n > 0); |
| 1057 | |
| 1058 | ++l_cblk; |
| 1059 | } |
| 1060 | |
| 1061 | ++l_band; |
| 1062 | } |
| 1063 | |
| 1064 | if (!opj_bio_inalign(l_bio)) { |
| 1065 | opj_bio_destroy(l_bio); |
| 1066 | return OPJ_FALSE; |
| 1067 | } |
| 1068 | |
| 1069 | l_header_data += opj_bio_numbytes(l_bio); |
| 1070 | opj_bio_destroy(l_bio); |
| 1071 | |
| 1072 | /* EPH markers */ |
| 1073 | if (p_tcp->csty & J2K_CP_CSTY_EPH) { |
Bo Xu | d53e6fd | 2014-09-30 11:12:05 -0700 | [diff] [blame] | 1074 | if ((*l_modified_length_ptr - (OPJ_UINT32)(l_header_data - *l_header_data_start)) < 2U) { |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 1075 | opj_event_msg(p_manager, EVT_WARNING, "Not enough space for expected EPH marker\n"); |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 1076 | } else if ((*l_header_data) != 0xff || (*(l_header_data + 1) != 0x92)) { |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 1077 | opj_event_msg(p_manager, EVT_WARNING, "Expected EPH marker\n"); |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 1078 | } else { |
| 1079 | l_header_data += 2; |
| 1080 | } |
| 1081 | } |
| 1082 | |
| 1083 | l_header_length = (OPJ_UINT32)(l_header_data - *l_header_data_start); |
| 1084 | JAS_FPRINTF( stderr, "hdrlen=%d \n", l_header_length ); |
| 1085 | JAS_FPRINTF( stderr, "packet body\n"); |
| 1086 | *l_modified_length_ptr -= l_header_length; |
| 1087 | *l_header_data_start += l_header_length; |
| 1088 | |
| 1089 | /* << INDEX */ |
| 1090 | /* End of packet header position. Currently only represents the distance to start of packet |
| 1091 | Will be updated later by incrementing with packet start value */ |
| 1092 | if (p_pack_info) { |
| 1093 | p_pack_info->end_ph_pos = (OPJ_INT32)(l_current_data - p_src_data); |
| 1094 | } |
| 1095 | /* INDEX >> */ |
| 1096 | |
| 1097 | *p_is_data_present = OPJ_TRUE; |
| 1098 | *p_data_read = (OPJ_UINT32)(l_current_data - p_src_data); |
| 1099 | |
| 1100 | return OPJ_TRUE; |
| 1101 | } |
| 1102 | |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 1103 | static OPJ_BOOL opj_t2_read_packet_data( opj_t2_t* p_t2, |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 1104 | opj_tcd_tile_t *p_tile, |
| 1105 | opj_pi_iterator_t *p_pi, |
| 1106 | OPJ_BYTE *p_src_data, |
| 1107 | OPJ_UINT32 * p_data_read, |
| 1108 | OPJ_UINT32 p_max_length, |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 1109 | opj_packet_info_t *pack_info, |
| 1110 | opj_event_mgr_t* p_manager) |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 1111 | { |
| 1112 | OPJ_UINT32 bandno, cblkno; |
| 1113 | OPJ_UINT32 l_nb_code_blocks; |
| 1114 | OPJ_BYTE *l_current_data = p_src_data; |
| 1115 | opj_tcd_band_t *l_band = 00; |
| 1116 | opj_tcd_cblk_dec_t* l_cblk = 00; |
| 1117 | opj_tcd_resolution_t* l_res = &p_tile->comps[p_pi->compno].resolutions[p_pi->resno]; |
| 1118 | |
| 1119 | OPJ_ARG_NOT_USED(p_t2); |
| 1120 | OPJ_ARG_NOT_USED(pack_info); |
| 1121 | |
| 1122 | l_band = l_res->bands; |
| 1123 | for (bandno = 0; bandno < l_res->numbands; ++bandno) { |
| 1124 | opj_tcd_precinct_t *l_prc = &l_band->precincts[p_pi->precno]; |
| 1125 | |
| 1126 | if ((l_band->x1-l_band->x0 == 0)||(l_band->y1-l_band->y0 == 0)) { |
| 1127 | ++l_band; |
| 1128 | continue; |
| 1129 | } |
| 1130 | |
| 1131 | l_nb_code_blocks = l_prc->cw * l_prc->ch; |
| 1132 | l_cblk = l_prc->cblks.dec; |
| 1133 | |
| 1134 | for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) { |
| 1135 | opj_tcd_seg_t *l_seg = 00; |
| 1136 | |
| 1137 | if (!l_cblk->numnewpasses) { |
| 1138 | /* nothing to do */ |
| 1139 | ++l_cblk; |
| 1140 | continue; |
| 1141 | } |
| 1142 | |
| 1143 | if (!l_cblk->numsegs) { |
| 1144 | l_seg = l_cblk->segs; |
| 1145 | ++l_cblk->numsegs; |
| 1146 | l_cblk->data_current_size = 0; |
| 1147 | } |
| 1148 | else { |
| 1149 | l_seg = &l_cblk->segs[l_cblk->numsegs - 1]; |
| 1150 | |
| 1151 | if (l_seg->numpasses == l_seg->maxpasses) { |
| 1152 | ++l_seg; |
| 1153 | ++l_cblk->numsegs; |
| 1154 | } |
| 1155 | } |
| 1156 | |
| 1157 | do { |
Bo Xu | d53e6fd | 2014-09-30 11:12:05 -0700 | [diff] [blame] | 1158 | /* Check possible overflow (on l_current_data only, assumes input args already checked) then size */ |
Bo Xu | e93d534 | 2014-10-03 12:29:54 -0700 | [diff] [blame] | 1159 | if ((((OPJ_SIZE_T)l_current_data + (OPJ_SIZE_T)l_seg->newlen) < (OPJ_SIZE_T)l_current_data) || (l_current_data + l_seg->newlen > p_src_data + p_max_length)) { |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 1160 | opj_event_msg(p_manager, EVT_ERROR, "read: segment too long (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n", |
| 1161 | l_seg->newlen, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno, p_pi->compno); |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 1162 | return OPJ_FALSE; |
| 1163 | } |
| 1164 | |
| 1165 | #ifdef USE_JPWL |
| 1166 | /* we need here a j2k handle to verify if making a check to |
| 1167 | the validity of cblocks parameters is selected from user (-W) */ |
| 1168 | |
| 1169 | /* let's check that we are not exceeding */ |
| 1170 | if ((l_cblk->len + l_seg->newlen) > 8192) { |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 1171 | opj_event_msg(p_manager, EVT_WARNING, |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 1172 | "JPWL: segment too long (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n", |
| 1173 | l_seg->newlen, cblkno, p_pi->precno, bandno, p_pi->resno, p_pi->compno); |
| 1174 | if (!JPWL_ASSUME) { |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 1175 | opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n"); |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 1176 | return OPJ_FALSE; |
| 1177 | } |
| 1178 | l_seg->newlen = 8192 - l_cblk->len; |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 1179 | opj_event_msg(p_manager, EVT_WARNING, " - truncating segment to %d\n", l_seg->newlen); |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 1180 | break; |
| 1181 | }; |
| 1182 | |
| 1183 | #endif /* USE_JPWL */ |
Bo Xu | d53e6fd | 2014-09-30 11:12:05 -0700 | [diff] [blame] | 1184 | /* Check possible overflow on size */ |
| 1185 | if ((l_cblk->data_current_size + l_seg->newlen) < l_cblk->data_current_size) { |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 1186 | opj_event_msg(p_manager, EVT_ERROR, "read: segment too long (%d) with current size (%d > %d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n", |
Bo Xu | d53e6fd | 2014-09-30 11:12:05 -0700 | [diff] [blame] | 1187 | l_seg->newlen, l_cblk->data_current_size, 0xFFFFFFFF - l_seg->newlen, cblkno, p_pi->precno, bandno, p_pi->resno, p_pi->compno); |
| 1188 | return OPJ_FALSE; |
| 1189 | } |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 1190 | /* Check if the cblk->data have allocated enough memory */ |
| 1191 | if ((l_cblk->data_current_size + l_seg->newlen) > l_cblk->data_max_size) { |
| 1192 | OPJ_BYTE* new_cblk_data = (OPJ_BYTE*) opj_realloc(l_cblk->data, l_cblk->data_current_size + l_seg->newlen); |
| 1193 | if(! new_cblk_data) { |
| 1194 | opj_free(l_cblk->data); |
Bo Xu | d53e6fd | 2014-09-30 11:12:05 -0700 | [diff] [blame] | 1195 | l_cblk->data = NULL; |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 1196 | l_cblk->data_max_size = 0; |
| 1197 | /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to realloc code block cata!\n"); */ |
| 1198 | return OPJ_FALSE; |
| 1199 | } |
| 1200 | l_cblk->data_max_size = l_cblk->data_current_size + l_seg->newlen; |
| 1201 | l_cblk->data = new_cblk_data; |
| 1202 | } |
| 1203 | |
| 1204 | memcpy(l_cblk->data + l_cblk->data_current_size, l_current_data, l_seg->newlen); |
| 1205 | |
| 1206 | if (l_seg->numpasses == 0) { |
| 1207 | l_seg->data = &l_cblk->data; |
| 1208 | l_seg->dataindex = l_cblk->data_current_size; |
| 1209 | } |
| 1210 | |
| 1211 | l_current_data += l_seg->newlen; |
| 1212 | l_seg->numpasses += l_seg->numnewpasses; |
| 1213 | l_cblk->numnewpasses -= l_seg->numnewpasses; |
| 1214 | |
| 1215 | l_seg->real_num_passes = l_seg->numpasses; |
| 1216 | l_cblk->data_current_size += l_seg->newlen; |
| 1217 | l_seg->len += l_seg->newlen; |
| 1218 | |
| 1219 | if (l_cblk->numnewpasses > 0) { |
| 1220 | ++l_seg; |
| 1221 | ++l_cblk->numsegs; |
| 1222 | } |
| 1223 | } while (l_cblk->numnewpasses > 0); |
| 1224 | |
| 1225 | l_cblk->real_num_segs = l_cblk->numsegs; |
| 1226 | ++l_cblk; |
| 1227 | } /* next code_block */ |
| 1228 | |
| 1229 | ++l_band; |
| 1230 | } |
| 1231 | |
| 1232 | *(p_data_read) = (OPJ_UINT32)(l_current_data - p_src_data); |
| 1233 | |
Bo Xu | d53e6fd | 2014-09-30 11:12:05 -0700 | [diff] [blame] | 1234 | |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 1235 | return OPJ_TRUE; |
| 1236 | } |
| 1237 | |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 1238 | static OPJ_BOOL opj_t2_skip_packet_data( opj_t2_t* p_t2, |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 1239 | opj_tcd_tile_t *p_tile, |
| 1240 | opj_pi_iterator_t *p_pi, |
| 1241 | OPJ_UINT32 * p_data_read, |
| 1242 | OPJ_UINT32 p_max_length, |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 1243 | opj_packet_info_t *pack_info, |
| 1244 | opj_event_mgr_t *p_manager) |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 1245 | { |
| 1246 | OPJ_UINT32 bandno, cblkno; |
| 1247 | OPJ_UINT32 l_nb_code_blocks; |
| 1248 | opj_tcd_band_t *l_band = 00; |
| 1249 | opj_tcd_cblk_dec_t* l_cblk = 00; |
| 1250 | opj_tcd_resolution_t* l_res = &p_tile->comps[p_pi->compno].resolutions[p_pi->resno]; |
| 1251 | |
| 1252 | OPJ_ARG_NOT_USED(p_t2); |
| 1253 | OPJ_ARG_NOT_USED(pack_info); |
| 1254 | |
| 1255 | *p_data_read = 0; |
| 1256 | l_band = l_res->bands; |
| 1257 | |
| 1258 | for (bandno = 0; bandno < l_res->numbands; ++bandno) { |
| 1259 | opj_tcd_precinct_t *l_prc = &l_band->precincts[p_pi->precno]; |
| 1260 | |
| 1261 | if ((l_band->x1-l_band->x0 == 0)||(l_band->y1-l_band->y0 == 0)) { |
| 1262 | ++l_band; |
| 1263 | continue; |
| 1264 | } |
| 1265 | |
| 1266 | l_nb_code_blocks = l_prc->cw * l_prc->ch; |
| 1267 | l_cblk = l_prc->cblks.dec; |
| 1268 | |
| 1269 | for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) { |
| 1270 | opj_tcd_seg_t *l_seg = 00; |
| 1271 | |
| 1272 | if (!l_cblk->numnewpasses) { |
| 1273 | /* nothing to do */ |
| 1274 | ++l_cblk; |
| 1275 | continue; |
| 1276 | } |
| 1277 | |
| 1278 | if (!l_cblk->numsegs) { |
| 1279 | l_seg = l_cblk->segs; |
| 1280 | ++l_cblk->numsegs; |
| 1281 | l_cblk->data_current_size = 0; |
| 1282 | } |
| 1283 | else { |
| 1284 | l_seg = &l_cblk->segs[l_cblk->numsegs - 1]; |
| 1285 | |
| 1286 | if (l_seg->numpasses == l_seg->maxpasses) { |
| 1287 | ++l_seg; |
| 1288 | ++l_cblk->numsegs; |
| 1289 | } |
| 1290 | } |
| 1291 | |
| 1292 | do { |
Bo Xu | 767aebb | 2014-10-21 13:05:17 -0700 | [diff] [blame] | 1293 | /* Check possible overflow then size */ |
| 1294 | if (((*p_data_read + l_seg->newlen) < (*p_data_read)) || ((*p_data_read + l_seg->newlen) > p_max_length)) { |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 1295 | opj_event_msg(p_manager, EVT_ERROR, "skip: segment too long (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n", |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 1296 | l_seg->newlen, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno, p_pi->compno); |
| 1297 | return OPJ_FALSE; |
| 1298 | } |
| 1299 | |
| 1300 | #ifdef USE_JPWL |
| 1301 | /* we need here a j2k handle to verify if making a check to |
| 1302 | the validity of cblocks parameters is selected from user (-W) */ |
| 1303 | |
| 1304 | /* let's check that we are not exceeding */ |
| 1305 | if ((l_cblk->len + l_seg->newlen) > 8192) { |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 1306 | opj_event_msg(p_manager, EVT_WARNING, |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 1307 | "JPWL: segment too long (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n", |
| 1308 | l_seg->newlen, cblkno, p_pi->precno, bandno, p_pi->resno, p_pi->compno); |
| 1309 | if (!JPWL_ASSUME) { |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 1310 | opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n"); |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 1311 | return -999; |
| 1312 | } |
| 1313 | l_seg->newlen = 8192 - l_cblk->len; |
Jun Fang | e865ed1 | 2015-10-13 15:28:55 +0800 | [diff] [blame] | 1314 | opj_event_msg(p_manager, EVT_WARNING, " - truncating segment to %d\n", l_seg->newlen); |
John Abd-El-Malek | 5110c47 | 2014-05-17 22:33:34 -0700 | [diff] [blame] | 1315 | break; |
| 1316 | }; |
| 1317 | |
| 1318 | #endif /* USE_JPWL */ |
| 1319 | JAS_FPRINTF(stderr, "p_data_read (%d) newlen (%d) \n", *p_data_read, l_seg->newlen ); |
| 1320 | *(p_data_read) += l_seg->newlen; |
| 1321 | |
| 1322 | l_seg->numpasses += l_seg->numnewpasses; |
| 1323 | l_cblk->numnewpasses -= l_seg->numnewpasses; |
| 1324 | if (l_cblk->numnewpasses > 0) |
| 1325 | { |
| 1326 | ++l_seg; |
| 1327 | ++l_cblk->numsegs; |
| 1328 | } |
| 1329 | } while (l_cblk->numnewpasses > 0); |
| 1330 | |
| 1331 | ++l_cblk; |
| 1332 | } |
| 1333 | |
| 1334 | ++l_band; |
| 1335 | } |
| 1336 | |
| 1337 | return OPJ_TRUE; |
| 1338 | } |
| 1339 | |
| 1340 | |
| 1341 | OPJ_BOOL opj_t2_init_seg( opj_tcd_cblk_dec_t* cblk, |
| 1342 | OPJ_UINT32 index, |
| 1343 | OPJ_UINT32 cblksty, |
| 1344 | OPJ_UINT32 first) |
| 1345 | { |
| 1346 | opj_tcd_seg_t* seg = 00; |
| 1347 | OPJ_UINT32 l_nb_segs = index + 1; |
| 1348 | |
| 1349 | if (l_nb_segs > cblk->m_current_max_segs) { |
| 1350 | opj_tcd_seg_t* new_segs; |
| 1351 | cblk->m_current_max_segs += OPJ_J2K_DEFAULT_NB_SEGS; |
| 1352 | |
| 1353 | new_segs = (opj_tcd_seg_t*) opj_realloc(cblk->segs, cblk->m_current_max_segs * sizeof(opj_tcd_seg_t)); |
| 1354 | if(! new_segs) { |
| 1355 | opj_free(cblk->segs); |
| 1356 | cblk->segs = NULL; |
| 1357 | cblk->m_current_max_segs = 0; |
| 1358 | /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to initialize segment %d\n", l_nb_segs); */ |
| 1359 | return OPJ_FALSE; |
| 1360 | } |
| 1361 | cblk->segs = new_segs; |
| 1362 | } |
| 1363 | |
| 1364 | seg = &cblk->segs[index]; |
| 1365 | memset(seg,0,sizeof(opj_tcd_seg_t)); |
| 1366 | |
| 1367 | if (cblksty & J2K_CCP_CBLKSTY_TERMALL) { |
| 1368 | seg->maxpasses = 1; |
| 1369 | } |
| 1370 | else if (cblksty & J2K_CCP_CBLKSTY_LAZY) { |
| 1371 | if (first) { |
| 1372 | seg->maxpasses = 10; |
| 1373 | } else { |
| 1374 | seg->maxpasses = (((seg - 1)->maxpasses == 1) || ((seg - 1)->maxpasses == 10)) ? 2 : 1; |
| 1375 | } |
| 1376 | } else { |
| 1377 | seg->maxpasses = 109; |
| 1378 | } |
| 1379 | |
| 1380 | return OPJ_TRUE; |
| 1381 | } |