+ /* 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)*/
+ opj_event_msg(p_manager, EVT_ERROR,
+ "Need to decode the main header before begin to decode the remaining codestream");
+ return OPJ_FALSE;
+ }
+
+ if (!p_start_x && !p_start_y && !p_end_x && !p_end_y) {
+ opj_event_msg(p_manager, EVT_INFO,
+ "No decoded area parameters, set the decoded area to the whole image\n");
+
+ p_j2k->m_specific_param.m_decoder.m_start_tile_x = 0;
+ p_j2k->m_specific_param.m_decoder.m_start_tile_y = 0;
+ p_j2k->m_specific_param.m_decoder.m_end_tile_x = l_cp->tw;
+ p_j2k->m_specific_param.m_decoder.m_end_tile_y = l_cp->th;
+
+ return OPJ_TRUE;
+ }
+
+ /* ----- */
+ /* 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) {
+ 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);
+ return OPJ_FALSE;
+ } else if ((OPJ_UINT32)p_start_x < l_image->x0) {
+ opj_event_msg(p_manager, EVT_WARNING,
+ "Left position of the decoded area (region_x0=%d) is outside the image area (XOsiz=%d).\n",
+ p_start_x, l_image->x0);
+ p_j2k->m_specific_param.m_decoder.m_start_tile_x = 0;
+ p_image->x0 = l_image->x0;
+ } else {
+ p_j2k->m_specific_param.m_decoder.m_start_tile_x = ((OPJ_UINT32)p_start_x -
+ l_cp->tx0) / l_cp->tdx;
+ p_image->x0 = (OPJ_UINT32)p_start_x;
+ }
+
+ /* Up */
+ 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);
+ return OPJ_FALSE;
+ } else if ((OPJ_UINT32)p_start_y < l_image->y0) {
+ opj_event_msg(p_manager, EVT_WARNING,
+ "Up position of the decoded area (region_y0=%d) is outside the image area (YOsiz=%d).\n",
+ p_start_y, l_image->y0);
+ p_j2k->m_specific_param.m_decoder.m_start_tile_y = 0;
+ p_image->y0 = l_image->y0;
+ } else {
+ p_j2k->m_specific_param.m_decoder.m_start_tile_y = ((OPJ_UINT32)p_start_y -
+ l_cp->ty0) / l_cp->tdy;
+ p_image->y0 = (OPJ_UINT32)p_start_y;
+ }
+
+ /* Right */
+ assert((OPJ_UINT32)p_end_x > 0);
+ assert((OPJ_UINT32)p_end_y > 0);
+ 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);
+ return OPJ_FALSE;
+ } else if ((OPJ_UINT32)p_end_x > l_image->x1) {
+ opj_event_msg(p_manager, EVT_WARNING,
+ "Right position of the decoded area (region_x1=%d) is outside the image area (Xsiz=%d).\n",
+ p_end_x, l_image->x1);
+ p_j2k->m_specific_param.m_decoder.m_end_tile_x = l_cp->tw;
+ p_image->x1 = l_image->x1;
+ } else {
+ p_j2k->m_specific_param.m_decoder.m_end_tile_x = (OPJ_UINT32)opj_int_ceildiv(
+ p_end_x - (OPJ_INT32)l_cp->tx0, (OPJ_INT32)l_cp->tdx);
+ p_image->x1 = (OPJ_UINT32)p_end_x;
+ }
+
+ /* Bottom */
+ 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);
+ return OPJ_FALSE;
+ }
+ if ((OPJ_UINT32)p_end_y > l_image->y1) {
+ opj_event_msg(p_manager, EVT_WARNING,
+ "Bottom position of the decoded area (region_y1=%d) is outside the image area (Ysiz=%d).\n",
+ p_end_y, l_image->y1);
+ p_j2k->m_specific_param.m_decoder.m_end_tile_y = l_cp->th;
+ p_image->y1 = l_image->y1;
+ } else {
+ p_j2k->m_specific_param.m_decoder.m_end_tile_y = (OPJ_UINT32)opj_int_ceildiv(
+ p_end_y - (OPJ_INT32)l_cp->ty0, (OPJ_INT32)l_cp->tdy);
+ p_image->y1 = (OPJ_UINT32)p_end_y;
+ }
+ /* ----- */
+
+ p_j2k->m_specific_param.m_decoder.m_discard_tiles = 1;
+
+ l_img_comp = p_image->comps;
+ for (it_comp = 0; it_comp < p_image->numcomps; ++it_comp) {
+ OPJ_INT32 l_h, l_w;
+
+ l_img_comp->x0 = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)p_image->x0,
+ (OPJ_INT32)l_img_comp->dx);
+ l_img_comp->y0 = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)p_image->y0,
+ (OPJ_INT32)l_img_comp->dy);
+ l_comp_x1 = opj_int_ceildiv((OPJ_INT32)p_image->x1, (OPJ_INT32)l_img_comp->dx);
+ l_comp_y1 = opj_int_ceildiv((OPJ_INT32)p_image->y1, (OPJ_INT32)l_img_comp->dy);
+
+ l_w = opj_int_ceildivpow2(l_comp_x1, (OPJ_INT32)l_img_comp->factor)
+ - opj_int_ceildivpow2((OPJ_INT32)l_img_comp->x0, (OPJ_INT32)l_img_comp->factor);
+ if (l_w < 0) {
+ opj_event_msg(p_manager, EVT_ERROR,
+ "Size x of the decoded component image is incorrect (comp[%d].w=%d).\n",
+ it_comp, l_w);
+ return OPJ_FALSE;
+ }
+ l_img_comp->w = (OPJ_UINT32)l_w;