Upgrade OpenJPEG to 2.2.0

This CL upgrades OpenJPEG by copying the files from 2.2.0 and then applying
patches. Patch files that are no longer relevant are deleted. The relevant
ones are applied manually due to changes in formatting in OpenJPEG. Patch 34
is added to account for opj_malloc changes in PDFium.

Bug: chromium:718731
Change-Id: I3d316893eab5e235c9f71222a6818b8ae0c98383
Reviewed-on: https://pdfium-review.googlesource.com/12770
Commit-Queue: dsinclair <dsinclair@chromium.org>
Reviewed-by: dsinclair <dsinclair@chromium.org>
diff --git a/third_party/libopenjpeg20/t2.c b/third_party/libopenjpeg20/t2.c
index 5af1a69..c8cfcc2 100644
--- a/third_party/libopenjpeg20/t2.c
+++ b/third_party/libopenjpeg20/t2.c
@@ -1,6 +1,6 @@
 /*
- * The copyright in this software is being made available under the 2-clauses 
- * BSD License, included below. This software may be subject to other third 
+ * The copyright in this software is being made available under the 2-clauses
+ * BSD License, included below. This software may be subject to other third
  * party and contributor rights, including patent rights, and no such rights
  * are granted under this license.
  *
@@ -8,10 +8,10 @@
  * Copyright (c) 2002-2014, Professor Benoit Macq
  * Copyright (c) 2001-2003, David Janssens
  * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux 
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux
  * Copyright (c) 2003-2014, Antonin Descampe
  * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * Copyright (c) 2008, 2011-2012, Centre National d'Etudes Spatiales (CNES), FR 
+ * Copyright (c) 2008, 2011-2012, Centre National d'Etudes Spatiales (CNES), FR
  * Copyright (c) 2012, CS Systemes d'Information, France
  * All rights reserved.
  *
@@ -38,6 +38,8 @@
  */
 
 #include "opj_includes.h"
+#include "opj_common.h"
+
 
 /** @defgroup T2 T2 - Implementation of a tier-2 coding */
 /*@{*/
@@ -47,7 +49,7 @@
 
 static void opj_t2_putcommacode(opj_bio_t *bio, OPJ_INT32 n);
 
-static OPJ_UINT32 opj_t2_getcommacode(opj_bio_t *bio); 
+static OPJ_UINT32 opj_t2_getcommacode(opj_bio_t *bio);
 /**
 Variable length code for signalling delta Zil (truncation point)
 @param bio  Bit Input/Output component
@@ -68,14 +70,14 @@
 @param cstr_info Codestream information structure
 @return
 */
-static OPJ_BOOL opj_t2_encode_packet(   OPJ_UINT32 tileno,
-                                        opj_tcd_tile_t *tile,
-                                        opj_tcp_t *tcp,
-                                        opj_pi_iterator_t *pi,
-                                        OPJ_BYTE *dest,
-                                        OPJ_UINT32 * p_data_written,
-                                        OPJ_UINT32 len,
-                                        opj_codestream_info_t *cstr_info);
+static OPJ_BOOL opj_t2_encode_packet(OPJ_UINT32 tileno,
+                                     opj_tcd_tile_t *tile,
+                                     opj_tcp_t *tcp,
+                                     opj_pi_iterator_t *pi,
+                                     OPJ_BYTE *dest,
+                                     OPJ_UINT32 * p_data_written,
+                                     OPJ_UINT32 len,
+                                     opj_codestream_info_t *cstr_info);
 
 /**
 Decode a packet of a tile from a source buffer
@@ -87,39 +89,40 @@
 @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
 */
-static OPJ_BOOL opj_t2_decode_packet(   opj_t2_t* t2,
-                                        opj_tcd_tile_t *tile,
-                                        opj_tcp_t *tcp,
-                                        opj_pi_iterator_t *pi,
-                                        OPJ_BYTE *src,
-                                        OPJ_UINT32 * data_read,
-                                        OPJ_UINT32 max_length,
-                                        opj_packet_info_t *pack_info,
-                                        opj_event_mgr_t *p_manager);
+static OPJ_BOOL opj_t2_decode_packet(opj_t2_t* t2,
+                                     opj_tcd_tile_t *tile,
+                                     opj_tcp_t *tcp,
+                                     opj_pi_iterator_t *pi,
+                                     OPJ_BYTE *src,
+                                     OPJ_UINT32 * data_read,
+                                     OPJ_UINT32 max_length,
+                                     opj_packet_info_t *pack_info,
+                                     opj_event_mgr_t *p_manager);
 
-static OPJ_BOOL opj_t2_skip_packet( opj_t2_t* p_t2,
-                                    opj_tcd_tile_t *p_tile,
-                                    opj_tcp_t *p_tcp,
-                                    opj_pi_iterator_t *p_pi,
-                                    OPJ_BYTE *p_src,
-                                    OPJ_UINT32 * p_data_read,
-                                    OPJ_UINT32 p_max_length,
-                                    opj_packet_info_t *p_pack_info,
-                                    opj_event_mgr_t *p_manager);
+static OPJ_BOOL opj_t2_skip_packet(opj_t2_t* p_t2,
+                                   opj_tcd_tile_t *p_tile,
+                                   opj_tcp_t *p_tcp,
+                                   opj_pi_iterator_t *p_pi,
+                                   OPJ_BYTE *p_src,
+                                   OPJ_UINT32 * p_data_read,
+                                   OPJ_UINT32 p_max_length,
+                                   opj_packet_info_t *p_pack_info,
+                                   opj_event_mgr_t *p_manager);
 
-static OPJ_BOOL opj_t2_read_packet_header(  opj_t2_t* p_t2,
-                                            opj_tcd_tile_t *p_tile,
-                                            opj_tcp_t *p_tcp,
-                                            opj_pi_iterator_t *p_pi,
-                                            OPJ_BOOL * p_is_data_present,
-                                            OPJ_BYTE *p_src_data,
-                                            OPJ_UINT32 * p_data_read,
-                                            OPJ_UINT32 p_max_length,
-                                            opj_packet_info_t *p_pack_info,
-                                            opj_event_mgr_t *p_manager);
+static OPJ_BOOL opj_t2_read_packet_header(opj_t2_t* p_t2,
+        opj_tcd_tile_t *p_tile,
+        opj_tcp_t *p_tcp,
+        opj_pi_iterator_t *p_pi,
+        OPJ_BOOL * p_is_data_present,
+        OPJ_BYTE *p_src_data,
+        OPJ_UINT32 * p_data_read,
+        OPJ_UINT32 p_max_length,
+        opj_packet_info_t *p_pack_info,
+        opj_event_mgr_t *p_manager);
 
 static OPJ_BOOL opj_t2_read_packet_data(opj_t2_t* p_t2,
                                         opj_tcd_tile_t *p_tile,
@@ -144,10 +147,10 @@
 @param cblksty
 @param first
 */
-static OPJ_BOOL opj_t2_init_seg(    opj_tcd_cblk_dec_t* cblk,
-                                    OPJ_UINT32 index,
-                                    OPJ_UINT32 cblksty,
-                                    OPJ_UINT32 first);
+static OPJ_BOOL opj_t2_init_seg(opj_tcd_cblk_dec_t* cblk,
+                                OPJ_UINT32 index,
+                                OPJ_UINT32 cblksty,
+                                OPJ_UINT32 first);
 
 /*@}*/
 
@@ -156,179 +159,192 @@
 /* ----------------------------------------------------------------------- */
 
 /* #define RESTART 0x04 */
-static void opj_t2_putcommacode(opj_bio_t *bio, OPJ_INT32 n) {
-        while (--n >= 0) {
-                opj_bio_write(bio, 1, 1);
-        }
-        opj_bio_write(bio, 0, 1);
+static void opj_t2_putcommacode(opj_bio_t *bio, OPJ_INT32 n)
+{
+    while (--n >= 0) {
+        opj_bio_write(bio, 1, 1);
+    }
+    opj_bio_write(bio, 0, 1);
 }
 
 static OPJ_UINT32 opj_t2_getcommacode(opj_bio_t *bio)
 {
     OPJ_UINT32 n = 0;
     while (opj_bio_read(bio, 1)) {
-	    ++n;
+        ++n;
     }
     return n;
 }
 
-static void opj_t2_putnumpasses(opj_bio_t *bio, OPJ_UINT32 n) {
-        if (n == 1) {
-                opj_bio_write(bio, 0, 1);
-        } else if (n == 2) {
-                opj_bio_write(bio, 2, 2);
-        } else if (n <= 5) {
-                opj_bio_write(bio, 0xc | (n - 3), 4);
-        } else if (n <= 36) {
-                opj_bio_write(bio, 0x1e0 | (n - 6), 9);
-        } else if (n <= 164) {
-                opj_bio_write(bio, 0xff80 | (n - 37), 16);
-        }
+static void opj_t2_putnumpasses(opj_bio_t *bio, OPJ_UINT32 n)
+{
+    if (n == 1) {
+        opj_bio_write(bio, 0, 1);
+    } else if (n == 2) {
+        opj_bio_write(bio, 2, 2);
+    } else if (n <= 5) {
+        opj_bio_write(bio, 0xc | (n - 3), 4);
+    } else if (n <= 36) {
+        opj_bio_write(bio, 0x1e0 | (n - 6), 9);
+    } else if (n <= 164) {
+        opj_bio_write(bio, 0xff80 | (n - 37), 16);
+    }
 }
 
-static OPJ_UINT32 opj_t2_getnumpasses(opj_bio_t *bio) {
-        OPJ_UINT32 n;
-        if (!opj_bio_read(bio, 1))
-                return 1;
-        if (!opj_bio_read(bio, 1))
-                return 2;
-        if ((n = opj_bio_read(bio, 2)) != 3)
-                return (3 + n);
-        if ((n = opj_bio_read(bio, 5)) != 31)
-                return (6 + n);
-        return (37 + opj_bio_read(bio, 7));
+static OPJ_UINT32 opj_t2_getnumpasses(opj_bio_t *bio)
+{
+    OPJ_UINT32 n;
+    if (!opj_bio_read(bio, 1)) {
+        return 1;
+    }
+    if (!opj_bio_read(bio, 1)) {
+        return 2;
+    }
+    if ((n = opj_bio_read(bio, 2)) != 3) {
+        return (3 + n);
+    }
+    if ((n = opj_bio_read(bio, 5)) != 31) {
+        return (6 + n);
+    }
+    return (37 + opj_bio_read(bio, 7));
 }
 
 /* ----------------------------------------------------------------------- */
 
-OPJ_BOOL opj_t2_encode_packets( opj_t2_t* p_t2,
-                                OPJ_UINT32 p_tile_no,
-                                opj_tcd_tile_t *p_tile,
-                                OPJ_UINT32 p_maxlayers,
-                                OPJ_BYTE *p_dest,
-                                OPJ_UINT32 * p_data_written,
-                                OPJ_UINT32 p_max_len,
-                                opj_codestream_info_t *cstr_info,
-                                OPJ_UINT32 p_tp_num,
-                                OPJ_INT32 p_tp_pos,
-                                OPJ_UINT32 p_pino,
-                                J2K_T2_MODE p_t2_mode)
+OPJ_BOOL opj_t2_encode_packets(opj_t2_t* p_t2,
+                               OPJ_UINT32 p_tile_no,
+                               opj_tcd_tile_t *p_tile,
+                               OPJ_UINT32 p_maxlayers,
+                               OPJ_BYTE *p_dest,
+                               OPJ_UINT32 * p_data_written,
+                               OPJ_UINT32 p_max_len,
+                               opj_codestream_info_t *cstr_info,
+                               OPJ_UINT32 p_tp_num,
+                               OPJ_INT32 p_tp_pos,
+                               OPJ_UINT32 p_pino,
+                               J2K_T2_MODE p_t2_mode)
 {
-        OPJ_BYTE *l_current_data = p_dest;
-        OPJ_UINT32 l_nb_bytes = 0;
-        OPJ_UINT32 compno;
-        OPJ_UINT32 poc;
-        opj_pi_iterator_t *l_pi = 00;
-        opj_pi_iterator_t *l_current_pi = 00;
-        opj_image_t *l_image = p_t2->image;
-        opj_cp_t *l_cp = p_t2->cp;
-        opj_tcp_t *l_tcp = &l_cp->tcps[p_tile_no];
-        OPJ_UINT32 pocno = (l_cp->rsiz == OPJ_PROFILE_CINEMA_4K)? 2: 1;
-        OPJ_UINT32 l_max_comp = l_cp->m_specific_param.m_enc.m_max_comp_size > 0 ? l_image->numcomps : 1;
-        OPJ_UINT32 l_nb_pocs = l_tcp->numpocs + 1;
+    OPJ_BYTE *l_current_data = p_dest;
+    OPJ_UINT32 l_nb_bytes = 0;
+    OPJ_UINT32 compno;
+    OPJ_UINT32 poc;
+    opj_pi_iterator_t *l_pi = 00;
+    opj_pi_iterator_t *l_current_pi = 00;
+    opj_image_t *l_image = p_t2->image;
+    opj_cp_t *l_cp = p_t2->cp;
+    opj_tcp_t *l_tcp = &l_cp->tcps[p_tile_no];
+    OPJ_UINT32 pocno = (l_cp->rsiz == OPJ_PROFILE_CINEMA_4K) ? 2 : 1;
+    OPJ_UINT32 l_max_comp = l_cp->m_specific_param.m_enc.m_max_comp_size > 0 ?
+                            l_image->numcomps : 1;
+    OPJ_UINT32 l_nb_pocs = l_tcp->numpocs + 1;
 
-        l_pi = opj_pi_initialise_encode(l_image, l_cp, p_tile_no, p_t2_mode);
-        if (!l_pi) {
-                return OPJ_FALSE;
-        }
+    l_pi = opj_pi_initialise_encode(l_image, l_cp, p_tile_no, p_t2_mode);
+    if (!l_pi) {
+        return OPJ_FALSE;
+    }
 
-        * p_data_written = 0;
+    * p_data_written = 0;
 
-        if (p_t2_mode == THRESH_CALC ){ /* Calculating threshold */
-                l_current_pi = l_pi;
+    if (p_t2_mode == THRESH_CALC) { /* Calculating threshold */
+        l_current_pi = l_pi;
 
-                for     (compno = 0; compno < l_max_comp; ++compno) {
-                        OPJ_UINT32 l_comp_len = 0;
-                        l_current_pi = l_pi;
+        for (compno = 0; compno < l_max_comp; ++compno) {
+            OPJ_UINT32 l_comp_len = 0;
+            l_current_pi = l_pi;
 
-                        for (poc = 0; poc < pocno ; ++poc) {
-                                OPJ_UINT32 l_tp_num = compno;
+            for (poc = 0; poc < pocno ; ++poc) {
+                OPJ_UINT32 l_tp_num = compno;
 
-                                /* TODO MSD : check why this function cannot fail (cf. v1) */
-                                opj_pi_create_encode(l_pi, l_cp,p_tile_no,poc,l_tp_num,p_tp_pos,p_t2_mode);
+                /* TODO MSD : check why this function cannot fail (cf. v1) */
+                opj_pi_create_encode(l_pi, l_cp, p_tile_no, poc, l_tp_num, p_tp_pos, p_t2_mode);
 
-                                if (l_current_pi->poc.prg == OPJ_PROG_UNKNOWN) {
-                                    /* TODO ADE : add an error */
-                                    opj_pi_destroy(l_pi, l_nb_pocs);
-                                    return OPJ_FALSE;
-                                }
-                                while (opj_pi_next(l_current_pi)) {
-                                        if (l_current_pi->layno < p_maxlayers) {
-                                                l_nb_bytes = 0;
-
-                                                if (! opj_t2_encode_packet(p_tile_no,p_tile, l_tcp, l_current_pi, l_current_data, &l_nb_bytes, p_max_len, cstr_info)) {
-                                                        opj_pi_destroy(l_pi, l_nb_pocs);
-                                                        return OPJ_FALSE;
-                                                }
-
-                                                l_comp_len += l_nb_bytes;
-                                                l_current_data += l_nb_bytes;
-                                                p_max_len -= l_nb_bytes;
-
-                                                * p_data_written += l_nb_bytes;
-                                        }
-                                }
-
-                                if (l_cp->m_specific_param.m_enc.m_max_comp_size) {
-                                        if (l_comp_len > l_cp->m_specific_param.m_enc.m_max_comp_size) {
-                                                opj_pi_destroy(l_pi, l_nb_pocs);
-                                                return OPJ_FALSE;
-                                        }
-                                }
-
-                                ++l_current_pi;
-                        }
-                }
-        }
-        else {  /* t2_mode == FINAL_PASS  */
-                opj_pi_create_encode(l_pi, l_cp,p_tile_no,p_pino,p_tp_num,p_tp_pos,p_t2_mode);
-
-                l_current_pi = &l_pi[p_pino];
                 if (l_current_pi->poc.prg == OPJ_PROG_UNKNOWN) {
                     /* TODO ADE : add an error */
                     opj_pi_destroy(l_pi, l_nb_pocs);
                     return OPJ_FALSE;
                 }
                 while (opj_pi_next(l_current_pi)) {
-                        if (l_current_pi->layno < p_maxlayers) {
-                                l_nb_bytes=0;
+                    if (l_current_pi->layno < p_maxlayers) {
+                        l_nb_bytes = 0;
 
-                                if (! opj_t2_encode_packet(p_tile_no,p_tile, l_tcp, l_current_pi, l_current_data, &l_nb_bytes, p_max_len, cstr_info)) {
-                                        opj_pi_destroy(l_pi, l_nb_pocs);
-                                        return OPJ_FALSE;
-                                }
-
-                                l_current_data += l_nb_bytes;
-                                p_max_len -= l_nb_bytes;
-
-                                * p_data_written += l_nb_bytes;
-
-                                /* INDEX >> */
-                                if(cstr_info) {
-                                        if(cstr_info->index_write) {
-                                                opj_tile_info_t *info_TL = &cstr_info->tile[p_tile_no];
-                                                opj_packet_info_t *info_PK = &info_TL->packet[cstr_info->packno];
-                                                if (!cstr_info->packno) {
-                                                        info_PK->start_pos = info_TL->end_header + 1;
-                                                } else {
-                                                        info_PK->start_pos = ((l_cp->m_specific_param.m_enc.m_tp_on | l_tcp->POC)&& info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[cstr_info->packno - 1].end_pos + 1;
-                                                }
-                                                info_PK->end_pos = info_PK->start_pos + l_nb_bytes - 1;
-                                                info_PK->end_ph_pos += info_PK->start_pos - 1;  /* End of packet header which now only represents the distance
-                                                                                                                                                                                                                                                   to start of packet is incremented by value of start of packet*/
-                                        }
-
-                                        cstr_info->packno++;
-                                }
-                                /* << INDEX */
-                                ++p_tile->packno;
+                        if (! opj_t2_encode_packet(p_tile_no, p_tile, l_tcp, l_current_pi,
+                                                   l_current_data, &l_nb_bytes, p_max_len, cstr_info)) {
+                            opj_pi_destroy(l_pi, l_nb_pocs);
+                            return OPJ_FALSE;
                         }
+
+                        l_comp_len += l_nb_bytes;
+                        l_current_data += l_nb_bytes;
+                        p_max_len -= l_nb_bytes;
+
+                        * p_data_written += l_nb_bytes;
+                    }
                 }
+
+                if (l_cp->m_specific_param.m_enc.m_max_comp_size) {
+                    if (l_comp_len > l_cp->m_specific_param.m_enc.m_max_comp_size) {
+                        opj_pi_destroy(l_pi, l_nb_pocs);
+                        return OPJ_FALSE;
+                    }
+                }
+
+                ++l_current_pi;
+            }
         }
+    } else { /* t2_mode == FINAL_PASS  */
+        opj_pi_create_encode(l_pi, l_cp, p_tile_no, p_pino, p_tp_num, p_tp_pos,
+                             p_t2_mode);
 
-        opj_pi_destroy(l_pi, l_nb_pocs);
+        l_current_pi = &l_pi[p_pino];
+        if (l_current_pi->poc.prg == OPJ_PROG_UNKNOWN) {
+            /* TODO ADE : add an error */
+            opj_pi_destroy(l_pi, l_nb_pocs);
+            return OPJ_FALSE;
+        }
+        while (opj_pi_next(l_current_pi)) {
+            if (l_current_pi->layno < p_maxlayers) {
+                l_nb_bytes = 0;
 
-        return OPJ_TRUE;
+                if (! opj_t2_encode_packet(p_tile_no, p_tile, l_tcp, l_current_pi,
+                                           l_current_data, &l_nb_bytes, p_max_len, cstr_info)) {
+                    opj_pi_destroy(l_pi, l_nb_pocs);
+                    return OPJ_FALSE;
+                }
+
+                l_current_data += l_nb_bytes;
+                p_max_len -= l_nb_bytes;
+
+                * p_data_written += l_nb_bytes;
+
+                /* INDEX >> */
+                if (cstr_info) {
+                    if (cstr_info->index_write) {
+                        opj_tile_info_t *info_TL = &cstr_info->tile[p_tile_no];
+                        opj_packet_info_t *info_PK = &info_TL->packet[cstr_info->packno];
+                        if (!cstr_info->packno) {
+                            info_PK->start_pos = info_TL->end_header + 1;
+                        } else {
+                            info_PK->start_pos = ((l_cp->m_specific_param.m_enc.m_tp_on | l_tcp->POC) &&
+                                                  info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[cstr_info->packno -
+                                                                            1].end_pos + 1;
+                        }
+                        info_PK->end_pos = info_PK->start_pos + l_nb_bytes - 1;
+                        info_PK->end_ph_pos += info_PK->start_pos -
+                                               1;  /* End of packet header which now only represents the distance
+                                                                                                                                                                                                                                                   to start of packet is incremented by value of start of packet*/
+                    }
+
+                    cstr_info->packno++;
+                }
+                /* << INDEX */
+                ++p_tile->packno;
+            }
+        }
+    }
+
+    opj_pi_destroy(l_pi, l_nb_pocs);
+
+    return OPJ_TRUE;
 }
 
 /* see issue 80 */
@@ -338,154 +354,167 @@
 /* issue 290 */
 static void opj_null_jas_fprintf(FILE* file, const char * format, ...)
 {
-  (void)file;
-  (void)format;
+    (void)file;
+    (void)format;
 }
 #define JAS_FPRINTF opj_null_jas_fprintf
 #endif
 
-OPJ_BOOL opj_t2_decode_packets( opj_t2_t *p_t2,
-                                OPJ_UINT32 p_tile_no,
-                                opj_tcd_tile_t *p_tile,
-                                OPJ_BYTE *p_src,
-                                OPJ_UINT32 * p_data_read,
-                                OPJ_UINT32 p_max_len,
-                                opj_codestream_index_t *p_cstr_index,
-                                opj_event_mgr_t *p_manager)
+OPJ_BOOL opj_t2_decode_packets(opj_t2_t *p_t2,
+                               OPJ_UINT32 p_tile_no,
+                               opj_tcd_tile_t *p_tile,
+                               OPJ_BYTE *p_src,
+                               OPJ_UINT32 * p_data_read,
+                               OPJ_UINT32 p_max_len,
+                               opj_codestream_index_t *p_cstr_index,
+                               opj_event_mgr_t *p_manager)
 {
-        OPJ_BYTE *l_current_data = p_src;
-        opj_pi_iterator_t *l_pi = 00;
-        OPJ_UINT32 pino;
-        opj_image_t *l_image = p_t2->image;
-        opj_cp_t *l_cp = p_t2->cp;
-        opj_tcp_t *l_tcp = &(p_t2->cp->tcps[p_tile_no]);
-        OPJ_UINT32 l_nb_bytes_read;
-        OPJ_UINT32 l_nb_pocs = l_tcp->numpocs + 1;
-        opj_pi_iterator_t *l_current_pi = 00;
+    OPJ_BYTE *l_current_data = p_src;
+    opj_pi_iterator_t *l_pi = 00;
+    OPJ_UINT32 pino;
+    opj_image_t *l_image = p_t2->image;
+    opj_cp_t *l_cp = p_t2->cp;
+    opj_tcp_t *l_tcp = &(p_t2->cp->tcps[p_tile_no]);
+    OPJ_UINT32 l_nb_bytes_read;
+    OPJ_UINT32 l_nb_pocs = l_tcp->numpocs + 1;
+    opj_pi_iterator_t *l_current_pi = 00;
 #ifdef TODO_MSD
-        OPJ_UINT32 curtp = 0;
-        OPJ_UINT32 tp_start_packno;
-#endif 
-        opj_packet_info_t *l_pack_info = 00;
-        opj_image_comp_t* l_img_comp = 00;
+    OPJ_UINT32 curtp = 0;
+    OPJ_UINT32 tp_start_packno;
+#endif
+    opj_packet_info_t *l_pack_info = 00;
+    opj_image_comp_t* l_img_comp = 00;
 
-        OPJ_ARG_NOT_USED(p_cstr_index);
+    OPJ_ARG_NOT_USED(p_cstr_index);
 
 #ifdef TODO_MSD
-        if (p_cstr_index) {
-                l_pack_info = p_cstr_index->tile_index[p_tile_no].packet;
-        }
+    if (p_cstr_index) {
+        l_pack_info = p_cstr_index->tile_index[p_tile_no].packet;
+    }
 #endif
 
-        /* create a packet iterator */
-        l_pi = opj_pi_create_decode(l_image, l_cp, p_tile_no);
-        if (!l_pi) {
-                return OPJ_FALSE;
+    /* create a packet iterator */
+    l_pi = opj_pi_create_decode(l_image, l_cp, p_tile_no);
+    if (!l_pi) {
+        return OPJ_FALSE;
+    }
+
+
+    l_current_pi = l_pi;
+
+    for (pino = 0; pino <= l_tcp->numpocs; ++pino) {
+
+        /* if the resolution needed is too low, one dim of the tilec could be equal to zero
+         * and no packets are used to decode this resolution and
+         * l_current_pi->resno is always >= p_tile->comps[l_current_pi->compno].minimum_num_resolutions
+         * and no l_img_comp->resno_decoded are computed
+         */
+        OPJ_BOOL* first_pass_failed = NULL;
+
+        if (l_current_pi->poc.prg == OPJ_PROG_UNKNOWN) {
+            /* TODO ADE : add an error */
+            opj_pi_destroy(l_pi, l_nb_pocs);
+            return OPJ_FALSE;
         }
 
+        first_pass_failed = (OPJ_BOOL*)opj_malloc(l_image->numcomps * sizeof(OPJ_BOOL));
+        if (!first_pass_failed) {
+            opj_pi_destroy(l_pi, l_nb_pocs);
+            return OPJ_FALSE;
+        }
+        memset(first_pass_failed, OPJ_TRUE, l_image->numcomps * sizeof(OPJ_BOOL));
 
-        l_current_pi = l_pi;
+        while (opj_pi_next(l_current_pi)) {
+            JAS_FPRINTF(stderr,
+                        "packet offset=00000166 prg=%d cmptno=%02d rlvlno=%02d prcno=%03d lyrno=%02d\n\n",
+                        l_current_pi->poc.prg1, l_current_pi->compno, l_current_pi->resno,
+                        l_current_pi->precno, l_current_pi->layno);
 
-        for     (pino = 0; pino <= l_tcp->numpocs; ++pino) {
+            if (l_tcp->num_layers_to_decode > l_current_pi->layno
+                    && l_current_pi->resno <
+                    p_tile->comps[l_current_pi->compno].minimum_num_resolutions) {
+                l_nb_bytes_read = 0;
 
-                /* if the resolution needed is too low, one dim of the tilec could be equal to zero
-                 * and no packets are used to decode this resolution and
-                 * l_current_pi->resno is always >= p_tile->comps[l_current_pi->compno].minimum_num_resolutions
-                 * and no l_img_comp->resno_decoded are computed
-                 */
-                OPJ_BOOL* first_pass_failed = NULL;
-					
-                if (l_current_pi->poc.prg == OPJ_PROG_UNKNOWN) {
-                    /* TODO ADE : add an error */
+                first_pass_failed[l_current_pi->compno] = OPJ_FALSE;
+
+                if (! opj_t2_decode_packet(p_t2, p_tile, l_tcp, l_current_pi, l_current_data,
+                                           &l_nb_bytes_read, p_max_len, l_pack_info, p_manager)) {
                     opj_pi_destroy(l_pi, l_nb_pocs);
+                    opj_free(first_pass_failed);
                     return OPJ_FALSE;
                 }
-					
-                first_pass_failed = (OPJ_BOOL*)opj_malloc(l_image->numcomps * sizeof(OPJ_BOOL));
-                if (!first_pass_failed)
-                {
-                    opj_pi_destroy(l_pi,l_nb_pocs);
+
+                l_img_comp = &(l_image->comps[l_current_pi->compno]);
+                l_img_comp->resno_decoded = opj_uint_max(l_current_pi->resno,
+                                            l_img_comp->resno_decoded);
+            } else {
+                l_nb_bytes_read = 0;
+                if (! opj_t2_skip_packet(p_t2, p_tile, l_tcp, l_current_pi, l_current_data,
+                                         &l_nb_bytes_read, p_max_len, l_pack_info, p_manager)) {
+                    opj_pi_destroy(l_pi, l_nb_pocs);
+                    opj_free(first_pass_failed);
                     return OPJ_FALSE;
                 }
-                memset(first_pass_failed, OPJ_TRUE, l_image->numcomps * sizeof(OPJ_BOOL));
+            }
 
-                while (opj_pi_next(l_current_pi)) {
-                  JAS_FPRINTF( stderr, "packet offset=00000166 prg=%d cmptno=%02d rlvlno=%02d prcno=%03d lyrno=%02d\n\n",
-                    l_current_pi->poc.prg1, l_current_pi->compno, l_current_pi->resno, l_current_pi->precno, l_current_pi->layno );
-
-                        if (l_tcp->num_layers_to_decode > l_current_pi->layno
-                                        && l_current_pi->resno < p_tile->comps[l_current_pi->compno].minimum_num_resolutions) {
-                                l_nb_bytes_read = 0;
-
-                                first_pass_failed[l_current_pi->compno] = OPJ_FALSE;
-
-                                if (! opj_t2_decode_packet(p_t2,p_tile,l_tcp,l_current_pi,l_current_data,&l_nb_bytes_read,p_max_len,l_pack_info, p_manager)) {
-                                        opj_pi_destroy(l_pi,l_nb_pocs);
-                                        opj_free(first_pass_failed);
-                                        return OPJ_FALSE;
-                                }
-
-                                l_img_comp = &(l_image->comps[l_current_pi->compno]);
-                                l_img_comp->resno_decoded = opj_uint_max(l_current_pi->resno, l_img_comp->resno_decoded);
-                        }
-                        else {
-                                l_nb_bytes_read = 0;
-                                if (! opj_t2_skip_packet(p_t2,p_tile,l_tcp,l_current_pi,l_current_data,&l_nb_bytes_read,p_max_len,l_pack_info, p_manager)) {
-                                        opj_pi_destroy(l_pi,l_nb_pocs);
-                                        opj_free(first_pass_failed);
-                                        return OPJ_FALSE;
-                                }
-                        }
-
-                        if (first_pass_failed[l_current_pi->compno]) {
-                                l_img_comp = &(l_image->comps[l_current_pi->compno]);
-                                if (l_img_comp->resno_decoded == 0)
-                                        l_img_comp->resno_decoded = p_tile->comps[l_current_pi->compno].minimum_num_resolutions - 1;
-                        }
-
-                        l_current_data += l_nb_bytes_read;
-                        p_max_len -= l_nb_bytes_read;
-
-                        /* INDEX >> */
-#ifdef TODO_MSD
-                        if(p_cstr_info) {
-                                opj_tile_info_v2_t *info_TL = &p_cstr_info->tile[p_tile_no];
-                                opj_packet_info_t *info_PK = &info_TL->packet[p_cstr_info->packno];
-                                tp_start_packno = 0;
-                                if (!p_cstr_info->packno) {
-                                        info_PK->start_pos = info_TL->end_header + 1;
-                                } else if (info_TL->packet[p_cstr_info->packno-1].end_pos >= (OPJ_INT32)p_cstr_info->tile[p_tile_no].tp[curtp].tp_end_pos){ /* New tile part */
-                                        info_TL->tp[curtp].tp_numpacks = p_cstr_info->packno - tp_start_packno; /* Number of packets in previous tile-part */
-                                        tp_start_packno = p_cstr_info->packno;
-                                        curtp++;
-                                        info_PK->start_pos = p_cstr_info->tile[p_tile_no].tp[curtp].tp_end_header+1;
-                                } else {
-                                        info_PK->start_pos = (l_cp->m_specific_param.m_enc.m_tp_on && info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[p_cstr_info->packno - 1].end_pos + 1;
-                                }
-                                info_PK->end_pos = info_PK->start_pos + l_nb_bytes_read - 1;
-                                info_PK->end_ph_pos += info_PK->start_pos - 1;  /* End of packet header which now only represents the distance */
-                                ++p_cstr_info->packno;
-                        }
-#endif
-                        /* << INDEX */
+            if (first_pass_failed[l_current_pi->compno]) {
+                l_img_comp = &(l_image->comps[l_current_pi->compno]);
+                if (l_img_comp->resno_decoded == 0) {
+                    l_img_comp->resno_decoded =
+                        p_tile->comps[l_current_pi->compno].minimum_num_resolutions - 1;
                 }
-                ++l_current_pi;
+            }
 
-                opj_free(first_pass_failed);
-        }
-        /* INDEX >> */
+            l_current_data += l_nb_bytes_read;
+            p_max_len -= l_nb_bytes_read;
+
+            /* INDEX >> */
 #ifdef TODO_MSD
-        if
-                (p_cstr_info) {
-                p_cstr_info->tile[p_tile_no].tp[curtp].tp_numpacks = p_cstr_info->packno - tp_start_packno; /* Number of packets in last tile-part */
-        }
+            if (p_cstr_info) {
+                opj_tile_info_v2_t *info_TL = &p_cstr_info->tile[p_tile_no];
+                opj_packet_info_t *info_PK = &info_TL->packet[p_cstr_info->packno];
+                tp_start_packno = 0;
+                if (!p_cstr_info->packno) {
+                    info_PK->start_pos = info_TL->end_header + 1;
+                } else if (info_TL->packet[p_cstr_info->packno - 1].end_pos >=
+                           (OPJ_INT32)
+                           p_cstr_info->tile[p_tile_no].tp[curtp].tp_end_pos) { /* New tile part */
+                    info_TL->tp[curtp].tp_numpacks = p_cstr_info->packno -
+                                                     tp_start_packno; /* Number of packets in previous tile-part */
+                    tp_start_packno = p_cstr_info->packno;
+                    curtp++;
+                    info_PK->start_pos = p_cstr_info->tile[p_tile_no].tp[curtp].tp_end_header + 1;
+                } else {
+                    info_PK->start_pos = (l_cp->m_specific_param.m_enc.m_tp_on &&
+                                          info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[p_cstr_info->packno -
+                                                                      1].end_pos + 1;
+                }
+                info_PK->end_pos = info_PK->start_pos + l_nb_bytes_read - 1;
+                info_PK->end_ph_pos += info_PK->start_pos -
+                                       1;  /* End of packet header which now only represents the distance */
+                ++p_cstr_info->packno;
+            }
 #endif
-        /* << INDEX */
+            /* << INDEX */
+        }
+        ++l_current_pi;
 
-        /* don't forget to release pi */
-        opj_pi_destroy(l_pi,l_nb_pocs);
-        *p_data_read = (OPJ_UINT32)(l_current_data - p_src);
-        return OPJ_TRUE;
+        opj_free(first_pass_failed);
+    }
+    /* INDEX >> */
+#ifdef TODO_MSD
+    if
+    (p_cstr_info) {
+        p_cstr_info->tile[p_tile_no].tp[curtp].tp_numpacks = p_cstr_info->packno -
+                tp_start_packno; /* Number of packets in last tile-part */
+    }
+#endif
+    /* << INDEX */
+
+    /* don't forget to release pi */
+    opj_pi_destroy(l_pi, l_nb_pocs);
+    *p_data_read = (OPJ_UINT32)(l_current_data - p_src);
+    return OPJ_TRUE;
 }
 
 /* ----------------------------------------------------------------------- */
@@ -499,883 +528,959 @@
 */
 opj_t2_t* opj_t2_create(opj_image_t *p_image, opj_cp_t *p_cp)
 {
-        /* create the t2 structure */
-        opj_t2_t *l_t2 = (opj_t2_t*)opj_calloc(1,sizeof(opj_t2_t));
-        if (!l_t2) {
-                return NULL;
-        }
+    /* create the t2 structure */
+    opj_t2_t *l_t2 = (opj_t2_t*)opj_calloc(1, sizeof(opj_t2_t));
+    if (!l_t2) {
+        return NULL;
+    }
 
-        l_t2->image = p_image;
-        l_t2->cp = p_cp;
+    l_t2->image = p_image;
+    l_t2->cp = p_cp;
 
-        return l_t2;
+    return l_t2;
 }
 
-void opj_t2_destroy(opj_t2_t *t2) {
-        if(t2) {
-                opj_free(t2);
-        }
-}
-
-static OPJ_BOOL opj_t2_decode_packet(  opj_t2_t* p_t2,
-                                opj_tcd_tile_t *p_tile,
-                                opj_tcp_t *p_tcp,
-                                opj_pi_iterator_t *p_pi,
-                                OPJ_BYTE *p_src,
-                                OPJ_UINT32 * p_data_read,
-                                OPJ_UINT32 p_max_length,
-                                opj_packet_info_t *p_pack_info,
-                                opj_event_mgr_t *p_manager)
+void opj_t2_destroy(opj_t2_t *t2)
 {
-        OPJ_BOOL l_read_data;
-        OPJ_UINT32 l_nb_bytes_read = 0;
-        OPJ_UINT32 l_nb_total_bytes_read = 0;
+    if (t2) {
+        opj_free(t2);
+    }
+}
 
-        *p_data_read = 0;
+static OPJ_BOOL opj_t2_decode_packet(opj_t2_t* p_t2,
+                                     opj_tcd_tile_t *p_tile,
+                                     opj_tcp_t *p_tcp,
+                                     opj_pi_iterator_t *p_pi,
+                                     OPJ_BYTE *p_src,
+                                     OPJ_UINT32 * p_data_read,
+                                     OPJ_UINT32 p_max_length,
+                                     opj_packet_info_t *p_pack_info,
+                                     opj_event_mgr_t *p_manager)
+{
+    OPJ_BOOL l_read_data;
+    OPJ_UINT32 l_nb_bytes_read = 0;
+    OPJ_UINT32 l_nb_total_bytes_read = 0;
 
-        if (! opj_t2_read_packet_header(p_t2,p_tile,p_tcp,p_pi,&l_read_data,p_src,&l_nb_bytes_read,p_max_length,p_pack_info, p_manager)) {
-                return OPJ_FALSE;
+    *p_data_read = 0;
+
+    if (! opj_t2_read_packet_header(p_t2, p_tile, p_tcp, p_pi, &l_read_data, p_src,
+                                    &l_nb_bytes_read, p_max_length, p_pack_info, p_manager)) {
+        return OPJ_FALSE;
+    }
+
+    p_src += l_nb_bytes_read;
+    l_nb_total_bytes_read += l_nb_bytes_read;
+    p_max_length -= l_nb_bytes_read;
+
+    /* we should read data for the packet */
+    if (l_read_data) {
+        l_nb_bytes_read = 0;
+
+        if (! opj_t2_read_packet_data(p_t2, p_tile, p_pi, p_src, &l_nb_bytes_read,
+                                      p_max_length, p_pack_info, p_manager)) {
+            return OPJ_FALSE;
         }
 
-        p_src += l_nb_bytes_read;
         l_nb_total_bytes_read += l_nb_bytes_read;
-        p_max_length -= l_nb_bytes_read;
+    }
 
-        /* we should read data for the packet */
-        if (l_read_data) {
-                l_nb_bytes_read = 0;
+    *p_data_read = l_nb_total_bytes_read;
 
-                if (! opj_t2_read_packet_data(p_t2,p_tile,p_pi,p_src,&l_nb_bytes_read,p_max_length,p_pack_info, p_manager)) {
-                        return OPJ_FALSE;
-                }
-
-                l_nb_total_bytes_read += l_nb_bytes_read;
-        }
-
-        *p_data_read = l_nb_total_bytes_read;
-
-        return OPJ_TRUE;
+    return OPJ_TRUE;
 }
 
-static OPJ_BOOL opj_t2_encode_packet(  OPJ_UINT32 tileno,
-                                opj_tcd_tile_t * tile,
-                                opj_tcp_t * tcp,
-                                opj_pi_iterator_t *pi,
-                                OPJ_BYTE *dest,
-                                OPJ_UINT32 * p_data_written,
-                                OPJ_UINT32 length,
-                                opj_codestream_info_t *cstr_info)
+static OPJ_BOOL opj_t2_encode_packet(OPJ_UINT32 tileno,
+                                     opj_tcd_tile_t * tile,
+                                     opj_tcp_t * tcp,
+                                     opj_pi_iterator_t *pi,
+                                     OPJ_BYTE *dest,
+                                     OPJ_UINT32 * p_data_written,
+                                     OPJ_UINT32 length,
+                                     opj_codestream_info_t *cstr_info)
 {
-        OPJ_UINT32 bandno, cblkno;
-        OPJ_BYTE* c = dest;
-        OPJ_UINT32 l_nb_bytes;
-        OPJ_UINT32 compno = pi->compno;     /* component value */
-        OPJ_UINT32 resno  = pi->resno;      /* resolution level value */
-        OPJ_UINT32 precno = pi->precno;     /* precinct value */
-        OPJ_UINT32 layno  = pi->layno;      /* quality layer value */
-        OPJ_UINT32 l_nb_blocks;
-        opj_tcd_band_t *band = 00;
-        opj_tcd_cblk_enc_t* cblk = 00;
-        opj_tcd_pass_t *pass = 00;
+    OPJ_UINT32 bandno, cblkno;
+    OPJ_BYTE* c = dest;
+    OPJ_UINT32 l_nb_bytes;
+    OPJ_UINT32 compno = pi->compno;     /* component value */
+    OPJ_UINT32 resno  = pi->resno;      /* resolution level value */
+    OPJ_UINT32 precno = pi->precno;     /* precinct value */
+    OPJ_UINT32 layno  = pi->layno;      /* quality layer value */
+    OPJ_UINT32 l_nb_blocks;
+    opj_tcd_band_t *band = 00;
+    opj_tcd_cblk_enc_t* cblk = 00;
+    opj_tcd_pass_t *pass = 00;
 
-        opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
-        opj_tcd_resolution_t *res = &tilec->resolutions[resno];
+    opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
+    opj_tcd_resolution_t *res = &tilec->resolutions[resno];
 
-        opj_bio_t *bio = 00;    /* BIO component */
+    opj_bio_t *bio = 00;    /* BIO component */
+    OPJ_BOOL packet_empty = OPJ_TRUE;
 
-        /* <SOP 0xff91> */
-        if (tcp->csty & J2K_CP_CSTY_SOP) {
-                c[0] = 255;
-                c[1] = 145;
-                c[2] = 0;
-                c[3] = 4;
+    /* <SOP 0xff91> */
+    if (tcp->csty & J2K_CP_CSTY_SOP) {
+        c[0] = 255;
+        c[1] = 145;
+        c[2] = 0;
+        c[3] = 4;
 #if 0
-                c[4] = (tile->packno % 65536) / 256;
-                c[5] = (tile->packno % 65536) % 256;
+        c[4] = (tile->packno % 65536) / 256;
+        c[5] = (tile->packno % 65536) % 256;
 #else
-                c[4] = (tile->packno >> 8) & 0xff; /* packno is uint32_t */
-                c[5] = tile->packno & 0xff;
+        c[4] = (tile->packno >> 8) & 0xff; /* packno is uint32_t */
+        c[5] = tile->packno & 0xff;
 #endif
-                c += 6;
-                length -= 6;
-        }
-        /* </SOP> */
+        c += 6;
+        length -= 6;
+    }
+    /* </SOP> */
 
-        if (!layno) {
-                band = res->bands;
-
-                for(bandno = 0; bandno < res->numbands; ++bandno) {
-                        opj_tcd_precinct_t *prc = &band->precincts[precno];
-
-                        opj_tgt_reset(prc->incltree);
-                        opj_tgt_reset(prc->imsbtree);
-
-                        l_nb_blocks = prc->cw * prc->ch;
-                        for     (cblkno = 0; cblkno < l_nb_blocks; ++cblkno) {
-                                cblk = &prc->cblks.enc[cblkno];
-
-                                cblk->numpasses = 0;
-                                opj_tgt_setvalue(prc->imsbtree, cblkno, band->numbps - (OPJ_INT32)cblk->numbps);
-                        }
-                        ++band;
-                }
-        }
-
-        bio = opj_bio_create();
-        if (!bio) {
-                /* FIXME event manager error callback */
-                return OPJ_FALSE;
-        }
-        opj_bio_init_enc(bio, c, length);
-        opj_bio_write(bio, 1, 1);           /* Empty header bit */
-
-        /* Writing Packet header */
+    if (!layno) {
         band = res->bands;
-        for (bandno = 0; bandno < res->numbands; ++bandno)      {
-                opj_tcd_precinct_t *prc = &band->precincts[precno];
 
-                l_nb_blocks = prc->cw * prc->ch;
-                cblk = prc->cblks.enc;
+        for (bandno = 0; bandno < res->numbands; ++bandno, ++band) {
+            opj_tcd_precinct_t *prc;
 
-                for (cblkno = 0; cblkno < l_nb_blocks; ++cblkno) {
-                        opj_tcd_layer_t *layer = &cblk->layers[layno];
+            /* Skip empty bands */
+            if (opj_tcd_is_band_empty(band)) {
+                continue;
+            }
 
-                        if (!cblk->numpasses && layer->numpasses) {
-                                opj_tgt_setvalue(prc->incltree, cblkno, (OPJ_INT32)layno);
-                        }
+            prc = &band->precincts[precno];
+            opj_tgt_reset(prc->incltree);
+            opj_tgt_reset(prc->imsbtree);
 
-                        ++cblk;
-                }
+            l_nb_blocks = prc->cw * prc->ch;
+            for (cblkno = 0; cblkno < l_nb_blocks; ++cblkno) {
+                cblk = &prc->cblks.enc[cblkno];
 
-                cblk = prc->cblks.enc;
-                for (cblkno = 0; cblkno < l_nb_blocks; cblkno++) {
-                        opj_tcd_layer_t *layer = &cblk->layers[layno];
-                        OPJ_UINT32 increment = 0;
-                        OPJ_UINT32 nump = 0;
-                        OPJ_UINT32 len = 0, passno;
-                        OPJ_UINT32 l_nb_passes;
+                cblk->numpasses = 0;
+                opj_tgt_setvalue(prc->imsbtree, cblkno, band->numbps - (OPJ_INT32)cblk->numbps);
+            }
+        }
+    }
 
-                        /* cblk inclusion bits */
-                        if (!cblk->numpasses) {
-                                opj_tgt_encode(bio, prc->incltree, cblkno, (OPJ_INT32)(layno + 1));
-                        } else {
-                                opj_bio_write(bio, layer->numpasses != 0, 1);
-                        }
+    bio = opj_bio_create();
+    if (!bio) {
+        /* FIXME event manager error callback */
+        return OPJ_FALSE;
+    }
+    opj_bio_init_enc(bio, c, length);
 
-                        /* if cblk not included, go to the next cblk  */
-                        if (!layer->numpasses) {
-                                ++cblk;
-                                continue;
-                        }
-
-                        /* if first instance of cblk --> zero bit-planes information */
-                        if (!cblk->numpasses) {
-                                cblk->numlenbits = 3;
-                                opj_tgt_encode(bio, prc->imsbtree, cblkno, 999);
-                        }
-
-                        /* number of coding passes included */
-                        opj_t2_putnumpasses(bio, layer->numpasses);
-                        l_nb_passes = cblk->numpasses + layer->numpasses;
-                        pass = cblk->passes +  cblk->numpasses;
-
-                        /* computation of the increase of the length indicator and insertion in the header     */
-                        for (passno = cblk->numpasses; passno < l_nb_passes; ++passno) {
-                                ++nump;
-                                len += pass->len;
-
-                                if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) {
-                                  increment = (OPJ_UINT32)opj_int_max((OPJ_INT32)increment, opj_int_floorlog2((OPJ_INT32)len) + 1
-                                    - ((OPJ_INT32)cblk->numlenbits + opj_int_floorlog2((OPJ_INT32)nump)));
-                                        len = 0;
-                                        nump = 0;
-                                }
-
-                                ++pass;
-                        }
-                        opj_t2_putcommacode(bio, (OPJ_INT32)increment);
-
-                        /* computation of the new Length indicator */
-                        cblk->numlenbits += increment;
-
-                        pass = cblk->passes +  cblk->numpasses;
-                        /* insertion of the codeword segment length */
-                        for (passno = cblk->numpasses; passno < l_nb_passes; ++passno) {
-                                nump++;
-                                len += pass->len;
-
-                                if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) {
-                                        opj_bio_write(bio, (OPJ_UINT32)len, cblk->numlenbits + (OPJ_UINT32)opj_int_floorlog2((OPJ_INT32)nump));
-                                        len = 0;
-                                        nump = 0;
-                                }
-                                ++pass;
-                        }
-
-                        ++cblk;
-                }
-
-                ++band;
+    /* 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;
         }
 
-        if (!opj_bio_flush(bio)) {
-                opj_bio_destroy(bio);
-                return OPJ_FALSE;               /* modified to eliminate longjmp !! */
+        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; !packet_empty &&
+            bandno < res->numbands; ++bandno, ++band)      {
+        opj_tcd_precinct_t *prc;
+
+        /* Skip empty bands */
+        if (opj_tcd_is_band_empty(band)) {
+            continue;
         }
 
-        l_nb_bytes = (OPJ_UINT32)opj_bio_numbytes(bio);
-        c += l_nb_bytes;
-        length -= l_nb_bytes;
+        prc = &band->precincts[precno];
+        l_nb_blocks = prc->cw * prc->ch;
+        cblk = prc->cblks.enc;
 
+        for (cblkno = 0; cblkno < l_nb_blocks; ++cblkno) {
+            opj_tcd_layer_t *layer = &cblk->layers[layno];
+
+            if (!cblk->numpasses && layer->numpasses) {
+                opj_tgt_setvalue(prc->incltree, cblkno, (OPJ_INT32)layno);
+            }
+
+            ++cblk;
+        }
+
+        cblk = prc->cblks.enc;
+        for (cblkno = 0; cblkno < l_nb_blocks; cblkno++) {
+            opj_tcd_layer_t *layer = &cblk->layers[layno];
+            OPJ_UINT32 increment = 0;
+            OPJ_UINT32 nump = 0;
+            OPJ_UINT32 len = 0, passno;
+            OPJ_UINT32 l_nb_passes;
+
+            /* cblk inclusion bits */
+            if (!cblk->numpasses) {
+                opj_tgt_encode(bio, prc->incltree, cblkno, (OPJ_INT32)(layno + 1));
+            } else {
+                opj_bio_write(bio, layer->numpasses != 0, 1);
+            }
+
+            /* if cblk not included, go to the next cblk  */
+            if (!layer->numpasses) {
+                ++cblk;
+                continue;
+            }
+
+            /* if first instance of cblk --> zero bit-planes information */
+            if (!cblk->numpasses) {
+                cblk->numlenbits = 3;
+                opj_tgt_encode(bio, prc->imsbtree, cblkno, 999);
+            }
+
+            /* number of coding passes included */
+            opj_t2_putnumpasses(bio, layer->numpasses);
+            l_nb_passes = cblk->numpasses + layer->numpasses;
+            pass = cblk->passes +  cblk->numpasses;
+
+            /* computation of the increase of the length indicator and insertion in the header     */
+            for (passno = cblk->numpasses; passno < l_nb_passes; ++passno) {
+                ++nump;
+                len += pass->len;
+
+                if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) {
+                    increment = (OPJ_UINT32)opj_int_max((OPJ_INT32)increment,
+                                                        opj_int_floorlog2((OPJ_INT32)len) + 1
+                                                        - ((OPJ_INT32)cblk->numlenbits + opj_int_floorlog2((OPJ_INT32)nump)));
+                    len = 0;
+                    nump = 0;
+                }
+
+                ++pass;
+            }
+            opj_t2_putcommacode(bio, (OPJ_INT32)increment);
+
+            /* computation of the new Length indicator */
+            cblk->numlenbits += increment;
+
+            pass = cblk->passes +  cblk->numpasses;
+            /* insertion of the codeword segment length */
+            for (passno = cblk->numpasses; passno < l_nb_passes; ++passno) {
+                nump++;
+                len += pass->len;
+
+                if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) {
+                    opj_bio_write(bio, (OPJ_UINT32)len,
+                                  cblk->numlenbits + (OPJ_UINT32)opj_int_floorlog2((OPJ_INT32)nump));
+                    len = 0;
+                    nump = 0;
+                }
+                ++pass;
+            }
+
+            ++cblk;
+        }
+    }
+
+    if (!opj_bio_flush(bio)) {
         opj_bio_destroy(bio);
+        return OPJ_FALSE;               /* modified to eliminate longjmp !! */
+    }
 
-        /* <EPH 0xff92> */
-        if (tcp->csty & J2K_CP_CSTY_EPH) {
-                c[0] = 255;
-                c[1] = 146;
-                c += 2;
-                length -= 2;
+    l_nb_bytes = (OPJ_UINT32)opj_bio_numbytes(bio);
+    c += l_nb_bytes;
+    length -= l_nb_bytes;
+
+    opj_bio_destroy(bio);
+
+    /* <EPH 0xff92> */
+    if (tcp->csty & J2K_CP_CSTY_EPH) {
+        c[0] = 255;
+        c[1] = 146;
+        c += 2;
+        length -= 2;
+    }
+    /* </EPH> */
+
+    /* << INDEX */
+    /* End of packet header position. Currently only represents the distance to start of packet
+       Will be updated later by incrementing with packet start value*/
+    if (cstr_info && cstr_info->index_write) {
+        opj_packet_info_t *info_PK = &cstr_info->tile[tileno].packet[cstr_info->packno];
+        info_PK->end_ph_pos = (OPJ_INT32)(c - dest);
+    }
+    /* INDEX >> */
+
+    /* Writing the packet body */
+    band = res->bands;
+    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;
         }
-        /* </EPH> */
 
-        /* << INDEX */
-        /* End of packet header position. Currently only represents the distance to start of packet
-           Will be updated later by incrementing with packet start value*/
-        if(cstr_info && cstr_info->index_write) {
+        prc = &band->precincts[precno];
+        l_nb_blocks = prc->cw * prc->ch;
+        cblk = prc->cblks.enc;
+
+        for (cblkno = 0; cblkno < l_nb_blocks; ++cblkno) {
+            opj_tcd_layer_t *layer = &cblk->layers[layno];
+
+            if (!layer->numpasses) {
+                ++cblk;
+                continue;
+            }
+
+            if (layer->len > length) {
+                return OPJ_FALSE;
+            }
+
+            memcpy(c, layer->data, layer->len);
+            cblk->numpasses += layer->numpasses;
+            c += layer->len;
+            length -= layer->len;
+
+            /* << INDEX */
+            if (cstr_info && cstr_info->index_write) {
                 opj_packet_info_t *info_PK = &cstr_info->tile[tileno].packet[cstr_info->packno];
-                info_PK->end_ph_pos = (OPJ_INT32)(c - dest);
-        }
-        /* INDEX >> */
-
-        /* Writing the packet body */
-        band = res->bands;
-        for (bandno = 0; bandno < res->numbands; bandno++) {
-                opj_tcd_precinct_t *prc = &band->precincts[precno];
-
-                l_nb_blocks = prc->cw * prc->ch;
-                cblk = prc->cblks.enc;
-
-                for (cblkno = 0; cblkno < l_nb_blocks; ++cblkno) {
-                        opj_tcd_layer_t *layer = &cblk->layers[layno];
-
-                        if (!layer->numpasses) {
-                                ++cblk;
-                                continue;
-                        }
-
-                        if (layer->len > length) {
-                                return OPJ_FALSE;
-                        }
-
-                        memcpy(c, layer->data, layer->len);
-                        cblk->numpasses += layer->numpasses;
-                        c += layer->len;
-                        length -= layer->len;
-
-                        /* << INDEX */
-                        if(cstr_info && cstr_info->index_write) {
-                                opj_packet_info_t *info_PK = &cstr_info->tile[tileno].packet[cstr_info->packno];
-                                info_PK->disto += layer->disto;
-                                if (cstr_info->D_max < info_PK->disto) {
-                                        cstr_info->D_max = info_PK->disto;
-                                }
-                        }
-
-                        ++cblk;
-                        /* INDEX >> */
+                info_PK->disto += layer->disto;
+                if (cstr_info->D_max < info_PK->disto) {
+                    cstr_info->D_max = info_PK->disto;
                 }
-                ++band;
+            }
+
+            ++cblk;
+            /* INDEX >> */
         }
+    }
 
-        assert( c >= dest );
-        * p_data_written += (OPJ_UINT32)(c - dest);
+    assert(c >= dest);
+    * p_data_written += (OPJ_UINT32)(c - dest);
 
-        return OPJ_TRUE;
+    return OPJ_TRUE;
 }
 
-static OPJ_BOOL opj_t2_skip_packet( opj_t2_t* p_t2,
-                                    opj_tcd_tile_t *p_tile,
-                                    opj_tcp_t *p_tcp,
-                                    opj_pi_iterator_t *p_pi,
-                                    OPJ_BYTE *p_src,
-                                    OPJ_UINT32 * p_data_read,
-                                    OPJ_UINT32 p_max_length,
-                                    opj_packet_info_t *p_pack_info,
-                                    opj_event_mgr_t *p_manager)
+static OPJ_BOOL opj_t2_skip_packet(opj_t2_t* p_t2,
+                                   opj_tcd_tile_t *p_tile,
+                                   opj_tcp_t *p_tcp,
+                                   opj_pi_iterator_t *p_pi,
+                                   OPJ_BYTE *p_src,
+                                   OPJ_UINT32 * p_data_read,
+                                   OPJ_UINT32 p_max_length,
+                                   opj_packet_info_t *p_pack_info,
+                                   opj_event_mgr_t *p_manager)
 {
-        OPJ_BOOL l_read_data;
-        OPJ_UINT32 l_nb_bytes_read = 0;
-        OPJ_UINT32 l_nb_total_bytes_read = 0;
+    OPJ_BOOL l_read_data;
+    OPJ_UINT32 l_nb_bytes_read = 0;
+    OPJ_UINT32 l_nb_total_bytes_read = 0;
 
-        *p_data_read = 0;
+    *p_data_read = 0;
 
-        if (! opj_t2_read_packet_header(p_t2,p_tile,p_tcp,p_pi,&l_read_data,p_src,&l_nb_bytes_read,p_max_length,p_pack_info, p_manager)) {
-                return OPJ_FALSE;
+    if (! opj_t2_read_packet_header(p_t2, p_tile, p_tcp, p_pi, &l_read_data, p_src,
+                                    &l_nb_bytes_read, p_max_length, p_pack_info, p_manager)) {
+        return OPJ_FALSE;
+    }
+
+    p_src += l_nb_bytes_read;
+    l_nb_total_bytes_read += l_nb_bytes_read;
+    p_max_length -= l_nb_bytes_read;
+
+    /* we should read data for the packet */
+    if (l_read_data) {
+        l_nb_bytes_read = 0;
+
+        if (! opj_t2_skip_packet_data(p_t2, p_tile, p_pi, &l_nb_bytes_read,
+                                      p_max_length, p_pack_info, p_manager)) {
+            return OPJ_FALSE;
         }
 
-        p_src += l_nb_bytes_read;
         l_nb_total_bytes_read += l_nb_bytes_read;
-        p_max_length -= l_nb_bytes_read;
+    }
+    *p_data_read = l_nb_total_bytes_read;
 
-        /* we should read data for the packet */
-        if (l_read_data) {
-                l_nb_bytes_read = 0;
-
-                if (! opj_t2_skip_packet_data(p_t2,p_tile,p_pi,&l_nb_bytes_read,p_max_length,p_pack_info, p_manager)) {
-                        return OPJ_FALSE;
-                }
-
-                l_nb_total_bytes_read += l_nb_bytes_read;
-        }
-        *p_data_read = l_nb_total_bytes_read;
-
-        return OPJ_TRUE;
+    return OPJ_TRUE;
 }
 
 
-static OPJ_BOOL opj_t2_read_packet_header( opj_t2_t* p_t2,
-                                    opj_tcd_tile_t *p_tile,
-                                    opj_tcp_t *p_tcp,
-                                    opj_pi_iterator_t *p_pi,
-                                    OPJ_BOOL * p_is_data_present,
-                                    OPJ_BYTE *p_src_data,
-                                    OPJ_UINT32 * p_data_read,
-                                    OPJ_UINT32 p_max_length,
-                                    opj_packet_info_t *p_pack_info,
-                                    opj_event_mgr_t *p_manager)
+static OPJ_BOOL opj_t2_read_packet_header(opj_t2_t* p_t2,
+        opj_tcd_tile_t *p_tile,
+        opj_tcp_t *p_tcp,
+        opj_pi_iterator_t *p_pi,
+        OPJ_BOOL * p_is_data_present,
+        OPJ_BYTE *p_src_data,
+        OPJ_UINT32 * p_data_read,
+        OPJ_UINT32 p_max_length,
+        opj_packet_info_t *p_pack_info,
+        opj_event_mgr_t *p_manager)
 
 {
-        /* loop */
-        OPJ_UINT32 bandno, cblkno;
-        OPJ_UINT32 l_nb_code_blocks;
-        OPJ_UINT32 l_remaining_length;
-        OPJ_UINT32 l_header_length;
-        OPJ_UINT32 * l_modified_length_ptr = 00;
-        OPJ_BYTE *l_current_data = p_src_data;
-        opj_cp_t *l_cp = p_t2->cp;
-        opj_bio_t *l_bio = 00;  /* BIO component */
-        opj_tcd_band_t *l_band = 00;
-        opj_tcd_cblk_dec_t* l_cblk = 00;
-        opj_tcd_resolution_t* l_res = &p_tile->comps[p_pi->compno].resolutions[p_pi->resno];
+    /* loop */
+    OPJ_UINT32 bandno, cblkno;
+    OPJ_UINT32 l_nb_code_blocks;
+    OPJ_UINT32 l_remaining_length;
+    OPJ_UINT32 l_header_length;
+    OPJ_UINT32 * l_modified_length_ptr = 00;
+    OPJ_BYTE *l_current_data = p_src_data;
+    opj_cp_t *l_cp = p_t2->cp;
+    opj_bio_t *l_bio = 00;  /* BIO component */
+    opj_tcd_band_t *l_band = 00;
+    opj_tcd_cblk_dec_t* l_cblk = 00;
+    opj_tcd_resolution_t* l_res =
+        &p_tile->comps[p_pi->compno].resolutions[p_pi->resno];
 
-        OPJ_BYTE *l_header_data = 00;
-        OPJ_BYTE **l_header_data_start = 00;
+    OPJ_BYTE *l_header_data = 00;
+    OPJ_BYTE **l_header_data_start = 00;
 
-        OPJ_UINT32 l_present;
+    OPJ_UINT32 l_present;
 
-        if (p_pi->layno == 0) {
-                l_band = l_res->bands;
-
-                /* reset tagtrees */
-                for (bandno = 0; bandno < l_res->numbands; ++bandno) {
-                        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)) ) {
-                                opj_tgt_reset(l_prc->incltree);
-                                opj_tgt_reset(l_prc->imsbtree);
-                                l_cblk = l_prc->cblks.dec;
-
-                                l_nb_code_blocks = l_prc->cw * l_prc->ch;
-                                for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) {
-                                        l_cblk->numsegs = 0;
-                                        l_cblk->real_num_segs = 0;
-                                        ++l_cblk;
-                                }
-                        }
-
-                        ++l_band;
-                }
-        }
-
-        /* SOP markers */
-
-        if (p_tcp->csty & J2K_CP_CSTY_SOP) {
-                if (p_max_length < 6) {
-												opj_event_msg(p_manager, EVT_WARNING, "Not enough space for expected SOP marker\n");
-                } else if ((*l_current_data) != 0xff || (*(l_current_data + 1) != 0x91)) {
-                        opj_event_msg(p_manager, EVT_WARNING, "Expected SOP marker\n");
-                } else {
-                        l_current_data += 6;
-                }
-
-                /** TODO : check the Nsop value */
-        }
-
-        /*
-        When the marker PPT/PPM is used the packet header are store in PPT/PPM marker
-        This part deal with this caracteristic
-        step 1: Read packet header in the saved structure
-        step 2: Return to codestream for decoding
-        */
-
-        l_bio = opj_bio_create();
-        if (! l_bio) {
-                return OPJ_FALSE;
-        }
-
-        if (l_cp->ppm == 1) { /* PPM */
-                l_header_data_start = &l_cp->ppm_data;
-                l_header_data = *l_header_data_start;
-                l_modified_length_ptr = &(l_cp->ppm_len);
-
-        }
-        else if (p_tcp->ppt == 1) { /* PPT */
-                l_header_data_start = &(p_tcp->ppt_data);
-                l_header_data = *l_header_data_start;
-                l_modified_length_ptr = &(p_tcp->ppt_len);
-        }
-        else {  /* Normal Case */
-                l_header_data_start = &(l_current_data);
-                l_header_data = *l_header_data_start;
-                l_remaining_length = (OPJ_UINT32)(p_src_data+p_max_length-l_header_data);
-                l_modified_length_ptr = &(l_remaining_length);
-        }
-
-        opj_bio_init_dec(l_bio, l_header_data,*l_modified_length_ptr);
-
-        l_present = opj_bio_read(l_bio, 1);
-        JAS_FPRINTF(stderr, "present=%d \n", l_present );
-        if (!l_present) {
-            /* TODO MSD: no test to control the output of this function*/
-                opj_bio_inalign(l_bio);
-                l_header_data += opj_bio_numbytes(l_bio);
-                opj_bio_destroy(l_bio);
-
-                /* EPH markers */
-                if (p_tcp->csty & J2K_CP_CSTY_EPH) {
-                        if ((*l_modified_length_ptr - (OPJ_UINT32)(l_header_data - *l_header_data_start)) < 2U) {
-                                opj_event_msg(p_manager, EVT_WARNING, "Not enough space for expected EPH marker\n");
-                        } else if ((*l_header_data) != 0xff || (*(l_header_data + 1) != 0x92)) {
-                                opj_event_msg(p_manager, EVT_WARNING, "Expected EPH marker\n");
-                        } else {
-                                l_header_data += 2;
-                        }
-                }
-
-                l_header_length = (OPJ_UINT32)(l_header_data - *l_header_data_start);
-                *l_modified_length_ptr -= l_header_length;
-                *l_header_data_start += l_header_length;
-
-                /* << INDEX */
-                /* End of packet header position. Currently only represents the distance to start of packet
-                   Will be updated later by incrementing with packet start value */
-                if (p_pack_info) {
-                        p_pack_info->end_ph_pos = (OPJ_INT32)(l_current_data - p_src_data);
-                }
-                /* INDEX >> */
-
-                * p_is_data_present = OPJ_FALSE;
-                *p_data_read = (OPJ_UINT32)(l_current_data - p_src_data);
-                return OPJ_TRUE;
-        }
-
+    if (p_pi->layno == 0) {
         l_band = l_res->bands;
-        for (bandno = 0; bandno < l_res->numbands; ++bandno) {
-                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;
-                        continue;
+        /* reset tagtrees */
+        for (bandno = 0; bandno < l_res->numbands; ++bandno) {
+            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)))) {
+                    opj_event_msg(p_manager, EVT_ERROR, "Invalid precinct\n");
+                    return OPJ_FALSE;
                 }
 
+
+                opj_tgt_reset(l_prc->incltree);
+                opj_tgt_reset(l_prc->imsbtree);
+                l_cblk = l_prc->cblks.dec;
+
                 l_nb_code_blocks = l_prc->cw * l_prc->ch;
-                l_cblk = l_prc->cblks.dec;
-                for (cblkno = 0; cblkno < l_nb_code_blocks; cblkno++) {
-                        OPJ_UINT32 l_included,l_increment, l_segno;
-                        OPJ_INT32 n;
-
-                        /* if cblk not yet included before --> inclusion tagtree */
-                        if (!l_cblk->numsegs) {
-                                l_included = opj_tgt_decode(l_bio, l_prc->incltree, cblkno, (OPJ_INT32)(p_pi->layno + 1));
-                                /* else one bit */
-                        }
-                        else {
-                                l_included = opj_bio_read(l_bio, 1);
-                        }
-
-                        /* if cblk not included */
-                        if (!l_included) {
-                                l_cblk->numnewpasses = 0;
-                                ++l_cblk;
-                                JAS_FPRINTF(stderr, "included=%d \n", l_included);
-                                continue;
-                        }
-
-                        /* if cblk not yet included --> zero-bitplane tagtree */
-                        if (!l_cblk->numsegs) {
-                                OPJ_UINT32 i = 0;
-
-                                while (!opj_tgt_decode(l_bio, l_prc->imsbtree, cblkno, (OPJ_INT32)i)) {
-                                        ++i;
-                                }
-
-                                l_cblk->numbps = (OPJ_UINT32)l_band->numbps + 1 - i;
-                                l_cblk->numlenbits = 3;
-                        }
-
-                        /* number of coding passes */
-                        l_cblk->numnewpasses = opj_t2_getnumpasses(l_bio);
-                        l_increment = opj_t2_getcommacode(l_bio);
-
-                        /* length indicator increment */
-                        l_cblk->numlenbits += l_increment;
-                        l_segno = 0;
-
-                        if (!l_cblk->numsegs) {
-                                if (! opj_t2_init_seg(l_cblk, l_segno, p_tcp->tccps[p_pi->compno].cblksty, 1)) {
-                                        opj_bio_destroy(l_bio);
-                                        return OPJ_FALSE;
-                                }
-                        }
-                        else {
-                                l_segno = l_cblk->numsegs - 1;
-                                if (l_cblk->segs[l_segno].numpasses == l_cblk->segs[l_segno].maxpasses) {
-                                        ++l_segno;
-                                        if (! opj_t2_init_seg(l_cblk, l_segno, p_tcp->tccps[p_pi->compno].cblksty, 0)) {
-                                                opj_bio_destroy(l_bio);
-                                                return OPJ_FALSE;
-                                        }
-                                }
-                        }
-                        n = (OPJ_INT32)l_cblk->numnewpasses;
-
-                        do {
-                                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));
-                                        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 );
-
-                                n -= (OPJ_INT32)l_cblk->segs[l_segno].numnewpasses;
-                                if (n > 0) {
-                                        ++l_segno;
-
-                                        if (! opj_t2_init_seg(l_cblk, l_segno, p_tcp->tccps[p_pi->compno].cblksty, 0)) {
-                                                opj_bio_destroy(l_bio);
-                                                return OPJ_FALSE;
-                                        }
-                                }
-                        } while (n > 0);
-
-                        ++l_cblk;
+                for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) {
+                    l_cblk->numsegs = 0;
+                    l_cblk->real_num_segs = 0;
+                    ++l_cblk;
                 }
+            }
 
-                ++l_band;
+            ++l_band;
+        }
+    }
+
+    /* SOP markers */
+
+    if (p_tcp->csty & J2K_CP_CSTY_SOP) {
+        if (p_max_length < 6) {
+            opj_event_msg(p_manager, EVT_WARNING,
+                          "Not enough space for expected SOP marker\n");
+        } else if ((*l_current_data) != 0xff || (*(l_current_data + 1) != 0x91)) {
+            opj_event_msg(p_manager, EVT_WARNING, "Expected SOP marker\n");
+        } else {
+            l_current_data += 6;
         }
 
-        if (!opj_bio_inalign(l_bio)) {
-                opj_bio_destroy(l_bio);
-                return OPJ_FALSE;
-        }
+        /** TODO : check the Nsop value */
+    }
 
+    /*
+    When the marker PPT/PPM is used the packet header are store in PPT/PPM marker
+    This part deal with this caracteristic
+    step 1: Read packet header in the saved structure
+    step 2: Return to codestream for decoding
+    */
+
+    l_bio = opj_bio_create();
+    if (! l_bio) {
+        return OPJ_FALSE;
+    }
+
+    if (l_cp->ppm == 1) { /* PPM */
+        l_header_data_start = &l_cp->ppm_data;
+        l_header_data = *l_header_data_start;
+        l_modified_length_ptr = &(l_cp->ppm_len);
+
+    } else if (p_tcp->ppt == 1) { /* PPT */
+        l_header_data_start = &(p_tcp->ppt_data);
+        l_header_data = *l_header_data_start;
+        l_modified_length_ptr = &(p_tcp->ppt_len);
+    } else { /* Normal Case */
+        l_header_data_start = &(l_current_data);
+        l_header_data = *l_header_data_start;
+        l_remaining_length = (OPJ_UINT32)(p_src_data + p_max_length - l_header_data);
+        l_modified_length_ptr = &(l_remaining_length);
+    }
+
+    opj_bio_init_dec(l_bio, l_header_data, *l_modified_length_ptr);
+
+    l_present = opj_bio_read(l_bio, 1);
+    JAS_FPRINTF(stderr, "present=%d \n", l_present);
+    if (!l_present) {
+        /* TODO MSD: no test to control the output of this function*/
+        opj_bio_inalign(l_bio);
         l_header_data += opj_bio_numbytes(l_bio);
         opj_bio_destroy(l_bio);
 
         /* EPH markers */
         if (p_tcp->csty & J2K_CP_CSTY_EPH) {
-                if ((*l_modified_length_ptr - (OPJ_UINT32)(l_header_data - *l_header_data_start)) < 2U) {
-                        opj_event_msg(p_manager, EVT_WARNING, "Not enough space for expected EPH marker\n");
-                } else if ((*l_header_data) != 0xff || (*(l_header_data + 1) != 0x92)) {
-                        opj_event_msg(p_manager, EVT_WARNING, "Expected EPH marker\n");
-                } else {
-                        l_header_data += 2;
-                }
+            if ((*l_modified_length_ptr - (OPJ_UINT32)(l_header_data -
+                    *l_header_data_start)) < 2U) {
+                opj_event_msg(p_manager, EVT_WARNING,
+                              "Not enough space for expected EPH marker\n");
+            } else if ((*l_header_data) != 0xff || (*(l_header_data + 1) != 0x92)) {
+                opj_event_msg(p_manager, EVT_WARNING, "Expected EPH marker\n");
+            } else {
+                l_header_data += 2;
+            }
         }
 
         l_header_length = (OPJ_UINT32)(l_header_data - *l_header_data_start);
-        JAS_FPRINTF( stderr, "hdrlen=%d \n", l_header_length );
-        JAS_FPRINTF( stderr, "packet body\n");
         *l_modified_length_ptr -= l_header_length;
         *l_header_data_start += l_header_length;
 
         /* << INDEX */
         /* End of packet header position. Currently only represents the distance to start of packet
-         Will be updated later by incrementing with packet start value */
+           Will be updated later by incrementing with packet start value */
         if (p_pack_info) {
-                p_pack_info->end_ph_pos = (OPJ_INT32)(l_current_data - p_src_data);
+            p_pack_info->end_ph_pos = (OPJ_INT32)(l_current_data - p_src_data);
         }
         /* INDEX >> */
 
-        *p_is_data_present = OPJ_TRUE;
+        * p_is_data_present = OPJ_FALSE;
         *p_data_read = (OPJ_UINT32)(l_current_data - p_src_data);
-
         return OPJ_TRUE;
-}
+    }
 
-static OPJ_BOOL opj_t2_read_packet_data(   opj_t2_t* p_t2,
-                                    opj_tcd_tile_t *p_tile,
-                                    opj_pi_iterator_t *p_pi,
-                                    OPJ_BYTE *p_src_data,
-                                    OPJ_UINT32 * p_data_read,
-                                    OPJ_UINT32 p_max_length,
-                                    opj_packet_info_t *pack_info,
-                                    opj_event_mgr_t* p_manager)
-{
-        OPJ_UINT32 bandno, cblkno;
-        OPJ_UINT32 l_nb_code_blocks;
-        OPJ_BYTE *l_current_data = p_src_data;
-        opj_tcd_band_t *l_band = 00;
-        opj_tcd_cblk_dec_t* l_cblk = 00;
-        opj_tcd_resolution_t* l_res = &p_tile->comps[p_pi->compno].resolutions[p_pi->resno];
+    l_band = l_res->bands;
+    for (bandno = 0; bandno < l_res->numbands; ++bandno, ++l_band) {
+        opj_tcd_precinct_t *l_prc = &(l_band->precincts[p_pi->precno]);
 
-        OPJ_ARG_NOT_USED(p_t2);
-        OPJ_ARG_NOT_USED(pack_info);
-
-        l_band = l_res->bands;
-        for (bandno = 0; bandno < l_res->numbands; ++bandno) {
-                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;
-                        continue;
-                }
-
-                l_nb_code_blocks = l_prc->cw * l_prc->ch;
-                l_cblk = l_prc->cblks.dec;
-
-                for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) {
-                        opj_tcd_seg_t *l_seg = 00;
-
-                        if (!l_cblk->numnewpasses) {
-                                /* nothing to do */
-                                ++l_cblk;
-                                continue;
-                        }
-
-                        if (!l_cblk->numsegs) {
-                                l_seg = l_cblk->segs;
-                                ++l_cblk->numsegs;
-                                l_cblk->data_current_size = 0;
-                        }
-                        else {
-                                l_seg = &l_cblk->segs[l_cblk->numsegs - 1];
-
-                                if (l_seg->numpasses == l_seg->maxpasses) {
-                                        ++l_seg;
-                                        ++l_cblk->numsegs;
-                                }
-                        }
-
-                        do {
-                                /* Check possible overflow (on l_current_data only, assumes input args already checked) then size */
-                                if ((((OPJ_SIZE_T)l_current_data + (OPJ_SIZE_T)l_seg->newlen) < (OPJ_SIZE_T)l_current_data) || (l_current_data + l_seg->newlen > p_src_data + p_max_length)) {
-                                        opj_event_msg(p_manager, EVT_ERROR, "read: segment too long (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
-																								l_seg->newlen, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno, p_pi->compno);
-                                        return OPJ_FALSE;
-                                }
-
-#ifdef USE_JPWL
-                        /* we need here a j2k handle to verify if making a check to
-                        the validity of cblocks parameters is selected from user (-W) */
-
-                                /* let's check that we are not exceeding */
-                                if ((l_cblk->len + l_seg->newlen) > 8192) {
-                                        opj_event_msg(p_manager, EVT_WARNING,
-                                                "JPWL: segment too long (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
-                                                l_seg->newlen, cblkno, p_pi->precno, bandno, p_pi->resno, p_pi->compno);
-                                        if (!JPWL_ASSUME) {
-                                                opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
-                                                return OPJ_FALSE;
-                                        }
-                                        l_seg->newlen = 8192 - l_cblk->len;
-                                        opj_event_msg(p_manager, EVT_WARNING, "      - truncating segment to %d\n", l_seg->newlen);
-                                        break;
-                                };
-
-#endif /* USE_JPWL */
-                                /* Check possible overflow on size */
-                                if ((l_cblk->data_current_size + l_seg->newlen) < 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, p_pi->precno, bandno, p_pi->resno, p_pi->compno);
-                                        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) {
-                                    OPJ_BYTE* new_cblk_data = (OPJ_BYTE*) opj_realloc(l_cblk->data, l_cblk->data_current_size + l_seg->newlen);
-                                    if(! new_cblk_data) {
-                                        opj_free(l_cblk->data);
-                                        l_cblk->data = NULL;
-                                        l_cblk->data_max_size = 0;
-                                        /* 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 = new_cblk_data;
-                                }
-                               
-                                memcpy(l_cblk->data + l_cblk->data_current_size, l_current_data, l_seg->newlen);
-
-                                if (l_seg->numpasses == 0) {
-                                        l_seg->data = &l_cblk->data;
-                                        l_seg->dataindex = l_cblk->data_current_size;
-                                }
-
-                                l_current_data += l_seg->newlen;
-                                l_seg->numpasses += l_seg->numnewpasses;
-                                l_cblk->numnewpasses -= l_seg->numnewpasses;
-
-                                l_seg->real_num_passes = l_seg->numpasses;
-                                l_cblk->data_current_size += l_seg->newlen;
-                                l_seg->len += l_seg->newlen;
-
-                                if (l_cblk->numnewpasses > 0) {
-                                        ++l_seg;
-                                        ++l_cblk->numsegs;
-                                }
-                        } while (l_cblk->numnewpasses > 0);
-
-                        l_cblk->real_num_segs = l_cblk->numsegs;
-                        ++l_cblk;
-                } /* next code_block */
-
-                ++l_band;
+        if (opj_tcd_is_band_empty(l_band)) {
+            continue;
         }
 
-        *(p_data_read) = (OPJ_UINT32)(l_current_data - p_src_data);
+        l_nb_code_blocks = l_prc->cw * l_prc->ch;
+        l_cblk = l_prc->cblks.dec;
+        for (cblkno = 0; cblkno < l_nb_code_blocks; cblkno++) {
+            OPJ_UINT32 l_included, l_increment, l_segno;
+            OPJ_INT32 n;
 
+            /* if cblk not yet included before --> inclusion tagtree */
+            if (!l_cblk->numsegs) {
+                l_included = opj_tgt_decode(l_bio, l_prc->incltree, cblkno,
+                                            (OPJ_INT32)(p_pi->layno + 1));
+                /* else one bit */
+            } else {
+                l_included = opj_bio_read(l_bio, 1);
+            }
 
-        return OPJ_TRUE;
-}
+            /* if cblk not included */
+            if (!l_included) {
+                l_cblk->numnewpasses = 0;
+                ++l_cblk;
+                JAS_FPRINTF(stderr, "included=%d \n", l_included);
+                continue;
+            }
 
-static OPJ_BOOL opj_t2_skip_packet_data(   opj_t2_t* p_t2,
-                                    opj_tcd_tile_t *p_tile,
-                                    opj_pi_iterator_t *p_pi,
-                                    OPJ_UINT32 * p_data_read,
-                                    OPJ_UINT32 p_max_length,
-                                    opj_packet_info_t *pack_info,
-                                    opj_event_mgr_t *p_manager)
-{
-        OPJ_UINT32 bandno, cblkno;
-        OPJ_UINT32 l_nb_code_blocks;
-        opj_tcd_band_t *l_band = 00;
-        opj_tcd_cblk_dec_t* l_cblk = 00;
-        opj_tcd_resolution_t* l_res = &p_tile->comps[p_pi->compno].resolutions[p_pi->resno];
+            /* if cblk not yet included --> zero-bitplane tagtree */
+            if (!l_cblk->numsegs) {
+                OPJ_UINT32 i = 0;
 
-        OPJ_ARG_NOT_USED(p_t2);
-        OPJ_ARG_NOT_USED(pack_info);
-
-        *p_data_read = 0;
-        l_band = l_res->bands;
-
-        for (bandno = 0; bandno < l_res->numbands; ++bandno) {
-                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;
-                        continue;
+                while (!opj_tgt_decode(l_bio, l_prc->imsbtree, cblkno, (OPJ_INT32)i)) {
+                    ++i;
                 }
 
-                l_nb_code_blocks = l_prc->cw * l_prc->ch;
-                l_cblk = l_prc->cblks.dec;
+                l_cblk->numbps = (OPJ_UINT32)l_band->numbps + 1 - i;
+                l_cblk->numlenbits = 3;
+            }
 
-                for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) {
-                        opj_tcd_seg_t *l_seg = 00;
+            /* number of coding passes */
+            l_cblk->numnewpasses = opj_t2_getnumpasses(l_bio);
+            l_increment = opj_t2_getcommacode(l_bio);
 
-                        if (!l_cblk->numnewpasses) {
-                                /* nothing to do */
-                                ++l_cblk;
-                                continue;
-                        }
+            /* length indicator increment */
+            l_cblk->numlenbits += l_increment;
+            l_segno = 0;
 
-                        if (!l_cblk->numsegs) {
-                                l_seg = l_cblk->segs;
-                                ++l_cblk->numsegs;
-                                l_cblk->data_current_size = 0;
-                        }
-                        else {
-                                l_seg = &l_cblk->segs[l_cblk->numsegs - 1];
-
-                                if (l_seg->numpasses == l_seg->maxpasses) {
-                                        ++l_seg;
-                                        ++l_cblk->numsegs;
-                                }
-                        }
-
-                        do {
-                                /* Check possible overflow then size */
-                                if (((*p_data_read + l_seg->newlen) < (*p_data_read)) || ((*p_data_read + l_seg->newlen) > p_max_length)) {
-                                        opj_event_msg(p_manager, EVT_ERROR, "skip: segment too long (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
-                                                l_seg->newlen, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno, p_pi->compno);
-                                        return OPJ_FALSE;
-                                }
-
-#ifdef USE_JPWL
-                        /* we need here a j2k handle to verify if making a check to
-                        the validity of cblocks parameters is selected from user (-W) */
-
-                                /* let's check that we are not exceeding */
-                                if ((l_cblk->len + l_seg->newlen) > 8192) {
-                                        opj_event_msg(p_manager, EVT_WARNING,
-                                                "JPWL: segment too long (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
-                                                l_seg->newlen, cblkno, p_pi->precno, bandno, p_pi->resno, p_pi->compno);
-                                        if (!JPWL_ASSUME) {
-                                                opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
-                                                return -999;
-                                        }
-                                        l_seg->newlen = 8192 - l_cblk->len;
-                                        opj_event_msg(p_manager, EVT_WARNING, "      - truncating segment to %d\n", l_seg->newlen);
-                                        break;
-                                };
-
-#endif /* USE_JPWL */
-                                        JAS_FPRINTF(stderr, "p_data_read (%d) newlen (%d) \n", *p_data_read, l_seg->newlen );
-                                *(p_data_read) += l_seg->newlen;
-
-                                l_seg->numpasses += l_seg->numnewpasses;
-                                l_cblk->numnewpasses -= l_seg->numnewpasses;
-                                if (l_cblk->numnewpasses > 0)
-                                {
-                                        ++l_seg;
-                                        ++l_cblk->numsegs;
-                                }
-                        } while (l_cblk->numnewpasses > 0);
-
-                        ++l_cblk;
+            if (!l_cblk->numsegs) {
+                if (! opj_t2_init_seg(l_cblk, l_segno, p_tcp->tccps[p_pi->compno].cblksty, 1)) {
+                    opj_bio_destroy(l_bio);
+                    return OPJ_FALSE;
                 }
-
-                ++l_band;
-        }
-
-        return OPJ_TRUE;
-}
-
-
-OPJ_BOOL opj_t2_init_seg(   opj_tcd_cblk_dec_t* cblk,
-                            OPJ_UINT32 index, 
-                            OPJ_UINT32 cblksty, 
-                            OPJ_UINT32 first)
-{
-        opj_tcd_seg_t* seg = 00;
-        OPJ_UINT32 l_nb_segs = index + 1;
-
-        if (l_nb_segs > cblk->m_current_max_segs) {
-                opj_tcd_seg_t* new_segs;
-                cblk->m_current_max_segs += OPJ_J2K_DEFAULT_NB_SEGS;
-
-                new_segs = (opj_tcd_seg_t*) opj_realloc(cblk->segs, cblk->m_current_max_segs * sizeof(opj_tcd_seg_t));
-                if(! new_segs) {
-                        opj_free(cblk->segs);
-                        cblk->segs = NULL;
-                        cblk->m_current_max_segs = 0;
-                        /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to initialize segment %d\n", l_nb_segs); */
+            } else {
+                l_segno = l_cblk->numsegs - 1;
+                if (l_cblk->segs[l_segno].numpasses == l_cblk->segs[l_segno].maxpasses) {
+                    ++l_segno;
+                    if (! opj_t2_init_seg(l_cblk, l_segno, p_tcp->tccps[p_pi->compno].cblksty, 0)) {
+                        opj_bio_destroy(l_bio);
                         return OPJ_FALSE;
+                    }
                 }
-                cblk->segs = new_segs;
-        }
+            }
+            n = (OPJ_INT32)l_cblk->numnewpasses;
 
-        seg = &cblk->segs[index];
-        memset(seg,0,sizeof(opj_tcd_seg_t));
-
-        if (cblksty & J2K_CCP_CBLKSTY_TERMALL) {
-                seg->maxpasses = 1;
-        }
-        else if (cblksty & J2K_CCP_CBLKSTY_LAZY) {
-                if (first) {
-                        seg->maxpasses = 10;
-                } else {
-                        seg->maxpasses = (((seg - 1)->maxpasses == 1) || ((seg - 1)->maxpasses == 10)) ? 2 : 1;
+            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);
+                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);
+
+                n -= (OPJ_INT32)l_cblk->segs[l_segno].numnewpasses;
+                if (n > 0) {
+                    ++l_segno;
+
+                    if (! opj_t2_init_seg(l_cblk, l_segno, p_tcp->tccps[p_pi->compno].cblksty, 0)) {
+                        opj_bio_destroy(l_bio);
+                        return OPJ_FALSE;
+                    }
+                }
+            } while (n > 0);
+
+            ++l_cblk;
+        }
+    }
+
+    if (!opj_bio_inalign(l_bio)) {
+        opj_bio_destroy(l_bio);
+        return OPJ_FALSE;
+    }
+
+    l_header_data += opj_bio_numbytes(l_bio);
+    opj_bio_destroy(l_bio);
+
+    /* EPH markers */
+    if (p_tcp->csty & J2K_CP_CSTY_EPH) {
+        if ((*l_modified_length_ptr - (OPJ_UINT32)(l_header_data -
+                *l_header_data_start)) < 2U) {
+            opj_event_msg(p_manager, EVT_WARNING,
+                          "Not enough space for expected EPH marker\n");
+        } else if ((*l_header_data) != 0xff || (*(l_header_data + 1) != 0x92)) {
+            opj_event_msg(p_manager, EVT_WARNING, "Expected EPH marker\n");
         } else {
-                seg->maxpasses = 109;
+            l_header_data += 2;
+        }
+    }
+
+    l_header_length = (OPJ_UINT32)(l_header_data - *l_header_data_start);
+    JAS_FPRINTF(stderr, "hdrlen=%d \n", l_header_length);
+    JAS_FPRINTF(stderr, "packet body\n");
+    *l_modified_length_ptr -= l_header_length;
+    *l_header_data_start += l_header_length;
+
+    /* << INDEX */
+    /* End of packet header position. Currently only represents the distance to start of packet
+     Will be updated later by incrementing with packet start value */
+    if (p_pack_info) {
+        p_pack_info->end_ph_pos = (OPJ_INT32)(l_current_data - p_src_data);
+    }
+    /* INDEX >> */
+
+    *p_is_data_present = OPJ_TRUE;
+    *p_data_read = (OPJ_UINT32)(l_current_data - p_src_data);
+
+    return OPJ_TRUE;
+}
+
+static OPJ_BOOL opj_t2_read_packet_data(opj_t2_t* p_t2,
+                                        opj_tcd_tile_t *p_tile,
+                                        opj_pi_iterator_t *p_pi,
+                                        OPJ_BYTE *p_src_data,
+                                        OPJ_UINT32 * p_data_read,
+                                        OPJ_UINT32 p_max_length,
+                                        opj_packet_info_t *pack_info,
+                                        opj_event_mgr_t* p_manager)
+{
+    OPJ_UINT32 bandno, cblkno;
+    OPJ_UINT32 l_nb_code_blocks;
+    OPJ_BYTE *l_current_data = p_src_data;
+    opj_tcd_band_t *l_band = 00;
+    opj_tcd_cblk_dec_t* l_cblk = 00;
+    opj_tcd_resolution_t* l_res =
+        &p_tile->comps[p_pi->compno].resolutions[p_pi->resno];
+
+    OPJ_ARG_NOT_USED(p_t2);
+    OPJ_ARG_NOT_USED(pack_info);
+
+    l_band = l_res->bands;
+    for (bandno = 0; bandno < l_res->numbands; ++bandno) {
+        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;
+            continue;
         }
 
-        return OPJ_TRUE;
+        l_nb_code_blocks = l_prc->cw * l_prc->ch;
+        l_cblk = l_prc->cblks.dec;
+
+        for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) {
+            opj_tcd_seg_t *l_seg = 00;
+
+            if (!l_cblk->numnewpasses) {
+                /* nothing to do */
+                ++l_cblk;
+                continue;
+            }
+
+            if (!l_cblk->numsegs) {
+                l_seg = l_cblk->segs;
+                ++l_cblk->numsegs;
+            } else {
+                l_seg = &l_cblk->segs[l_cblk->numsegs - 1];
+
+                if (l_seg->numpasses == l_seg->maxpasses) {
+                    ++l_seg;
+                    ++l_cblk->numsegs;
+                }
+            }
+
+            do {
+                /* Check possible overflow (on l_current_data only, assumes input args already checked) then size */
+                if ((((OPJ_SIZE_T)l_current_data + (OPJ_SIZE_T)l_seg->newlen) <
+                        (OPJ_SIZE_T)l_current_data) ||
+                        (l_current_data + l_seg->newlen > p_src_data + p_max_length)) {
+                    opj_event_msg(p_manager, EVT_ERROR,
+                                  "read: segment too long (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
+                                  l_seg->newlen, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno,
+                                  p_pi->compno);
+                    return OPJ_FALSE;
+                }
+
+#ifdef USE_JPWL
+                /* we need here a j2k handle to verify if making a check to
+                the validity of cblocks parameters is selected from user (-W) */
+
+                /* let's check that we are not exceeding */
+                if ((l_cblk->len + l_seg->newlen) > 8192) {
+                    opj_event_msg(p_manager, EVT_WARNING,
+                                  "JPWL: segment too long (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
+                                  l_seg->newlen, cblkno, p_pi->precno, bandno, p_pi->resno, p_pi->compno);
+                    if (!JPWL_ASSUME) {
+                        opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
+                        return OPJ_FALSE;
+                    }
+                    l_seg->newlen = 8192 - l_cblk->len;
+                    opj_event_msg(p_manager, EVT_WARNING, "      - truncating segment to %d\n",
+                                  l_seg->newlen);
+                    break;
+                };
+
+#endif /* USE_JPWL */
+
+                if (l_cblk->numchunks == l_cblk->numchunksalloc) {
+                    OPJ_UINT32 l_numchunksalloc = l_cblk->numchunksalloc * 2 + 1;
+                    opj_tcd_seg_data_chunk_t* l_chunks =
+                        (opj_tcd_seg_data_chunk_t*)opj_realloc(l_cblk->chunks,
+                                l_numchunksalloc * sizeof(opj_tcd_seg_data_chunk_t));
+                    if (l_chunks == NULL) {
+                        opj_event_msg(p_manager, EVT_ERROR,
+                                      "cannot allocate opj_tcd_seg_data_chunk_t* array");
+                        return OPJ_FALSE;
+                    }
+                    l_cblk->chunks = l_chunks;
+                    l_cblk->numchunksalloc = l_numchunksalloc;
+                }
+
+                l_cblk->chunks[l_cblk->numchunks].data = l_current_data;
+                l_cblk->chunks[l_cblk->numchunks].len = l_seg->newlen;
+                l_cblk->numchunks ++;
+
+                l_current_data += l_seg->newlen;
+                l_seg->len += l_seg->newlen;
+                l_seg->numpasses += l_seg->numnewpasses;
+                l_cblk->numnewpasses -= l_seg->numnewpasses;
+
+                l_seg->real_num_passes = l_seg->numpasses;
+
+                if (l_cblk->numnewpasses > 0) {
+                    ++l_seg;
+                    ++l_cblk->numsegs;
+                }
+            } while (l_cblk->numnewpasses > 0);
+
+            l_cblk->real_num_segs = l_cblk->numsegs;
+            ++l_cblk;
+        } /* next code_block */
+
+        ++l_band;
+    }
+
+    *(p_data_read) = (OPJ_UINT32)(l_current_data - p_src_data);
+
+
+    return OPJ_TRUE;
+}
+
+static OPJ_BOOL opj_t2_skip_packet_data(opj_t2_t* p_t2,
+                                        opj_tcd_tile_t *p_tile,
+                                        opj_pi_iterator_t *p_pi,
+                                        OPJ_UINT32 * p_data_read,
+                                        OPJ_UINT32 p_max_length,
+                                        opj_packet_info_t *pack_info,
+                                        opj_event_mgr_t *p_manager)
+{
+    OPJ_UINT32 bandno, cblkno;
+    OPJ_UINT32 l_nb_code_blocks;
+    opj_tcd_band_t *l_band = 00;
+    opj_tcd_cblk_dec_t* l_cblk = 00;
+    opj_tcd_resolution_t* l_res =
+        &p_tile->comps[p_pi->compno].resolutions[p_pi->resno];
+
+    OPJ_ARG_NOT_USED(p_t2);
+    OPJ_ARG_NOT_USED(pack_info);
+
+    *p_data_read = 0;
+    l_band = l_res->bands;
+
+    for (bandno = 0; bandno < l_res->numbands; ++bandno) {
+        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;
+            continue;
+        }
+
+        l_nb_code_blocks = l_prc->cw * l_prc->ch;
+        l_cblk = l_prc->cblks.dec;
+
+        for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) {
+            opj_tcd_seg_t *l_seg = 00;
+
+            if (!l_cblk->numnewpasses) {
+                /* nothing to do */
+                ++l_cblk;
+                continue;
+            }
+
+            if (!l_cblk->numsegs) {
+                l_seg = l_cblk->segs;
+                ++l_cblk->numsegs;
+            } else {
+                l_seg = &l_cblk->segs[l_cblk->numsegs - 1];
+
+                if (l_seg->numpasses == l_seg->maxpasses) {
+                    ++l_seg;
+                    ++l_cblk->numsegs;
+                }
+            }
+
+            do {
+                /* Check possible overflow then size */
+                if (((*p_data_read + l_seg->newlen) < (*p_data_read)) ||
+                        ((*p_data_read + l_seg->newlen) > p_max_length)) {
+                    opj_event_msg(p_manager, EVT_ERROR,
+                                  "skip: segment too long (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
+                                  l_seg->newlen, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno,
+                                  p_pi->compno);
+                    return OPJ_FALSE;
+                }
+
+#ifdef USE_JPWL
+                /* we need here a j2k handle to verify if making a check to
+                the validity of cblocks parameters is selected from user (-W) */
+
+                /* let's check that we are not exceeding */
+                if ((l_cblk->len + l_seg->newlen) > 8192) {
+                    opj_event_msg(p_manager, EVT_WARNING,
+                                  "JPWL: segment too long (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
+                                  l_seg->newlen, cblkno, p_pi->precno, bandno, p_pi->resno, p_pi->compno);
+                    if (!JPWL_ASSUME) {
+                        opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
+                        return -999;
+                    }
+                    l_seg->newlen = 8192 - l_cblk->len;
+                    opj_event_msg(p_manager, EVT_WARNING, "      - truncating segment to %d\n",
+                                  l_seg->newlen);
+                    break;
+                };
+
+#endif /* USE_JPWL */
+                JAS_FPRINTF(stderr, "p_data_read (%d) newlen (%d) \n", *p_data_read,
+                            l_seg->newlen);
+                *(p_data_read) += l_seg->newlen;
+
+                l_seg->numpasses += l_seg->numnewpasses;
+                l_cblk->numnewpasses -= l_seg->numnewpasses;
+                if (l_cblk->numnewpasses > 0) {
+                    ++l_seg;
+                    ++l_cblk->numsegs;
+                }
+            } while (l_cblk->numnewpasses > 0);
+
+            ++l_cblk;
+        }
+
+        ++l_band;
+    }
+
+    return OPJ_TRUE;
+}
+
+
+static OPJ_BOOL opj_t2_init_seg(opj_tcd_cblk_dec_t* cblk,
+                                OPJ_UINT32 index,
+                                OPJ_UINT32 cblksty,
+                                OPJ_UINT32 first)
+{
+    opj_tcd_seg_t* seg = 00;
+    OPJ_UINT32 l_nb_segs = index + 1;
+
+    if (l_nb_segs > cblk->m_current_max_segs) {
+        opj_tcd_seg_t* new_segs;
+        OPJ_UINT32 l_m_current_max_segs = cblk->m_current_max_segs +
+                                          OPJ_J2K_DEFAULT_NB_SEGS;
+
+        new_segs = (opj_tcd_seg_t*) opj_realloc(cblk->segs,
+                                                l_m_current_max_segs * sizeof(opj_tcd_seg_t));
+        if (! new_segs) {
+            /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to initialize segment %d\n", l_nb_segs); */
+            return OPJ_FALSE;
+        }
+        cblk->segs = new_segs;
+        memset(new_segs + cblk->m_current_max_segs,
+               0, OPJ_J2K_DEFAULT_NB_SEGS * sizeof(opj_tcd_seg_t));
+        cblk->m_current_max_segs = l_m_current_max_segs;
+    }
+
+    seg = &cblk->segs[index];
+    opj_tcd_reinit_segment(seg);
+
+    if (cblksty & J2K_CCP_CBLKSTY_TERMALL) {
+        seg->maxpasses = 1;
+    } else if (cblksty & J2K_CCP_CBLKSTY_LAZY) {
+        if (first) {
+            seg->maxpasses = 10;
+        } else {
+            seg->maxpasses = (((seg - 1)->maxpasses == 1) ||
+                              ((seg - 1)->maxpasses == 10)) ? 2 : 1;
+        }
+    } else {
+        /* See paragraph "B.10.6 Number of coding passes" of the standard.
+         * Probably that 109 must be interpreted a (Mb-1)*3 + 1 with Mb=37,
+         * Mb being the maximum number of bit-planes available for the
+         * representation of coefficients in the sub-band */
+        seg->maxpasses = 109;
+    }
+
+    return OPJ_TRUE;
 }