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 ? */
+ /* Avoids later undefined shift in computation of */
+ /* p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps[i].m_dc_level_shift = 1
+ << (l_image->comps[i].prec - 1); */
+ if (l_img_comp->prec > 31) {
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",
+ "Invalid values for comp = %d : prec=%u (should be between 1 and 38 according to the JPEG2000 norm. OpenJpeg only supports up to 31)\n",
i, l_img_comp->prec);
return OPJ_FALSE;
}
++l_current_tile_param;
}
- p_j2k->m_specific_param.m_decoder.m_state =
- J2K_STATE_MH; /* FIXME J2K_DEC_STATE_MH; */
+ p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_MH;
opj_image_comp_header_update(l_image, l_cp);
return OPJ_TRUE;
l_cp = &(p_j2k->m_cp);
l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH)
- ? /*FIXME J2K_DEC_STATE_TPH*/
+ ?
&l_cp->tcps[p_j2k->m_current_tile_number] :
p_j2k->m_specific_param.m_decoder.m_default_tcp;
l_image = p_j2k->m_private_image;
l_tile_x = p_j2k->m_current_tile_number % l_cp->tw;
l_tile_y = p_j2k->m_current_tile_number / l_cp->tw;
+ /* Fixes issue with id_000020,sig_06,src_001958,op_flip4,pos_149 */
+ /* of https://github.com/uclouvain/openjpeg/issues/939 */
+ /* We must avoid reading twice the same tile part number for a given tile */
+ /* so as to avoid various issues, like opj_j2k_merge_ppt being called */
+ /* several times. */
+ /* ISO 15444-1 A.4.2 Start of tile-part (SOT) mandates that tile parts */
+ /* should appear in increasing order. */
+ if (l_tcp->m_current_tile_part_number + 1 != (OPJ_INT32)l_current_part) {
+ opj_event_msg(p_manager, EVT_ERROR,
+ "Invalid tile part index for tile number %d. "
+ "Got %d, expected %d\n",
+ p_j2k->m_current_tile_number,
+ l_current_part,
+ l_tcp->m_current_tile_part_number + 1);
+ return OPJ_FALSE;
+ }
+ ++ l_tcp->m_current_tile_part_number;
+
#ifdef USE_JPWL
if (l_cp->correct) {
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read MCT marker\n");
return OPJ_FALSE;
}
+
+ /* Update m_mcc_records[].m_offset_array and m_decorrelation_array
+ * to point to the new addresses */
+ if (new_mct_records != l_tcp->m_mct_records) {
+ for (i = 0; i < l_tcp->m_nb_mcc_records; ++i) {
+ opj_simple_mcc_decorrelation_data_t* l_mcc_record =
+ &(l_tcp->m_mcc_records[i]);
+ if (l_mcc_record->m_decorrelation_array) {
+ l_mcc_record->m_decorrelation_array =
+ new_mct_records +
+ (l_mcc_record->m_decorrelation_array -
+ l_tcp->m_mct_records);
+ }
+ if (l_mcc_record->m_offset_array) {
+ l_mcc_record->m_offset_array =
+ new_mct_records +
+ (l_mcc_record->m_offset_array -
+ l_tcp->m_mct_records);
+ }
+ }
+ }
+
l_tcp->m_mct_records = new_mct_records;
l_mct_data = l_tcp->m_mct_records + l_tcp->m_nb_mct_records;
memset(l_mct_data, 0, (l_tcp->m_nb_max_mct_records - l_tcp->m_nb_mct_records) *
if (l_mct_data->m_data) {
opj_free(l_mct_data->m_data);
l_mct_data->m_data = 00;
+ l_mct_data->m_data_size = 0;
}
l_mct_data->m_index = l_indix;
++p_header_data;
l_comp->sgnd = (l_comp_def >> 7) & 1;
l_comp->prec = (l_comp_def & 0x7f) + 1;
+
+ if (l_comp->prec > 31) {
+ 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. OpenJpeg only supports up to 31)\n",
+ i, l_comp->prec);
+ return OPJ_FALSE;
+ }
++l_comp;
}
l_tcp->cod = 0;
l_tcp->ppt = 0;
l_tcp->ppt_data = 00;
+ l_tcp->m_current_tile_part_number = -1;
/* Remove memory not owned by this tile in case of early error return. */
l_tcp->m_mct_decoding_matrix = 00;
l_tcp->m_nb_max_mct_records = 0;
/* Current marker is the EOC marker ?*/
if (l_current_marker == J2K_MS_EOC) {
- if (p_j2k->m_specific_param.m_decoder.m_state != J2K_STATE_EOC) {
- p_j2k->m_current_tile_number = 0;
- p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_EOC;
- }
+ p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_EOC;
}
/* FIXME DOC ???*/
*p_tile_index = p_j2k->m_current_tile_number;
*p_go_on = OPJ_TRUE;
*p_data_size = opj_tcd_get_decoded_tile_size(p_j2k->m_tcd);
+ if (*p_data_size == UINT_MAX) {
+ return OPJ_FALSE;
+ }
*p_tile_x0 = p_j2k->m_tcd->tcd_image->tiles->x0;
*p_tile_y0 = p_j2k->m_tcd->tcd_image->tiles->y0;
*p_tile_x1 = p_j2k->m_tcd->tcd_image->tiles->x1;
*p_tile_y1 = p_j2k->m_tcd->tcd_image->tiles->y1;
*p_nb_comps = p_j2k->m_tcd->tcd_image->tiles->numcomps;
- p_j2k->m_specific_param.m_decoder.m_state |=
- 0x0080;/* FIXME J2K_DEC_STATE_DATA;*/
+ p_j2k->m_specific_param.m_decoder.m_state |= J2K_STATE_DATA;
return OPJ_TRUE;
}
assert(p_j2k != 00);
assert(p_manager != 00);
- if (!(p_j2k->m_specific_param.m_decoder.m_state &
- 0x0080/*FIXME J2K_DEC_STATE_DATA*/)
+ if (!(p_j2k->m_specific_param.m_decoder.m_state & J2K_STATE_DATA)
|| (p_tile_index != p_j2k->m_current_tile_number)) {
return OPJ_FALSE;
}
p_tile_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;*/
+ p_j2k->m_specific_param.m_decoder.m_state |= J2K_STATE_ERR;
opj_event_msg(p_manager, EVT_ERROR, "Failed to decode.\n");
return OPJ_FALSE;
}
opj_j2k_tcp_data_destroy(l_tcp);
p_j2k->m_specific_param.m_decoder.m_can_decode = 0;
- p_j2k->m_specific_param.m_decoder.m_state &= (~
- (0x0080u)); /* FIXME J2K_DEC_STATE_DATA);*/
+ p_j2k->m_specific_param.m_decoder.m_state &= (~(OPJ_UINT32)J2K_STATE_DATA);
if (opj_stream_get_number_byte_left(p_stream) == 0
&& p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_NEOC) {
return OPJ_TRUE;
}
- if (p_j2k->m_specific_param.m_decoder.m_state !=
- 0x0100) { /*FIXME J2K_DEC_STATE_EOC)*/
+ if (p_j2k->m_specific_param.m_decoder.m_state != J2K_STATE_EOC) {
if (opj_stream_read_data(p_stream, l_data, 2, p_manager) != 2) {
opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
return OPJ_FALSE;
if (l_current_marker == J2K_MS_EOC) {
p_j2k->m_current_tile_number = 0;
- p_j2k->m_specific_param.m_decoder.m_state = 0x0100;/*FIXME J2K_DEC_STATE_EOC;*/
+ p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_EOC;
} else if (l_current_marker != J2K_MS_SOT) {
if (opj_stream_get_number_byte_left(p_stream) == 0) {
p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_NEOC;
if (l_img_comp_src->sgnd) {
for (j = 0; j < l_height_dest; ++j) {
for (k = 0; k < l_width_dest; ++k) {
- *(l_dest_ptr++) = *(l_src_ptr++);
+ OPJ_INT16 val;
+ memcpy(&val, l_src_ptr, sizeof(val));
+ l_src_ptr ++;
+ *(l_dest_ptr++) = val;
}
l_dest_ptr += l_line_offset_dest;
} else {
for (j = 0; j < l_height_dest; ++j) {
for (k = 0; k < l_width_dest; ++k) {
- *(l_dest_ptr++) = (*(l_src_ptr++)) & 0xffff;
+ OPJ_INT16 val;
+ memcpy(&val, l_src_ptr, sizeof(val));
+ l_src_ptr ++;
+ *(l_dest_ptr++) = val & 0xffff;
}
l_dest_ptr += l_line_offset_dest;
l_src_ptr += l_start_offset_src;
for (j = 0; j < l_height_dest; ++j) {
- for (k = 0; k < l_width_dest; ++k) {
- *(l_dest_ptr++) = (*(l_src_ptr++));
- }
-
- l_dest_ptr += l_line_offset_dest;
- l_src_ptr += l_line_offset_src ;
+ memcpy(l_dest_ptr, l_src_ptr, l_width_dest * sizeof(OPJ_INT32));
+ l_dest_ptr += l_width_dest + l_line_offset_dest;
+ l_src_ptr += l_width_dest + l_line_offset_src ;
}
l_src_ptr += l_end_offset_src;
opj_image_comp_t* l_img_comp = NULL;
/* Check if we are read the main header */
- if (p_j2k->m_specific_param.m_decoder.m_state !=
- J2K_STATE_TPHSOT) { /* FIXME J2K_DEC_STATE_TPHSOT)*/
+ if (p_j2k->m_specific_param.m_decoder.m_state != J2K_STATE_TPHSOT) {
opj_event_msg(p_manager, EVT_ERROR,
"Need to decode the main header before begin to decode the remaining codestream");
return OPJ_FALSE;
/* Check if the positions provided by the user are correct */
/* Left */
- assert(p_start_x >= 0);
- assert(p_start_y >= 0);
-
- if ((OPJ_UINT32)p_start_x > l_image->x1) {
+ if (p_start_x < 0) {
+ opj_event_msg(p_manager, EVT_ERROR,
+ "Left position of the decoded area (region_x0=%d) should be >= 0.\n",
+ p_start_x);
+ return OPJ_FALSE;
+ } else if ((OPJ_UINT32)p_start_x > l_image->x1) {
opj_event_msg(p_manager, EVT_ERROR,
"Left position of the decoded area (region_x0=%d) is outside the image area (Xsiz=%d).\n",
p_start_x, l_image->x1);
}
/* Up */
- if ((OPJ_UINT32)p_start_y > l_image->y1) {
+ if (p_start_x < 0) {
+ opj_event_msg(p_manager, EVT_ERROR,
+ "Up position of the decoded area (region_y0=%d) should be >= 0.\n",
+ p_start_y);
+ return OPJ_FALSE;
+ } else if ((OPJ_UINT32)p_start_y > l_image->y1) {
opj_event_msg(p_manager, EVT_ERROR,
"Up position of the decoded area (region_y0=%d) is outside the image area (Ysiz=%d).\n",
p_start_y, l_image->y1);
}
/* Right */
- assert((OPJ_UINT32)p_end_x > 0);
- assert((OPJ_UINT32)p_end_y > 0);
- if ((OPJ_UINT32)p_end_x < l_image->x0) {
+ if (p_end_x <= 0) {
+ opj_event_msg(p_manager, EVT_ERROR,
+ "Right position of the decoded area (region_x1=%d) should be > 0.\n",
+ p_end_x);
+ return OPJ_FALSE;
+ } else if ((OPJ_UINT32)p_end_x < l_image->x0) {
opj_event_msg(p_manager, EVT_ERROR,
"Right position of the decoded area (region_x1=%d) is outside the image area (XOsiz=%d).\n",
p_end_x, l_image->x0);
}
/* Bottom */
- if ((OPJ_UINT32)p_end_y < l_image->y0) {
+ if (p_end_y <= 0) {
+ opj_event_msg(p_manager, EVT_ERROR,
+ "Bottom position of the decoded area (region_y1=%d) should be > 0.\n",
+ p_end_y);
+ return OPJ_FALSE;
+ } else if ((OPJ_UINT32)p_end_y < l_image->y0) {
opj_event_msg(p_manager, EVT_ERROR,
"Bottom position of the decoded area (region_y1=%d) is outside the image area (YOsiz=%d).\n",
p_end_y, l_image->y0);
l_cp = &(p_j2k->m_cp);
l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH)
- ? /* FIXME J2K_DEC_STATE_TPH*/
+ ?
&l_cp->tcps[p_j2k->m_current_tile_number] :
p_j2k->m_specific_param.m_decoder.m_default_tcp;
l_cp = &(p_j2k->m_cp);
/* come from tile part header or main header ?*/
l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH)
- ? /*FIXME J2K_DEC_STATE_TPH*/
+ ?
&l_cp->tcps[p_j2k->m_current_tile_number] :
p_j2k->m_specific_param.m_decoder.m_default_tcp;
OPJ_INT32 l_tile_x0, l_tile_y0, l_tile_x1, l_tile_y1;
OPJ_UINT32 l_nb_comps;
OPJ_BYTE * l_current_data;
+ OPJ_UINT32 l_nb_tiles;
+ OPJ_UINT32 i;
l_current_data = (OPJ_BYTE*)opj_malloc(1000);
if (! l_current_data) {
}
}
+ /* Reset current tile part number for all tiles, and not only the one */
+ /* of interest. */
+ /* Not completely sure this is always correct but required for */
+ /* ./build/bin/j2k_random_tile_access ./build/tests/tte1.j2k */
+ l_nb_tiles = p_j2k->m_cp.tw * p_j2k->m_cp.th;
+ for (i = 0; i < l_nb_tiles; ++i) {
+ p_j2k->m_cp.tcps[i].m_current_tile_part_number = -1;
+ }
+
for (;;) {
if (! opj_j2k_read_tile_header(p_j2k,
&l_current_tile_no,