X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libopenjpeg%2Fj2k.c;h=509b627fadb44f3a91b2de1b79e70898884a83a3;hb=71e0106846294256faa3df75429e0a9ecd163233;hp=98a1a106a261f9a19626eb317cdbf919d94d3171;hpb=6965e3e03cd58c5a485dab576298fbfdb9aad7c9;p=openjpeg.git diff --git a/libopenjpeg/j2k.c b/libopenjpeg/j2k.c index 98a1a106..509b627f 100644 --- a/libopenjpeg/j2k.c +++ b/libopenjpeg/j2k.c @@ -8,7 +8,7 @@ * Copyright (c) 2008, Jerome Fimes, Communications & Systemes * Copyright (c) 2006-2007, Parvatha Elangovan * Copyright (c) 2010-2011, Kaori Hagihara - * Copyright (c) 2011, Mickael Savinaud, Communications & Systemes + * Copyright (c) 2011-2012, Mickael Savinaud, Communications & Systemes * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -49,23 +49,22 @@ void j2k_setup_header_reading (opj_j2k_v2_t *p_j2k); /** * The read header procedure. */ -opj_bool j2k_read_header_procedure( - opj_j2k_v2_t *p_j2k, - struct opj_stream_private *p_stream, - struct opj_event_mgr * p_manager); +static opj_bool j2k_read_header_procedure( opj_j2k_v2_t *p_j2k, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager); /** * The default encoding validation procedure without any extension. * * @param p_j2k the jpeg2000 codec to validate. - * @param p_stream the input stream to validate. + * @param p_stream the input stream to validate. * @param p_manager the user event manager. * * @return true if the parameters are correct. */ -opj_bool j2k_encoding_validation ( opj_j2k_v2_t * p_j2k, - opj_stream_private_t *p_stream, - opj_event_mgr_t * p_manager ); +static opj_bool j2k_encoding_validation ( opj_j2k_v2_t * p_j2k, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager ); /** * The default decoding validation procedure without any extension. @@ -76,11 +75,9 @@ opj_bool j2k_encoding_validation ( opj_j2k_v2_t * p_j2k, * * @return true if the parameters are correct. */ -opj_bool j2k_decoding_validation ( - opj_j2k_v2_t * p_j2k, - opj_stream_private_t *p_stream, - opj_event_mgr_t * p_manager - ); +static opj_bool j2k_decoding_validation ( opj_j2k_v2_t * p_j2k, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager ); /** * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters @@ -109,29 +106,29 @@ static void j2k_setup_end_compress (opj_j2k_v2_t *p_j2k); * * @return true if the parameters are correct. */ -opj_bool j2k_mct_validation ( opj_j2k_v2_t * p_j2k, - opj_stream_private_t *p_stream, - opj_event_mgr_t * p_manager ); +static opj_bool j2k_mct_validation (opj_j2k_v2_t * p_j2k, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager ); /** * Builds the tcd decoder to use to decode tile. */ -opj_bool j2k_build_decoder (opj_j2k_v2_t * p_j2k, - opj_stream_private_t *p_stream, - opj_event_mgr_t * p_manager ); +static opj_bool j2k_build_decoder ( opj_j2k_v2_t * p_j2k, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager ); /** * Builds the tcd encoder to use to encode tile. */ -opj_bool j2k_build_encoder (opj_j2k_v2_t * p_j2k, - opj_stream_private_t *p_stream, - opj_event_mgr_t * p_manager ); +static opj_bool j2k_build_encoder ( opj_j2k_v2_t * p_j2k, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager ); /** * Creates a tile-coder decoder. * - * @param p_stream the stream to write data to. + * @param p_stream the stream to write data to. * @param p_j2k J2K codec. - * @param p_manager the user event manager. + * @param p_manager the user event manager. */ static opj_bool j2k_create_tcd( opj_j2k_v2_t *p_j2k, struct opj_stream_private *p_stream, @@ -141,18 +138,16 @@ static opj_bool j2k_create_tcd( opj_j2k_v2_t *p_j2k, * Excutes the given procedures on the given codec. * * @param p_procedure_list the list of procedures to execute - * @param p_j2k the jpeg2000 codec to execute the procedures on. - * @param p_stream the stream to execute the procedures on. + * @param p_j2k the jpeg2000 codec to execute the procedures on. + * @param p_stream the stream to execute the procedures on. * @param p_manager the user manager. * * @return true if all the procedures were successfully executed. */ -static opj_bool j2k_exec ( - opj_j2k_v2_t * p_j2k, - opj_procedure_list_t * p_procedure_list, - opj_stream_private_t *p_stream, - opj_event_mgr_t * p_manager - ); +static opj_bool j2k_exec ( opj_j2k_v2_t * p_j2k, + opj_procedure_list_t * p_procedure_list, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager); /** * Updates the rates of the tcp. @@ -162,23 +157,23 @@ static opj_bool j2k_exec ( * @param p_manager the user event manager. */ static opj_bool j2k_update_rates( opj_j2k_v2_t *p_j2k, - struct opj_stream_private *p_stream, - struct opj_event_mgr * p_manager ); + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager ); /** * Copies the decoding tile parameters onto all the tile parameters. * Creates also the tile decoder. */ -opj_bool j2k_copy_default_tcp_and_create_tcd ( opj_j2k_v2_t * p_j2k, - opj_stream_private_t *p_stream, - opj_event_mgr_t * p_manager ); +static opj_bool j2k_copy_default_tcp_and_create_tcd ( opj_j2k_v2_t * p_j2k, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager ); /** * Destroys the memory associated with the decoding of headers. */ -opj_bool j2k_destroy_header_memory (opj_j2k_v2_t * p_j2k, - opj_stream_private_t *p_stream, - opj_event_mgr_t * p_manager ); +static opj_bool j2k_destroy_header_memory ( opj_j2k_v2_t * p_j2k, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager ); /** * Reads the lookup table containing all the marker, status and action, and returns the handler associated @@ -247,13 +242,11 @@ static OPJ_UINT32 j2k_get_SPCod_SPCoc_size (opj_j2k_v2_t *p_j2k, * @param p_header_size the size of the data contained in the COM marker. * @param p_manager the user event manager. */ -static opj_bool j2k_read_SPCod_SPCoc( - opj_j2k_v2_t *p_j2k, - OPJ_UINT32 compno, - OPJ_BYTE * p_header_data, - OPJ_UINT32 * p_header_size, - struct opj_event_mgr * p_manager - ); +static opj_bool j2k_read_SPCod_SPCoc( opj_j2k_v2_t *p_j2k, + OPJ_UINT32 compno, + OPJ_BYTE * p_header_data, + OPJ_UINT32 * p_header_size, + opj_event_mgr_t * p_manager ); /** * Gets the size taken by writing SQcd or SQcc element, i.e. the quantization values of a band in the QCD or QCC. @@ -284,8 +277,7 @@ static opj_bool j2k_write_SQcd_SQcc(opj_j2k_v2_t *p_j2k, OPJ_UINT32 p_comp_no, OPJ_BYTE * p_data, OPJ_UINT32 * p_header_size, - struct opj_event_mgr * p_manager - ); + opj_event_mgr_t * p_manager); /** * Updates the Tile Length Marker. @@ -303,38 +295,32 @@ static void j2k_update_tlm ( opj_j2k_v2_t * p_j2k, OPJ_UINT32 p_tile_part_size); * @param p_manager the user event manager. * */ -static opj_bool j2k_read_SQcd_SQcc( - opj_j2k_v2_t *p_j2k, - OPJ_UINT32 compno, - OPJ_BYTE * p_header_data, - OPJ_UINT32 * p_header_size, - struct opj_event_mgr * p_manager - ); +static opj_bool j2k_read_SQcd_SQcc( opj_j2k_v2_t *p_j2k, + OPJ_UINT32 compno, + OPJ_BYTE * p_header_data, + OPJ_UINT32 * p_header_size, + opj_event_mgr_t * p_manager ); /** * Copies the tile component parameters of all the component from the first tile component. * * @param p_j2k the J2k codec. */ -static void j2k_copy_tile_component_parameters( - opj_j2k_v2_t *p_j2k - ); +static void j2k_copy_tile_component_parameters( opj_j2k_v2_t *p_j2k ); /** * Copies the tile quantization parameters of all the component from the first tile component. * * @param p_j2k the J2k codec. */ -static void j2k_copy_tile_quantization_parameters( - opj_j2k_v2_t *p_j2k - ); +static void j2k_copy_tile_quantization_parameters( opj_j2k_v2_t *p_j2k ); /** * Reads the tiles. */ -opj_bool j2k_decode_tiles ( opj_j2k_v2_t *p_j2k, - opj_stream_private_t *p_stream, - opj_event_mgr_t * p_manager); +static opj_bool j2k_decode_tiles ( opj_j2k_v2_t *p_j2k, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager); static opj_bool j2k_pre_write_tile ( opj_j2k_v2_t * p_j2k, @@ -356,7 +342,7 @@ static opj_bool j2k_post_write_tile (opj_j2k_v2_t * p_j2k, * Sets up the procedures to do on writing header. * Developers wanting to extend the library can add their own writing procedures. */ -void j2k_setup_header_writting (opj_j2k_v2_t *p_j2k); +static void j2k_setup_header_writting (opj_j2k_v2_t *p_j2k); static opj_bool j2k_write_first_tile_part( opj_j2k_v2_t *p_j2k, OPJ_BYTE * p_data, @@ -4582,7 +4568,7 @@ opj_bool j2k_read_plt_v2 ( assert(p_manager != 00); if (p_header_size < 1) { - opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading PLM marker\n"); + opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading PLT marker\n"); return OPJ_FALSE; } @@ -4605,7 +4591,7 @@ opj_bool j2k_read_plt_v2 ( } if (l_packet_len != 0) { - opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading PLM marker\n"); + opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading PLT marker\n"); return OPJ_FALSE; } @@ -5240,7 +5226,7 @@ static void j2k_read_sot(opj_j2k_t *j2k) { static int backup_tileno = 0; /* tileno is negative or larger than the number of tiles!!! */ - if ((tileno < 0) || (tileno > (cp->tw * cp->th))) { + if ((tileno < 0) || (tileno >= (cp->tw * cp->th))) { opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: bad tile number (%d out of a maximum of %d)\n", tileno, (cp->tw * cp->th)); @@ -5257,8 +5243,18 @@ static void j2k_read_sot(opj_j2k_t *j2k) { /* keep your private count of tiles */ backup_tileno++; - }; + } + else #endif /* USE_JPWL */ + { + /* tileno is negative or larger than the number of tiles!!! */ + if ((tileno < 0) || (tileno >= (cp->tw * cp->th))) { + opj_event_msg(j2k->cinfo, EVT_ERROR, + "JPWL: bad tile number (%d out of a maximum of %d)\n", + tileno, (cp->tw * cp->th)); + return; + } + } if (cp->tileno_size == 0) { cp->tileno[cp->tileno_size] = tileno; @@ -5297,8 +5293,18 @@ static void j2k_read_sot(opj_j2k_t *j2k) { totlen); } - }; + } + else #endif /* USE_JPWL */ + { + /* totlen is negative or larger than the bytes left!!! */ + if ((totlen < 0) || (totlen > (cio_numbytesleft(cio) + 8))) { + opj_event_msg(j2k->cinfo, EVT_ERROR, + "JPWL: bad tile byte size (%d bytes against %d bytes left)\n", + totlen, cio_numbytesleft(cio) + 8); + return; + } + } if (!totlen) totlen = cio_numbytesleft(cio) + 8; @@ -5520,6 +5526,7 @@ opj_bool j2k_read_sot_v2 ( /* Index */ if (p_j2k->cstr_index) { + assert(p_j2k->cstr_index->tile_index != 00); p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tileno = p_j2k->m_current_tile_number; p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_tpsno = l_current_part; @@ -6033,7 +6040,9 @@ opj_bool j2k_write_eoc_v2( opj_j2k_v2_t *p_j2k, /* UniPG>> */ #ifdef USE_JPWL /* update markers struct */ + /* j2k_add_marker(p_j2k->cstr_info, J2K_MS_EOC, p_stream_tell(p_stream) - 2, 2); +*/ #endif /* USE_JPWL */ if ( opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,2,p_manager) != 2) { @@ -6303,7 +6312,7 @@ opj_bool j2k_update_rates( opj_j2k_v2_t *p_j2k, static void j2k_read_eoc(opj_j2k_t *j2k) { int i, tileno; - opj_bool success; + opj_bool success = OPJ_FALSE; /* if packets should be decoded */ if (j2k->cp->limit_decoding != DECODE_ALL_BUT_PACKETS) { @@ -6311,11 +6320,16 @@ static void j2k_read_eoc(opj_j2k_t *j2k) { tcd_malloc_decode(tcd, j2k->image, j2k->cp); for (i = 0; i < j2k->cp->tileno_size; i++) { tcd_malloc_decode_tile(tcd, j2k->image, j2k->cp, i, j2k->cstr_info); - tileno = j2k->cp->tileno[i]; - success = tcd_decode_tile(tcd, j2k->tile_data[tileno], j2k->tile_len[tileno], tileno, j2k->cstr_info); - opj_free(j2k->tile_data[tileno]); - j2k->tile_data[tileno] = NULL; - tcd_free_decode_tile(tcd, i); + if (j2k->cp->tileno[i] != -1) + { + tileno = j2k->cp->tileno[i]; + success = tcd_decode_tile(tcd, j2k->tile_data[tileno], j2k->tile_len[tileno], tileno, j2k->cstr_info); + opj_free(j2k->tile_data[tileno]); + j2k->tile_data[tileno] = NULL; + tcd_free_decode_tile(tcd, i); + } + else + success = OPJ_FALSE; if (success == OPJ_FALSE) { j2k->state |= J2K_STATE_ERR; break; @@ -7610,22 +7624,7 @@ opj_bool j2k_read_cbd ( opj_j2k_v2_t *p_j2k, /* J2K / JPT decoder interface */ /* ----------------------------------------------------------------------- */ -opj_j2k_t* j2k_create_decompress(opj_common_ptr cinfo) { - opj_j2k_t *j2k = (opj_j2k_t*) opj_calloc(1, sizeof(opj_j2k_t)); - if(!j2k) - return NULL; - j2k->default_tcp = (opj_tcp_t*) opj_calloc(1, sizeof(opj_tcp_t)); - if(!j2k->default_tcp) { - opj_free(j2k); - return NULL; - } - - j2k->cinfo = cinfo; - j2k->tile_data = NULL; - - return j2k; -} void j2k_destroy_decompress(opj_j2k_t *j2k) { int i = 0; @@ -7674,27 +7673,8 @@ void j2k_destroy_decompress(opj_j2k_t *j2k) { opj_free(j2k); } -void j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters) { - if(j2k && parameters) { - /* create and initialize the coding parameters structure */ - opj_cp_t *cp = (opj_cp_t*) opj_calloc(1, sizeof(opj_cp_t)); - cp->reduce = parameters->cp_reduce; - cp->layer = parameters->cp_layer; - cp->limit_decoding = parameters->cp_limit_decoding; - -#ifdef USE_JPWL - cp->correct = parameters->jpwl_correct; - cp->exp_comps = parameters->jpwl_exp_comps; - cp->max_tiles = parameters->jpwl_max_tiles; -#endif /* USE_JPWL */ - - - /* keep a link to cp so that we can destroy it later in j2k_destroy_decompress */ - j2k->cp = cp; - } -} -void j2k_setup_decoder_v2(opj_j2k_v2_t *j2k, opj_dparameters_t *parameters) +void opj_j2k_setup_decoder(opj_j2k_v2_t *j2k, opj_dparameters_t *parameters) { if(j2k && parameters) { j2k->m_cp.m_specific_param.m_dec.m_layer = parameters->cp_layer; @@ -8923,6 +8903,10 @@ opj_bool j2k_read_header( struct opj_stream_private *p_stream, /* Copy codestream image information to the output image */ opj_copy_image_header(p_j2k->m_private_image, *p_image); + /*Allocate and initialize some elements of codestrem index*/ + if (!j2k_allocate_tile_element_cstr_index(p_j2k)){ + return OPJ_FALSE; + } return OPJ_TRUE; } @@ -10524,7 +10508,7 @@ opj_bool j2k_set_decode_area( opj_j2k_v2_t *p_j2k, * * @return a handle to a J2K decompressor if successful, NULL otherwise. */ -opj_j2k_v2_t* j2k_create_decompress_v2(void) +opj_j2k_v2_t* opj_j2k_create_decompress(void) { opj_j2k_v2_t *l_j2k = (opj_j2k_v2_t*) opj_malloc(sizeof(opj_j2k_v2_t)); if (!l_j2k) { @@ -11232,33 +11216,43 @@ void j2k_dump_MH_index(opj_j2k_v2_t* p_j2k, FILE* out_stream) if (cstr_index->tile_index){ - fprintf(out_stream, "\t Tile index: {\n"); - - for (it_tile=0; it_tile < cstr_index->nb_of_tiles ; it_tile++){ - OPJ_UINT32 nb_of_tile_part = cstr_index->tile_index[it_tile].nb_tps; - fprintf(out_stream, "\t\t nb of tile-part in tile [%d]=%d\n", it_tile, nb_of_tile_part); - - if (cstr_index->tile_index[it_tile].tp_index){ - for (it_tile_part =0; it_tile_part < nb_of_tile_part; it_tile_part++){ - fprintf(out_stream, "\t\t\t tile-part[%d]: star_pos=%" PRIi64 ", end_header=%" PRIi64 ", end_pos=%" PRIi64 ".\n", - it_tile_part, - cstr_index->tile_index[it_tile].tp_index[it_tile_part].start_pos, - cstr_index->tile_index[it_tile].tp_index[it_tile_part].end_header, - cstr_index->tile_index[it_tile].tp_index[it_tile_part].end_pos); - } - } - - if (cstr_index->tile_index[it_tile].marker){ - for (it_marker=0; it_marker < cstr_index->tile_index[it_tile].marknum ; it_marker++){ - fprintf(out_stream, "\t\t type=%#x, pos=%" PRIi64 ", len=%d\n", - cstr_index->tile_index[it_tile].marker[it_marker].type, - cstr_index->tile_index[it_tile].marker[it_marker].pos, - cstr_index->tile_index[it_tile].marker[it_marker].len ); - } - } - } - fprintf(out_stream,"\t }\n"); + /* Simple test to avoid to write empty information*/ + OPJ_UINT32 l_acc_nb_of_tile_part = 0; + for (it_tile=0; it_tile < cstr_index->nb_of_tiles ; it_tile++){ + l_acc_nb_of_tile_part += cstr_index->tile_index[it_tile].nb_tps; + } + + if (l_acc_nb_of_tile_part) + { + fprintf(out_stream, "\t Tile index: {\n"); + + for (it_tile=0; it_tile < cstr_index->nb_of_tiles ; it_tile++){ + OPJ_UINT32 nb_of_tile_part = cstr_index->tile_index[it_tile].nb_tps; + + fprintf(out_stream, "\t\t nb of tile-part in tile [%d]=%d\n", it_tile, nb_of_tile_part); + + if (cstr_index->tile_index[it_tile].tp_index){ + for (it_tile_part =0; it_tile_part < nb_of_tile_part; it_tile_part++){ + fprintf(out_stream, "\t\t\t tile-part[%d]: star_pos=%" PRIi64 ", end_header=%" PRIi64 ", end_pos=%" PRIi64 ".\n", + it_tile_part, + cstr_index->tile_index[it_tile].tp_index[it_tile_part].start_pos, + cstr_index->tile_index[it_tile].tp_index[it_tile_part].end_header, + cstr_index->tile_index[it_tile].tp_index[it_tile_part].end_pos); + } + } + + if (cstr_index->tile_index[it_tile].marker){ + for (it_marker=0; it_marker < cstr_index->tile_index[it_tile].marknum ; it_marker++){ + fprintf(out_stream, "\t\t type=%#x, pos=%" PRIi64 ", len=%d\n", + cstr_index->tile_index[it_tile].marker[it_marker].type, + cstr_index->tile_index[it_tile].marker[it_marker].pos, + cstr_index->tile_index[it_tile].marker[it_marker].len ); + } + } + } + fprintf(out_stream,"\t }\n"); + } } fprintf(out_stream,"}\n"); @@ -11630,11 +11624,7 @@ opj_bool j2k_decode_tiles ( opj_j2k_v2_t *p_j2k, } l_max_data_size = 1000; - /*Allocate and initialize some elements of codestrem index*/ - if (!j2k_allocate_tile_element_cstr_index(p_j2k)){ - opj_free(l_current_data); - return OPJ_FALSE; - } + while (OPJ_TRUE) { if (! j2k_read_tile_header( p_j2k, @@ -11795,7 +11785,7 @@ static opj_bool j2k_decode_one_tile ( opj_j2k_v2_t *p_j2k, if(l_current_tile_no == l_tile_no_to_dec) { /* 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) ) { + if (!(opj_stream_read_seek(p_stream, p_j2k->cstr_index->main_head_end + 2, p_manager) ) ) { opj_event_msg_v2(p_manager, EVT_ERROR, "Problem with seek function\n"); return OPJ_FALSE; } @@ -12290,7 +12280,7 @@ opj_bool j2k_post_write_tile ( opj_j2k_v2_t * p_j2k, l_current_data = p_j2k->m_specific_param.m_encoder.m_encoded_tile_data; if (! tcd_copy_tile_data(l_tcd,p_data,p_data_size)) { - opj_event_msg_v2(p_manager, EVT_ERROR, "Size mismtach between tile data and sent data." ); + opj_event_msg_v2(p_manager, EVT_ERROR, "Size mismatch between tile data and sent data." ); return OPJ_FALSE; }