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