[trunk] WIP: enhance j2k_to_image with new get_decoded_tile functionality
[openjpeg.git] / libopenjpeg / jp2.c
index 9263950fb9ca55831efadaffe84c780a3da409fe..ad5527bb19b117922c41c9c030ca1c885874a2d6 100644 (file)
@@ -1484,11 +1484,14 @@ opj_image_t* opj_jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio,
 
 }/* opj_jp2_decode() */
 
-opj_bool opj_jp2_decode_v2(    opj_jp2_v2_t *jp2,
-                                                       struct opj_stream_private *cio,
-                                                       opj_image_t* p_image,
-                                                       struct opj_event_mgr * p_manager)
+opj_bool jp2_decode_v2(        opj_jp2_v2_t *jp2,
+                                               struct opj_stream_private *cio,
+                                               opj_image_t* p_image,
+                                               struct opj_event_mgr * p_manager)
 {
+       if (!p_image)
+               return OPJ_FALSE;
+
        /* J2K decoding */
        if( ! j2k_decode_v2(jp2->j2k, cio, p_image, p_manager) ) {
                opj_event_msg_v2(p_manager, EVT_ERROR, "Failed to decode the codestream in the JP2 file\n");
@@ -2438,7 +2441,7 @@ static opj_bool jp2_read_boxhdr_char(
  */
 opj_bool jp2_read_header(      struct opj_stream_private *p_stream,
                                                        opj_jp2_v2_t *jp2,
-                                                       opj_image_t* p_image,
+                                                       opj_image_t** p_image,
                                                        struct opj_event_mgr * p_manager
                                                        )
 {
@@ -2527,7 +2530,7 @@ opj_bool jp2_read_tile_header(    opj_jp2_v2_t * p_jp2,
  * @param      p_stream                        the stream to write data to.
  * @param      p_manager       the user event manager.
  */
-opj_bool opj_jp2_decode_tile (
+opj_bool jp2_decode_tile (
                                        opj_jp2_v2_t * p_jp2,
                                        OPJ_UINT32 p_tile_index,
                                        OPJ_BYTE * p_data,
@@ -2567,11 +2570,33 @@ void jp2_destroy(opj_jp2_v2_t *jp2)
                }
 
                if (jp2->color.jp2_cdef) {
+                       if (jp2->color.jp2_cdef->info) {
+                               opj_free(jp2->color.jp2_cdef->info);
+                               jp2->color.jp2_cdef->info = NULL;
+                       }
+
                        opj_free(jp2->color.jp2_cdef);
                        jp2->color.jp2_cdef = 00;
                }
 
                if (jp2->color.jp2_pclr) {
+                       if (jp2->color.jp2_pclr->cmap) {
+                               opj_free(jp2->color.jp2_pclr->cmap);
+                               jp2->color.jp2_pclr->cmap = NULL;
+                       }
+                       if (jp2->color.jp2_pclr->channel_sign) {
+                               opj_free(jp2->color.jp2_pclr->channel_sign);
+                               jp2->color.jp2_pclr->channel_sign = NULL;
+                       }
+                       if (jp2->color.jp2_pclr->channel_size) {
+                               opj_free(jp2->color.jp2_pclr->channel_size);
+                               jp2->color.jp2_pclr->channel_size = NULL;
+                       }
+                       if (jp2->color.jp2_pclr->entries) {
+                               opj_free(jp2->color.jp2_pclr->entries);
+                               jp2->color.jp2_pclr->entries = NULL;
+                       }
+
                        opj_free(jp2->color.jp2_pclr);
                        jp2->color.jp2_pclr = 00;
                }
@@ -2602,13 +2627,75 @@ void jp2_destroy(opj_jp2_v2_t *jp2)
  * @return     true                    if the area could be set.
  */
 opj_bool jp2_set_decode_area(  opj_jp2_v2_t *p_jp2,
+                                                               opj_image_t* p_image,
                                                                OPJ_INT32 p_start_x, OPJ_INT32 p_start_y,
                                                                OPJ_INT32 p_end_x, OPJ_INT32 p_end_y,
                                                                struct opj_event_mgr * p_manager )
 {
-       return j2k_set_decode_area(p_jp2->j2k, p_start_x, p_start_y, p_end_x, p_end_y, p_manager);
+       return j2k_set_decode_area(p_jp2->j2k, p_image, p_start_x, p_start_y, p_end_x, p_end_y, p_manager);
+}
+
+/**
+ * Get the decoded tile.
+ *
+ * @param      p_jp2                   the jpeg2000 codec.
+ * @param      p_stream                input_stream
+ * @param      p_image                 output image.   .
+ * @param      p_manager               the user event manager
+ * @param      tile_index              index of the tile we want decode
+ *
+ * @return     true                    if succeed.
+ */
+opj_bool jp2_get_tile( opj_jp2_v2_t *jp2,
+                                               opj_stream_private_t *p_stream,
+                                               opj_image_t* p_image,
+                                               struct opj_event_mgr * p_manager,
+                                               OPJ_UINT32 tile_index )
+{
+       if (!p_image)
+               return OPJ_FALSE;
+
+       opj_event_msg_v2(p_manager, EVT_WARNING, "JP2 box which are after the codestream will not be read by this function.\n");
+
+       if (! j2k_get_tile(jp2->j2k, p_stream, p_image, p_manager, tile_index) ){
+               opj_event_msg_v2(p_manager, EVT_ERROR, "Failed to decode the codestream in the JP2 file\n");
+               return OPJ_FALSE;
+       }
+
+       /* Set Image Color Space */
+       if (jp2->enumcs == 16)
+               p_image->color_space = CLRSPC_SRGB;
+       else if (jp2->enumcs == 17)
+               p_image->color_space = CLRSPC_GRAY;
+       else if (jp2->enumcs == 18)
+               p_image->color_space = CLRSPC_SYCC;
+       else
+               p_image->color_space = CLRSPC_UNKNOWN;
+
+       /* Apply the color space if needed */
+       if(jp2->color.jp2_cdef) {
+               jp2_apply_cdef(p_image, &(jp2->color));
+       }
+
+       if(jp2->color.jp2_pclr) {
+               /* Part 1, I.5.3.4: Either both or none : */
+               if( !jp2->color.jp2_pclr->cmap)
+                       jp2_free_pclr(&(jp2->color));
+               else
+                       jp2_apply_pclr(p_image, &(jp2->color));
+       }
+
+       if(jp2->color.icc_profile_buf) {
+               p_image->icc_profile_buf = jp2->color.icc_profile_buf;
+               p_image->icc_profile_len = jp2->color.icc_profile_len;
+               jp2->color.icc_profile_buf = NULL;
+       }
+
+       return OPJ_TRUE;
 }
 
+
+
 /* ----------------------------------------------------------------------- */
 /* JP2 encoder interface                                             */
 /* ----------------------------------------------------------------------- */
@@ -2677,3 +2764,8 @@ opj_codestream_info_v2_t* jp2_get_cstr_info(opj_jp2_v2_t* p_jp2)
        return j2k_get_cstr_info(p_jp2->j2k);
 }
 
+opj_bool jp2_set_decoded_resolution_factor(opj_jp2_v2_t *p_jp2, OPJ_UINT32 res_factor, opj_event_mgr_t * p_manager)
+{
+       return j2k_set_decoded_resolution_factor(p_jp2->j2k, res_factor, p_manager);
+}
+