]> granicus.if.org Git - openjpeg/commitdiff
[trunk] WIP: add stream length value to read unknown marker size, backport 855 into...
authorMickael Savinaud <savmickael@users.noreply.github.com>
Tue, 11 Oct 2011 08:01:31 +0000 (08:01 +0000)
committerMickael Savinaud <savmickael@users.noreply.github.com>
Tue, 11 Oct 2011 08:01:31 +0000 (08:01 +0000)
CHANGES
libopenjpeg/cio.c
libopenjpeg/cio.h
libopenjpeg/j2k.c
libopenjpeg/openjpeg.c
libopenjpeg/openjpeg.h
libopenjpeg/tcd.c

diff --git a/CHANGES b/CHANGES
index e1f2f5333ed3e4795c7f58b88720f164d464fe08..75a962fa57776a11cb183bae5a64ed5cfe38bc4b 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,7 @@ What's New for OpenJPEG
 + : added
 
 October 11, 2011
+* [mickael] WIP: add stream length value to read unknown marker size, backport 855 into V2 framework, correct memory leak into get_cstr_info
 * [mickael] WIP: add output elements about decoding of jp2 files with last tile part lenght equal zero
 * [mickael] WIP: correct mistake with JP2 files and manage correctly the text_GBR.jp2 filecase
 
index a65ff5c448638a8ab19dc091a4afec2b093ccb6b..85a320c8c549a8953670044e84b8ecf7d52ffa7f 100644 (file)
@@ -439,11 +439,11 @@ OPJ_API void OPJ_CALLCONV opj_stream_destroy(opj_stream_t* p_stream)
 OPJ_API void OPJ_CALLCONV opj_stream_set_read_function(opj_stream_t* p_stream, opj_stream_read_fn p_function)
 {
        opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
-       if
-               ((!l_stream) || (! (l_stream->m_status & opj_stream_e_input)))
-       {
+
+       if ((!l_stream) || (! (l_stream->m_status & opj_stream_e_input))) {
                return;
        }
+
        l_stream->m_read_fn = p_function;
 }
 
@@ -501,6 +501,18 @@ OPJ_API void OPJ_CALLCONV opj_stream_set_user_data(opj_stream_t* p_stream, void
        l_stream->m_user_data = p_data;
 }
 
+/**
+ * Sets the given data to be used as a user data for the stream.
+ * @param              p_stream        the stream to modify
+ * @param              p_data          the data to set.
+*/
+OPJ_API void OPJ_CALLCONV opj_stream_set_user_data_length(opj_stream_t* p_stream, OPJ_UINT32 data_length)
+{
+       opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
+
+       l_stream->m_user_data_length = data_length;
+}
+
 /**
  * Reads some bytes from the stream.
  * @param              p_stream        the stream to read data from.
@@ -852,6 +864,21 @@ OPJ_SIZE_T opj_stream_tell (const opj_stream_private_t * p_stream)
        return p_stream->m_byte_offset;
 }
 
+
+/**
+ * Get the number of bytes left before the end of the stream (similar to cio_numbytesleft).
+ *
+ * @param              p_stream        the stream to get the information from.
+ *
+ * @return             Number of bytes left before the end of the stream.
+ */
+OPJ_SIZE_T opj_stream_get_number_byte_left (const opj_stream_private_t * p_stream)
+{
+       return p_stream->m_user_data_length ?
+                               p_stream->m_user_data_length - p_stream->m_byte_offset :
+                               0;
+}
+
 /**
  * Skips a number of bytes from the stream.
  * @param              p_stream        the stream to skip data from.
index d98aa8610d8704cbedbce014f9ec83bf4b841476..55df189f73f5bae039d36b7dac84b788bda2d234 100644 (file)
@@ -125,6 +125,11 @@ typedef struct opj_stream_private
         */
        void *                                  m_user_data;
 
+       /**
+        * User data length
+        */
+       OPJ_UINT32                              m_user_data_length;
+
        /**
         * Pointer to actual read function (NULL at the initialization of the cio.
         */
@@ -326,6 +331,16 @@ OPJ_SIZE_T opj_stream_skip (opj_stream_private_t * p_stream,OPJ_SIZE_T p_size, s
  */
 OPJ_SIZE_T opj_stream_tell (const opj_stream_private_t * p_stream);
 
+
+/**
+ * Get the number of bytes left before the end of the stream (similar to cio_numbytesleft).
+ *
+ * @param              p_stream        the stream to get the information from.
+ *
+ * @return             Number of bytes left before the end of the stream.
+ */
+OPJ_SIZE_T opj_stream_get_number_byte_left (const opj_stream_private_t * p_stream);
+
 /**
  * Skips a number of bytes from the stream.
  * @param              p_stream        the stream to skip data from.
index 4bd37eac4ed55fda4fa06f88ed73e52f76747861..2de55b5e495c3fa5c0f00f9f479df57c1a97c624 100644 (file)
@@ -3352,10 +3352,9 @@ opj_bool j2k_read_sot_v2 (
 
        /* Ref A.4.2: Psot could be equal zero if it is the last tile-part of the codestream.*/
        if (!l_tot_len) {
-               opj_event_msg_v2(p_manager, EVT_ERROR, "Psot value of the current tile-part is equal to zero, "
-                               "for the moment we couldn't manage this case (need to compute the number of byte left"
-                               " in the codestream).\n");
-               return OPJ_FALSE;
+               opj_event_msg_v2(p_manager, EVT_INFO, "Psot value of the current tile-part is equal to zero, "
+                               "we assuming it is the last tile-part of the codestream.\n");
+               p_j2k->m_specific_param.m_decoder.m_last_tile_part = 1;
        }
 
        opj_read_bytes(p_header_data,&l_current_part ,1);       /* TPsot */
@@ -3575,7 +3574,11 @@ opj_bool j2k_read_sod_v2 (
        assert(p_stream != 00);
 
        l_tcp = &(p_j2k->m_cp.tcps[p_j2k->m_current_tile_number]);
-       p_j2k->m_specific_param.m_decoder.m_sot_length -= 2;
+
+       if (p_j2k->m_specific_param.m_decoder.m_last_tile_part)
+               p_j2k->m_specific_param.m_decoder.m_sot_length = opj_stream_get_number_byte_left(p_stream) - 2;
+       else
+               p_j2k->m_specific_param.m_decoder.m_sot_length -= 2;
 
        l_current_data = &(l_tcp->m_data);
        l_tile_len = &l_tcp->m_data_size;
@@ -6765,7 +6768,7 @@ opj_codestream_info_v2_t* j2k_get_cstr_info(opj_j2k_v2_t* p_j2k)
        cstr_info->m_default_tile_info.numlayers = l_default_tile->numlayers;
        cstr_info->m_default_tile_info.mct = l_default_tile->mct;
 
-       cstr_info->m_default_tile_info.tccp_info = (opj_tccp_info_t*) opj_calloc(1,sizeof(opj_tccp_info_t));
+       cstr_info->m_default_tile_info.tccp_info = (opj_tccp_info_t*) opj_calloc(cstr_info->nbcomps, sizeof(opj_tccp_info_t));
 
        for (compno = 0; compno < numcomps; compno++) {
                opj_tccp_t *l_tccp = &(l_default_tile->tccps[compno]);
@@ -6781,8 +6784,8 @@ opj_codestream_info_v2_t* j2k_get_cstr_info(opj_j2k_v2_t* p_j2k)
                l_tccp_info->qmfbid = l_tccp->qmfbid;
                if (l_tccp->numresolutions < J2K_MAXRLVLS)
                {
-                       memcpy(l_tccp_info->prch, l_tccp->prch, l_tccp->numresolutions);
-                       memcpy(l_tccp_info->prcw, l_tccp->prcw, l_tccp->numresolutions);
+                       memcpy(l_tccp_info->prch, l_tccp->prch, l_tccp->numresolutions - 1);
+                       memcpy(l_tccp_info->prcw, l_tccp->prcw, l_tccp->numresolutions - 1);
                }
 
                /* quantization style*/
index bec5f225a342af205867c2ff3fb07677ff2565da..629fc31239552fa29778a13285e3de2b62b88b4a 100644 (file)
@@ -126,6 +126,17 @@ OPJ_UINT32 opj_read_from_file (void * p_buffer, OPJ_UINT32 p_nb_bytes, FILE * p_
        return l_nb_read ? l_nb_read : -1;
 }
 
+OPJ_UINT32 opj_get_data_length_from_file (FILE * p_file)
+{
+       OPJ_UINT32 file_length = 0;
+
+       fseek(p_file, 0, SEEK_END);
+       file_length = ftell(p_file);
+       fseek(p_file, 0, SEEK_SET);
+
+       return file_length;
+}
+
 OPJ_UINT32 opj_write_from_file (void * p_buffer, OPJ_UINT32 p_nb_bytes, FILE * p_file)
 {
        return fwrite(p_buffer,1,p_nb_bytes,p_file);
@@ -586,6 +597,7 @@ opj_stream_t* OPJ_CALLCONV opj_stream_create_file_stream (FILE * p_file, OPJ_UIN
        }
 
        opj_stream_set_user_data(l_stream, p_file);
+       opj_stream_set_user_data_length(l_stream, opj_get_data_length_from_file(p_file));
        opj_stream_set_read_function(l_stream, (opj_stream_read_fn) opj_read_from_file);
        opj_stream_set_write_function(l_stream, (opj_stream_write_fn) opj_write_from_file);
        opj_stream_set_skip_function(l_stream, (opj_stream_skip_fn) opj_skip_from_file);
index 5cc8de1be2958517560310e25a14ab64e8660cca..34ad7ab8208938c9f94a8936dc20e416742c7d4b 100644 (file)
@@ -1085,6 +1085,13 @@ OPJ_API void OPJ_CALLCONV opj_stream_set_seek_function(opj_stream_t* p_stream, o
 */
 OPJ_API void OPJ_CALLCONV opj_stream_set_user_data (opj_stream_t* p_stream, void * p_data);
 
+/**
+ * Sets the length of the user data for the stream.
+ * @param              p_stream                the stream to modify
+ * @param              data_length             length of the user_data.
+*/
+OPJ_API void OPJ_CALLCONV opj_stream_set_user_data_length(opj_stream_t* p_stream, OPJ_UINT32 data_length);
+
 
 /**
  * Helper function.
index 537e95cff40d5b1280882ec1cf8025bce31fc097..e3a7dd3222251a03456af2e9848eb73b8f4e2762 100644 (file)
@@ -2458,53 +2458,60 @@ opj_bool tcd_mct_decode ( opj_tcd_v2_t *p_tcd )
        }
 
        l_samples = (l_tile_comp->x1 - l_tile_comp->x0) * (l_tile_comp->y1 - l_tile_comp->y0);
-       if (l_tcp->mct == 2) {
-               OPJ_BYTE ** l_data;
 
-               if (! l_tcp->m_mct_decoding_matrix) {
-                       return OPJ_TRUE;
-               }
+       if (l_tile->numcomps >= 3 ){
+               if (l_tcp->mct == 2) {
+                       OPJ_BYTE ** l_data;
 
-               l_data = (OPJ_BYTE **) opj_malloc(l_tile->numcomps*sizeof(OPJ_BYTE*));
-               if (! l_data) {
-                       return OPJ_FALSE;
-               }
+                       if (! l_tcp->m_mct_decoding_matrix) {
+                               return OPJ_TRUE;
+                       }
 
-               for (i=0;i<l_tile->numcomps;++i) {
-                       l_data[i] = (OPJ_BYTE*) l_tile_comp->data;
-                       ++l_tile_comp;
-               }
+                       l_data = (OPJ_BYTE **) opj_malloc(l_tile->numcomps*sizeof(OPJ_BYTE*));
+                       if (! l_data) {
+                               return OPJ_FALSE;
+                       }
 
-               if (! mct_decode_custom(// MCT data
-                                                               (OPJ_BYTE*) l_tcp->m_mct_decoding_matrix,
-                                                               // size of components
-                                                               l_samples,
-                                                               // components
-                                                               l_data,
-                                                               // nb of components (i.e. size of pData)
-                                                               l_tile->numcomps,
-                                                               // tells if the data is signed
-                                                               p_tcd->image->comps->sgnd)) {
-                       opj_free(l_data);
-                       return OPJ_FALSE;
-               }
+                       for (i=0;i<l_tile->numcomps;++i) {
+                               l_data[i] = (OPJ_BYTE*) l_tile_comp->data;
+                               ++l_tile_comp;
+                       }
 
-               opj_free(l_data);
-       }
-       else {
-               if (l_tcp->tccps->qmfbid == 1) {
-                       mct_decode(     l_tile->comps[0].data,
-                                               l_tile->comps[1].data,
-                                               l_tile->comps[2].data,
-                                               l_samples);
+                       if (! mct_decode_custom(// MCT data
+                                                                       (OPJ_BYTE*) l_tcp->m_mct_decoding_matrix,
+                                                                       // size of components
+                                                                       l_samples,
+                                                                       // components
+                                                                       l_data,
+                                                                       // nb of components (i.e. size of pData)
+                                                                       l_tile->numcomps,
+                                                                       // tells if the data is signed
+                                                                       p_tcd->image->comps->sgnd)) {
+                               opj_free(l_data);
+                               return OPJ_FALSE;
+                       }
+
+                       opj_free(l_data);
                }
                else {
-                       mct_decode_real(        (float*)l_tile->comps[0].data,
-                                                               (float*)l_tile->comps[1].data,
-                                                               (float*)l_tile->comps[2].data,
-                                                               l_samples);
+                       if (l_tcp->tccps->qmfbid == 1) {
+                               mct_decode(     l_tile->comps[0].data,
+                                                       l_tile->comps[1].data,
+                                                       l_tile->comps[2].data,
+                                                       l_samples);
+                       }
+                       else {
+                               mct_decode_real(        (float*)l_tile->comps[0].data,
+                                                                       (float*)l_tile->comps[1].data,
+                                                                       (float*)l_tile->comps[2].data,
+                                                                       l_samples);
+                       }
                }
        }
+       else {
+               /* FIXME need to use opj_event_msg_v2 function */
+               fprintf(stderr,"Number of components (%d) is inconsistent with a MCT. Skip the MCT step.\n",l_tile->numcomps);
+       }
 
        return OPJ_TRUE;
 }