opj_j2k_read_sot(): check current TPSot number regarding previous (non-zero) TNsot...
[openjpeg.git] / src / lib / openjp2 / t2.c
index 7d27f6887ab05db326170cf82e9cbd638d1e7174..93b77ef0a3bd09aa717ff9fc4860cdbf7bee7d77 100644 (file)
@@ -89,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
 */
@@ -613,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) {
@@ -635,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);
 
@@ -648,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;
         }
     }
 
@@ -658,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;
 
@@ -747,8 +791,6 @@ static OPJ_BOOL opj_t2_encode_packet(OPJ_UINT32 tileno,
 
             ++cblk;
         }
-
-        ++band;
     }
 
     if (!opj_bio_flush(bio)) {
@@ -782,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;
 
@@ -817,7 +865,6 @@ static OPJ_BOOL opj_t2_encode_packet(OPJ_UINT32 tileno,
             ++cblk;
             /* INDEX >> */
         }
-        ++band;
     }
 
     assert(c >= dest);
@@ -904,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)))) {
@@ -1013,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;
         }
 
@@ -1082,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);
@@ -1103,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)) {