#define OPJ_BOX_SIZE 1024
+#define OPJ_UNUSED(x) (void)x
+
/** @name Local static functions */
/*@{*/
opj_event_mgr_t * p_manager);
static OPJ_BOOL opj_jp2_skip_jp2c(opj_jp2_t *jp2,
- opj_stream_private_t *cio,
+ opj_stream_private_t *stream,
opj_event_mgr_t * p_manager);
/**
/**
Apply collected palette data
-@param color Collector for profile, cdef and pclr data
-@param image
+@param image Image.
+@param color Collector for profile, cdef and pclr data.
+@param p_manager the user event manager.
+@return true in case of success
*/
-static void opj_jp2_apply_pclr(opj_image_t *image, opj_jp2_color_t *color);
+static OPJ_BOOL opj_jp2_apply_pclr(opj_image_t *image,
+ opj_jp2_color_t *color,
+ opj_event_mgr_t * p_manager);
static void opj_jp2_free_pclr(opj_jp2_color_t *color);
opj_event_mgr_t * p_manager);
/**
- * Excutes the given procedures on the given codec.
+ * Executes the given procedures on the given codec.
*
* @param p_procedure_list the list of procedures to execute
* @param jp2 the jpeg2000 file codec to execute the procedures on.
opj_event_mgr_t * p_manager);
/**
- * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
+ * Sets up the validation ,i.e. adds the procedures to launch to make sure the codec parameters
* are valid. Developpers wanting to extend the library can add their own validation procedures.
*/
static OPJ_BOOL opj_jp2_setup_encoding_validation(opj_jp2_t *jp2,
opj_event_mgr_t * p_manager);
/**
- * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
+ * Sets up the validation ,i.e. adds the procedures to launch to make sure the codec parameters
* are valid. Developpers wanting to extend the library can add their own validation procedures.
*/
static OPJ_BOOL opj_jp2_setup_decoding_validation(opj_jp2_t *jp2,
opj_read_bytes(p_image_header_data, &(jp2->IPR), 1); /* IPR */
++ p_image_header_data;
+ jp2->j2k->m_cp.allow_different_bit_depth_sign = (jp2->bpc == 255);
+ jp2->j2k->ihdr_w = jp2->w;
+ jp2->j2k->ihdr_h = jp2->h;
+ jp2->has_ihdr = 1;
+
return OPJ_TRUE;
}
}
/* verify that no component is targeted more than once */
for (i = 0; i < nr_channels; i++) {
- OPJ_UINT16 pcol = cmap[i].pcol;
- assert(cmap[i].mtyp == 0 || cmap[i].mtyp == 1);
- if (pcol >= nr_channels) {
+ OPJ_BYTE mtyp = cmap[i].mtyp;
+ OPJ_BYTE pcol = cmap[i].pcol;
+ /* See ISO 15444-1 Table I.14 – MTYPi field values */
+ if (mtyp != 0 && mtyp != 1) {
+ opj_event_msg(p_manager, EVT_ERROR,
+ "Invalid value for cmap[%d].mtyp = %d.\n", i,
+ mtyp);
+ is_sane = OPJ_FALSE;
+ } else if (pcol >= nr_channels) {
opj_event_msg(p_manager, EVT_ERROR,
"Invalid component/palette index for direct mapping %d.\n", pcol);
is_sane = OPJ_FALSE;
- } else if (pcol_usage[pcol] && cmap[i].mtyp == 1) {
+ } else if (pcol_usage[pcol] && mtyp == 1) {
opj_event_msg(p_manager, EVT_ERROR, "Component %d is mapped twice.\n", pcol);
is_sane = OPJ_FALSE;
- } else if (cmap[i].mtyp == 0 && cmap[i].pcol != 0) {
+ } else if (mtyp == 0 && pcol != 0) {
/* I.5.3.5 PCOL: If the value of the MTYP field for this channel is 0, then
* the value of this field shall be 0. */
opj_event_msg(p_manager, EVT_ERROR, "Direct use at #%d however pcol=%d.\n", i,
pcol);
is_sane = OPJ_FALSE;
+ } else if (mtyp == 1 && pcol != i) {
+ /* OpenJPEG implementation limitation. See assert(i == pcol); */
+ /* in opj_jp2_apply_pclr() */
+ opj_event_msg(p_manager, EVT_ERROR,
+ "Implementation limitation: for palette mapping, "
+ "pcol[%d] should be equal to %d, but is equal "
+ "to %d.\n", i, i, pcol);
+ is_sane = OPJ_FALSE;
} else {
pcol_usage[pcol] = OPJ_TRUE;
}
if (!pcol_usage[i]) {
is_sane = 0U;
opj_event_msg(p_manager, EVT_WARNING,
- "Component mapping seems wrong. Trying to correct.\n", i);
+ "Component mapping seems wrong. Trying to correct.\n");
break;
}
}
}
/* file9.jp2 */
-static void opj_jp2_apply_pclr(opj_image_t *image, opj_jp2_color_t *color)
+static OPJ_BOOL opj_jp2_apply_pclr(opj_image_t *image,
+ opj_jp2_color_t *color,
+ opj_event_mgr_t * p_manager)
{
opj_image_comp_t *old_comps, *new_comps;
OPJ_BYTE *channel_size, *channel_sign;
cmap = color->jp2_pclr->cmap;
nr_channels = color->jp2_pclr->nr_channels;
+ for (i = 0; i < nr_channels; ++i) {
+ /* Palette mapping: */
+ cmp = cmap[i].cmp;
+ if (image->comps[cmp].data == NULL) {
+ opj_event_msg(p_manager, EVT_ERROR,
+ "image->comps[%d].data == NULL in opj_jp2_apply_pclr().\n", i);
+ return OPJ_FALSE;
+ }
+ }
+
old_comps = image->comps;
new_comps = (opj_image_comp_t*)
opj_malloc(nr_channels * sizeof(opj_image_comp_t));
if (!new_comps) {
- /* FIXME no error code for opj_jp2_apply_pclr */
- /* FIXME event manager error callback */
- return;
+ opj_event_msg(p_manager, EVT_ERROR,
+ "Memory allocation failure in opj_jp2_apply_pclr().\n");
+ return OPJ_FALSE;
}
for (i = 0; i < nr_channels; ++i) {
pcol = cmap[i].pcol;
/* Palette mapping: */
new_comps[i].data = (OPJ_INT32*)
- opj_malloc(old_comps[cmp].w * old_comps[cmp].h * sizeof(OPJ_INT32));
+ opj_image_data_alloc(sizeof(OPJ_INT32) * old_comps[cmp].w * old_comps[cmp].h);
if (!new_comps[i].data) {
+ while (i > 0) {
+ -- i;
+ opj_image_data_free(new_comps[i].data);
+ }
opj_free(new_comps);
- new_comps = NULL;
- /* FIXME no error code for opj_jp2_apply_pclr */
- /* FIXME event manager error callback */
- return;
+ opj_event_msg(p_manager, EVT_ERROR,
+ "Memory allocation failure in opj_jp2_apply_pclr().\n");
+ return OPJ_FALSE;
}
new_comps[i].prec = channel_size[i];
new_comps[i].sgnd = channel_sign[i];
cmp = cmap[i].cmp;
pcol = cmap[i].pcol;
src = old_comps[cmp].data;
- assert(src);
+ assert(src); /* verified above */
max = new_comps[pcol].w * new_comps[pcol].h;
/* Direct use: */
if (cmap[i].mtyp == 0) {
- assert(cmp == 0);
dst = new_comps[i].data;
assert(dst);
for (j = 0; j < max; ++j) {
max = image->numcomps;
for (i = 0; i < max; ++i) {
if (old_comps[i].data) {
- opj_free(old_comps[i].data);
+ opj_image_data_free(old_comps[i].data);
}
}
image->comps = new_comps;
image->numcomps = nr_channels;
- opj_jp2_free_pclr(color);
-
+ return OPJ_TRUE;
}/* apply_pclr() */
static OPJ_BOOL opj_jp2_read_pclr(opj_jp2_t *jp2,
return OPJ_FALSE;
}
- entries = (OPJ_UINT32*) opj_malloc((size_t)nr_channels * nr_entries * sizeof(
- OPJ_UINT32));
+ entries = (OPJ_UINT32*) opj_malloc(sizeof(OPJ_UINT32) * nr_channels *
+ nr_entries);
if (!entries) {
return OPJ_FALSE;
}
"COLR BOX meth value is not a regular value (%d), "
"so we will ignore the entire Colour Specification box. \n", jp2->meth);
}
+
return OPJ_TRUE;
}
return OPJ_FALSE;
}
+ if (jp2->j2k->m_specific_param.m_decoder.m_numcomps_to_decode) {
+ /* Bypass all JP2 component transforms */
+ return OPJ_TRUE;
+ }
+
if (!jp2->ignore_pclr_cmap_cdef) {
if (!opj_jp2_check_color(p_image, &(jp2->color), p_manager)) {
return OPJ_FALSE;
if (!jp2->color.jp2_pclr->cmap) {
opj_jp2_free_pclr(&(jp2->color));
} else {
- opj_jp2_apply_pclr(p_image, &(jp2->color));
+ if (!opj_jp2_apply_pclr(p_image, &(jp2->color), p_manager)) {
+ return OPJ_FALSE;
+ }
}
}
assert(jp2 != 00);
assert(p_manager != 00);
+ OPJ_UNUSED(jp2);
+
/* write box length */
opj_write_bytes(l_signature_data, 12, 4);
/* writes box type */
assert(cio != 00);
assert(p_manager != 00);
+ OPJ_UNUSED(p_manager);
+
/* JPEG2000 codec validation */
/* STATE checking */
jp2->jp2_state |= JP2_STATE_UNKNOWN;
if (opj_stream_skip(stream, l_current_data_size,
p_manager) != l_current_data_size) {
- opj_event_msg(p_manager, EVT_ERROR,
- "Problem with skipping JPEG2000 box, stream error\n");
- opj_free(l_current_data);
- return OPJ_FALSE;
+ if (jp2->jp2_state & JP2_STATE_CODESTREAM) {
+ /* If we already read the codestream, do not error out */
+ /* Needed for data/input/nonregression/issue254.jp2 */
+ opj_event_msg(p_manager, EVT_WARNING,
+ "Problem with skipping JPEG2000 box, stream error\n");
+ opj_free(l_current_data);
+ return OPJ_TRUE;
+ } else {
+ opj_event_msg(p_manager, EVT_ERROR,
+ "Problem with skipping JPEG2000 box, stream error\n");
+ opj_free(l_current_data);
+ return OPJ_FALSE;
+ }
}
}
}
}
/**
- * Excutes the given procedures on the given codec.
+ * Executes the given procedures on the given codec.
*
* @param p_procedure_list the list of procedures to execute
* @param jp2 the jpeg2000 file codec to execute the procedures on.
}
jp2->jp2_state |= JP2_STATE_HEADER;
+ jp2->has_jp2h = 1;
return OPJ_TRUE;
}
if (! opj_jp2_exec(jp2, jp2->m_procedure_list, p_stream, p_manager)) {
return OPJ_FALSE;
}
+ if (jp2->has_jp2h == 0) {
+ opj_event_msg(p_manager, EVT_ERROR, "JP2H box missing. Required.\n");
+ return OPJ_FALSE;
+ }
+ if (jp2->has_ihdr == 0) {
+ opj_event_msg(p_manager, EVT_ERROR, "IHDR box_missing. Required.\n");
+ return OPJ_FALSE;
+ }
return opj_j2k_read_header(p_stream,
jp2->j2k,
assert(jp2 != 00);
assert(p_manager != 00);
+ OPJ_UNUSED(jp2);
+ OPJ_UNUSED(p_manager);
+
/* DEVELOPER CORNER, add your custom validation procedure */
return OPJ_TRUE;
}
}
+OPJ_BOOL opj_jp2_set_decoded_components(opj_jp2_t *p_jp2,
+ OPJ_UINT32 numcomps,
+ const OPJ_UINT32* comps_indices,
+ opj_event_mgr_t * p_manager)
+{
+ return opj_j2k_set_decoded_components(p_jp2->j2k,
+ numcomps, comps_indices,
+ p_manager);
+}
+
OPJ_BOOL opj_jp2_set_decode_area(opj_jp2_t *p_jp2,
opj_image_t* p_image,
OPJ_INT32 p_start_x, OPJ_INT32 p_start_y,
return OPJ_FALSE;
}
+ if (p_jp2->j2k->m_specific_param.m_decoder.m_numcomps_to_decode) {
+ /* Bypass all JP2 component transforms */
+ return OPJ_TRUE;
+ }
+
if (!opj_jp2_check_color(p_image, &(p_jp2->color), p_manager)) {
return OPJ_FALSE;
}
if (!p_jp2->color.jp2_pclr->cmap) {
opj_jp2_free_pclr(&(p_jp2->color));
} else {
- opj_jp2_apply_pclr(p_image, &(p_jp2->color));
+ if (!opj_jp2_apply_pclr(p_image, &(p_jp2->color), p_manager)) {
+ return OPJ_FALSE;
+ }
}
}
OPJ_OFF_T j2k_codestream_exit;
OPJ_BYTE l_data_header [24];
+ OPJ_UNUSED(jp2);
+
/* preconditions */
assert(jp2 != 00);
assert(cio != 00);
OPJ_OFF_T j2k_codestream_exit;
OPJ_BYTE l_data_header [24];
+ OPJ_UNUSED(jp2);
+
/* preconditions */
assert(jp2 != 00);
assert(cio != 00);