Merge branch 't1_flag_optimizations'
[openjpeg.git] / src / lib / openjp2 / t2.c
index f7395dfcaf469bdf342661d5e80ac77830cd6417..7a90065b2bc71c1e1ec73930f37603178c4f61ad 100644 (file)
@@ -38,6 +38,8 @@
  */
 
 #include "opj_includes.h"
+#include "opj_common.h"
+
 
 /** @defgroup T2 T2 - Implementation of a tier-2 coding */
 /*@{*/
@@ -611,6 +613,7 @@ static OPJ_BOOL opj_t2_encode_packet(OPJ_UINT32 tileno,
     opj_tcd_resolution_t *res = &tilec->resolutions[resno];
 
     opj_bio_t *bio = 00;    /* BIO component */
+    OPJ_BOOL packet_empty = OPJ_TRUE;
 
     /* <SOP 0xff91> */
     if (tcp->csty & J2K_CP_CSTY_SOP) {
@@ -661,11 +664,42 @@ static OPJ_BOOL opj_t2_encode_packet(OPJ_UINT32 tileno,
         return OPJ_FALSE;
     }
     opj_bio_init_enc(bio, c, length);
-    opj_bio_write(bio, 1, 1);           /* Empty header bit */
+
+    /* Check if the packet is empty */
+    /* Note: we could also skip that step and always write a packet header */
+    band = res->bands;
+    for (bandno = 0; bandno < res->numbands; ++bandno, ++band) {
+        opj_tcd_precinct_t *prc;
+        /* Skip empty bands */
+        if (opj_tcd_is_band_empty(band)) {
+            continue;
+        }
+
+        prc = &band->precincts[precno];
+        l_nb_blocks = prc->cw * prc->ch;
+        cblk = prc->cblks.enc;
+        for (cblkno = 0; cblkno < l_nb_blocks; cblkno++, ++cblk) {
+            opj_tcd_layer_t *layer = &cblk->layers[layno];
+
+            /* if cblk not included, go to the next cblk  */
+            if (!layer->numpasses) {
+                continue;
+            }
+            packet_empty = OPJ_FALSE;
+            break;
+        }
+        if (!packet_empty) {
+            break;
+        }
+    }
+
+    opj_bio_write(bio, packet_empty ? 0 : 1, 1);           /* Empty header bit */
+
 
     /* Writing Packet header */
     band = res->bands;
-    for (bandno = 0; bandno < res->numbands; ++bandno, ++band)      {
+    for (bandno = 0; !packet_empty &&
+            bandno < res->numbands; ++bandno, ++band)      {
         opj_tcd_precinct_t *prc;
 
         /* Skip empty bands */
@@ -789,7 +823,7 @@ static OPJ_BOOL opj_t2_encode_packet(OPJ_UINT32 tileno,
 
     /* Writing the packet body */
     band = res->bands;
-    for (bandno = 0; bandno < res->numbands; bandno++, ++band) {
+    for (bandno = 0; !packet_empty && bandno < res->numbands; bandno++, ++band) {
         opj_tcd_precinct_t *prc;
 
         /* Skip empty bands */
@@ -1244,7 +1278,8 @@ static OPJ_BOOL opj_t2_read_packet_data(opj_t2_t* p_t2,
 
 #endif /* USE_JPWL */
                 /* Check possible overflow on size */
-                if ((l_cblk->data_current_size + l_seg->newlen) < l_cblk->data_current_size) {
+                if ((l_cblk->data_current_size + l_seg->newlen + OPJ_COMMON_CBLK_DATA_EXTRA) <
+                        l_cblk->data_current_size) {
                     opj_event_msg(p_manager, EVT_ERROR,
                                   "read: segment too long (%d) with current size (%d > %d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
                                   l_seg->newlen, l_cblk->data_current_size, 0xFFFFFFFF - l_seg->newlen, cblkno,
@@ -1252,9 +1287,10 @@ static OPJ_BOOL opj_t2_read_packet_data(opj_t2_t* p_t2,
                     return OPJ_FALSE;
                 }
                 /* Check if the cblk->data have allocated enough memory */
-                if ((l_cblk->data_current_size + l_seg->newlen) > l_cblk->data_max_size) {
+                if ((l_cblk->data_current_size + l_seg->newlen + OPJ_COMMON_CBLK_DATA_EXTRA) >
+                        l_cblk->data_max_size) {
                     OPJ_BYTE* new_cblk_data = (OPJ_BYTE*) opj_realloc(l_cblk->data,
-                                              l_cblk->data_current_size + l_seg->newlen);
+                                              l_cblk->data_current_size + l_seg->newlen + OPJ_COMMON_CBLK_DATA_EXTRA);
                     if (! new_cblk_data) {
                         opj_free(l_cblk->data);
                         l_cblk->data = NULL;
@@ -1262,7 +1298,8 @@ static OPJ_BOOL opj_t2_read_packet_data(opj_t2_t* p_t2,
                         /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to realloc code block cata!\n"); */
                         return OPJ_FALSE;
                     }
-                    l_cblk->data_max_size = l_cblk->data_current_size + l_seg->newlen;
+                    l_cblk->data_max_size = l_cblk->data_current_size + l_seg->newlen +
+                                            OPJ_COMMON_CBLK_DATA_EXTRA;
                     l_cblk->data = new_cblk_data;
                 }