/* 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;
}
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;
}
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) {
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;
}
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;
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;
}
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*/
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;
}
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)
++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)
for (j=0;j<l_cp->tw;++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;
}
}
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;
}
}
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;
}
}
+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 */
/* ----------------------------------------------------------------------- */
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;
}
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");
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);
}
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;
}
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;
/* 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;i<l_nb_tiles;++i) {
- opj_j2k_dump_tile_info( l_tcp,(OPJ_INT32)p_j2k->m_private_image->numcomps, out_stream);
- ++l_tcp;
+ if (p_j2k->m_private_image) {
+ for (i=0;i<l_nb_tiles;++i) {
+ opj_j2k_dump_tile_info( l_tcp,(OPJ_INT32)p_j2k->m_private_image->numcomps, out_stream);
+ ++l_tcp;
+ }
}
}
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;
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)
{
- /* move into the codestream to the the first SOT (FIXME or not move?)*/
+ /* move into the codestream to 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);
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);
}
}
OPJ_UINT32 l_nb_tiles;
OPJ_UINT32 l_max_tile_size = 0, l_current_tile_size;
OPJ_BYTE * l_current_data = 00;
+ OPJ_BOOL l_reuse_data = OPJ_FALSE;
opj_tcd_t* p_tcd = 00;
/* preconditions */
p_tcd = p_j2k->m_tcd;
l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
+ if (l_nb_tiles == 1) {
+ l_reuse_data = OPJ_TRUE;
+#ifdef __SSE__
+ for (j=0;j<p_j2k->m_tcd->image->numcomps;++j) {
+ opj_image_comp_t * l_img_comp = p_tcd->image->comps + j;
+ if (((size_t)l_img_comp->data & 0xFU) != 0U) { /* tile data shall be aligned on 16 bytes */
+ l_reuse_data = OPJ_FALSE;
+ }
+ }
+#endif
+ }
for (i=0;i<l_nb_tiles;++i) {
if (! opj_j2k_pre_write_tile(p_j2k,i,p_stream,p_manager)) {
if (l_current_data) {
/* otherwise, allocate the data */
for (j=0;j<p_j2k->m_tcd->image->numcomps;++j) {
opj_tcd_tilecomp_t* l_tilec = p_tcd->tcd_image->tiles->comps + j;
- if (l_nb_tiles == 1) {
+ if (l_reuse_data) {
opj_image_comp_t * l_img_comp = p_tcd->image->comps + j;
l_tilec->data = l_img_comp->data;
l_tilec->ownsData = OPJ_FALSE;
}
}
l_current_tile_size = opj_tcd_get_encoded_tile_size(p_j2k->m_tcd);
- if (l_nb_tiles > 1) {
+ if (!l_reuse_data) {
if (l_current_tile_size > l_max_tile_size) {
OPJ_BYTE *l_new_current_data = (OPJ_BYTE *) opj_realloc(l_current_data, l_current_tile_size);
if (! l_new_current_data) {
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;
}
}
- /* now copy data into the the tile component */
+ /* now copy data into the tile component */
if (! opj_tcd_copy_tile_data(p_j2k->m_tcd,p_data,p_data_size)) {
opj_event_msg(p_manager, EVT_ERROR, "Size mismatch between tile data and sent data." );
return OPJ_FALSE;