opj_j2k_read_sot(): check current TPSot number regarding previous (non-zero) TNsot...
[openjpeg.git] / src / lib / openjp2 / t2.c
index b0990963a2a4e722e134a8036305e4f535fb3b23..93b77ef0a3bd09aa717ff9fc4860cdbf7bee7d77 100644 (file)
@@ -38,6 +38,8 @@
  */
 
 #include "opj_includes.h"
+#include "opj_common.h"
+
 
 /** @defgroup T2 T2 - Implementation of a tier-2 coding */
 /*@{*/
@@ -87,6 +89,7 @@ Decode a packet of a tile from a source buffer
 @param data_read   FIXME DOC
 @param max_length  FIXME DOC
 @param pack_info Packet information
+@param p_manager the user event manager
 
 @return  FIXME DOC
 */
@@ -611,6 +614,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) {
@@ -633,9 +637,15 @@ static OPJ_BOOL opj_t2_encode_packet(OPJ_UINT32 tileno,
     if (!layno) {
         band = res->bands;
 
-        for (bandno = 0; bandno < res->numbands; ++bandno) {
-            opj_tcd_precinct_t *prc = &band->precincts[precno];
+        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];
             opj_tgt_reset(prc->incltree);
             opj_tgt_reset(prc->imsbtree);
 
@@ -646,7 +656,6 @@ static OPJ_BOOL opj_t2_encode_packet(OPJ_UINT32 tileno,
                 cblk->numpasses = 0;
                 opj_tgt_setvalue(prc->imsbtree, cblkno, band->numbps - (OPJ_INT32)cblk->numbps);
             }
-            ++band;
         }
     }
 
@@ -656,13 +665,50 @@ 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)      {
-        opj_tcd_precinct_t *prc = &band->precincts[precno];
+    for (bandno = 0; !packet_empty &&
+            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;
 
@@ -745,8 +791,6 @@ static OPJ_BOOL opj_t2_encode_packet(OPJ_UINT32 tileno,
 
             ++cblk;
         }
-
-        ++band;
     }
 
     if (!opj_bio_flush(bio)) {
@@ -780,9 +824,15 @@ static OPJ_BOOL opj_t2_encode_packet(OPJ_UINT32 tileno,
 
     /* Writing the packet body */
     band = res->bands;
-    for (bandno = 0; bandno < res->numbands; bandno++) {
-        opj_tcd_precinct_t *prc = &band->precincts[precno];
+    for (bandno = 0; !packet_empty && 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;
 
@@ -815,7 +865,6 @@ static OPJ_BOOL opj_t2_encode_packet(OPJ_UINT32 tileno,
             ++cblk;
             /* INDEX >> */
         }
-        ++band;
     }
 
     assert(c >= dest);
@@ -902,7 +951,7 @@ static OPJ_BOOL opj_t2_read_packet_header(opj_t2_t* p_t2,
 
         /* reset tagtrees */
         for (bandno = 0; bandno < l_res->numbands; ++bandno) {
-            if (!((l_band->x1 - l_band->x0 == 0) || (l_band->y1 - l_band->y0 == 0))) {
+            if (!opj_tcd_is_band_empty(l_band)) {
                 opj_tcd_precinct_t *l_prc = &l_band->precincts[p_pi->precno];
                 if (!(p_pi->precno < (l_band->precincts_data_size / sizeof(
                                           opj_tcd_precinct_t)))) {
@@ -1011,11 +1060,10 @@ static OPJ_BOOL opj_t2_read_packet_header(opj_t2_t* p_t2,
     }
 
     l_band = l_res->bands;
-    for (bandno = 0; bandno < l_res->numbands; ++bandno) {
+    for (bandno = 0; bandno < l_res->numbands; ++bandno, ++l_band) {
         opj_tcd_precinct_t *l_prc = &(l_band->precincts[p_pi->precno]);
 
-        if ((l_band->x1 - l_band->x0 == 0) || (l_band->y1 - l_band->y0 == 0)) {
-            ++l_band;
+        if (opj_tcd_is_band_empty(l_band)) {
             continue;
         }
 
@@ -1080,10 +1128,19 @@ static OPJ_BOOL opj_t2_read_packet_header(opj_t2_t* p_t2,
             n = (OPJ_INT32)l_cblk->numnewpasses;
 
             do {
+                OPJ_UINT32 bit_number;
                 l_cblk->segs[l_segno].numnewpasses = (OPJ_UINT32)opj_int_min((OPJ_INT32)(
                         l_cblk->segs[l_segno].maxpasses - l_cblk->segs[l_segno].numpasses), n);
-                l_cblk->segs[l_segno].newlen = opj_bio_read(l_bio,
-                                               l_cblk->numlenbits + opj_uint_floorlog2(l_cblk->segs[l_segno].numnewpasses));
+                bit_number = l_cblk->numlenbits + opj_uint_floorlog2(
+                                 l_cblk->segs[l_segno].numnewpasses);
+                if (bit_number > 32) {
+                    opj_event_msg(p_manager, EVT_ERROR,
+                                  "Invalid bit number %d in opj_t2_read_packet_header()\n",
+                                  bit_number);
+                    opj_bio_destroy(l_bio);
+                    return OPJ_FALSE;
+                }
+                l_cblk->segs[l_segno].newlen = opj_bio_read(l_bio, bit_number);
                 JAS_FPRINTF(stderr, "included=%d numnewpasses=%d increment=%d len=%d \n",
                             l_included, l_cblk->segs[l_segno].numnewpasses, l_increment,
                             l_cblk->segs[l_segno].newlen);
@@ -1101,8 +1158,6 @@ static OPJ_BOOL opj_t2_read_packet_header(opj_t2_t* p_t2,
 
             ++l_cblk;
         }
-
-        ++l_band;
     }
 
     if (!opj_bio_inalign(l_bio)) {
@@ -1233,7 +1288,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,
@@ -1241,9 +1297,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;
@@ -1251,7 +1308,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;
                 }