X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fopenjp2%2Fj2k.c;h=68b2f82e540408623217c942e953d1f3b1320d09;hb=d4b7f03cfa4732132767188782683f3d957da912;hp=da06f36eb1087c889ec8bccd6a323998980cc9b4;hpb=99c4f621bd32ddfec25cb126d4d462642e9d43a6;p=openjpeg.git diff --git a/src/lib/openjp2/j2k.c b/src/lib/openjp2/j2k.c index da06f36e..68b2f82e 100644 --- a/src/lib/openjp2/j2k.c +++ b/src/lib/openjp2/j2k.c @@ -212,6 +212,18 @@ static void opj_j2k_tcp_data_destroy (opj_tcp_t *p_tcp); */ static void opj_j2k_cp_destroy (opj_cp_t *p_cp); +/** + * Compare 2 a SPCod/ SPCoc elements, i.e. the coding style of a given component of a tile. + * + * @param p_j2k J2K codec. + * @param p_tile_no Tile number + * @param p_first_comp_no The 1st component number to compare. + * @param p_second_comp_no The 1st component number to compare. + * + * @return OPJ_TRUE if SPCdod are equals. + */ +static OPJ_BOOL opj_j2k_compare_SPCod_SPCoc(opj_j2k_t *p_j2k, OPJ_UINT32 p_tile_no, OPJ_UINT32 p_first_comp_no, OPJ_UINT32 p_second_comp_no); + /** * Writes a SPCod or SPCoc element, i.e. the coding style of a given component of a tile. * @@ -271,6 +283,19 @@ static OPJ_UINT32 opj_j2k_get_SQcd_SQcc_size ( opj_j2k_t *p_j2k, OPJ_UINT32 p_tile_no, OPJ_UINT32 p_comp_no ); +/** + * Compares 2 SQcd or SQcc element, i.e. the quantization values of a band in the QCD or QCC. + * + * @param p_j2k J2K codec. + * @param p_tile_no the tile to output. + * @param p_first_comp_no the first component number to compare. + * @param p_second_comp_no the second component number to compare. + * + * @return OPJ_TRUE if equals. + */ +static OPJ_BOOL opj_j2k_compare_SQcd_SQcc(opj_j2k_t *p_j2k, OPJ_UINT32 p_tile_no, OPJ_UINT32 p_first_comp_no, OPJ_UINT32 p_second_comp_no); + + /** * Writes a SQcd or SQcc element, i.e. the quantization values of a band in the QCD or QCC. * @@ -484,7 +509,17 @@ static OPJ_BOOL opj_j2k_read_cod ( opj_j2k_t *p_j2k, OPJ_UINT32 p_header_size, opj_event_mgr_t * p_manager); -#if 0 +/** + * Compares 2 COC markers (Coding style component) + * + * @param p_j2k J2K codec. + * @param p_first_comp_no the index of the first component to compare. + * @param p_second_comp_no the index of the second component to compare. + * + * @return OPJ_TRUE if equals + */ +static OPJ_BOOL opj_j2k_compare_coc(opj_j2k_t *p_j2k, OPJ_UINT32 p_first_comp_no, OPJ_UINT32 p_second_comp_no); + /** * Writes the COC marker (Coding style component) * @@ -497,9 +532,7 @@ 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 ); -#endif -#if 0 /** * Writes the COC marker (Coding style component) * @@ -514,7 +547,6 @@ static void opj_j2k_write_coc_in_memory(opj_j2k_t *p_j2k, OPJ_BYTE * p_data, OPJ_UINT32 * p_data_written, opj_event_mgr_t * p_manager ); -#endif /** * Gets the maximum size taken by a coc. @@ -557,7 +589,18 @@ static OPJ_BOOL opj_j2k_read_qcd ( opj_j2k_t *p_j2k, OPJ_BYTE * p_header_data, OPJ_UINT32 p_header_size, opj_event_mgr_t * p_manager ); -#if 0 + +/** + * Compare QCC markers (quantization component) + * + * @param p_j2k J2K codec. + * @param p_first_comp_no the index of the first component to compare. + * @param p_second_comp_no the index of the second component to compare. + * + * @return OPJ_TRUE if equals. + */ +static OPJ_BOOL opj_j2k_compare_qcc(opj_j2k_t *p_j2k, OPJ_UINT32 p_first_comp_no, OPJ_UINT32 p_second_comp_no); + /** * Writes the QCC marker (quantization component) * @@ -570,9 +613,7 @@ 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 ); -#endif -#if 0 /** * Writes the QCC marker (quantization component) * @@ -587,7 +628,6 @@ static void opj_j2k_write_qcc_in_memory(opj_j2k_t *p_j2k, OPJ_BYTE * p_data, OPJ_UINT32 * p_data_written, opj_event_mgr_t * p_manager ); -#endif /** * Gets the maximum size taken by a qcc. @@ -1097,7 +1137,7 @@ static OPJ_BOOL opj_j2k_read_cbd ( opj_j2k_t *p_j2k, OPJ_UINT32 p_header_size, opj_event_mgr_t * p_manager); -#if 0 + /** * Writes COC marker for each component. * @@ -1108,9 +1148,7 @@ static OPJ_BOOL opj_j2k_read_cbd ( opj_j2k_t *p_j2k, static OPJ_BOOL opj_j2k_write_all_coc( opj_j2k_t *p_j2k, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ); -#endif -#if 0 /** * Writes QCC marker for each component. * @@ -1121,7 +1159,6 @@ static OPJ_BOOL opj_j2k_write_all_coc( opj_j2k_t *p_j2k, static OPJ_BOOL opj_j2k_write_all_qcc( opj_j2k_t *p_j2k, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ); -#endif /** * Writes regions of interests. @@ -2026,17 +2063,17 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k, /* testcase 4035.pdf.SIGSEGV.d8b.3375 */ /* testcase issue427-null-image-size.jp2 */ if ((l_image->x0 >= l_image->x1) || (l_image->y0 >= l_image->y1)) { - opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker: negative or zero image size (%d x %d)\n", l_image->x1 - l_image->x0, l_image->y1 - l_image->y0); + opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker: negative or zero image size (%" PRId64 " x %" PRId64 ")\n", (OPJ_INT64)l_image->x1 - l_image->x0, (OPJ_INT64)l_image->y1 - l_image->y0); return OPJ_FALSE; } /* testcase 2539.pdf.SIGFPE.706.1712 (also 3622.pdf.SIGFPE.706.2916 and 4008.pdf.SIGFPE.706.3345 and maybe more) */ - if (!(l_cp->tdx * l_cp->tdy)) { + if ((l_cp->tdx == 0U) || (l_cp->tdy == 0U)) { opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker: invalid tile size (tdx: %d, tdy: %d)\n", l_cp->tdx, l_cp->tdy); return OPJ_FALSE; } /* testcase 1610.pdf.SIGSEGV.59c.681 */ - if (((OPJ_UINT64)l_image->x1) * ((OPJ_UINT64)l_image->y1) != (l_image->x1 * l_image->y1)) { + if ((0xFFFFFFFFU / l_image->x1) < l_image->y1) { opj_event_msg(p_manager, EVT_ERROR, "Prevent buffer overflow (x1: %d, y1: %d)\n", l_image->x1, l_image->y1); return OPJ_FALSE; } @@ -2057,7 +2094,7 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k, opj_event_msg(p_manager, EVT_ERROR, "JPWL: bad image size (%d x %d)\n", l_image->x1, l_image->y1); - if (!JPWL_ASSUME || JPWL_ASSUME) { + if (!JPWL_ASSUME) { opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n"); return OPJ_FALSE; } @@ -2117,10 +2154,16 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k, if( l_img_comp->dx < 1 || l_img_comp->dx > 255 || l_img_comp->dy < 1 || l_img_comp->dy > 255 ) { opj_event_msg(p_manager, EVT_ERROR, - "Invalid values for comp = %d : dx=%u dy=%u\n (should be between 1 and 255 according the JPEG2000 norm)", + "Invalid values for comp = %d : dx=%u dy=%u (should be between 1 and 255 according to the JPEG2000 norm)\n", i, l_img_comp->dx, l_img_comp->dy); return OPJ_FALSE; } + if( l_img_comp->prec > 38) { /* TODO openjpeg won't handle more than ? */ + opj_event_msg(p_manager, EVT_ERROR, + "Invalid values for comp = %d : prec=%u (should be between 1 and 38 according to the JPEG2000 norm)\n", + i, l_img_comp->prec); + return OPJ_FALSE; + } #ifdef USE_JPWL if (l_cp->correct) { @@ -2233,7 +2276,7 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k, if (!l_cp->tcps) { opj_event_msg(p_manager, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR, "JPWL: could not alloc tcps field of cp\n"); - if (!JPWL_ASSUME || JPWL_ASSUME) { + if (!JPWL_ASSUME) { opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n"); return OPJ_FALSE; } @@ -2399,22 +2442,22 @@ static OPJ_BOOL opj_j2k_write_cod( opj_j2k_t *p_j2k, l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data; - opj_write_bytes(l_current_data,J2K_MS_COD,2); /* COD */ + opj_write_bytes(l_current_data,J2K_MS_COD,2); /* COD */ l_current_data += 2; - opj_write_bytes(l_current_data,l_code_size-2,2); /* L_COD */ + opj_write_bytes(l_current_data,l_code_size-2,2); /* L_COD */ l_current_data += 2; - opj_write_bytes(l_current_data,l_tcp->csty,1); /* Scod */ + opj_write_bytes(l_current_data,l_tcp->csty,1); /* Scod */ ++l_current_data; - opj_write_bytes(l_current_data,l_tcp->prg,1); /* SGcod (A) */ + opj_write_bytes(l_current_data,(OPJ_UINT32)l_tcp->prg,1); /* SGcod (A) */ ++l_current_data; - opj_write_bytes(l_current_data,l_tcp->numlayers,2); /* SGcod (B) */ + opj_write_bytes(l_current_data,l_tcp->numlayers,2); /* SGcod (B) */ l_current_data+=2; - opj_write_bytes(l_current_data,l_tcp->mct,1); /* SGcod (C) */ + opj_write_bytes(l_current_data,l_tcp->mct,1); /* SGcod (C) */ ++l_current_data; l_remaining_size -= 9; @@ -2541,6 +2584,9 @@ static OPJ_BOOL opj_j2k_read_cod ( opj_j2k_t *p_j2k, p_j2k->cstr_info->prog = l_tcp->prg; p_j2k->cstr_info->numlayers = l_tcp->numlayers; p_j2k->cstr_info->numdecompos = (OPJ_INT32*) opj_malloc(l_image->numcomps * sizeof(OPJ_UINT32)); + if(!p_j2k->cstr_info->numdecompos){ + return OPJ_FALSE; + } for (i = 0; i < l_image->numcomps; ++i) { p_j2k->cstr_info->numdecompos[i] = l_tcp->tccps[i].numresolutions - 1; } @@ -2550,7 +2596,6 @@ static OPJ_BOOL opj_j2k_read_cod ( opj_j2k_t *p_j2k, return OPJ_TRUE; } -#if 0 static OPJ_BOOL opj_j2k_write_coc( opj_j2k_t *p_j2k, OPJ_UINT32 p_comp_no, opj_stream_private_t *p_stream, @@ -2595,9 +2640,26 @@ static OPJ_BOOL opj_j2k_write_coc( opj_j2k_t *p_j2k, return OPJ_TRUE; } -#endif -#if 0 +static OPJ_BOOL opj_j2k_compare_coc(opj_j2k_t *p_j2k, OPJ_UINT32 p_first_comp_no, OPJ_UINT32 p_second_comp_no) +{ + opj_cp_t *l_cp = NULL; + opj_tcp_t *l_tcp = NULL; + + /* preconditions */ + assert(p_j2k != 00); + + l_cp = &(p_j2k->m_cp); + l_tcp = &l_cp->tcps[p_j2k->m_current_tile_number]; + + if (l_tcp->tccps[p_first_comp_no].csty != l_tcp->tccps[p_second_comp_no].csty) { + return OPJ_FALSE; + } + + + return opj_j2k_compare_SPCod_SPCoc(p_j2k, p_j2k->m_current_tile_number, p_first_comp_no, p_second_comp_no); +} + static void opj_j2k_write_coc_in_memory( opj_j2k_t *p_j2k, OPJ_UINT32 p_comp_no, OPJ_BYTE * p_data, @@ -2642,7 +2704,6 @@ static void opj_j2k_write_coc_in_memory( opj_j2k_t *p_j2k, opj_j2k_write_SPCod_SPCoc(p_j2k,p_j2k->m_current_tile_number,0,l_current_data,&l_remaining_size,p_manager); * p_data_written = l_coc_size; } -#endif static OPJ_UINT32 opj_j2k_get_max_coc_size(opj_j2k_t *p_j2k) { @@ -2816,7 +2877,6 @@ static OPJ_BOOL opj_j2k_read_qcd ( opj_j2k_t *p_j2k, return OPJ_TRUE; } -#if 0 static OPJ_BOOL opj_j2k_write_qcc( opj_j2k_t *p_j2k, OPJ_UINT32 p_comp_no, opj_stream_private_t *p_stream, @@ -2855,9 +2915,12 @@ static OPJ_BOOL opj_j2k_write_qcc( opj_j2k_t *p_j2k, return OPJ_TRUE; } -#endif -#if 0 +static OPJ_BOOL opj_j2k_compare_qcc(opj_j2k_t *p_j2k, OPJ_UINT32 p_first_comp_no, OPJ_UINT32 p_second_comp_no) +{ + return opj_j2k_compare_SQcd_SQcc(p_j2k,p_j2k->m_current_tile_number,p_first_comp_no, p_second_comp_no); +} + static void opj_j2k_write_qcc_in_memory( opj_j2k_t *p_j2k, OPJ_UINT32 p_comp_no, OPJ_BYTE * p_data, @@ -2906,7 +2969,6 @@ static void opj_j2k_write_qcc_in_memory( opj_j2k_t *p_j2k, *p_data_written = l_qcc_size; } -#endif static OPJ_UINT32 opj_j2k_get_max_qcc_size (opj_j2k_t *p_j2k) { @@ -3112,7 +3174,7 @@ static void opj_j2k_write_poc_in_memory( opj_j2k_t *p_j2k, opj_write_bytes(l_current_data,l_current_poc->compno1,l_poc_room); /* CEpoc_i */ l_current_data+=l_poc_room; - opj_write_bytes(l_current_data,l_current_poc->prg,1); /* Ppoc_i */ + opj_write_bytes(l_current_data, (OPJ_UINT32)l_current_poc->prg,1); /* Ppoc_i */ ++l_current_data; /* change the value of the max layer according to the actual number of layers in the file, components and resolutions*/ @@ -4568,7 +4630,7 @@ static OPJ_BOOL opj_j2k_read_rgn (opj_j2k_t *p_j2k, opj_event_msg(p_manager, EVT_ERROR, "JPWL: bad component number in RGN (%d when there are only %d)\n", l_comp_room, l_nb_comp); - if (!JPWL_ASSUME || JPWL_ASSUME) { + if (!JPWL_ASSUME) { opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n"); return OPJ_FALSE; } @@ -4653,7 +4715,7 @@ static OPJ_BOOL opj_j2k_update_rates( opj_j2k_t *p_j2k, l_rates = l_tcp->rates; /* Modification of the RATE >> */ - if (*l_rates) { + if (*l_rates > 0.0f) { *l_rates = (( (OPJ_FLOAT32) (l_size_pixel * (OPJ_UINT32)(l_x1 - l_x0) * (OPJ_UINT32)(l_y1 - l_y0))) / ((*l_rates) * (OPJ_FLOAT32)l_bits_empty) @@ -4665,7 +4727,7 @@ static OPJ_BOOL opj_j2k_update_rates( opj_j2k_t *p_j2k, ++l_rates; for (k = 1; k < l_tcp->numlayers; ++k) { - if (*l_rates) { + if (*l_rates > 0.0f) { *l_rates = (( (OPJ_FLOAT32) (l_size_pixel * (OPJ_UINT32)(l_x1 - l_x0) * (OPJ_UINT32)(l_y1 - l_y0))) / ((*l_rates) * (OPJ_FLOAT32)l_bits_empty) @@ -4688,11 +4750,11 @@ static OPJ_BOOL opj_j2k_update_rates( opj_j2k_t *p_j2k, for (j=0;jtw;++j) { l_rates = l_tcp->rates; - if (*l_rates) { + if (*l_rates > 0.0f) { *l_rates -= l_sot_remove; - if (*l_rates < 30) { - *l_rates = 30; + if (*l_rates < 30.0f) { + *l_rates = 30.0f; } } @@ -4702,22 +4764,22 @@ static OPJ_BOOL opj_j2k_update_rates( opj_j2k_t *p_j2k, for (k = 1; k < l_last_res; ++k) { - if (*l_rates) { + if (*l_rates > 0.0f) { *l_rates -= l_sot_remove; - if (*l_rates < *(l_rates - 1) + 10) { - *l_rates = (*(l_rates - 1)) + 20; + if (*l_rates < *(l_rates - 1) + 10.0f) { + *l_rates = (*(l_rates - 1)) + 20.0f; } } ++l_rates; } - if (*l_rates) { + if (*l_rates > 0.0f) { *l_rates -= (l_sot_remove + 2.f); - if (*l_rates < *(l_rates - 1) + 10) { - *l_rates = (*(l_rates - 1)) + 20; + if (*l_rates < *(l_rates - 1) + 10.0f) { + *l_rates = (*(l_rates - 1)) + 20.0f; } } @@ -4877,52 +4939,54 @@ static OPJ_BOOL opj_j2k_write_mct_data_group( opj_j2k_t *p_j2k, return OPJ_TRUE; } -#if 0 -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 ) +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 ) { - OPJ_UINT32 compno; - - /* preconditions */ - assert(p_j2k != 00); - assert(p_manager != 00); - assert(p_stream != 00); - - for (compno = 0; compno < p_j2k->m_private_image->numcomps; ++compno) - { - if (! opj_j2k_write_coc(p_j2k,compno,p_stream, p_manager)) { - return OPJ_FALSE; - } - } - - return OPJ_TRUE; + OPJ_UINT32 compno; + + /* preconditions */ + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); + + for (compno = 1; compno < p_j2k->m_private_image->numcomps; ++compno) + { + /* cod is first component of first tile */ + if (! opj_j2k_compare_coc(p_j2k, 0, compno)) { + if (! opj_j2k_write_coc(p_j2k,compno,p_stream, p_manager)) { + return OPJ_FALSE; + } + } + } + + return OPJ_TRUE; } -#endif -#if 0 -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 ) +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 ) { - OPJ_UINT32 compno; - - /* preconditions */ - assert(p_j2k != 00); - assert(p_manager != 00); - assert(p_stream != 00); - - for (compno = 0; compno < p_j2k->m_private_image->numcomps; ++compno) - { - if (! opj_j2k_write_qcc(p_j2k,compno,p_stream, p_manager)) { - return OPJ_FALSE; - } - } - - return OPJ_TRUE; + OPJ_UINT32 compno; + + /* preconditions */ + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); + + for (compno = 1; compno < p_j2k->m_private_image->numcomps; ++compno) + { + /* qcd is first component of first tile */ + if (! opj_j2k_compare_qcc(p_j2k, 0, compno)) { + if (! opj_j2k_write_qcc(p_j2k,compno,p_stream, p_manager)) { + return OPJ_FALSE; + } + } + } + return OPJ_TRUE; } -#endif - static OPJ_BOOL opj_j2k_write_regions( opj_j2k_t *p_j2k, struct opj_stream_private *p_stream, @@ -5307,7 +5371,7 @@ static OPJ_BOOL opj_j2k_write_mcc_record( opj_j2k_t *p_j2k, l_current_data+=l_nb_bytes_for_comp; } - l_tmcc = ((!p_mcc_record->m_is_irreversible)&1)<<16; + l_tmcc = ((!p_mcc_record->m_is_irreversible) & 1U) << 16; if (p_mcc_record->m_decorrelation_array) { l_tmcc |= p_mcc_record->m_decorrelation_array->m_index; @@ -5880,6 +5944,32 @@ void opj_j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters) } } +OPJ_BOOL opj_j2k_set_threads(opj_j2k_t *j2k, OPJ_UINT32 num_threads) +{ + if( opj_has_thread_support() ) + { + opj_thread_pool_destroy(j2k->m_tp); + j2k->m_tp = opj_thread_pool_create((int)num_threads); + if( j2k->m_tp == 0 ) + { + j2k->m_tp = opj_thread_pool_create(0); + return OPJ_FALSE; + } + return OPJ_TRUE; + } + return OPJ_FALSE; +} + +static int opj_j2k_get_default_thread_count() +{ + const char* num_threads = getenv("OPJ_NUM_THREADS"); + if( num_threads == NULL || !opj_has_thread_support() ) + return 0; + if( strcmp(num_threads, "ALL_CPUS") == 0 ) + return opj_get_num_cpus(); + return atoi(num_threads); +} + /* ----------------------------------------------------------------------- */ /* J2K encoder interface */ /* ----------------------------------------------------------------------- */ @@ -5917,6 +6007,17 @@ opj_j2k_t* opj_j2k_create_compress(void) return NULL; } + l_j2k->m_tp = opj_thread_pool_create(opj_j2k_get_default_thread_count()); + if( !l_j2k->m_tp ) + { + l_j2k->m_tp = opj_thread_pool_create(0); + } + if( !l_j2k->m_tp ) + { + opj_j2k_destroy(l_j2k); + return NULL; + } + return l_j2k; } @@ -7422,7 +7523,7 @@ static OPJ_BOOL opj_j2k_copy_default_tcp_and_create_tcd ( opj_j2k_t * p_j2 return OPJ_FALSE; } - if ( !opj_tcd_init(p_j2k->m_tcd, l_image, &(p_j2k->m_cp)) ) { + if ( !opj_tcd_init(p_j2k->m_tcd, l_image, &(p_j2k->m_cp), p_j2k->m_tp) ) { opj_tcd_destroy(p_j2k->m_tcd); p_j2k->m_tcd = 00; opj_event_msg(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n"); @@ -7503,6 +7604,9 @@ void opj_j2k_destroy (opj_j2k_t *p_j2k) opj_image_destroy(p_j2k->m_output_image); p_j2k->m_output_image = NULL; + opj_thread_pool_destroy(p_j2k->m_tp); + p_j2k->m_tp = NULL; + opj_free(p_j2k); } @@ -8594,6 +8698,17 @@ opj_j2k_t* opj_j2k_create_decompress(void) return 00; } + l_j2k->m_tp = opj_thread_pool_create(opj_j2k_get_default_thread_count()); + if( !l_j2k->m_tp ) + { + l_j2k->m_tp = opj_thread_pool_create(0); + } + if( !l_j2k->m_tp ) + { + opj_j2k_destroy(l_j2k); + return NULL; + } + return l_j2k; } @@ -8645,6 +8760,52 @@ static OPJ_UINT32 opj_j2k_get_SPCod_SPCoc_size ( opj_j2k_t *p_j2k, } } +static OPJ_BOOL opj_j2k_compare_SPCod_SPCoc(opj_j2k_t *p_j2k, OPJ_UINT32 p_tile_no, OPJ_UINT32 p_first_comp_no, OPJ_UINT32 p_second_comp_no) +{ + OPJ_UINT32 i; + opj_cp_t *l_cp = NULL; + opj_tcp_t *l_tcp = NULL; + opj_tccp_t *l_tccp0 = NULL; + opj_tccp_t *l_tccp1 = NULL; + + /* preconditions */ + assert(p_j2k != 00); + + l_cp = &(p_j2k->m_cp); + l_tcp = &l_cp->tcps[p_tile_no]; + l_tccp0 = &l_tcp->tccps[p_first_comp_no]; + l_tccp1 = &l_tcp->tccps[p_second_comp_no]; + + if (l_tccp0->numresolutions != l_tccp1->numresolutions) { + return OPJ_FALSE; + } + if (l_tccp0->cblkw != l_tccp1->cblkw) { + return OPJ_FALSE; + } + if (l_tccp0->cblkh != l_tccp1->cblkh) { + return OPJ_FALSE; + } + if (l_tccp0->cblksty != l_tccp1->cblksty) { + return OPJ_FALSE; + } + if (l_tccp0->qmfbid != l_tccp1->qmfbid) { + return OPJ_FALSE; + } + if ((l_tccp0->csty & J2K_CCP_CSTY_PRT) != (l_tccp1->csty & J2K_CCP_CSTY_PRT)) { + return OPJ_FALSE; + } + + for (i = 0U; i < l_tccp0->numresolutions; ++i) { + if (l_tccp0->prcw[i] != l_tccp1->prcw[i]) { + return OPJ_FALSE; + } + if (l_tccp0->prch[i] != l_tccp1->prch[i]) { + return OPJ_FALSE; + } + } + return OPJ_TRUE; +} + static OPJ_BOOL opj_j2k_write_SPCod_SPCoc( opj_j2k_t *p_j2k, OPJ_UINT32 p_tile_no, OPJ_UINT32 p_comp_no, @@ -8779,6 +8940,10 @@ static OPJ_BOOL opj_j2k_read_SPCod_SPCoc( opj_j2k_t *p_j2k, opj_read_bytes(l_current_ptr,&l_tccp->cblksty ,1); /* SPcoc (G) */ ++l_current_ptr; + if (l_tccp->cblksty & 0xC0U) { /* 2 msb are reserved, assume we can't read */ + opj_event_msg(p_manager, EVT_ERROR, "Error reading SPCod SPCoc element, Invalid code-block style found\n"); + return OPJ_FALSE; + } opj_read_bytes(l_current_ptr,&l_tccp->qmfbid ,1); /* SPcoc (H) */ ++l_current_ptr; @@ -8898,6 +9063,54 @@ static OPJ_UINT32 opj_j2k_get_SQcd_SQcc_size ( opj_j2k_t *p_j2k, } } +static OPJ_BOOL opj_j2k_compare_SQcd_SQcc(opj_j2k_t *p_j2k, OPJ_UINT32 p_tile_no, OPJ_UINT32 p_first_comp_no, OPJ_UINT32 p_second_comp_no) +{ + opj_cp_t *l_cp = NULL; + opj_tcp_t *l_tcp = NULL; + opj_tccp_t *l_tccp0 = NULL; + opj_tccp_t *l_tccp1 = NULL; + OPJ_UINT32 l_band_no, l_num_bands; + + /* preconditions */ + assert(p_j2k != 00); + + l_cp = &(p_j2k->m_cp); + l_tcp = &l_cp->tcps[p_tile_no]; + l_tccp0 = &l_tcp->tccps[p_first_comp_no]; + l_tccp1 = &l_tcp->tccps[p_second_comp_no]; + + if (l_tccp0->qntsty != l_tccp1->qntsty ) { + return OPJ_FALSE; + } + if (l_tccp0->numgbits != l_tccp1->numgbits ) { + return OPJ_FALSE; + } + if (l_tccp0->qntsty == J2K_CCP_QNTSTY_SIQNT) { + l_num_bands = 1U; + } else { + l_num_bands = l_tccp0->numresolutions * 3U - 2U; + if (l_num_bands != (l_tccp1->numresolutions * 3U - 2U)) { + return OPJ_FALSE; + } + } + + for (l_band_no = 0; l_band_no < l_num_bands; ++l_band_no) { + if (l_tccp0->stepsizes[l_band_no].expn != l_tccp1->stepsizes[l_band_no].expn ) { + return OPJ_FALSE; + } + } + if (l_tccp0->qntsty != J2K_CCP_QNTSTY_NOQNT) + { + for (l_band_no = 0; l_band_no < l_num_bands; ++l_band_no) { + if (l_tccp0->stepsizes[l_band_no].mant != l_tccp1->stepsizes[l_band_no].mant ) { + return OPJ_FALSE; + } + } + } + return OPJ_TRUE; +} + + static OPJ_BOOL opj_j2k_write_SQcd_SQcc( opj_j2k_t *p_j2k, OPJ_UINT32 p_tile_no, OPJ_UINT32 p_comp_no, @@ -9185,16 +9398,19 @@ void j2k_dump (opj_j2k_t* p_j2k, OPJ_INT32 flag, FILE* out_stream) /* Dump the codestream info from main header */ if (flag & OPJ_J2K_MH_INFO){ - opj_j2k_dump_MH_info(p_j2k, out_stream); + if (p_j2k->m_private_image) + opj_j2k_dump_MH_info(p_j2k, out_stream); } /* Dump all tile/codestream info */ if (flag & OPJ_J2K_TCH_INFO){ OPJ_UINT32 l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw; OPJ_UINT32 i; opj_tcp_t * l_tcp = p_j2k->m_cp.tcps; - for (i=0;im_private_image->numcomps, out_stream); - ++l_tcp; + if (p_j2k->m_private_image) { + for (i=0;im_private_image->numcomps, out_stream); + ++l_tcp; + } } } @@ -9714,9 +9930,7 @@ static OPJ_BOOL opj_j2k_decode_one_tile ( opj_j2k_t *p_j2k, if (! l_new_current_data) { opj_free(l_current_data); l_current_data = NULL; - /* TODO: LH: why tile numbering policy used in messages differs from - the one used in opj_j2k_decode_tiles() ? */ - opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to decode tile %d/%d\n", l_current_tile_no, (p_j2k->m_cp.th * p_j2k->m_cp.tw) - 1); + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to decode tile %d/%d\n", l_current_tile_no+1, p_j2k->m_cp.th * p_j2k->m_cp.tw); return OPJ_FALSE; } l_current_data = l_new_current_data; @@ -9727,13 +9941,13 @@ static OPJ_BOOL opj_j2k_decode_one_tile ( opj_j2k_t *p_j2k, opj_free(l_current_data); return OPJ_FALSE; } - opj_event_msg(p_manager, EVT_INFO, "Tile %d/%d has been decoded.\n", l_current_tile_no, (p_j2k->m_cp.th * p_j2k->m_cp.tw) - 1); + opj_event_msg(p_manager, EVT_INFO, "Tile %d/%d has been decoded.\n", l_current_tile_no+1, p_j2k->m_cp.th * p_j2k->m_cp.tw); if (! opj_j2k_update_image_data(p_j2k->m_tcd,l_current_data, p_j2k->m_output_image)) { opj_free(l_current_data); return OPJ_FALSE; } - opj_event_msg(p_manager, EVT_INFO, "Image data has been updated with tile %d.\n\n", l_current_tile_no); + opj_event_msg(p_manager, EVT_INFO, "Image data has been updated with tile %d.\n\n", l_current_tile_no+1); if(l_current_tile_no == l_tile_no_to_dec) { @@ -9746,7 +9960,7 @@ static OPJ_BOOL opj_j2k_decode_one_tile ( opj_j2k_t *p_j2k, break; } else { - opj_event_msg(p_manager, EVT_WARNING, "Tile read, decode and updated is not the desired (%d vs %d).\n", l_current_tile_no, l_tile_no_to_dec); + opj_event_msg(p_manager, EVT_WARNING, "Tile read, decoded and updated is not the desired one (%d vs %d).\n", l_current_tile_no+1, l_tile_no_to_dec+1); } } @@ -10368,16 +10582,14 @@ static OPJ_BOOL opj_j2k_setup_header_writing (opj_j2k_t *p_j2k, opj_event_mgr_t if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_qcd, p_manager)) { return OPJ_FALSE; } + 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; + } if (OPJ_IS_CINEMA(p_j2k->m_cp.rsiz)) { - /* No need for COC or QCC, QCD and COD are used - 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; - } - */ if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_tlm, p_manager)) { return OPJ_FALSE; } @@ -10475,7 +10687,6 @@ static OPJ_BOOL opj_j2k_write_first_tile_part (opj_j2k_t *p_j2k, p_total_data_size -= l_current_nb_bytes_written; } #endif - if (l_cp->tcps[p_j2k->m_current_tile_number].numpocs) { l_current_nb_bytes_written = 0; opj_j2k_write_poc_in_memory(p_j2k,p_data,&l_current_nb_bytes_written,p_manager); @@ -10774,7 +10985,7 @@ static OPJ_BOOL opj_j2k_create_tcd( opj_j2k_t *p_j2k, return OPJ_FALSE; } - if (!opj_tcd_init(p_j2k->m_tcd,p_j2k->m_private_image,&p_j2k->m_cp)) { + if (!opj_tcd_init(p_j2k->m_tcd,p_j2k->m_private_image,&p_j2k->m_cp, p_j2k->m_tp)) { opj_tcd_destroy(p_j2k->m_tcd); p_j2k->m_tcd = 00; return OPJ_FALSE;