]> granicus.if.org Git - openjpeg/commitdiff
Refactor opj_j2k_read_ppt
authormayeut <mayeut@users.noreply.github.com>
Sun, 12 Jul 2015 13:55:58 +0000 (15:55 +0200)
committermayeut <mayeut@users.noreply.github.com>
Sun, 12 Jul 2015 13:55:58 +0000 (15:55 +0200)
Update uclouvain/openjpeg#470
Update uclouvain/openjpeg#532

src/lib/openjp2/j2k.c
src/lib/openjp2/j2k.h

index 5892d579c0f9e785e176e2f0376544374f0700aa..7903ec54f54532563e14ccf47f37448a182f2bab 100644 (file)
@@ -753,6 +753,17 @@ static OPJ_BOOL opj_j2k_read_ppt (  opj_j2k_t *p_j2k,
                                     OPJ_BYTE * p_header_data,
                                     OPJ_UINT32 p_header_size,
                                     opj_event_mgr_t * p_manager );
+
+/**
+ * Merges all PPT markers read (Packed packet headers, tile-part header)
+ *
+ * @param       p_tcp   the tile.
+ * @param       p_manager               the user event manager.
+ */
+static OPJ_BOOL opj_j2k_merge_ppt (  opj_tcp_t *p_tcp,
+                                                                                                                                          opj_event_mgr_t * p_manager );
+
+
 /**
  * Writes the TLM marker (Tile Length Marker)
  *
@@ -3876,74 +3887,124 @@ static OPJ_BOOL opj_j2k_read_ppt (  opj_j2k_t *p_j2k,
                                     opj_event_mgr_t * p_manager
                                     )
 {
-        opj_cp_t *l_cp = 00;
-        opj_tcp_t *l_tcp = 00;
-        OPJ_UINT32 l_Z_ppt;
-
-        /* preconditions */
-        assert(p_header_data != 00);
-        assert(p_j2k != 00);
-        assert(p_manager != 00);
+       opj_cp_t *l_cp = 00;
+       opj_tcp_t *l_tcp = 00;
+       OPJ_UINT32 l_Z_ppt;
 
-        /* We need to have the Z_ppt element at minimum */
-        if (p_header_size < 1) {
-                opj_event_msg(p_manager, EVT_ERROR, "Error reading PPT marker\n");
-                return OPJ_FALSE;
-        }
-
-        l_cp = &(p_j2k->m_cp);
-        if (l_cp->ppm){
-                opj_event_msg(p_manager, EVT_ERROR, "Error reading PPT marker: packet header have been previously found in the main header (PPM marker).\n");
-                return OPJ_FALSE;
-        }
-
-        l_tcp = &(l_cp->tcps[p_j2k->m_current_tile_number]);
-        l_tcp->ppt = 1;
-
-        opj_read_bytes(p_header_data,&l_Z_ppt,1);               /* Z_ppt */
-        ++p_header_data;
-        --p_header_size;
-
-        /* Allocate buffer to read the packet header */
-        if (l_Z_ppt == 0) {
-                /* First PPT marker */
-                l_tcp->ppt_data_size = 0;
-                l_tcp->ppt_len = p_header_size;
-
-                opj_free(l_tcp->ppt_buffer);
-                l_tcp->ppt_buffer = (OPJ_BYTE *) opj_calloc(l_tcp->ppt_len, sizeof(OPJ_BYTE) );
-                if (l_tcp->ppt_buffer == 00) {
-                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
-                        return OPJ_FALSE;
-                }
-                l_tcp->ppt_data = l_tcp->ppt_buffer;
+       /* preconditions */
+       assert(p_header_data != 00);
+       assert(p_j2k != 00);
+       assert(p_manager != 00);
 
-                /* memset(l_tcp->ppt_buffer,0,l_tcp->ppt_len); */
-        }
-        else {
-                OPJ_BYTE *new_ppt_buffer;
-                l_tcp->ppt_len += p_header_size;
-
-                new_ppt_buffer = (OPJ_BYTE *) opj_realloc(l_tcp->ppt_buffer, l_tcp->ppt_len);
-                if (! new_ppt_buffer) {
-                        opj_free(l_tcp->ppt_buffer);
-                        l_tcp->ppt_buffer = NULL;
-                        l_tcp->ppt_len = 0;
-                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
-                        return OPJ_FALSE;
-                }
-                l_tcp->ppt_buffer = new_ppt_buffer;
-                l_tcp->ppt_data = l_tcp->ppt_buffer;
+       /* We need to have the Z_ppt element + 1 byte of Ippt at minimum */
+       if (p_header_size < 2) {
+               opj_event_msg(p_manager, EVT_ERROR, "Error reading PPT marker\n");
+               return OPJ_FALSE;
+       }
 
-                memset(l_tcp->ppt_buffer+l_tcp->ppt_data_size,0,p_header_size);
-        }
+       l_cp = &(p_j2k->m_cp);
+       if (l_cp->ppm){
+               opj_event_msg(p_manager, EVT_ERROR, "Error reading PPT marker: packet header have been previously found in the main header (PPM marker).\n");
+               return OPJ_FALSE;
+       }
 
-        /* Read packet header from buffer */
-        memcpy(l_tcp->ppt_buffer+l_tcp->ppt_data_size,p_header_data,p_header_size);
+       l_tcp = &(l_cp->tcps[p_j2k->m_current_tile_number]);
+       l_tcp->ppt = 1;
 
-        l_tcp->ppt_data_size += p_header_size;
+       opj_read_bytes(p_header_data,&l_Z_ppt,1);               /* Z_ppt */
+       ++p_header_data;
+       --p_header_size;
+       
+       /* check allocation needed */
+       if (l_tcp->ppt_markers == NULL) { /* first PPT marker */
+               OPJ_UINT32 l_newCount = l_Z_ppt + 1U; /* can't overflow, l_Z_ppt is UINT8 */
+               assert(l_tcp->ppt_markers_count == 0U);
+               
+               l_tcp->ppt_markers = (opj_ppt *) opj_calloc(l_newCount, sizeof(opj_ppt));
+               if (l_tcp->ppt_markers == NULL) {
+                       opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
+                       return OPJ_FALSE;
+               }
+               l_tcp->ppt_markers_count = l_newCount;
+       } else if (l_tcp->ppt_markers_count <= l_Z_ppt) {
+               OPJ_UINT32 l_newCount = l_Z_ppt + 1U; /* can't overflow, l_Z_ppt is UINT8 */
+               opj_ppt *new_ppt_markers;
+               new_ppt_markers = (opj_ppt *) opj_realloc(l_tcp->ppt_markers, l_newCount * sizeof(opj_ppt));
+               if (new_ppt_markers == NULL) {
+                       /* clean up to be done on l_tcp destruction */
+                       opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
+                       return OPJ_FALSE;
+               }
+               l_tcp->ppt_markers = new_ppt_markers;
+               memset(l_tcp->ppt_markers + l_tcp->ppt_markers_count, 0, (l_newCount - l_tcp->ppt_markers_count) * sizeof(opj_ppt));
+               l_tcp->ppt_markers_count = l_newCount;
+       }
+       
+       if (l_tcp->ppt_markers[l_Z_ppt].m_data != NULL) {
+               /* clean up to be done on l_tcp destruction */
+               opj_event_msg(p_manager, EVT_ERROR, "Zppt %u already read\n", l_Z_ppt);
+               return OPJ_FALSE;
+       }
+       
+       l_tcp->ppt_markers[l_Z_ppt].m_data = opj_malloc(p_header_size);
+       if (l_tcp->ppt_markers[l_Z_ppt].m_data == NULL) {
+               /* clean up to be done on l_tcp destruction */
+               opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
+               return OPJ_FALSE;
+       }
+       l_tcp->ppt_markers[l_Z_ppt].m_data_size = p_header_size;
+       memcpy(l_tcp->ppt_markers[l_Z_ppt].m_data, p_header_data, p_header_size);
+       return OPJ_TRUE;
+}
 
-        return OPJ_TRUE;
+/**
+ * Merges all PPT markers read (Packed packet headers, tile-part header)
+ *
+ * @param       p_tcp   the tile.
+ * @param       p_manager               the user event manager.
+ */
+static OPJ_BOOL opj_j2k_merge_ppt(opj_tcp_t *p_tcp, opj_event_mgr_t * p_manager)
+{
+       OPJ_UINT32 i, l_ppt_data_size;
+       /* preconditions */
+       assert(p_tcp != 00);
+       assert(p_manager != 00);
+       assert(p_tcp->ppt_buffer == NULL);
+       
+       if (p_tcp->ppt == 0U) {
+               return OPJ_TRUE;
+       }
+       
+       l_ppt_data_size = 0U;
+       for (i = 0U; i < p_tcp->ppt_markers_count; ++i) {
+               l_ppt_data_size += p_tcp->ppt_markers[i].m_data_size; /* can't overflow, max 256 markers of max 65536 bytes */
+       }
+       
+       p_tcp->ppt_buffer = (OPJ_BYTE *) opj_malloc(l_ppt_data_size);
+       if (p_tcp->ppt_buffer == 00) {
+               opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
+               return OPJ_FALSE;
+       }
+       p_tcp->ppt_len = l_ppt_data_size;
+       l_ppt_data_size = 0U;
+       for (i = 0U; i < p_tcp->ppt_markers_count; ++i) {
+               if (p_tcp->ppt_markers[i].m_data != NULL) { /* standard doesn't seem to require contiguous Zppt */
+                       memcpy(p_tcp->ppt_buffer + l_ppt_data_size, p_tcp->ppt_markers[i].m_data, p_tcp->ppt_markers[i].m_data_size);
+                       l_ppt_data_size += p_tcp->ppt_markers[i].m_data_size; /* can't overflow, max 256 markers of max 65536 bytes */
+                       
+                       opj_free(p_tcp->ppt_markers[i].m_data);
+                       p_tcp->ppt_markers[i].m_data = NULL;
+                       p_tcp->ppt_markers[i].m_data_size = 0U;
+               }
+       }
+       
+       p_tcp->ppt_markers_count = 0U;
+       opj_free(p_tcp->ppt_markers);
+       p_tcp->ppt_markers = NULL;
+       
+       p_tcp->ppt_data = p_tcp->ppt_buffer;
+       p_tcp->ppt_data_size = p_tcp->ppt_len;
+       return OPJ_TRUE;
 }
 
 OPJ_BOOL opj_j2k_write_tlm(     opj_j2k_t *p_j2k,
@@ -7623,60 +7684,72 @@ void j2k_destroy_cstr_index (opj_codestream_index_t *p_cstr_ind)
 
 void opj_j2k_tcp_destroy (opj_tcp_t *p_tcp)
 {
-        if (p_tcp == 00) {
-                return;
-        }
-
-        if (p_tcp->ppt_buffer != 00) {
-                opj_free(p_tcp->ppt_buffer);
-                p_tcp->ppt_buffer = 00;
-        }
-
-        if (p_tcp->tccps != 00) {
-                opj_free(p_tcp->tccps);
-                p_tcp->tccps = 00;
-        }
-
-        if (p_tcp->m_mct_coding_matrix != 00) {
-                opj_free(p_tcp->m_mct_coding_matrix);
-                p_tcp->m_mct_coding_matrix = 00;
-        }
-
-        if (p_tcp->m_mct_decoding_matrix != 00) {
-                opj_free(p_tcp->m_mct_decoding_matrix);
-                p_tcp->m_mct_decoding_matrix = 00;
-        }
-
-        if (p_tcp->m_mcc_records) {
-                opj_free(p_tcp->m_mcc_records);
-                p_tcp->m_mcc_records = 00;
-                p_tcp->m_nb_max_mcc_records = 0;
-                p_tcp->m_nb_mcc_records = 0;
-        }
-
-        if (p_tcp->m_mct_records) {
-                opj_mct_data_t * l_mct_data = p_tcp->m_mct_records;
-                OPJ_UINT32 i;
-
-                for (i=0;i<p_tcp->m_nb_mct_records;++i) {
-                        if (l_mct_data->m_data) {
-                                opj_free(l_mct_data->m_data);
-                                l_mct_data->m_data = 00;
-                        }
-
-                        ++l_mct_data;
-                }
-
-                opj_free(p_tcp->m_mct_records);
-                p_tcp->m_mct_records = 00;
-        }
+       if (p_tcp == 00) {
+               return;
+       }
+       
+       if (p_tcp->ppt_markers != 00) {
+               OPJ_UINT32 i;
+               for (i = 0U; i < p_tcp->ppt_markers_count; ++i) {
+                       if (p_tcp->ppt_markers[i].m_data != NULL) {
+                               opj_free(p_tcp->ppt_markers[i].m_data);
+                       }
+               }
+               p_tcp->ppt_markers_count = 0U;
+               opj_free(p_tcp->ppt_markers);
+               p_tcp->ppt_markers = NULL;
+       }
+       
+       if (p_tcp->ppt_buffer != 00) {
+               opj_free(p_tcp->ppt_buffer);
+               p_tcp->ppt_buffer = 00;
+       }
+       
+       if (p_tcp->tccps != 00) {
+               opj_free(p_tcp->tccps);
+               p_tcp->tccps = 00;
+       }
+       
+       if (p_tcp->m_mct_coding_matrix != 00) {
+               opj_free(p_tcp->m_mct_coding_matrix);
+               p_tcp->m_mct_coding_matrix = 00;
+       }
+       
+       if (p_tcp->m_mct_decoding_matrix != 00) {
+               opj_free(p_tcp->m_mct_decoding_matrix);
+               p_tcp->m_mct_decoding_matrix = 00;
+       }
+       
+       if (p_tcp->m_mcc_records) {
+               opj_free(p_tcp->m_mcc_records);
+               p_tcp->m_mcc_records = 00;
+               p_tcp->m_nb_max_mcc_records = 0;
+               p_tcp->m_nb_mcc_records = 0;
+       }
+       
+       if (p_tcp->m_mct_records) {
+               opj_mct_data_t * l_mct_data = p_tcp->m_mct_records;
+               OPJ_UINT32 i;
+               
+               for (i=0;i<p_tcp->m_nb_mct_records;++i) {
+                       if (l_mct_data->m_data) {
+                               opj_free(l_mct_data->m_data);
+                               l_mct_data->m_data = 00;
+                       }
+                       
+                       ++l_mct_data;
+               }
+               
+               opj_free(p_tcp->m_mct_records);
+               p_tcp->m_mct_records = 00;
+       }
 
-        if (p_tcp->mct_norms != 00) {
-                opj_free(p_tcp->mct_norms);
-                p_tcp->mct_norms = 00;
-        }
+       if (p_tcp->mct_norms != 00) {
+               opj_free(p_tcp->mct_norms);
+               p_tcp->mct_norms = 00;
+       }
 
-        opj_j2k_tcp_data_destroy(p_tcp);
+       opj_j2k_tcp_data_destroy(p_tcp);
 
 }
 
@@ -8111,6 +8184,11 @@ OPJ_BOOL opj_j2k_decode_tile (  opj_j2k_t * p_j2k,
                 opj_j2k_tcp_destroy(l_tcp);
                 return OPJ_FALSE;
         }
+       
+        if (! opj_j2k_merge_ppt(l_tcp, p_manager)) {
+                opj_j2k_tcp_destroy(l_tcp);
+                return OPJ_FALSE;
+        }
 
         if (! opj_tcd_decode_tile(      p_j2k->m_tcd,
                                                                 l_tcp->m_data,
index 2374e559b2c512c92242eba442370f159356284f..3853926a2852bc3029a8ebe5704ff4bf2ce08340 100644 (file)
@@ -232,6 +232,12 @@ typedef struct opj_simple_mcc_decorrelation_data
 }
 opj_simple_mcc_decorrelation_data_t;
 
+typedef struct opj_ppt_struct
+{
+       OPJ_BYTE*   m_data; /* m_data == NULL => Zppt not read yet */
+       OPJ_UINT32      m_data_size;
+} opj_ppt;
+
 /**
 Tile coding parameters :
 this structure is used to store coding/decoding parameters common to all
@@ -254,6 +260,12 @@ typedef struct opj_tcp
        OPJ_UINT32 numpocs;
        /** progression order changes */
        opj_poc_t pocs[32];
+       
+       /** number of ppt markers (reserved size) */
+       OPJ_UINT32 ppt_markers_count;
+       /** ppt markers data (table indexed by Zppm) */
+       opj_ppt* ppt_markers;
+       
        /** packet header store there for futur use in t2_decode_packet */
        OPJ_BYTE *ppt_data;
        /** used to keep a track of the allocated memory */