diff options
author | Jun Fang <jun_fang@foxitsoftware.com> | 2015-10-13 15:28:55 +0800 |
---|---|---|
committer | Jun Fang <jun_fang@foxitsoftware.com> | 2015-10-13 15:28:55 +0800 |
commit | c212b684cb028a5d98e57f711c9eed931b853a44 (patch) | |
tree | f2c937d16b1156f57d8dbc86ec21db11a5b34174 /third_party/libopenjpeg20/j2k.c | |
parent | 3acb1ef909a22368507ed13817c4988c818e3aee (diff) | |
download | pdfium-c212b684cb028a5d98e57f711c9eed931b853a44.tar.xz |
upgrade openjpeg to commit# cf352af
BUG=457480,497355
R=tsepez@chromium.org
Review URL: https://codereview.chromium.org/1338973005 .
Diffstat (limited to 'third_party/libopenjpeg20/j2k.c')
-rw-r--r-- | third_party/libopenjpeg20/j2k.c | 1675 |
1 files changed, 934 insertions, 741 deletions
diff --git a/third_party/libopenjpeg20/j2k.c b/third_party/libopenjpeg20/j2k.c index 7b4bc58a6c..849d0b4242 100644 --- a/third_party/libopenjpeg20/j2k.c +++ b/third_party/libopenjpeg20/j2k.c @@ -51,7 +51,7 @@ /** * Sets up the procedures to do on reading header. Developpers wanting to extend the library can add their own reading procedures. */ -static void opj_j2k_setup_header_reading (opj_j2k_t *p_j2k); +static OPJ_BOOL opj_j2k_setup_header_reading (opj_j2k_t *p_j2k, opj_event_mgr_t * p_manager); /** * The read header procedure. @@ -90,19 +90,19 @@ static OPJ_BOOL opj_j2k_decoding_validation ( opj_j2k_t * p_j2k, * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters * are valid. Developpers wanting to extend the library can add their own validation procedures. */ -static void opj_j2k_setup_encoding_validation (opj_j2k_t *p_j2k); +static OPJ_BOOL opj_j2k_setup_encoding_validation (opj_j2k_t *p_j2k, opj_event_mgr_t * p_manager); /** * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters * are valid. Developpers wanting to extend the library can add their own validation procedures. */ -static void opj_j2k_setup_decoding_validation (opj_j2k_t *p_j2k); +static OPJ_BOOL opj_j2k_setup_decoding_validation (opj_j2k_t *p_j2k, opj_event_mgr_t * p_manager); /** * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters * are valid. Developpers wanting to extend the library can add their own validation procedures. */ -static void opj_j2k_setup_end_compress (opj_j2k_t *p_j2k); +static OPJ_BOOL opj_j2k_setup_end_compress (opj_j2k_t *p_j2k, opj_event_mgr_t * p_manager); /** * The mct encoding validation procedure. @@ -360,7 +360,7 @@ static OPJ_BOOL opj_j2k_post_write_tile (opj_j2k_t * p_j2k, * Sets up the procedures to do on writing header. * Developers wanting to extend the library can add their own writing procedures. */ -static void opj_j2k_setup_header_writing (opj_j2k_t *p_j2k); +static OPJ_BOOL opj_j2k_setup_header_writing (opj_j2k_t *p_j2k, opj_event_mgr_t * p_manager); static OPJ_BOOL opj_j2k_write_first_tile_part( opj_j2k_t *p_j2k, OPJ_BYTE * p_data, @@ -718,28 +718,28 @@ static OPJ_BOOL opj_j2k_read_plt ( opj_j2k_t *p_j2k, OPJ_UINT32 p_header_size, opj_event_mgr_t * p_manager ); -#if 0 /** - * Reads a PPM marker (Packed packet headers, main header) + * Reads a PPM marker (Packed headers, main header) * * @param p_header_data the data contained in the POC box. * @param p_j2k the jpeg2000 codec. * @param p_header_size the size of the data contained in the POC marker. * @param p_manager the user event manager. -*/ -static OPJ_BOOL j2k_read_ppm_v2 ( - opj_j2k_t *p_j2k, - OPJ_BYTE * p_header_data, - OPJ_UINT32 p_header_size, - struct opj_event_mgr * p_manager - ); -#endif + */ -static OPJ_BOOL j2k_read_ppm_v3 ( - opj_j2k_t *p_j2k, - OPJ_BYTE * p_header_data, - OPJ_UINT32 p_header_size, - opj_event_mgr_t * p_manager ); +static OPJ_BOOL opj_j2k_read_ppm ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + opj_event_mgr_t * p_manager ); + +/** + * Merges all PPM markers read (Packed headers, main header) + * + * @param p_cp main coding parameters. + * @param p_manager the user event manager. + */ +static OPJ_BOOL opj_j2k_merge_ppm ( opj_cp_t *p_cp, opj_event_mgr_t * p_manager ); /** * Reads a PPT marker (Packed packet headers, tile-part header) @@ -753,6 +753,17 @@ static OPJ_BOOL opj_j2k_read_ppt ( opj_j2k_t *p_j2k, OPJ_BYTE * p_header_data, OPJ_UINT32 p_header_size, opj_event_mgr_t * p_manager ); + +/** + * Merges all PPT markers read (Packed headers, tile-part header) + * + * @param p_tcp the tile. + * @param p_manager the user event manager. + */ +static OPJ_BOOL opj_j2k_merge_ppt ( opj_tcp_t *p_tcp, + opj_event_mgr_t * p_manager ); + + /** * Writes the TLM marker (Tile Length Marker) * @@ -780,12 +791,32 @@ static OPJ_BOOL opj_j2k_write_sot( opj_j2k_t *p_j2k, opj_event_mgr_t * p_manager ); /** - * Reads a PPT marker (Packed packet headers, tile-part header) + * Reads values from a SOT marker (Start of tile-part) * - * @param p_header_data the data contained in the PPT box. - * @param p_j2k the jpeg2000 codec. + * the j2k decoder state is not affected. No side effects, no checks except for p_header_size. + * + * @param p_header_data the data contained in the SOT marker. + * @param p_header_size the size of the data contained in the SOT marker. + * @param p_tile_no Isot. + * @param p_tot_len Psot. + * @param p_current_part TPsot. + * @param p_num_parts TNsot. + * @param p_manager the user event manager. + */ +static OPJ_BOOL opj_j2k_get_sot_values(OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + OPJ_UINT32* p_tile_no, + OPJ_UINT32* p_tot_len, + OPJ_UINT32* p_current_part, + OPJ_UINT32* p_num_parts, + opj_event_mgr_t * p_manager ); +/** + * Reads a SOT marker (Start of tile-part) + * + * @param p_header_data the data contained in the SOT marker. + * @param p_j2k the jpeg2000 codec. * @param p_header_size the size of the data contained in the PPT marker. - * @param p_manager the user event manager. + * @param p_manager the user event manager. */ static OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_j2k, OPJ_BYTE * p_header_data, @@ -821,7 +852,7 @@ static OPJ_BOOL opj_j2k_read_sod( opj_j2k_t *p_j2k, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ); -void opj_j2k_update_tlm (opj_j2k_t * p_j2k, OPJ_UINT32 p_tile_part_size ) +static void opj_j2k_update_tlm (opj_j2k_t * p_j2k, OPJ_UINT32 p_tile_part_size ) { opj_write_bytes(p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current,p_j2k->m_current_tile_number,1); /* PSOT */ ++p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current; @@ -1179,6 +1210,18 @@ static void opj_j2k_set_cinema_parameters(opj_cparameters_t *parameters, opj_ima static OPJ_BOOL opj_j2k_is_cinema_compliant(opj_image_t *image, OPJ_UINT16 rsiz, opj_event_mgr_t *p_manager); +/** + * Checks for invalid number of tile-parts in SOT marker (TPsot==TNsot). See issue 254. + * + * @param p_stream the stream to read data from. + * @param tile_no tile number we're looking for. + * @param p_correction_needed output value. if true, non conformant codestream needs TNsot correction. + * @param p_manager the user event manager. + * + * @return true if the function was successful, false else. + */ +static OPJ_BOOL opj_j2k_need_nb_tile_parts_correction(opj_stream_private_t *p_stream, OPJ_UINT32 tile_no, OPJ_BOOL* p_correction_needed, opj_event_mgr_t * p_manager ); + /*@}*/ /*@}*/ @@ -1189,7 +1232,7 @@ typedef struct j2k_prog_order{ char str_prog[5]; }j2k_prog_order_t; -j2k_prog_order_t j2k_prog_order_list[] = { +static j2k_prog_order_t j2k_prog_order_list[] = { {OPJ_CPRL, "CPRL"}, {OPJ_LRCP, "LRCP"}, {OPJ_PCRL, "PCRL"}, @@ -1211,7 +1254,7 @@ static const OPJ_UINT32 MCT_ELEMENT_SIZE [] = typedef void (* opj_j2k_mct_function) (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem); -const opj_j2k_mct_function j2k_mct_read_functions_to_float [] = +static const opj_j2k_mct_function j2k_mct_read_functions_to_float [] = { opj_j2k_read_int16_to_float, opj_j2k_read_int32_to_float, @@ -1219,7 +1262,7 @@ const opj_j2k_mct_function j2k_mct_read_functions_to_float [] = opj_j2k_read_float64_to_float }; -const opj_j2k_mct_function j2k_mct_read_functions_to_int32 [] = +static const opj_j2k_mct_function j2k_mct_read_functions_to_int32 [] = { opj_j2k_read_int16_to_int32, opj_j2k_read_int32_to_int32, @@ -1227,7 +1270,7 @@ const opj_j2k_mct_function j2k_mct_read_functions_to_int32 [] = opj_j2k_read_float64_to_int32 }; -const opj_j2k_mct_function j2k_mct_write_functions_from_float [] = +static const opj_j2k_mct_function j2k_mct_write_functions_from_float [] = { opj_j2k_write_float_to_int16, opj_j2k_write_float_to_int32, @@ -1249,7 +1292,7 @@ typedef struct opj_dec_memory_marker_handler } opj_dec_memory_marker_handler_t; -const opj_dec_memory_marker_handler_t j2k_memory_marker_handler_tab [] = +static const opj_dec_memory_marker_handler_t j2k_memory_marker_handler_tab [] = { {J2K_MS_SOT, J2K_STATE_MH | J2K_STATE_TPHSOT, opj_j2k_read_sot}, {J2K_MS_COD, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_cod}, @@ -1262,7 +1305,7 @@ const opj_dec_memory_marker_handler_t j2k_memory_marker_handler_tab [] = {J2K_MS_TLM, J2K_STATE_MH, opj_j2k_read_tlm}, {J2K_MS_PLM, J2K_STATE_MH, opj_j2k_read_plm}, {J2K_MS_PLT, J2K_STATE_TPH, opj_j2k_read_plt}, - {J2K_MS_PPM, J2K_STATE_MH, j2k_read_ppm_v3}, + {J2K_MS_PPM, J2K_STATE_MH, opj_j2k_read_ppm}, {J2K_MS_PPT, J2K_STATE_TPH, opj_j2k_read_ppt}, {J2K_MS_SOP, 0, 0}, {J2K_MS_CRG, J2K_STATE_MH, opj_j2k_read_crg}, @@ -1286,7 +1329,7 @@ const opj_dec_memory_marker_handler_t j2k_memory_marker_handler_tab [] = {J2K_MS_UNK, J2K_STATE_MH | J2K_STATE_TPH, 0}/*opj_j2k_read_unk is directly used*/ }; -void opj_j2k_read_int16_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem) +static void opj_j2k_read_int16_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem) { OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data; OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data; @@ -1302,7 +1345,7 @@ void opj_j2k_read_int16_to_float (const void * p_src_data, void * p_dest_data, } } -void opj_j2k_read_int32_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem) +static void opj_j2k_read_int32_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem) { OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data; OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data; @@ -1318,7 +1361,7 @@ void opj_j2k_read_int32_to_float (const void * p_src_data, void * p_dest_data, } } -void opj_j2k_read_float32_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem) +static void opj_j2k_read_float32_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem) { OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data; OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data; @@ -1334,7 +1377,7 @@ void opj_j2k_read_float32_to_float (const void * p_src_data, void * p_dest_data } } -void opj_j2k_read_float64_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem) +static void opj_j2k_read_float64_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem) { OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data; OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data; @@ -1350,7 +1393,7 @@ void opj_j2k_read_float64_to_float (const void * p_src_data, void * p_dest_data } } -void opj_j2k_read_int16_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem) +static void opj_j2k_read_int16_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem) { OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data; OPJ_INT32 * l_dest_data = (OPJ_INT32 *) p_dest_data; @@ -1366,7 +1409,7 @@ void opj_j2k_read_int16_to_int32 (const void * p_src_data, void * p_dest_data, } } -void opj_j2k_read_int32_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem) +static void opj_j2k_read_int32_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem) { OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data; OPJ_INT32 * l_dest_data = (OPJ_INT32 *) p_dest_data; @@ -1382,7 +1425,7 @@ void opj_j2k_read_int32_to_int32 (const void * p_src_data, void * p_dest_data, } } -void opj_j2k_read_float32_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem) +static void opj_j2k_read_float32_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem) { OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data; OPJ_INT32 * l_dest_data = (OPJ_INT32 *) p_dest_data; @@ -1398,7 +1441,7 @@ void opj_j2k_read_float32_to_int32 (const void * p_src_data, void * p_dest_data } } -void opj_j2k_read_float64_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem) +static void opj_j2k_read_float64_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem) { OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data; OPJ_INT32 * l_dest_data = (OPJ_INT32 *) p_dest_data; @@ -1414,7 +1457,7 @@ void opj_j2k_read_float64_to_int32 (const void * p_src_data, void * p_dest_data } } -void opj_j2k_write_float_to_int16 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem) +static void opj_j2k_write_float_to_int16 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem) { OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data; OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data; @@ -1430,7 +1473,7 @@ void opj_j2k_write_float_to_int16 (const void * p_src_data, void * p_dest_data, } } -void opj_j2k_write_float_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem) +static void opj_j2k_write_float_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem) { OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data; OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data; @@ -1446,7 +1489,7 @@ void opj_j2k_write_float_to_int32 (const void * p_src_data, void * p_dest_data, } } -void opj_j2k_write_float_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem) +static void opj_j2k_write_float_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem) { OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data; OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data; @@ -1462,7 +1505,7 @@ void opj_j2k_write_float_to_float (const void * p_src_data, void * p_dest_data, } } -void opj_j2k_write_float_to_float64 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem) +static void opj_j2k_write_float_to_float64 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem) { OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data; OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data; @@ -1488,7 +1531,7 @@ char *opj_j2k_convert_progression_order(OPJ_PROG_ORDER prg_order){ return po->str_prog; } -OPJ_BOOL opj_j2k_check_poc_val( const opj_poc_t *p_pocs, +static OPJ_BOOL opj_j2k_check_poc_val( const opj_poc_t *p_pocs, OPJ_UINT32 p_nb_pocs, OPJ_UINT32 p_nb_resolutions, OPJ_UINT32 p_num_comps, @@ -1592,7 +1635,7 @@ OPJ_BOOL opj_j2k_check_poc_val( const opj_poc_t *p_pocs, /* ----------------------------------------------------------------------- */ -OPJ_UINT32 opj_j2k_get_num_tp(opj_cp_t *cp, OPJ_UINT32 pino, OPJ_UINT32 tileno) +static OPJ_UINT32 opj_j2k_get_num_tp(opj_cp_t *cp, OPJ_UINT32 pino, OPJ_UINT32 tileno) { const OPJ_CHAR *prog = 00; OPJ_INT32 i; @@ -1650,7 +1693,7 @@ OPJ_UINT32 opj_j2k_get_num_tp(opj_cp_t *cp, OPJ_UINT32 pino, OPJ_UINT32 tileno) return tpnum; } -OPJ_BOOL opj_j2k_calculate_tp( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_calculate_tp( opj_j2k_t *p_j2k, opj_cp_t *cp, OPJ_UINT32 * p_nb_tiles, opj_image_t *image, @@ -1728,7 +1771,7 @@ OPJ_BOOL opj_j2k_calculate_tp( opj_j2k_t *p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_write_soc( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_write_soc( opj_j2k_t *p_j2k, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ) { @@ -1806,7 +1849,7 @@ static OPJ_BOOL opj_j2k_read_soc( opj_j2k_t *p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_write_siz( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_write_siz( opj_j2k_t *p_j2k, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ) { @@ -1999,14 +2042,8 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k, } /* testcase issue427-illegal-tile-offset.jp2 */ - l_tx1 = l_cp->tx0 + l_cp->tdx; - if (l_tx1 < l_cp->tx0) { /* manage overflow */ - l_tx1 = 0xFFFFFFFFU; - } - l_ty1 = l_cp->ty0 + l_cp->tdy; - if (l_ty1 < l_cp->ty0) { /* manage overflow */ - l_ty1 = 0xFFFFFFFFU; - } + l_tx1 = opj_uint_adds(l_cp->tx0, l_cp->tdx); /* manage overflow */ + l_ty1 = opj_uint_adds(l_cp->ty0, l_cp->tdy); /* manage overflow */ if ((l_cp->tx0 > l_image->x0) || (l_cp->ty0 > l_image->y0) || (l_tx1 <= l_image->x0) || (l_ty1 <= l_image->y0) ) { opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker: illegal tile offset\n"); return OPJ_FALSE; @@ -2254,7 +2291,7 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_write_com( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_write_com( opj_j2k_t *p_j2k, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ) @@ -2328,7 +2365,7 @@ static OPJ_BOOL opj_j2k_read_com ( opj_j2k_t *p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_write_cod( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_write_cod( opj_j2k_t *p_j2k, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ) { @@ -2514,7 +2551,7 @@ static OPJ_BOOL opj_j2k_read_cod ( opj_j2k_t *p_j2k, } #if 0 -OPJ_BOOL opj_j2k_write_coc( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_write_coc( opj_j2k_t *p_j2k, OPJ_UINT32 p_comp_no, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ) @@ -2561,7 +2598,7 @@ OPJ_BOOL opj_j2k_write_coc( opj_j2k_t *p_j2k, #endif #if 0 -void opj_j2k_write_coc_in_memory( opj_j2k_t *p_j2k, +static void opj_j2k_write_coc_in_memory( opj_j2k_t *p_j2k, OPJ_UINT32 p_comp_no, OPJ_BYTE * p_data, OPJ_UINT32 * p_data_written, @@ -2607,7 +2644,7 @@ void opj_j2k_write_coc_in_memory( opj_j2k_t *p_j2k, } #endif -OPJ_UINT32 opj_j2k_get_max_coc_size(opj_j2k_t *p_j2k) +static OPJ_UINT32 opj_j2k_get_max_coc_size(opj_j2k_t *p_j2k) { OPJ_UINT32 i,j; OPJ_UINT32 l_nb_comp; @@ -2689,7 +2726,7 @@ static OPJ_BOOL opj_j2k_read_coc ( opj_j2k_t *p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_write_qcd( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_write_qcd( opj_j2k_t *p_j2k, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ) @@ -2780,7 +2817,7 @@ static OPJ_BOOL opj_j2k_read_qcd ( opj_j2k_t *p_j2k, } #if 0 -OPJ_BOOL opj_j2k_write_qcc( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_write_qcc( opj_j2k_t *p_j2k, OPJ_UINT32 p_comp_no, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager @@ -2821,7 +2858,7 @@ OPJ_BOOL opj_j2k_write_qcc( opj_j2k_t *p_j2k, #endif #if 0 -void opj_j2k_write_qcc_in_memory( opj_j2k_t *p_j2k, +static void opj_j2k_write_qcc_in_memory( opj_j2k_t *p_j2k, OPJ_UINT32 p_comp_no, OPJ_BYTE * p_data, OPJ_UINT32 * p_data_written, @@ -2871,7 +2908,7 @@ void opj_j2k_write_qcc_in_memory( opj_j2k_t *p_j2k, } #endif -OPJ_UINT32 opj_j2k_get_max_qcc_size (opj_j2k_t *p_j2k) +static OPJ_UINT32 opj_j2k_get_max_qcc_size (opj_j2k_t *p_j2k) { return opj_j2k_get_max_coc_size(p_j2k); } @@ -2963,7 +3000,7 @@ static OPJ_BOOL opj_j2k_read_qcc( opj_j2k_t *p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_write_poc( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_write_poc( opj_j2k_t *p_j2k, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ) @@ -3014,7 +3051,7 @@ OPJ_BOOL opj_j2k_write_poc( opj_j2k_t *p_j2k, return OPJ_TRUE; } -void opj_j2k_write_poc_in_memory( opj_j2k_t *p_j2k, +static void opj_j2k_write_poc_in_memory( opj_j2k_t *p_j2k, OPJ_BYTE * p_data, OPJ_UINT32 * p_data_written, opj_event_mgr_t * p_manager @@ -3089,7 +3126,7 @@ void opj_j2k_write_poc_in_memory( opj_j2k_t *p_j2k, *p_data_written = l_poc_size; } -OPJ_UINT32 opj_j2k_get_max_poc_size(opj_j2k_t *p_j2k) +static OPJ_UINT32 opj_j2k_get_max_poc_size(opj_j2k_t *p_j2k) { opj_tcp_t * l_tcp = 00; OPJ_UINT32 l_nb_tiles = 0; @@ -3109,7 +3146,7 @@ OPJ_UINT32 opj_j2k_get_max_poc_size(opj_j2k_t *p_j2k) return 4 + 9 * l_max_poc; } -OPJ_UINT32 opj_j2k_get_max_toc_size (opj_j2k_t *p_j2k) +static OPJ_UINT32 opj_j2k_get_max_toc_size (opj_j2k_t *p_j2k) { OPJ_UINT32 i; OPJ_UINT32 l_nb_tiles; @@ -3128,7 +3165,7 @@ OPJ_UINT32 opj_j2k_get_max_toc_size (opj_j2k_t *p_j2k) return 12 * l_max; } -OPJ_UINT32 opj_j2k_get_specific_header_sizes(opj_j2k_t *p_j2k) +static OPJ_UINT32 opj_j2k_get_specific_header_sizes(opj_j2k_t *p_j2k) { OPJ_UINT32 l_nb_bytes = 0; OPJ_UINT32 l_nb_comps; @@ -3458,382 +3495,220 @@ static OPJ_BOOL opj_j2k_read_plt ( opj_j2k_t *p_j2k, return OPJ_TRUE; } -#if 0 -OPJ_BOOL j2k_read_ppm_v2 ( - opj_j2k_t *p_j2k, - OPJ_BYTE * p_header_data, - OPJ_UINT32 p_header_size, - struct opj_event_mgr * p_manager - ) -{ - - opj_cp_t *l_cp = 00; - OPJ_UINT32 l_remaining_data, l_Z_ppm, l_N_ppm; - - /* preconditions */ - assert(p_header_data != 00); - assert(p_j2k != 00); - assert(p_manager != 00); - - if (p_header_size < 1) { - opj_event_msg(p_manager, EVT_ERROR, "Error reading PPM marker\n"); - return OPJ_FALSE; - } - - l_cp = &(p_j2k->m_cp); - l_cp->ppm = 1; - - opj_read_bytes(p_header_data,&l_Z_ppm,1); /* Z_ppm */ - ++p_header_data; - --p_header_size; - - /* First PPM marker */ - if (l_Z_ppm == 0) { - if (p_header_size < 4) { - opj_event_msg(p_manager, EVT_ERROR, "Error reading PPM marker\n"); - return OPJ_FALSE; - } - - opj_read_bytes(p_header_data,&l_N_ppm,4); /* N_ppm */ - p_header_data+=4; - p_header_size-=4; - - /* First PPM marker: Initialization */ - l_cp->ppm_len = l_N_ppm; - l_cp->ppm_data_size = 0; - - l_cp->ppm_buffer = (OPJ_BYTE *) opj_malloc(l_cp->ppm_len); - if (l_cp->ppm_buffer == 00) { - opj_event_msg(p_manager, EVT_ERROR, "Not enough memory reading ppm marker\n"); - return OPJ_FALSE; - } - memset(l_cp->ppm_buffer,0,l_cp->ppm_len); - - l_cp->ppm_data = l_cp->ppm_buffer; - } - - while (1) { - if (l_cp->ppm_data_size == l_cp->ppm_len) { - if (p_header_size >= 4) { - /* read a N_ppm */ - opj_read_bytes(p_header_data,&l_N_ppm,4); /* N_ppm */ - p_header_data+=4; - p_header_size-=4; - l_cp->ppm_len += l_N_ppm ; - - OPJ_BYTE *new_ppm_buffer = (OPJ_BYTE *) opj_realloc(l_cp->ppm_buffer, l_cp->ppm_len); - if (! new_ppm_buffer) { - opj_free(l_cp->ppm_buffer); - l_cp->ppm_buffer = NULL; - l_cp->ppm_len = 0; - l_cp->ppm_data = NULL; - opj_event_msg(p_manager, EVT_ERROR, "Not enough memory reading ppm marker\n"); - return OPJ_FALSE; - } - l_cp->ppm_buffer = new_ppm_buffer; - memset(l_cp->ppm_buffer+l_cp->ppm_data_size,0,l_N_ppm); - l_cp->ppm_data = l_cp->ppm_buffer; - } - else { - return OPJ_FALSE; - } - } - - l_remaining_data = l_cp->ppm_len - l_cp->ppm_data_size; +/** + * Reads a PPM marker (Packed packet headers, main header) + * + * @param p_header_data the data contained in the POC box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the POC marker. + * @param p_manager the user event manager. + */ - if (l_remaining_data <= p_header_size) { - /* we must store less information than available in the packet */ - memcpy(l_cp->ppm_buffer + l_cp->ppm_data_size , p_header_data , l_remaining_data); - l_cp->ppm_data_size = l_cp->ppm_len; - p_header_size -= l_remaining_data; - p_header_data += l_remaining_data; - } - else { - memcpy(l_cp->ppm_buffer + l_cp->ppm_data_size , p_header_data , p_header_size); - l_cp->ppm_data_size += p_header_size; - p_header_data += p_header_size; - p_header_size = 0; - break; - } - } +static OPJ_BOOL opj_j2k_read_ppm ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + opj_event_mgr_t * p_manager ) +{ + opj_cp_t *l_cp = 00; + OPJ_UINT32 l_Z_ppm; + + /* preconditions */ + assert(p_header_data != 00); + assert(p_j2k != 00); + assert(p_manager != 00); + + /* We need to have the Z_ppm element + 1 byte of Nppm/Ippm at minimum */ + if (p_header_size < 2) { + opj_event_msg(p_manager, EVT_ERROR, "Error reading PPM marker\n"); + return OPJ_FALSE; + } + + l_cp = &(p_j2k->m_cp); + l_cp->ppm = 1; + + opj_read_bytes(p_header_data,&l_Z_ppm,1); /* Z_ppm */ + ++p_header_data; + --p_header_size; + + /* check allocation needed */ + if (l_cp->ppm_markers == NULL) { /* first PPM marker */ + OPJ_UINT32 l_newCount = l_Z_ppm + 1U; /* can't overflow, l_Z_ppm is UINT8 */ + assert(l_cp->ppm_markers_count == 0U); + + l_cp->ppm_markers = (opj_ppx *) opj_calloc(l_newCount, sizeof(opj_ppx)); + if (l_cp->ppm_markers == NULL) { + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPM marker\n"); + return OPJ_FALSE; + } + l_cp->ppm_markers_count = l_newCount; + } else if (l_cp->ppm_markers_count <= l_Z_ppm) { + OPJ_UINT32 l_newCount = l_Z_ppm + 1U; /* can't overflow, l_Z_ppm is UINT8 */ + opj_ppx *new_ppm_markers; + new_ppm_markers = (opj_ppx *) opj_realloc(l_cp->ppm_markers, l_newCount * sizeof(opj_ppx)); + if (new_ppm_markers == NULL) { + /* clean up to be done on l_cp destruction */ + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPM marker\n"); + return OPJ_FALSE; + } + l_cp->ppm_markers = new_ppm_markers; + memset(l_cp->ppm_markers + l_cp->ppm_markers_count, 0, (l_newCount - l_cp->ppm_markers_count) * sizeof(opj_ppx)); + l_cp->ppm_markers_count = l_newCount; + } + + if (l_cp->ppm_markers[l_Z_ppm].m_data != NULL) { + /* clean up to be done on l_cp destruction */ + opj_event_msg(p_manager, EVT_ERROR, "Zppm %u already read\n", l_Z_ppm); + return OPJ_FALSE; + } + + l_cp->ppm_markers[l_Z_ppm].m_data = opj_malloc(p_header_size); + if (l_cp->ppm_markers[l_Z_ppm].m_data == NULL) { + /* clean up to be done on l_cp destruction */ + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPM marker\n"); + return OPJ_FALSE; + } + l_cp->ppm_markers[l_Z_ppm].m_data_size = p_header_size; + memcpy(l_cp->ppm_markers[l_Z_ppm].m_data, p_header_data, p_header_size); - return OPJ_TRUE; + return OPJ_TRUE; } -#endif -OPJ_BOOL j2k_read_ppm_v3 ( - opj_j2k_t *p_j2k, - OPJ_BYTE * p_header_data, - OPJ_UINT32 p_header_size, - struct opj_event_mgr * p_manager - ) +/** + * Merges all PPM markers read (Packed headers, main header) + * + * @param p_cp main coding parameters. + * @param p_manager the user event manager. + */ +static OPJ_BOOL opj_j2k_merge_ppm ( opj_cp_t *p_cp, opj_event_mgr_t * p_manager ) { - opj_cp_t *l_cp = 00; - OPJ_UINT32 l_remaining_data, l_Z_ppm, l_N_ppm; - - /* preconditions */ - assert(p_header_data != 00); - assert(p_j2k != 00); - assert(p_manager != 00); - - /* Minimum size of PPM marker is equal to the size of Zppm element */ - if (p_header_size < 1) { - opj_event_msg(p_manager, EVT_ERROR, "Error reading PPM marker\n"); - return OPJ_FALSE; - } - - l_cp = &(p_j2k->m_cp); - l_cp->ppm = 1; - - opj_read_bytes(p_header_data,&l_Z_ppm,1); /* Z_ppm */ - ++p_header_data; - --p_header_size; - - /* First PPM marker */ - if (l_Z_ppm == 0) { - if (l_cp->ppm_data != NULL) { - opj_event_msg(p_manager, EVT_ERROR, "Zppm O already processed. Found twice.\n"); - opj_free(l_cp->ppm_data); - l_cp->ppm_data = NULL; - l_cp->ppm_buffer = NULL; - l_cp->ppm = 0; /* do not use PPM */ - return OPJ_FALSE; - } - /* We need now at least the Nppm^0 element */ - if (p_header_size < 4) { - opj_event_msg(p_manager, EVT_ERROR, "Error reading PPM marker\n"); - return OPJ_FALSE; - } - - opj_read_bytes(p_header_data,&l_N_ppm,4); /* First N_ppm */ - p_header_data+=4; - p_header_size-=4; - - /* sanity check: how much bytes is left for Ippm */ - if( p_header_size < l_N_ppm ) - { - opj_event_msg(p_manager, EVT_ERROR, "Not enough bytes (%u) to hold Ippm series (%u), Index (%d)\n", p_header_size, l_N_ppm, l_Z_ppm ); - opj_free(l_cp->ppm_data); - l_cp->ppm_data = NULL; - l_cp->ppm_buffer = NULL; - l_cp->ppm = 0; /* do not use PPM */ - return OPJ_FALSE; - } - - /* First PPM marker: Initialization */ - l_cp->ppm_len = l_N_ppm; - l_cp->ppm_data_read = 0; - - l_cp->ppm_data = (OPJ_BYTE *) opj_calloc(1,l_cp->ppm_len); - l_cp->ppm_buffer = l_cp->ppm_data; - if (l_cp->ppm_data == 00) { - opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read ppm marker\n"); - return OPJ_FALSE; - } - - l_cp->ppm_data_current = l_cp->ppm_data; - - /*l_cp->ppm_data = l_cp->ppm_buffer;*/ - } - else { - if (p_header_size < 4) { - opj_event_msg(p_manager, EVT_WARNING, "Empty PPM marker\n"); - return OPJ_TRUE; - } - else { - /* Uncompleted Ippm series in the previous PPM marker?*/ - if (l_cp->ppm_data_read < l_cp->ppm_len) { - /* Get the place where add the remaining Ippm series*/ - l_cp->ppm_data_current = &(l_cp->ppm_data[l_cp->ppm_data_read]); - l_N_ppm = l_cp->ppm_len - l_cp->ppm_data_read; - } - else { - OPJ_BYTE *new_ppm_data; - opj_read_bytes(p_header_data,&l_N_ppm,4); /* First N_ppm */ - p_header_data+=4; - p_header_size-=4; - - /* sanity check: how much bytes is left for Ippm */ - if( p_header_size < l_N_ppm ) - { - opj_event_msg(p_manager, EVT_ERROR, "Not enough bytes (%u) to hold Ippm series (%u), Index (%d)\n", p_header_size, l_N_ppm, l_Z_ppm ); - opj_free(l_cp->ppm_data); - l_cp->ppm_data = NULL; - l_cp->ppm_buffer = NULL; - l_cp->ppm = 0; /* do not use PPM */ - return OPJ_FALSE; - } - /* Increase the size of ppm_data to add the new Ippm series*/ - assert(l_cp->ppm_data == l_cp->ppm_buffer && "We need ppm_data and ppm_buffer to be the same when reallocating"); - new_ppm_data = (OPJ_BYTE *) opj_realloc(l_cp->ppm_data, l_cp->ppm_len + l_N_ppm); - if (! new_ppm_data) { - opj_free(l_cp->ppm_data); - l_cp->ppm_data = NULL; - l_cp->ppm_buffer = NULL; /* TODO: no need for a new local variable: ppm_buffer and ppm_data are enough */ - l_cp->ppm_len = 0; - opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to increase the size of ppm_data to add the new Ippm series\n"); - return OPJ_FALSE; - } - l_cp->ppm_data = new_ppm_data; - l_cp->ppm_buffer = l_cp->ppm_data; - - /* Keep the position of the place where concatenate the new series*/ - l_cp->ppm_data_current = &(l_cp->ppm_data[l_cp->ppm_len]); - l_cp->ppm_len += l_N_ppm; - } - } - } - - l_remaining_data = p_header_size; - - while (l_remaining_data >= l_N_ppm) { - /* read a complete Ippm series*/ - memcpy(l_cp->ppm_data_current, p_header_data, l_N_ppm); - p_header_size -= l_N_ppm; - p_header_data += l_N_ppm; - - l_cp->ppm_data_read += l_N_ppm; /* Increase the number of data read*/ - - if (p_header_size) - { - if (p_header_size < 4) { - opj_free(l_cp->ppm_data); - l_cp->ppm_data = NULL; - l_cp->ppm_buffer = NULL; /* TODO: no need for a new local variable: ppm_buffer and ppm_data are enough */ - l_cp->ppm_len = 0; - l_cp->ppm = 0; - opj_event_msg(p_manager, EVT_ERROR, "Error reading PPM marker\n"); - return OPJ_FALSE; - } - opj_read_bytes(p_header_data,&l_N_ppm,4); /* N_ppm^i */ - p_header_data+=4; - p_header_size-=4; - } - else { - l_remaining_data = p_header_size; - break; - } - - l_remaining_data = p_header_size; - - /* Next Ippm series is a complete series ?*/ - if (l_remaining_data >= l_N_ppm) { - OPJ_BYTE *new_ppm_data; - /* Increase the size of ppm_data to add the new Ippm series*/ - assert(l_cp->ppm_data == l_cp->ppm_buffer && "We need ppm_data and ppm_buffer to be the same when reallocating"); - /* Overflow check */ - if ((l_cp->ppm_len + l_N_ppm) < l_N_ppm) { - opj_free(l_cp->ppm_data); - l_cp->ppm_data = NULL; - l_cp->ppm_buffer = NULL; /* TODO: no need for a new local variable: ppm_buffer and ppm_data are enough */ - l_cp->ppm_len = 0; - opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to increase the size of ppm_data to add the new (complete) Ippm series\n"); - return OPJ_FALSE; - } - new_ppm_data = (OPJ_BYTE *) opj_realloc(l_cp->ppm_data, l_cp->ppm_len + l_N_ppm); - if (! new_ppm_data) { - opj_free(l_cp->ppm_data); - l_cp->ppm_data = NULL; - l_cp->ppm_buffer = NULL; /* TODO: no need for a new local variable: ppm_buffer and ppm_data are enough */ - l_cp->ppm_len = 0; - opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to increase the size of ppm_data to add the new (complete) Ippm series\n"); - return OPJ_FALSE; - } - l_cp->ppm_data = new_ppm_data; - l_cp->ppm_buffer = l_cp->ppm_data; - - /* Keep the position of the place where concatenate the new series */ - l_cp->ppm_data_current = &(l_cp->ppm_data[l_cp->ppm_len]); - l_cp->ppm_len += l_N_ppm; - } - - } - - /* Need to read an incomplete Ippm series*/ - if (l_remaining_data) { - OPJ_BYTE *new_ppm_data; - assert(l_cp->ppm_data == l_cp->ppm_buffer && "We need ppm_data and ppm_buffer to be the same when reallocating"); - - /* Overflow check */ - if ((l_cp->ppm_len + l_N_ppm) < l_N_ppm) { - opj_free(l_cp->ppm_data); - l_cp->ppm_data = NULL; - l_cp->ppm_buffer = NULL; /* TODO: no need for a new local variable: ppm_buffer and ppm_data are enough */ - l_cp->ppm_len = 0; - opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to increase the size of ppm_data to add the new (complete) Ippm series\n"); - return OPJ_FALSE; - } - new_ppm_data = (OPJ_BYTE *) opj_realloc(l_cp->ppm_data, l_cp->ppm_len + l_N_ppm); - if (! new_ppm_data) { - opj_free(l_cp->ppm_data); - l_cp->ppm_data = NULL; - l_cp->ppm_buffer = NULL; /* TODO: no need for a new local variable: ppm_buffer and ppm_data are enough */ - l_cp->ppm_len = 0; - opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to increase the size of ppm_data to add the new (incomplete) Ippm series\n"); - return OPJ_FALSE; - } - l_cp->ppm_data = new_ppm_data; - l_cp->ppm_buffer = l_cp->ppm_data; - - /* Keep the position of the place where concatenate the new series*/ - l_cp->ppm_data_current = &(l_cp->ppm_data[l_cp->ppm_len]); - l_cp->ppm_len += l_N_ppm; - - /* Read incomplete Ippm series*/ - memcpy(l_cp->ppm_data_current, p_header_data, l_remaining_data); - p_header_size -= l_remaining_data; - p_header_data += l_remaining_data; - - l_cp->ppm_data_read += l_remaining_data; /* Increase the number of data read*/ - } - -#ifdef CLEAN_MSD - - if (l_cp->ppm_data_size == l_cp->ppm_len) { - if (p_header_size >= 4) { - /* read a N_ppm*/ - opj_read_bytes(p_header_data,&l_N_ppm,4); /* N_ppm */ - p_header_data+=4; - p_header_size-=4; - l_cp->ppm_len += l_N_ppm ; - - OPJ_BYTE *new_ppm_buffer = (OPJ_BYTE *) opj_realloc(l_cp->ppm_buffer, l_cp->ppm_len); - if (! new_ppm_buffer) { - opj_free(l_cp->ppm_buffer); - l_cp->ppm_buffer = NULL; - l_cp->ppm_len = 0; - opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read ppm marker\n"); - return OPJ_FALSE; - } - l_cp->ppm_buffer = new_ppm_buffer; - memset(l_cp->ppm_buffer+l_cp->ppm_data_size,0,l_N_ppm); - - l_cp->ppm_data = l_cp->ppm_buffer; - } - else { - return OPJ_FALSE; - } - } - - l_remaining_data = l_cp->ppm_len - l_cp->ppm_data_size; - - if (l_remaining_data <= p_header_size) { - /* we must store less information than available in the packet */ - memcpy(l_cp->ppm_buffer + l_cp->ppm_data_size , p_header_data , l_remaining_data); - l_cp->ppm_data_size = l_cp->ppm_len; - p_header_size -= l_remaining_data; - p_header_data += l_remaining_data; - } - else { - memcpy(l_cp->ppm_buffer + l_cp->ppm_data_size , p_header_data , p_header_size); - l_cp->ppm_data_size += p_header_size; - p_header_data += p_header_size; - p_header_size = 0; - break; - } - } -#endif - return OPJ_TRUE; + OPJ_UINT32 i, l_ppm_data_size, l_N_ppm_remaining; + + /* preconditions */ + assert(p_cp != 00); + assert(p_manager != 00); + assert(p_cp->ppm_buffer == NULL); + + if (p_cp->ppm == 0U) { + return OPJ_TRUE; + } + + l_ppm_data_size = 0U; + l_N_ppm_remaining = 0U; + for (i = 0U; i < p_cp->ppm_markers_count; ++i) { + if (p_cp->ppm_markers[i].m_data != NULL) { /* standard doesn't seem to require contiguous Zppm */ + OPJ_UINT32 l_N_ppm; + OPJ_UINT32 l_data_size = p_cp->ppm_markers[i].m_data_size; + const OPJ_BYTE* l_data = p_cp->ppm_markers[i].m_data; + + if (l_N_ppm_remaining >= l_data_size) { + l_N_ppm_remaining -= l_data_size; + l_data_size = 0U; + } else { + l_data += l_N_ppm_remaining; + l_data_size -= l_N_ppm_remaining; + l_N_ppm_remaining = 0U; + } + + if (l_data_size > 0U) { + do + { + /* read Nppm */ + if (l_data_size < 4U) { + /* clean up to be done on l_cp destruction */ + opj_event_msg(p_manager, EVT_ERROR, "Not enough bytes to read Nppm\n"); + return OPJ_FALSE; + } + opj_read_bytes(l_data, &l_N_ppm, 4); + l_data+=4; + l_data_size-=4; + l_ppm_data_size += l_N_ppm; /* can't overflow, max 256 markers of max 65536 bytes, that is when PPM markers are not corrupted which is checked elsewhere */ + + if (l_data_size >= l_N_ppm) { + l_data_size -= l_N_ppm; + l_data += l_N_ppm; + } else { + l_N_ppm_remaining = l_N_ppm - l_data_size; + l_data_size = 0U; + } + } while (l_data_size > 0U); + } + } + } + + if (l_N_ppm_remaining != 0U) { + /* clean up to be done on l_cp destruction */ + opj_event_msg(p_manager, EVT_ERROR, "Corrupted PPM markers\n"); + return OPJ_FALSE; + } + + p_cp->ppm_buffer = (OPJ_BYTE *) opj_malloc(l_ppm_data_size); + if (p_cp->ppm_buffer == 00) { + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPM marker\n"); + return OPJ_FALSE; + } + p_cp->ppm_len = l_ppm_data_size; + l_ppm_data_size = 0U; + l_N_ppm_remaining = 0U; + for (i = 0U; i < p_cp->ppm_markers_count; ++i) { + if (p_cp->ppm_markers[i].m_data != NULL) { /* standard doesn't seem to require contiguous Zppm */ + OPJ_UINT32 l_N_ppm; + OPJ_UINT32 l_data_size = p_cp->ppm_markers[i].m_data_size; + const OPJ_BYTE* l_data = p_cp->ppm_markers[i].m_data; + + if (l_N_ppm_remaining >= l_data_size) { + memcpy(p_cp->ppm_buffer + l_ppm_data_size, l_data, l_data_size); + l_ppm_data_size += l_data_size; + l_N_ppm_remaining -= l_data_size; + l_data_size = 0U; + } else { + memcpy(p_cp->ppm_buffer + l_ppm_data_size, l_data, l_N_ppm_remaining); + l_ppm_data_size += l_N_ppm_remaining; + l_data += l_N_ppm_remaining; + l_data_size -= l_N_ppm_remaining; + l_N_ppm_remaining = 0U; + } + + if (l_data_size > 0U) { + do + { + /* read Nppm */ + if (l_data_size < 4U) { + /* clean up to be done on l_cp destruction */ + opj_event_msg(p_manager, EVT_ERROR, "Not enough bytes to read Nppm\n"); + return OPJ_FALSE; + } + opj_read_bytes(l_data, &l_N_ppm, 4); + l_data+=4; + l_data_size-=4; + + if (l_data_size >= l_N_ppm) { + memcpy(p_cp->ppm_buffer + l_ppm_data_size, l_data, l_N_ppm); + l_ppm_data_size += l_N_ppm; + l_data_size -= l_N_ppm; + l_data += l_N_ppm; + } else { + memcpy(p_cp->ppm_buffer + l_ppm_data_size, l_data, l_data_size); + l_ppm_data_size += l_data_size; + l_N_ppm_remaining = l_N_ppm - l_data_size; + l_data_size = 0U; + } + } while (l_data_size > 0U); + } + opj_free(p_cp->ppm_markers[i].m_data); + p_cp->ppm_markers[i].m_data = NULL; + p_cp->ppm_markers[i].m_data_size = 0U; + } + } + + p_cp->ppm_data = p_cp->ppm_buffer; + p_cp->ppm_data_size = p_cp->ppm_len; + + p_cp->ppm_markers_count = 0U; + opj_free(p_cp->ppm_markers); + p_cp->ppm_markers = NULL; + + return OPJ_TRUE; } /** @@ -3850,77 +3725,127 @@ static OPJ_BOOL opj_j2k_read_ppt ( opj_j2k_t *p_j2k, opj_event_mgr_t * p_manager ) { - opj_cp_t *l_cp = 00; - opj_tcp_t *l_tcp = 00; - OPJ_UINT32 l_Z_ppt; - - /* preconditions */ - assert(p_header_data != 00); - assert(p_j2k != 00); - assert(p_manager != 00); - - /* We need to have the Z_ppt element at minimum */ - if (p_header_size < 1) { - opj_event_msg(p_manager, EVT_ERROR, "Error reading PPT marker\n"); - return OPJ_FALSE; - } - - l_cp = &(p_j2k->m_cp); - if (l_cp->ppm){ - opj_event_msg(p_manager, EVT_ERROR, "Error reading PPT marker: packet header have been previously found in the main header (PPM marker).\n"); - return OPJ_FALSE; - } + opj_cp_t *l_cp = 00; + opj_tcp_t *l_tcp = 00; + OPJ_UINT32 l_Z_ppt; - l_tcp = &(l_cp->tcps[p_j2k->m_current_tile_number]); - l_tcp->ppt = 1; + /* preconditions */ + assert(p_header_data != 00); + assert(p_j2k != 00); + assert(p_manager != 00); - opj_read_bytes(p_header_data,&l_Z_ppt,1); /* Z_ppt */ - ++p_header_data; - --p_header_size; - - /* Allocate buffer to read the packet header */ - if (l_Z_ppt == 0) { - /* First PPT marker */ - l_tcp->ppt_data_size = 0; - l_tcp->ppt_len = p_header_size; - - opj_free(l_tcp->ppt_buffer); - l_tcp->ppt_buffer = (OPJ_BYTE *) opj_calloc(l_tcp->ppt_len, sizeof(OPJ_BYTE) ); - if (l_tcp->ppt_buffer == 00) { - opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n"); - return OPJ_FALSE; - } - l_tcp->ppt_data = l_tcp->ppt_buffer; - - /* memset(l_tcp->ppt_buffer,0,l_tcp->ppt_len); */ - } - else { - OPJ_BYTE *new_ppt_buffer; - l_tcp->ppt_len += p_header_size; - - new_ppt_buffer = (OPJ_BYTE *) opj_realloc(l_tcp->ppt_buffer, l_tcp->ppt_len); - if (! new_ppt_buffer) { - opj_free(l_tcp->ppt_buffer); - l_tcp->ppt_buffer = NULL; - l_tcp->ppt_len = 0; - opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n"); - return OPJ_FALSE; - } - l_tcp->ppt_buffer = new_ppt_buffer; - l_tcp->ppt_data = l_tcp->ppt_buffer; + /* We need to have the Z_ppt element + 1 byte of Ippt at minimum */ + if (p_header_size < 2) { + opj_event_msg(p_manager, EVT_ERROR, "Error reading PPT marker\n"); + return OPJ_FALSE; + } - memset(l_tcp->ppt_buffer+l_tcp->ppt_data_size,0,p_header_size); - } + l_cp = &(p_j2k->m_cp); + if (l_cp->ppm){ + opj_event_msg(p_manager, EVT_ERROR, "Error reading PPT marker: packet header have been previously found in the main header (PPM marker).\n"); + return OPJ_FALSE; + } - /* Read packet header from buffer */ - memcpy(l_tcp->ppt_buffer+l_tcp->ppt_data_size,p_header_data,p_header_size); + l_tcp = &(l_cp->tcps[p_j2k->m_current_tile_number]); + l_tcp->ppt = 1; - l_tcp->ppt_data_size += p_header_size; + opj_read_bytes(p_header_data,&l_Z_ppt,1); /* Z_ppt */ + ++p_header_data; + --p_header_size; + + /* check allocation needed */ + if (l_tcp->ppt_markers == NULL) { /* first PPT marker */ + OPJ_UINT32 l_newCount = l_Z_ppt + 1U; /* can't overflow, l_Z_ppt is UINT8 */ + assert(l_tcp->ppt_markers_count == 0U); + + l_tcp->ppt_markers = (opj_ppx *) opj_calloc(l_newCount, sizeof(opj_ppx)); + if (l_tcp->ppt_markers == NULL) { + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n"); + return OPJ_FALSE; + } + l_tcp->ppt_markers_count = l_newCount; + } else if (l_tcp->ppt_markers_count <= l_Z_ppt) { + OPJ_UINT32 l_newCount = l_Z_ppt + 1U; /* can't overflow, l_Z_ppt is UINT8 */ + opj_ppx *new_ppt_markers; + new_ppt_markers = (opj_ppx *) opj_realloc(l_tcp->ppt_markers, l_newCount * sizeof(opj_ppx)); + if (new_ppt_markers == NULL) { + /* clean up to be done on l_tcp destruction */ + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n"); + return OPJ_FALSE; + } + l_tcp->ppt_markers = new_ppt_markers; + memset(l_tcp->ppt_markers + l_tcp->ppt_markers_count, 0, (l_newCount - l_tcp->ppt_markers_count) * sizeof(opj_ppx)); + l_tcp->ppt_markers_count = l_newCount; + } + + if (l_tcp->ppt_markers[l_Z_ppt].m_data != NULL) { + /* clean up to be done on l_tcp destruction */ + opj_event_msg(p_manager, EVT_ERROR, "Zppt %u already read\n", l_Z_ppt); + return OPJ_FALSE; + } + + l_tcp->ppt_markers[l_Z_ppt].m_data = opj_malloc(p_header_size); + if (l_tcp->ppt_markers[l_Z_ppt].m_data == NULL) { + /* clean up to be done on l_tcp destruction */ + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n"); + return OPJ_FALSE; + } + l_tcp->ppt_markers[l_Z_ppt].m_data_size = p_header_size; + memcpy(l_tcp->ppt_markers[l_Z_ppt].m_data, p_header_data, p_header_size); + return OPJ_TRUE; +} - return OPJ_TRUE; +/** + * Merges all PPT markers read (Packed packet headers, tile-part header) + * + * @param p_tcp the tile. + * @param p_manager the user event manager. + */ +static OPJ_BOOL opj_j2k_merge_ppt(opj_tcp_t *p_tcp, opj_event_mgr_t * p_manager) +{ + OPJ_UINT32 i, l_ppt_data_size; + /* preconditions */ + assert(p_tcp != 00); + assert(p_manager != 00); + assert(p_tcp->ppt_buffer == NULL); + + if (p_tcp->ppt == 0U) { + return OPJ_TRUE; + } + + l_ppt_data_size = 0U; + for (i = 0U; i < p_tcp->ppt_markers_count; ++i) { + l_ppt_data_size += p_tcp->ppt_markers[i].m_data_size; /* can't overflow, max 256 markers of max 65536 bytes */ + } + + p_tcp->ppt_buffer = (OPJ_BYTE *) opj_malloc(l_ppt_data_size); + if (p_tcp->ppt_buffer == 00) { + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n"); + return OPJ_FALSE; + } + p_tcp->ppt_len = l_ppt_data_size; + l_ppt_data_size = 0U; + for (i = 0U; i < p_tcp->ppt_markers_count; ++i) { + if (p_tcp->ppt_markers[i].m_data != NULL) { /* standard doesn't seem to require contiguous Zppt */ + memcpy(p_tcp->ppt_buffer + l_ppt_data_size, p_tcp->ppt_markers[i].m_data, p_tcp->ppt_markers[i].m_data_size); + l_ppt_data_size += p_tcp->ppt_markers[i].m_data_size; /* can't overflow, max 256 markers of max 65536 bytes */ + + opj_free(p_tcp->ppt_markers[i].m_data); + p_tcp->ppt_markers[i].m_data = NULL; + p_tcp->ppt_markers[i].m_data_size = 0U; + } + } + + p_tcp->ppt_markers_count = 0U; + opj_free(p_tcp->ppt_markers); + p_tcp->ppt_markers = NULL; + + p_tcp->ppt_data = p_tcp->ppt_buffer; + p_tcp->ppt_data_size = p_tcp->ppt_len; + return OPJ_TRUE; } -OPJ_BOOL opj_j2k_write_tlm( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_write_tlm( opj_j2k_t *p_j2k, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ) @@ -3974,7 +3899,7 @@ OPJ_BOOL opj_j2k_write_tlm( opj_j2k_t *p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_write_sot( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_write_sot( opj_j2k_t *p_j2k, OPJ_BYTE * p_data, OPJ_UINT32 * p_data_written, const opj_stream_private_t *p_stream, @@ -4018,7 +3943,36 @@ OPJ_BOOL opj_j2k_write_sot( opj_j2k_t *p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_get_sot_values(OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + OPJ_UINT32* p_tile_no, + OPJ_UINT32* p_tot_len, + OPJ_UINT32* p_current_part, + OPJ_UINT32* p_num_parts, + opj_event_mgr_t * p_manager ) +{ + /* preconditions */ + assert(p_header_data != 00); + assert(p_manager != 00); + + /* Size of this marker is fixed = 12 (we have already read marker and its size)*/ + if (p_header_size != 8) { + opj_event_msg(p_manager, EVT_ERROR, "Error reading SOT marker\n"); + return OPJ_FALSE; + } + + opj_read_bytes(p_header_data,p_tile_no,2); /* Isot */ + p_header_data+=2; + opj_read_bytes(p_header_data,p_tot_len,4); /* Psot */ + p_header_data+=4; + opj_read_bytes(p_header_data,p_current_part,1); /* TPsot */ + ++p_header_data; + opj_read_bytes(p_header_data,p_num_parts ,1); /* TNsot */ + ++p_header_data; + return OPJ_TRUE; +} + +static OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_j2k, OPJ_BYTE * p_header_data, OPJ_UINT32 p_header_size, opj_event_mgr_t * p_manager ) @@ -4030,19 +3984,16 @@ OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_j2k, OPJ_UINT32 l_tile_x,l_tile_y; /* preconditions */ - assert(p_header_data != 00); + assert(p_j2k != 00); assert(p_manager != 00); - - /* Size of this marker is fixed = 12 (we have already read marker and its size)*/ - if (p_header_size != 8) { + + if (! opj_j2k_get_sot_values(p_header_data, p_header_size, &(p_j2k->m_current_tile_number), &l_tot_len, &l_current_part, &l_num_parts, p_manager)) { opj_event_msg(p_manager, EVT_ERROR, "Error reading SOT marker\n"); return OPJ_FALSE; } l_cp = &(p_j2k->m_cp); - opj_read_bytes(p_header_data,&(p_j2k->m_current_tile_number),2); /* Isot */ - p_header_data+=2; /* testcase 2.pdf.SIGFPE.706.1112 */ if (p_j2k->m_current_tile_number >= l_cp->tw * l_cp->th) { @@ -4085,9 +4036,6 @@ OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_j2k, /* Optimization possible here with a more complex data structure and with the removing of tiles */ /* since the time taken by this function can only grow at the time */ - opj_read_bytes(p_header_data,&l_tot_len,4); /* Psot */ - p_header_data+=4; - /* PSot should be equal to zero or >=14 or <= 2^32-1 */ if ((l_tot_len !=0 ) && (l_tot_len < 14) ) { @@ -4130,13 +4078,8 @@ OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_j2k, p_j2k->m_specific_param.m_decoder.m_last_tile_part = 1; } - opj_read_bytes(p_header_data,&l_current_part ,1); /* TPsot */ - ++p_header_data; - - opj_read_bytes(p_header_data,&l_num_parts ,1); /* TNsot */ - ++p_header_data; - if (l_num_parts != 0) { /* Number of tile-part header is provided by this tile-part header */ + l_num_parts += p_j2k->m_specific_param.m_decoder.m_nb_tile_parts_correction; /* Useful to manage the case of textGBR.jp2 file because two values of TNSot are allowed: the correct numbers of * tile-parts for that tile and zero (A.4.2 of 15444-1 : 2002). */ if (l_tcp->m_nb_tile_parts) { @@ -4286,7 +4229,7 @@ OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_write_sod( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_write_sod( opj_j2k_t *p_j2k, opj_tcd_t * p_tile_coder, OPJ_BYTE * p_data, OPJ_UINT32 * p_data_written, @@ -4360,7 +4303,7 @@ OPJ_BOOL opj_j2k_write_sod( opj_j2k_t *p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_read_sod (opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_read_sod (opj_j2k_t *p_j2k, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ) @@ -4408,7 +4351,7 @@ OPJ_BOOL opj_j2k_read_sod (opj_j2k_t *p_j2k, } if (! *l_current_data) { /* LH: oddly enough, in this path, l_tile_len!=0. - * TODO: If this was consistant, we could simplify the code to only use realloc(), as realloc(0,...) default to malloc(0,...). + * TODO: If this was consistent, we could simplify the code to only use realloc(), as realloc(0,...) default to malloc(0,...). */ *l_current_data = (OPJ_BYTE*) opj_malloc(p_j2k->m_specific_param.m_decoder.m_sot_length); } @@ -4481,7 +4424,7 @@ OPJ_BOOL opj_j2k_read_sod (opj_j2k_t *p_j2k, return OPJ_TRUE; } - OPJ_BOOL opj_j2k_write_rgn(opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_write_rgn(opj_j2k_t *p_j2k, OPJ_UINT32 p_tile_no, OPJ_UINT32 p_comp_no, OPJ_UINT32 nb_comps, @@ -4538,7 +4481,7 @@ OPJ_BOOL opj_j2k_read_sod (opj_j2k_t *p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_write_eoc( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_write_eoc( opj_j2k_t *p_j2k, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ) @@ -4648,18 +4591,18 @@ static OPJ_BOOL opj_j2k_read_rgn (opj_j2k_t *p_j2k, } -OPJ_FLOAT32 opj_j2k_get_tp_stride (opj_tcp_t * p_tcp) +static OPJ_FLOAT32 opj_j2k_get_tp_stride (opj_tcp_t * p_tcp) { return (OPJ_FLOAT32) ((p_tcp->m_nb_tile_parts - 1) * 14); } -OPJ_FLOAT32 opj_j2k_get_default_stride (opj_tcp_t * p_tcp) +static OPJ_FLOAT32 opj_j2k_get_default_stride (opj_tcp_t * p_tcp) { (void)p_tcp; return 0; } -OPJ_BOOL opj_j2k_update_rates( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_update_rates( opj_j2k_t *p_j2k, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ) { @@ -4822,7 +4765,7 @@ OPJ_BOOL opj_j2k_update_rates( opj_j2k_t *p_j2k, } #if 0 -OPJ_BOOL opj_j2k_read_eoc ( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_read_eoc ( opj_j2k_t *p_j2k, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ) { @@ -4872,7 +4815,7 @@ OPJ_BOOL opj_j2k_read_eoc ( opj_j2k_t *p_j2k, } #endif -OPJ_BOOL opj_j2k_get_end_header(opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_get_end_header(opj_j2k_t *p_j2k, struct opj_stream_private *p_stream, struct opj_event_mgr * p_manager ) { @@ -4886,7 +4829,7 @@ OPJ_BOOL opj_j2k_get_end_header(opj_j2k_t *p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_write_mct_data_group( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_write_mct_data_group( opj_j2k_t *p_j2k, struct opj_stream_private *p_stream, struct opj_event_mgr * p_manager ) { @@ -4935,7 +4878,7 @@ OPJ_BOOL opj_j2k_write_mct_data_group( opj_j2k_t *p_j2k, } #if 0 -OPJ_BOOL opj_j2k_write_all_coc(opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_write_all_coc(opj_j2k_t *p_j2k, struct opj_stream_private *p_stream, struct opj_event_mgr * p_manager ) { @@ -4958,7 +4901,7 @@ OPJ_BOOL opj_j2k_write_all_coc(opj_j2k_t *p_j2k, #endif #if 0 -OPJ_BOOL opj_j2k_write_all_qcc(opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_write_all_qcc(opj_j2k_t *p_j2k, struct opj_stream_private *p_stream, struct opj_event_mgr * p_manager ) { @@ -4981,7 +4924,7 @@ OPJ_BOOL opj_j2k_write_all_qcc(opj_j2k_t *p_j2k, #endif -OPJ_BOOL opj_j2k_write_regions( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_write_regions( opj_j2k_t *p_j2k, struct opj_stream_private *p_stream, struct opj_event_mgr * p_manager ) { @@ -4995,7 +4938,7 @@ OPJ_BOOL opj_j2k_write_regions( opj_j2k_t *p_j2k, l_tccp = p_j2k->m_cp.tcps->tccps; - for (compno = 0; compno < p_j2k->m_private_image->numcomps; ++compno) { + for (compno = 0; compno < p_j2k->m_private_image->numcomps; ++compno) { if (l_tccp->roishift) { if (! opj_j2k_write_rgn(p_j2k,0,compno,p_j2k->m_private_image->numcomps,p_stream,p_manager)) { @@ -5009,7 +4952,7 @@ OPJ_BOOL opj_j2k_write_regions( opj_j2k_t *p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_write_epc( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_write_epc( opj_j2k_t *p_j2k, struct opj_stream_private *p_stream, struct opj_event_mgr * p_manager ) { @@ -5047,7 +4990,7 @@ OPJ_BOOL opj_j2k_write_epc( opj_j2k_t *p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_read_unk ( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_read_unk ( opj_j2k_t *p_j2k, opj_stream_private_t *p_stream, OPJ_UINT32 *output_marker, opj_event_mgr_t * p_manager @@ -5064,7 +5007,7 @@ OPJ_BOOL opj_j2k_read_unk ( opj_j2k_t *p_j2k, opj_event_msg(p_manager, EVT_WARNING, "Unknown marker\n"); - while(1) { + for (;;) { /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer*/ if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) { opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); @@ -5109,7 +5052,7 @@ OPJ_BOOL opj_j2k_read_unk ( opj_j2k_t *p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_write_mct_record( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_write_mct_record( opj_j2k_t *p_j2k, opj_mct_data_t * p_mct_record, struct opj_stream_private *p_stream, struct opj_event_mgr * p_manager ) @@ -5281,7 +5224,7 @@ static OPJ_BOOL opj_j2k_read_mct ( opj_j2k_t *p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_write_mcc_record( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_write_mcc_record( opj_j2k_t *p_j2k, struct opj_simple_mcc_decorrelation_data * p_mcc_record, struct opj_stream_private *p_stream, struct opj_event_mgr * p_manager ) @@ -5384,7 +5327,7 @@ OPJ_BOOL opj_j2k_write_mcc_record( opj_j2k_t *p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_read_mcc ( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_read_mcc ( opj_j2k_t *p_j2k, OPJ_BYTE * p_header_data, OPJ_UINT32 p_header_size, opj_event_mgr_t * p_manager ) @@ -5599,7 +5542,7 @@ OPJ_BOOL opj_j2k_read_mcc ( opj_j2k_t *p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_write_mco( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_write_mco( opj_j2k_t *p_j2k, struct opj_stream_private *p_stream, struct opj_event_mgr * p_manager ) @@ -5616,8 +5559,7 @@ OPJ_BOOL opj_j2k_write_mco( opj_j2k_t *p_j2k, assert(p_stream != 00); l_tcp =&(p_j2k->m_cp.tcps[p_j2k->m_current_tile_number]); - l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data; - + l_mco_size = 5 + l_tcp->m_nb_mcc_records; if (l_mco_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) { @@ -5632,6 +5574,8 @@ OPJ_BOOL opj_j2k_write_mco( opj_j2k_t *p_j2k, p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data; p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_mco_size; } + l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data; + opj_write_bytes(l_current_data,J2K_MS_MCO,2); /* MCO */ l_current_data += 2; @@ -5639,14 +5583,13 @@ OPJ_BOOL opj_j2k_write_mco( opj_j2k_t *p_j2k, opj_write_bytes(l_current_data,l_mco_size-2,2); /* Lmco */ l_current_data += 2; - opj_write_bytes(l_current_data,l_tcp->m_nb_mcc_records,1); /* Nmco : only one tranform stage*/ + opj_write_bytes(l_current_data,l_tcp->m_nb_mcc_records,1); /* Nmco : only one transform stage*/ ++l_current_data; l_mcc_record = l_tcp->m_mcc_records; - for (i=0;i<l_tcp->m_nb_mcc_records;++i) { + for (i=0;i<l_tcp->m_nb_mcc_records;++i) { opj_write_bytes(l_current_data,l_mcc_record->m_index,1);/* Imco -> use the mcc indicated by 1*/ ++l_current_data; - ++l_mcc_record; } @@ -5692,7 +5635,7 @@ static OPJ_BOOL opj_j2k_read_mco ( opj_j2k_t *p_j2k, return OPJ_FALSE; } - opj_read_bytes(p_header_data,&l_nb_stages,1); /* Nmco : only one tranform stage*/ + opj_read_bytes(p_header_data,&l_nb_stages,1); /* Nmco : only one transform stage*/ ++p_header_data; if (l_nb_stages > 1) { @@ -5729,7 +5672,7 @@ static OPJ_BOOL opj_j2k_read_mco ( opj_j2k_t *p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_add_mct(opj_tcp_t * p_tcp, opj_image_t * p_image, OPJ_UINT32 p_index) +static OPJ_BOOL opj_j2k_add_mct(opj_tcp_t * p_tcp, opj_image_t * p_image, OPJ_UINT32 p_index) { OPJ_UINT32 i; opj_simple_mcc_decorrelation_data_t * l_mcc_record; @@ -5811,7 +5754,7 @@ OPJ_BOOL opj_j2k_add_mct(opj_tcp_t * p_tcp, opj_image_t * p_image, OPJ_UINT32 p_ return OPJ_TRUE; } -OPJ_BOOL opj_j2k_write_cbd( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_write_cbd( opj_j2k_t *p_j2k, struct opj_stream_private *p_stream, struct opj_event_mgr * p_manager ) { @@ -5977,7 +5920,7 @@ opj_j2k_t* opj_j2k_create_compress(void) return l_j2k; } -int opj_j2k_initialise_4K_poc(opj_poc_t *POC, int numres){ +static int opj_j2k_initialise_4K_poc(opj_poc_t *POC, int numres){ POC[0].tile = 1; POC[0].resno0 = 0; POC[0].compno0 = 0; @@ -5995,7 +5938,7 @@ int opj_j2k_initialise_4K_poc(opj_poc_t *POC, int numres){ return 2; } -void opj_j2k_set_cinema_parameters(opj_cparameters_t *parameters, opj_image_t *image, opj_event_mgr_t *p_manager) +static void opj_j2k_set_cinema_parameters(opj_cparameters_t *parameters, opj_image_t *image, opj_event_mgr_t *p_manager) { /* Configure cinema parameters */ int i; @@ -6132,7 +6075,7 @@ void opj_j2k_set_cinema_parameters(opj_cparameters_t *parameters, opj_image_t *i } -OPJ_BOOL opj_j2k_is_cinema_compliant(opj_image_t *image, OPJ_UINT16 rsiz, opj_event_mgr_t *p_manager) +static OPJ_BOOL opj_j2k_is_cinema_compliant(opj_image_t *image, OPJ_UINT16 rsiz, opj_event_mgr_t *p_manager) { OPJ_UINT32 i; @@ -6797,7 +6740,11 @@ OPJ_BOOL opj_j2k_read_header( opj_stream_private_t *p_stream, } /* customization of the validation */ - opj_j2k_setup_decoding_validation(p_j2k); + if (! opj_j2k_setup_decoding_validation(p_j2k, p_manager)) { + opj_image_destroy(p_j2k->m_private_image); + p_j2k->m_private_image = NULL; + return OPJ_FALSE; + } /* validation of the parameters codec */ if (! opj_j2k_exec(p_j2k, p_j2k->m_validation_list, p_stream,p_manager)) { @@ -6807,7 +6754,11 @@ OPJ_BOOL opj_j2k_read_header( opj_stream_private_t *p_stream, } /* customization of the encoding */ - opj_j2k_setup_header_reading(p_j2k); + if (! opj_j2k_setup_header_reading(p_j2k, p_manager)) { + opj_image_destroy(p_j2k->m_private_image); + p_j2k->m_private_image = NULL; + return OPJ_FALSE; + } /* read header */ if (! opj_j2k_exec (p_j2k,p_j2k->m_procedure_list,p_stream,p_manager)) { @@ -6832,30 +6783,42 @@ OPJ_BOOL opj_j2k_read_header( opj_stream_private_t *p_stream, return OPJ_TRUE; } -void opj_j2k_setup_header_reading (opj_j2k_t *p_j2k) +static OPJ_BOOL opj_j2k_setup_header_reading (opj_j2k_t *p_j2k, opj_event_mgr_t * p_manager) { /* preconditions*/ assert(p_j2k != 00); + assert(p_manager != 00); - opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_read_header_procedure); + if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_read_header_procedure, p_manager)) { + return OPJ_FALSE; + } /* DEVELOPER CORNER, add your custom procedures */ - opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_copy_default_tcp_and_create_tcd); - + if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_copy_default_tcp_and_create_tcd, p_manager)) { + return OPJ_FALSE; + } + + return OPJ_TRUE; } -void opj_j2k_setup_decoding_validation (opj_j2k_t *p_j2k) +static OPJ_BOOL opj_j2k_setup_decoding_validation (opj_j2k_t *p_j2k, opj_event_mgr_t * p_manager) { /* preconditions*/ assert(p_j2k != 00); + assert(p_manager != 00); - opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)opj_j2k_build_decoder); - opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)opj_j2k_decoding_validation); - /* DEVELOPER CORNER, add your custom validation procedure */ + if (! opj_procedure_list_add_procedure(p_j2k->m_validation_list,(opj_procedure)opj_j2k_build_decoder, p_manager)) { + return OPJ_FALSE; + } + if (! opj_procedure_list_add_procedure(p_j2k->m_validation_list,(opj_procedure)opj_j2k_decoding_validation, p_manager)) { + return OPJ_FALSE; + } + /* DEVELOPER CORNER, add your custom validation procedure */ + return OPJ_TRUE; } -OPJ_BOOL opj_j2k_mct_validation ( opj_j2k_t * p_j2k, +static OPJ_BOOL opj_j2k_mct_validation ( opj_j2k_t * p_j2k, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ) { @@ -7041,7 +7004,7 @@ OPJ_BOOL opj_j2k_setup_mct_encoding(opj_tcp_t * p_tcp, opj_image_t * p_image) return OPJ_TRUE; } -OPJ_BOOL opj_j2k_build_decoder (opj_j2k_t * p_j2k, +static OPJ_BOOL opj_j2k_build_decoder (opj_j2k_t * p_j2k, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ) { @@ -7053,7 +7016,7 @@ OPJ_BOOL opj_j2k_build_decoder (opj_j2k_t * p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_build_encoder (opj_j2k_t * p_j2k, +static OPJ_BOOL opj_j2k_build_encoder (opj_j2k_t * p_j2k, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ) { @@ -7065,7 +7028,7 @@ OPJ_BOOL opj_j2k_build_encoder (opj_j2k_t * p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_encoding_validation ( opj_j2k_t * p_j2k, +static OPJ_BOOL opj_j2k_encoding_validation ( opj_j2k_t * p_j2k, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ) { @@ -7108,7 +7071,7 @@ OPJ_BOOL opj_j2k_encoding_validation ( opj_j2k_t * p_j2k, return l_is_valid; } -OPJ_BOOL opj_j2k_decoding_validation ( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_decoding_validation ( opj_j2k_t *p_j2k, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ) @@ -7138,7 +7101,7 @@ OPJ_BOOL opj_j2k_decoding_validation ( opj_j2k_t *p_j2k, return l_is_valid; } -OPJ_BOOL opj_j2k_read_header_procedure( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_read_header_procedure( opj_j2k_t *p_j2k, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager) { @@ -7284,6 +7247,11 @@ OPJ_BOOL opj_j2k_read_header_procedure( opj_j2k_t *p_j2k, opj_event_msg(p_manager, EVT_ERROR, "required QCD marker not found in main header\n"); return OPJ_FALSE; } + + if (! opj_j2k_merge_ppm(&(p_j2k->m_cp), p_manager)) { + opj_event_msg(p_manager, EVT_ERROR, "Failed to merge PPM data\n"); + return OPJ_FALSE; + } opj_event_msg(p_manager, EVT_INFO, "Main header has been correctly decoded.\n"); @@ -7296,7 +7264,7 @@ OPJ_BOOL opj_j2k_read_header_procedure( opj_j2k_t *p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_exec ( opj_j2k_t * p_j2k, +static OPJ_BOOL opj_j2k_exec ( opj_j2k_t * p_j2k, opj_procedure_list_t * p_procedure_list, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ) @@ -7464,7 +7432,7 @@ static OPJ_BOOL opj_j2k_copy_default_tcp_and_create_tcd ( opj_j2k_t * p_j2 return OPJ_TRUE; } -const opj_dec_memory_marker_handler_t * opj_j2k_get_marker_handler (OPJ_UINT32 p_id) +static const opj_dec_memory_marker_handler_t * opj_j2k_get_marker_handler (OPJ_UINT32 p_id) { const opj_dec_memory_marker_handler_t *e; for (e = j2k_memory_marker_handler_tab; e->id != 0; ++e) { @@ -7577,66 +7545,78 @@ void j2k_destroy_cstr_index (opj_codestream_index_t *p_cstr_ind) } } -void opj_j2k_tcp_destroy (opj_tcp_t *p_tcp) +static void opj_j2k_tcp_destroy (opj_tcp_t *p_tcp) { - if (p_tcp == 00) { - return; - } - - if (p_tcp->ppt_buffer != 00) { - opj_free(p_tcp->ppt_buffer); - p_tcp->ppt_buffer = 00; - } - - if (p_tcp->tccps != 00) { - opj_free(p_tcp->tccps); - p_tcp->tccps = 00; - } - - if (p_tcp->m_mct_coding_matrix != 00) { - opj_free(p_tcp->m_mct_coding_matrix); - p_tcp->m_mct_coding_matrix = 00; - } - - if (p_tcp->m_mct_decoding_matrix != 00) { - opj_free(p_tcp->m_mct_decoding_matrix); - p_tcp->m_mct_decoding_matrix = 00; - } - - if (p_tcp->m_mcc_records) { - opj_free(p_tcp->m_mcc_records); - p_tcp->m_mcc_records = 00; - p_tcp->m_nb_max_mcc_records = 0; - p_tcp->m_nb_mcc_records = 0; - } - - if (p_tcp->m_mct_records) { - opj_mct_data_t * l_mct_data = p_tcp->m_mct_records; - OPJ_UINT32 i; - - for (i=0;i<p_tcp->m_nb_mct_records;++i) { - if (l_mct_data->m_data) { - opj_free(l_mct_data->m_data); - l_mct_data->m_data = 00; - } - - ++l_mct_data; - } - - opj_free(p_tcp->m_mct_records); - p_tcp->m_mct_records = 00; - } + if (p_tcp == 00) { + return; + } + + if (p_tcp->ppt_markers != 00) { + OPJ_UINT32 i; + for (i = 0U; i < p_tcp->ppt_markers_count; ++i) { + if (p_tcp->ppt_markers[i].m_data != NULL) { + opj_free(p_tcp->ppt_markers[i].m_data); + } + } + p_tcp->ppt_markers_count = 0U; + opj_free(p_tcp->ppt_markers); + p_tcp->ppt_markers = NULL; + } + + if (p_tcp->ppt_buffer != 00) { + opj_free(p_tcp->ppt_buffer); + p_tcp->ppt_buffer = 00; + } + + if (p_tcp->tccps != 00) { + opj_free(p_tcp->tccps); + p_tcp->tccps = 00; + } + + if (p_tcp->m_mct_coding_matrix != 00) { + opj_free(p_tcp->m_mct_coding_matrix); + p_tcp->m_mct_coding_matrix = 00; + } + + if (p_tcp->m_mct_decoding_matrix != 00) { + opj_free(p_tcp->m_mct_decoding_matrix); + p_tcp->m_mct_decoding_matrix = 00; + } + + if (p_tcp->m_mcc_records) { + opj_free(p_tcp->m_mcc_records); + p_tcp->m_mcc_records = 00; + p_tcp->m_nb_max_mcc_records = 0; + p_tcp->m_nb_mcc_records = 0; + } + + if (p_tcp->m_mct_records) { + opj_mct_data_t * l_mct_data = p_tcp->m_mct_records; + OPJ_UINT32 i; + + for (i=0;i<p_tcp->m_nb_mct_records;++i) { + if (l_mct_data->m_data) { + opj_free(l_mct_data->m_data); + l_mct_data->m_data = 00; + } + + ++l_mct_data; + } + + opj_free(p_tcp->m_mct_records); + p_tcp->m_mct_records = 00; + } - if (p_tcp->mct_norms != 00) { - opj_free(p_tcp->mct_norms); - p_tcp->mct_norms = 00; - } + if (p_tcp->mct_norms != 00) { + opj_free(p_tcp->mct_norms); + p_tcp->mct_norms = 00; + } - opj_j2k_tcp_data_destroy(p_tcp); + opj_j2k_tcp_data_destroy(p_tcp); } -void opj_j2k_tcp_data_destroy (opj_tcp_t *p_tcp) +static void opj_j2k_tcp_data_destroy (opj_tcp_t *p_tcp) { if (p_tcp->m_data) { opj_free(p_tcp->m_data); @@ -7645,39 +7625,148 @@ void opj_j2k_tcp_data_destroy (opj_tcp_t *p_tcp) } } -void opj_j2k_cp_destroy (opj_cp_t *p_cp) +static void opj_j2k_cp_destroy (opj_cp_t *p_cp) { - OPJ_UINT32 l_nb_tiles; - opj_tcp_t * l_current_tile = 00; - OPJ_UINT32 i; + OPJ_UINT32 l_nb_tiles; + opj_tcp_t * l_current_tile = 00; - if (p_cp == 00) - { - return; - } - if (p_cp->tcps != 00) - { - l_current_tile = p_cp->tcps; - l_nb_tiles = p_cp->th * p_cp->tw; + if (p_cp == 00) + { + return; + } + if (p_cp->tcps != 00) + { + OPJ_UINT32 i; + l_current_tile = p_cp->tcps; + l_nb_tiles = p_cp->th * p_cp->tw; + + for (i = 0U; i < l_nb_tiles; ++i) + { + opj_j2k_tcp_destroy(l_current_tile); + ++l_current_tile; + } + opj_free(p_cp->tcps); + p_cp->tcps = 00; + } + if (p_cp->ppm_markers != 00) { + OPJ_UINT32 i; + for (i = 0U; i < p_cp->ppm_markers_count; ++i) { + if (p_cp->ppm_markers[i].m_data != NULL) { + opj_free(p_cp->ppm_markers[i].m_data); + } + } + p_cp->ppm_markers_count = 0U; + opj_free(p_cp->ppm_markers); + p_cp->ppm_markers = NULL; + } + opj_free(p_cp->ppm_buffer); + p_cp->ppm_buffer = 00; + p_cp->ppm_data = NULL; /* ppm_data belongs to the allocated buffer pointed by ppm_buffer */ + opj_free(p_cp->comment); + p_cp->comment = 00; + if (! p_cp->m_is_decoder) + { + opj_free(p_cp->m_specific_param.m_enc.m_matrice); + p_cp->m_specific_param.m_enc.m_matrice = 00; + } +} - for (i = 0; i < l_nb_tiles; ++i) - { - opj_j2k_tcp_destroy(l_current_tile); - ++l_current_tile; - } - opj_free(p_cp->tcps); - p_cp->tcps = 00; - } - opj_free(p_cp->ppm_buffer); - p_cp->ppm_buffer = 00; - p_cp->ppm_data = NULL; /* ppm_data belongs to the allocated buffer pointed by ppm_buffer */ - opj_free(p_cp->comment); - p_cp->comment = 00; - if (! p_cp->m_is_decoder) - { - opj_free(p_cp->m_specific_param.m_enc.m_matrice); - p_cp->m_specific_param.m_enc.m_matrice = 00; - } +static OPJ_BOOL opj_j2k_need_nb_tile_parts_correction(opj_stream_private_t *p_stream, OPJ_UINT32 tile_no, OPJ_BOOL* p_correction_needed, opj_event_mgr_t * p_manager ) +{ + OPJ_BYTE l_header_data[10]; + OPJ_OFF_T l_stream_pos_backup; + OPJ_UINT32 l_current_marker; + OPJ_UINT32 l_marker_size; + OPJ_UINT32 l_tile_no, l_tot_len, l_current_part, l_num_parts; + + /* initialize to no correction needed */ + *p_correction_needed = OPJ_FALSE; + + l_stream_pos_backup = opj_stream_tell(p_stream); + if (l_stream_pos_backup == -1) { + /* let's do nothing */ + return OPJ_TRUE; + } + + for (;;) { + /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer */ + if (opj_stream_read_data(p_stream,l_header_data, 2, p_manager) != 2) { + /* assume all is OK */ + if (! opj_stream_seek(p_stream, l_stream_pos_backup, p_manager)) { + return OPJ_FALSE; + } + return OPJ_TRUE; + } + + /* Read 2 bytes from buffer as the new marker ID */ + opj_read_bytes(l_header_data, &l_current_marker, 2); + + if (l_current_marker != J2K_MS_SOT) { + /* assume all is OK */ + if (! opj_stream_seek(p_stream, l_stream_pos_backup, p_manager)) { + return OPJ_FALSE; + } + return OPJ_TRUE; + } + + /* Try to read 2 bytes (the marker size) from stream and copy them into the buffer */ + if (opj_stream_read_data(p_stream, l_header_data, 2, p_manager) != 2) { + opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); + return OPJ_FALSE; + } + + /* Read 2 bytes from the buffer as the marker size */ + opj_read_bytes(l_header_data, &l_marker_size, 2); + + /* Check marker size for SOT Marker */ + if (l_marker_size != 10) { + opj_event_msg(p_manager, EVT_ERROR, "Inconsistent marker size\n"); + return OPJ_FALSE; + } + l_marker_size -= 2; + + if (opj_stream_read_data(p_stream, l_header_data, l_marker_size, p_manager) != l_marker_size) { + opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); + return OPJ_FALSE; + } + + if (! opj_j2k_get_sot_values(l_header_data, l_marker_size, &l_tile_no, &l_tot_len, &l_current_part, &l_num_parts, p_manager)) { + return OPJ_FALSE; + } + + if (l_tile_no == tile_no) { + /* we found what we were looking for */ + break; + } + + if ((l_tot_len == 0U) || (l_tot_len < 14U)) { + /* last SOT until EOC or invalid Psot value */ + /* assume all is OK */ + if (! opj_stream_seek(p_stream, l_stream_pos_backup, p_manager)) { + return OPJ_FALSE; + } + return OPJ_TRUE; + } + l_tot_len -= 12U; + /* look for next SOT marker */ + if (opj_stream_skip(p_stream, (OPJ_OFF_T)(l_tot_len), p_manager) != (OPJ_OFF_T)(l_tot_len)) { + /* assume all is OK */ + if (! opj_stream_seek(p_stream, l_stream_pos_backup, p_manager)) { + return OPJ_FALSE; + } + return OPJ_TRUE; + } + } + + /* check for correction */ + if (l_current_part == l_num_parts) { + *p_correction_needed = OPJ_TRUE; + } + + if (! opj_stream_seek(p_stream, l_stream_pos_backup, p_manager)) { + return OPJ_FALSE; + } + return OPJ_TRUE; } OPJ_BOOL opj_j2k_read_tile_header( opj_j2k_t * p_j2k, @@ -7694,7 +7783,6 @@ OPJ_BOOL opj_j2k_read_tile_header( opj_j2k_t * p_j2k, OPJ_UINT32 l_marker_size; const opj_dec_memory_marker_handler_t * l_marker_handler = 00; opj_tcp_t * l_tcp = NULL; - OPJ_UINT32 l_nb_tiles; /* preconditions */ assert(p_stream != 00); @@ -7844,7 +7932,30 @@ OPJ_BOOL opj_j2k_read_tile_header( opj_j2k_t * p_j2k, if (! opj_j2k_read_sod(p_j2k, p_stream, p_manager)) { return OPJ_FALSE; } - + if (p_j2k->m_specific_param.m_decoder.m_can_decode && !p_j2k->m_specific_param.m_decoder.m_nb_tile_parts_correction_checked) { + /* Issue 254 */ + OPJ_BOOL l_correction_needed; + + p_j2k->m_specific_param.m_decoder.m_nb_tile_parts_correction_checked = 1; + if(!opj_j2k_need_nb_tile_parts_correction(p_stream, p_j2k->m_current_tile_number, &l_correction_needed, p_manager)) { + opj_event_msg(p_manager, EVT_ERROR, "opj_j2k_apply_nb_tile_parts_correction error\n"); + return OPJ_FALSE; + } + if (l_correction_needed) { + OPJ_UINT32 l_nb_tiles = p_j2k->m_cp.tw * p_j2k->m_cp.th; + OPJ_UINT32 l_tile_no; + + p_j2k->m_specific_param.m_decoder.m_can_decode = 0; + p_j2k->m_specific_param.m_decoder.m_nb_tile_parts_correction = 1; + /* correct tiles */ + for (l_tile_no = 0U; l_tile_no < l_nb_tiles; ++l_tile_no) { + if (p_j2k->m_cp.tcps[l_tile_no].m_nb_tile_parts != 0U) { + p_j2k->m_cp.tcps[l_tile_no].m_nb_tile_parts+=1; + } + } + opj_event_msg(p_manager, EVT_WARNING, "Non conformant codestream TPsot==TNsot.\n"); + } + } if (! p_j2k->m_specific_param.m_decoder.m_can_decode){ /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer */ if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) { @@ -7883,8 +7994,8 @@ OPJ_BOOL opj_j2k_read_tile_header( opj_j2k_t * p_j2k, /* FIXME DOC ???*/ if ( ! p_j2k->m_specific_param.m_decoder.m_can_decode) { + OPJ_UINT32 l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw; l_tcp = p_j2k->m_cp.tcps + p_j2k->m_current_tile_number; - l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw; while( (p_j2k->m_current_tile_number < l_nb_tiles) && (l_tcp->m_data == 00) ) { ++p_j2k->m_current_tile_number; @@ -7897,8 +8008,12 @@ OPJ_BOOL opj_j2k_read_tile_header( opj_j2k_t * p_j2k, } } + if (! opj_j2k_merge_ppt(p_j2k->m_cp.tcps + p_j2k->m_current_tile_number, p_manager)) { + opj_event_msg(p_manager, EVT_ERROR, "Failed to merge PPT data\n"); + return OPJ_FALSE; + } /*FIXME ???*/ - if (! opj_tcd_init_decode_tile(p_j2k->m_tcd, p_j2k->m_current_tile_number)) { + if (! opj_tcd_init_decode_tile(p_j2k->m_tcd, p_j2k->m_current_tile_number, p_manager)) { opj_event_msg(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n"); return OPJ_FALSE; } @@ -7951,7 +8066,7 @@ OPJ_BOOL opj_j2k_decode_tile ( opj_j2k_t * p_j2k, l_tcp->m_data, l_tcp->m_data_size, p_tile_index, - p_j2k->cstr_index) ) { + p_j2k->cstr_index, p_manager) ) { opj_j2k_tcp_destroy(l_tcp); p_j2k->m_specific_param.m_decoder.m_state |= 0x8000;/*FIXME J2K_DEC_STATE_ERR;*/ opj_event_msg(p_manager, EVT_ERROR, "Failed to decode.\n"); @@ -8003,16 +8118,16 @@ OPJ_BOOL opj_j2k_decode_tile ( opj_j2k_t * p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data, opj_image_t* p_output_image) +static OPJ_BOOL opj_j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data, opj_image_t* p_output_image) { OPJ_UINT32 i,j,k = 0; OPJ_UINT32 l_width_src,l_height_src; OPJ_UINT32 l_width_dest,l_height_dest; OPJ_INT32 l_offset_x0_src, l_offset_y0_src, l_offset_x1_src, l_offset_y1_src; - OPJ_INT32 l_start_offset_src, l_line_offset_src, l_end_offset_src ; + OPJ_SIZE_T l_start_offset_src, l_line_offset_src, l_end_offset_src ; OPJ_UINT32 l_start_x_dest , l_start_y_dest; OPJ_UINT32 l_x0_dest, l_y0_dest, l_x1_dest, l_y1_dest; - OPJ_INT32 l_start_offset_dest, l_line_offset_dest; + OPJ_SIZE_T l_start_offset_dest, l_line_offset_dest; opj_image_comp_t * l_img_comp_src = 00; opj_image_comp_t * l_img_comp_dest = 00; @@ -8038,8 +8153,8 @@ OPJ_BOOL opj_j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data, opj_im const OPJ_UINT32 MAX_SIZE = UINT32_MAX / sizeof(OPJ_INT32); if (height == 0 || width > MAX_SIZE / height) { return OPJ_FALSE; - } - l_img_comp_dest->data = (OPJ_INT32*) opj_calloc(width * height, sizeof(OPJ_INT32)); + } + l_img_comp_dest->data = (OPJ_INT32*)opj_calloc(width * height, sizeof(OPJ_INT32)); if (!l_img_comp_dest->data) { return OPJ_FALSE; } @@ -8073,9 +8188,9 @@ OPJ_BOOL opj_j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data, opj_im l_height_src = (OPJ_UINT32)(l_res->y1 - l_res->y0); /* Border of the current output component*/ - l_x0_dest = (OPJ_UINT32)opj_int_ceildivpow2((OPJ_INT32)l_img_comp_dest->x0, (OPJ_INT32)l_img_comp_dest->factor); - l_y0_dest = (OPJ_UINT32)opj_int_ceildivpow2((OPJ_INT32)l_img_comp_dest->y0, (OPJ_INT32)l_img_comp_dest->factor); - l_x1_dest = l_x0_dest + l_img_comp_dest->w; + l_x0_dest = opj_uint_ceildivpow2(l_img_comp_dest->x0, l_img_comp_dest->factor); + l_y0_dest = opj_uint_ceildivpow2(l_img_comp_dest->y0, l_img_comp_dest->factor); + l_x1_dest = l_x0_dest + l_img_comp_dest->w; /* can't overflow given that image->x1 is uint32 */ l_y1_dest = l_y0_dest + l_img_comp_dest->h; /*if (i == 0) { @@ -8106,7 +8221,7 @@ OPJ_BOOL opj_j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data, opj_im } } else { - l_start_x_dest = 0 ; + l_start_x_dest = 0U; l_offset_x0_src = (OPJ_INT32)l_x0_dest - l_res->x0; if ( l_x1_dest >= (OPJ_UINT32)l_res->x1 ) { @@ -8133,7 +8248,7 @@ OPJ_BOOL opj_j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data, opj_im } } else { - l_start_y_dest = 0 ; + l_start_y_dest = 0U; l_offset_y0_src = (OPJ_INT32)l_y0_dest - l_res->y0; if ( l_y1_dest >= (OPJ_UINT32)l_res->y1 ) { @@ -8156,13 +8271,13 @@ OPJ_BOOL opj_j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data, opj_im /*-----*/ /* Compute the input buffer offset */ - l_start_offset_src = l_offset_x0_src + l_offset_y0_src * (OPJ_INT32)l_width_src; - l_line_offset_src = l_offset_x1_src + l_offset_x0_src; - l_end_offset_src = l_offset_y1_src * (OPJ_INT32)l_width_src - l_offset_x0_src; + l_start_offset_src = (OPJ_SIZE_T)l_offset_x0_src + (OPJ_SIZE_T)l_offset_y0_src * (OPJ_SIZE_T)l_width_src; + l_line_offset_src = (OPJ_SIZE_T)l_offset_x1_src + (OPJ_SIZE_T)l_offset_x0_src; + l_end_offset_src = (OPJ_SIZE_T)l_offset_y1_src * (OPJ_SIZE_T)l_width_src - (OPJ_SIZE_T)l_offset_x0_src; /* Compute the output buffer offset */ - l_start_offset_dest = (OPJ_INT32)(l_start_x_dest + l_start_y_dest * l_img_comp_dest->w); - l_line_offset_dest = (OPJ_INT32)(l_img_comp_dest->w - l_width_dest); + l_start_offset_dest = (OPJ_SIZE_T)l_start_x_dest + (OPJ_SIZE_T)l_start_y_dest * (OPJ_SIZE_T)l_img_comp_dest->w; + l_line_offset_dest = (OPJ_SIZE_T)l_img_comp_dest->w - (OPJ_SIZE_T)l_width_dest; /* Move the output buffer to the first place where we will write*/ l_dest_ptr = l_img_comp_dest->data + l_start_offset_dest; @@ -8436,6 +8551,10 @@ opj_j2k_t* opj_j2k_create_decompress(void) l_j2k->m_is_decoder = 1; l_j2k->m_cp.m_is_decoder = 1; +#ifdef OPJ_DISABLE_TPSOT_FIX + l_j2k->m_specific_param.m_decoder.m_nb_tile_parts_correction_checked = 1; +#endif + l_j2k->m_specific_param.m_decoder.m_default_tcp = (opj_tcp_t*) opj_calloc(1,sizeof(opj_tcp_t)); if (!l_j2k->m_specific_param.m_decoder.m_default_tcp) { opj_j2k_destroy(l_j2k); @@ -8478,7 +8597,7 @@ opj_j2k_t* opj_j2k_create_decompress(void) return l_j2k; } -opj_codestream_index_t* opj_j2k_create_cstr_index(void) +static opj_codestream_index_t* opj_j2k_create_cstr_index(void) { opj_codestream_index_t* cstr_index = (opj_codestream_index_t*) opj_calloc(1,sizeof(opj_codestream_index_t)); @@ -8489,15 +8608,17 @@ opj_codestream_index_t* opj_j2k_create_cstr_index(void) cstr_index->marknum = 0; cstr_index->marker = (opj_marker_info_t*) opj_calloc(cstr_index->maxmarknum, sizeof(opj_marker_info_t)); - if (!cstr_index-> marker) + if (!cstr_index-> marker) { + opj_free(cstr_index); return NULL; + } cstr_index->tile_index = NULL; return cstr_index; } -OPJ_UINT32 opj_j2k_get_SPCod_SPCoc_size ( opj_j2k_t *p_j2k, +static OPJ_UINT32 opj_j2k_get_SPCod_SPCoc_size ( opj_j2k_t *p_j2k, OPJ_UINT32 p_tile_no, OPJ_UINT32 p_comp_no ) { @@ -8524,7 +8645,7 @@ OPJ_UINT32 opj_j2k_get_SPCod_SPCoc_size ( opj_j2k_t *p_j2k, } } -OPJ_BOOL opj_j2k_write_SPCod_SPCoc( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_write_SPCod_SPCoc( opj_j2k_t *p_j2k, OPJ_UINT32 p_tile_no, OPJ_UINT32 p_comp_no, OPJ_BYTE * p_data, @@ -8590,7 +8711,7 @@ OPJ_BOOL opj_j2k_write_SPCod_SPCoc( opj_j2k_t *p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_read_SPCod_SPCoc( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_read_SPCod_SPCoc( opj_j2k_t *p_j2k, OPJ_UINT32 compno, OPJ_BYTE * p_header_data, OPJ_UINT32 * p_header_size, @@ -8713,7 +8834,7 @@ OPJ_BOOL opj_j2k_read_SPCod_SPCoc( opj_j2k_t *p_j2k, return OPJ_TRUE; } -void opj_j2k_copy_tile_component_parameters( opj_j2k_t *p_j2k ) +static void opj_j2k_copy_tile_component_parameters( opj_j2k_t *p_j2k ) { /* loop */ OPJ_UINT32 i; @@ -8746,7 +8867,7 @@ void opj_j2k_copy_tile_component_parameters( opj_j2k_t *p_j2k ) } } -OPJ_UINT32 opj_j2k_get_SQcd_SQcc_size ( opj_j2k_t *p_j2k, +static OPJ_UINT32 opj_j2k_get_SQcd_SQcc_size ( opj_j2k_t *p_j2k, OPJ_UINT32 p_tile_no, OPJ_UINT32 p_comp_no ) { @@ -8777,7 +8898,7 @@ OPJ_UINT32 opj_j2k_get_SQcd_SQcc_size ( opj_j2k_t *p_j2k, } } -OPJ_BOOL opj_j2k_write_SQcd_SQcc( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_write_SQcd_SQcc( opj_j2k_t *p_j2k, OPJ_UINT32 p_tile_no, OPJ_UINT32 p_comp_no, OPJ_BYTE * p_data, @@ -8850,7 +8971,7 @@ OPJ_BOOL opj_j2k_write_SQcd_SQcc( opj_j2k_t *p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_read_SQcd_SQcc(opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_read_SQcd_SQcc(opj_j2k_t *p_j2k, OPJ_UINT32 p_comp_no, OPJ_BYTE* p_header_data, OPJ_UINT32 * p_header_size, @@ -8967,7 +9088,7 @@ OPJ_BOOL opj_j2k_read_SQcd_SQcc(opj_j2k_t *p_j2k, return OPJ_TRUE; } -void opj_j2k_copy_tile_quantization_parameters( opj_j2k_t *p_j2k ) +static void opj_j2k_copy_tile_quantization_parameters( opj_j2k_t *p_j2k ) { OPJ_UINT32 i; opj_cp_t *l_cp = NULL; @@ -9094,7 +9215,7 @@ void j2k_dump (opj_j2k_t* p_j2k, OPJ_INT32 flag, FILE* out_stream) } -void opj_j2k_dump_MH_index(opj_j2k_t* p_j2k, FILE* out_stream) +static void opj_j2k_dump_MH_index(opj_j2k_t* p_j2k, FILE* out_stream) { opj_codestream_index_t* cstr_index = p_j2k->cstr_index; OPJ_UINT32 it_marker, it_tile, it_tile_part; @@ -9163,7 +9284,7 @@ void opj_j2k_dump_MH_index(opj_j2k_t* p_j2k, FILE* out_stream) } -void opj_j2k_dump_MH_info(opj_j2k_t* p_j2k, FILE* out_stream) +static void opj_j2k_dump_MH_info(opj_j2k_t* p_j2k, FILE* out_stream) { fprintf(out_stream, "Codestream info from main header: {\n"); @@ -9403,7 +9524,7 @@ opj_codestream_index_t* j2k_get_cstr_index(opj_j2k_t* p_j2k) return l_cstr_index; } -OPJ_BOOL opj_j2k_allocate_tile_element_cstr_index(opj_j2k_t *p_j2k) +static OPJ_BOOL opj_j2k_allocate_tile_element_cstr_index(opj_j2k_t *p_j2k) { OPJ_UINT32 it_tile=0; @@ -9424,7 +9545,7 @@ OPJ_BOOL opj_j2k_allocate_tile_element_cstr_index(opj_j2k_t *p_j2k) return OPJ_TRUE; } -OPJ_BOOL opj_j2k_decode_tiles ( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_decode_tiles ( opj_j2k_t *p_j2k, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager) { @@ -9443,7 +9564,7 @@ OPJ_BOOL opj_j2k_decode_tiles ( opj_j2k_t *p_j2k, } l_max_data_size = 1000; - while (OPJ_TRUE) { + for (;;) { if (! opj_j2k_read_tile_header( p_j2k, &l_current_tile_no, &l_data_size, @@ -9500,14 +9621,18 @@ OPJ_BOOL opj_j2k_decode_tiles ( opj_j2k_t *p_j2k, /** * Sets up the procedures to do on decoding data. Developpers wanting to extend the library can add their own reading procedures. */ -static void opj_j2k_setup_decoding (opj_j2k_t *p_j2k) +static OPJ_BOOL opj_j2k_setup_decoding (opj_j2k_t *p_j2k, opj_event_mgr_t * p_manager) { /* preconditions*/ assert(p_j2k != 00); + assert(p_manager != 00); - opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_decode_tiles); + if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_decode_tiles, p_manager)) { + return OPJ_FALSE; + } /* DEVELOPER CORNER, add your custom procedures */ + return OPJ_TRUE; } /* @@ -9550,14 +9675,14 @@ static OPJ_BOOL opj_j2k_decode_one_tile ( opj_j2k_t *p_j2k, * so move to the last SOT read */ if ( !(opj_stream_read_seek(p_stream, p_j2k->m_specific_param.m_decoder.m_last_sot_read_pos+2, p_manager)) ){ opj_event_msg(p_manager, EVT_ERROR, "Problem with seek function\n"); - opj_free(l_current_data); + opj_free(l_current_data); return OPJ_FALSE; } } else{ if ( !(opj_stream_read_seek(p_stream, p_j2k->cstr_index->tile_index[l_tile_no_to_dec].tp_index[0].start_pos+2, p_manager)) ) { opj_event_msg(p_manager, EVT_ERROR, "Problem with seek function\n"); - opj_free(l_current_data); + opj_free(l_current_data); return OPJ_FALSE; } } @@ -9566,7 +9691,7 @@ static OPJ_BOOL opj_j2k_decode_one_tile ( opj_j2k_t *p_j2k, p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_TPHSOT; } - while (OPJ_TRUE) { + for (;;) { if (! opj_j2k_read_tile_header( p_j2k, &l_current_tile_no, &l_data_size, @@ -9615,6 +9740,7 @@ static OPJ_BOOL opj_j2k_decode_one_tile ( opj_j2k_t *p_j2k, /* move into the codestream to the the first SOT (FIXME or not move?)*/ if (!(opj_stream_read_seek(p_stream, p_j2k->cstr_index->main_head_end + 2, p_manager) ) ) { opj_event_msg(p_manager, EVT_ERROR, "Problem with seek function\n"); + opj_free(l_current_data); return OPJ_FALSE; } break; @@ -9633,14 +9759,18 @@ static OPJ_BOOL opj_j2k_decode_one_tile ( opj_j2k_t *p_j2k, /** * Sets up the procedures to do on decoding one tile. Developpers wanting to extend the library can add their own reading procedures. */ -static void opj_j2k_setup_decoding_tile (opj_j2k_t *p_j2k) +static OPJ_BOOL opj_j2k_setup_decoding_tile (opj_j2k_t *p_j2k, opj_event_mgr_t * p_manager) { /* preconditions*/ assert(p_j2k != 00); + assert(p_manager != 00); - opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_decode_one_tile); + if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_decode_one_tile, p_manager)) { + return OPJ_FALSE; + } /* DEVELOPER CORNER, add your custom procedures */ + return OPJ_TRUE; } OPJ_BOOL opj_j2k_decode(opj_j2k_t * p_j2k, @@ -9652,7 +9782,7 @@ OPJ_BOOL opj_j2k_decode(opj_j2k_t * p_j2k, if (!p_image) return OPJ_FALSE; - + p_j2k->m_output_image = opj_image_create0(); if (! (p_j2k->m_output_image)) { return OPJ_FALSE; @@ -9660,7 +9790,7 @@ OPJ_BOOL opj_j2k_decode(opj_j2k_t * p_j2k, opj_copy_image_header(p_image, p_j2k->m_output_image); /* customization of the decoding */ - opj_j2k_setup_decoding(p_j2k); + opj_j2k_setup_decoding(p_j2k, p_manager); /* Decode the codestream */ if (! opj_j2k_exec (p_j2k,p_j2k->m_procedure_list,p_stream,p_manager)) { @@ -9756,7 +9886,7 @@ OPJ_BOOL opj_j2k_get_tile( opj_j2k_t *p_j2k, p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec = (OPJ_INT32)tile_index; /* customization of the decoding */ - opj_j2k_setup_decoding_tile(p_j2k); + opj_j2k_setup_decoding_tile(p_j2k, p_manager); /* Decode the codestream */ if (! opj_j2k_exec (p_j2k,p_j2k->m_procedure_list,p_stream,p_manager)) { @@ -9851,7 +9981,6 @@ OPJ_BOOL opj_j2k_encode(opj_j2k_t * p_j2k, } return OPJ_FALSE; } - opj_alloc_tile_component_data(l_tilec); } } l_current_tile_size = opj_tcd_get_encoded_tile_size(p_j2k->m_tcd); @@ -9877,11 +10006,15 @@ OPJ_BOOL opj_j2k_encode(opj_j2k_t * p_j2k, /* now copy this data into the tile component */ if (! opj_tcd_copy_tile_data(p_j2k->m_tcd,l_current_data,l_current_tile_size)) { opj_event_msg(p_manager, EVT_ERROR, "Size mismatch between tile data and sent data." ); + opj_free(l_current_data); return OPJ_FALSE; } } if (! opj_j2k_post_write_tile (p_j2k,p_stream,p_manager)) { + if (l_current_data) { + opj_free(l_current_data); + } return OPJ_FALSE; } } @@ -9897,7 +10030,9 @@ OPJ_BOOL opj_j2k_end_compress( opj_j2k_t *p_j2k, opj_event_mgr_t * p_manager) { /* customization of the encoding */ - opj_j2k_setup_end_compress(p_j2k); + if (! opj_j2k_setup_end_compress(p_j2k, p_manager)) { + return OPJ_FALSE; + } if (! opj_j2k_exec (p_j2k, p_j2k->m_procedure_list, p_stream, p_manager)) { @@ -9937,7 +10072,9 @@ OPJ_BOOL opj_j2k_start_compress(opj_j2k_t *p_j2k, } /* customization of the validation */ - opj_j2k_setup_encoding_validation (p_j2k); + if (! opj_j2k_setup_encoding_validation (p_j2k, p_manager)) { + return OPJ_FALSE; + } /* validation of the parameters codec */ if (! opj_j2k_exec(p_j2k,p_j2k->m_validation_list,p_stream,p_manager)) { @@ -9945,7 +10082,9 @@ OPJ_BOOL opj_j2k_start_compress(opj_j2k_t *p_j2k, } /* customization of the encoding */ - opj_j2k_setup_header_writing(p_j2k); + if (! opj_j2k_setup_header_writing(p_j2k, p_manager)) { + return OPJ_FALSE; + } /* write header */ if (! opj_j2k_exec (p_j2k,p_j2k->m_procedure_list,p_stream,p_manager)) { @@ -9955,7 +10094,7 @@ OPJ_BOOL opj_j2k_start_compress(opj_j2k_t *p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_pre_write_tile ( opj_j2k_t * p_j2k, +static OPJ_BOOL opj_j2k_pre_write_tile ( opj_j2k_t * p_j2k, OPJ_UINT32 p_tile_index, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ) @@ -9973,14 +10112,14 @@ OPJ_BOOL opj_j2k_pre_write_tile ( opj_j2k_t * p_j2k, p_j2k->m_specific_param.m_encoder.m_current_poc_tile_part_number = 0; /* initialisation before tile encoding */ - if (! opj_tcd_init_encode_tile(p_j2k->m_tcd, p_j2k->m_current_tile_number)) { + if (! opj_tcd_init_encode_tile(p_j2k->m_tcd, p_j2k->m_current_tile_number, p_manager)) { return OPJ_FALSE; } return OPJ_TRUE; } -void opj_get_tile_dimensions(opj_image_t * l_image, +static void opj_get_tile_dimensions(opj_image_t * l_image, opj_tcd_tilecomp_t * l_tilec, opj_image_comp_t * l_img_comp, OPJ_UINT32* l_size_comp, @@ -10011,7 +10150,7 @@ void opj_get_tile_dimensions(opj_image_t * l_image, *l_tile_offset = ((OPJ_UINT32)l_tilec->x0 - *l_offset_x) + ((OPJ_UINT32)l_tilec->y0 - *l_offset_y) * *l_image_width; } -void opj_j2k_get_tile_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data) +static void opj_j2k_get_tile_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data) { OPJ_UINT32 i,j,k = 0; @@ -10104,7 +10243,7 @@ void opj_j2k_get_tile_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data) } } -OPJ_BOOL opj_j2k_post_write_tile ( opj_j2k_t * p_j2k, +static OPJ_BOOL opj_j2k_post_write_tile ( opj_j2k_t * p_j2k, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ) { @@ -10146,79 +10285,133 @@ OPJ_BOOL opj_j2k_post_write_tile ( opj_j2k_t * p_j2k, return OPJ_TRUE; } -void opj_j2k_setup_end_compress (opj_j2k_t *p_j2k) +static OPJ_BOOL opj_j2k_setup_end_compress (opj_j2k_t *p_j2k, opj_event_mgr_t * p_manager) { /* preconditions */ assert(p_j2k != 00); + assert(p_manager != 00); /* DEVELOPER CORNER, insert your custom procedures */ - opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_eoc ); + if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_eoc, p_manager)) { + return OPJ_FALSE; + } if (OPJ_IS_CINEMA(p_j2k->m_cp.rsiz)) { - opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_updated_tlm); + if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_updated_tlm, p_manager)) { + return OPJ_FALSE; + } } - opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_epc ); - opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_end_encoding ); - opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_destroy_header_memory); + if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_epc, p_manager)) { + return OPJ_FALSE; + } + if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_end_encoding, p_manager)) { + return OPJ_FALSE; + } + if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_destroy_header_memory, p_manager)) { + return OPJ_FALSE; + } + return OPJ_TRUE; } -void opj_j2k_setup_encoding_validation (opj_j2k_t *p_j2k) +static OPJ_BOOL opj_j2k_setup_encoding_validation (opj_j2k_t *p_j2k, opj_event_mgr_t * p_manager) { /* preconditions */ assert(p_j2k != 00); + assert(p_manager != 00); - opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)opj_j2k_build_encoder); - opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)opj_j2k_encoding_validation); + if (! opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)opj_j2k_build_encoder, p_manager)) { + return OPJ_FALSE; + } + if (! opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)opj_j2k_encoding_validation, p_manager)) { + return OPJ_FALSE; + } /* DEVELOPER CORNER, add your custom validation procedure */ - opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)opj_j2k_mct_validation); + if (! opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)opj_j2k_mct_validation, p_manager)) { + return OPJ_FALSE; + } + + return OPJ_TRUE; } -void opj_j2k_setup_header_writing (opj_j2k_t *p_j2k) +static OPJ_BOOL opj_j2k_setup_header_writing (opj_j2k_t *p_j2k, opj_event_mgr_t * p_manager) { /* preconditions */ assert(p_j2k != 00); + assert(p_manager != 00); - opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_init_info ); - opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_soc ); - opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_siz ); - opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_cod ); - opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_qcd ); + if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_init_info, p_manager)) { + return OPJ_FALSE; + } + if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_soc, p_manager)) { + return OPJ_FALSE; + } + if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_siz, p_manager)) { + return OPJ_FALSE; + } + if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_cod, p_manager)) { + return OPJ_FALSE; + } + if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_qcd, p_manager)) { + return OPJ_FALSE; + } if (OPJ_IS_CINEMA(p_j2k->m_cp.rsiz)) { /* No need for COC or QCC, QCD and COD are used - opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_all_coc ); - opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_all_qcc ); + if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_all_coc, p_manager)) { + return OPJ_FALSE; + } + if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_all_qcc, p_manager)) { + return OPJ_FALSE; + } */ - opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_tlm ); + if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_tlm, p_manager)) { + return OPJ_FALSE; + } if (p_j2k->m_cp.rsiz == OPJ_PROFILE_CINEMA_4K) { - opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_poc ); + if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_poc, p_manager)) { + return OPJ_FALSE; + } } } - opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_regions); + if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_regions, p_manager)) { + return OPJ_FALSE; + } if (p_j2k->m_cp.comment != 00) { - opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_com); + if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_com, p_manager)) { + return OPJ_FALSE; + } } /* DEVELOPER CORNER, insert your custom procedures */ if (p_j2k->m_cp.rsiz & OPJ_EXTENSION_MCT) { - opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_mct_data_group ); + if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_mct_data_group, p_manager)) { + return OPJ_FALSE; + } } /* End of Developer Corner */ if (p_j2k->cstr_index) { - opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_get_end_header ); + if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_get_end_header, p_manager)) { + return OPJ_FALSE; + } } - opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_create_tcd); - opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_update_rates); + if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_create_tcd, p_manager)) { + return OPJ_FALSE; + } + if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_update_rates, p_manager)) { + return OPJ_FALSE; + } + + return OPJ_TRUE; } -OPJ_BOOL opj_j2k_write_first_tile_part (opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_write_first_tile_part (opj_j2k_t *p_j2k, OPJ_BYTE * p_data, OPJ_UINT32 * p_data_written, OPJ_UINT32 p_total_data_size, @@ -10298,7 +10491,7 @@ OPJ_BOOL opj_j2k_write_first_tile_part (opj_j2k_t *p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_write_all_tile_parts( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_write_all_tile_parts( opj_j2k_t *p_j2k, OPJ_BYTE * p_data, OPJ_UINT32 * p_data_written, OPJ_UINT32 p_total_data_size, @@ -10409,7 +10602,7 @@ OPJ_BOOL opj_j2k_write_all_tile_parts( opj_j2k_t *p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_write_updated_tlm( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_write_updated_tlm( opj_j2k_t *p_j2k, struct opj_stream_private *p_stream, struct opj_event_mgr * p_manager ) { @@ -10440,7 +10633,7 @@ OPJ_BOOL opj_j2k_write_updated_tlm( opj_j2k_t *p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_end_encoding( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_end_encoding( opj_j2k_t *p_j2k, struct opj_stream_private *p_stream, struct opj_event_mgr * p_manager ) { @@ -10491,7 +10684,7 @@ static OPJ_BOOL opj_j2k_destroy_header_memory ( opj_j2k_t * p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_init_info( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_init_info( opj_j2k_t *p_j2k, struct opj_stream_private *p_stream, struct opj_event_mgr * p_manager ) { |