/*
 * 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.
 *
 * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
 * 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-2014, Antonin Descampe
 * Copyright (c) 2005, Herve Drolon, FreeImage Team
 * Copyright (c) 2008, 2011-2012, Centre National d'Etudes Spatiales (CNES), FR 
 * Copyright (c) 2012, CS Systemes d'Information, France
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "opj_includes.h"

/** @defgroup T2 T2 - Implementation of a tier-2 coding */
/*@{*/

/** @name Local static functions */
/*@{*/

static void opj_t2_putcommacode(opj_bio_t *bio, OPJ_INT32 n);

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
@param n    delta Zil
*/
static void opj_t2_putnumpasses(opj_bio_t *bio, OPJ_UINT32 n);
static OPJ_UINT32 opj_t2_getnumpasses(opj_bio_t *bio);

/**
Encode a packet of a tile to a destination buffer
@param tileno Number of the tile encoded
@param tile Tile for which to write the packets
@param tcp Tile coding parameters
@param pi Packet identity
@param dest Destination buffer
@param p_data_written   FIXME DOC
@param len Length of the destination buffer
@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);

/**
Decode a packet of a tile from a source buffer
@param t2 T2 handle
@param tile Tile for which to write the packets
@param tcp Tile coding parameters
@param pi Packet identity
@param src Source buffer
@param data_read   FIXME DOC
@param max_length  FIXME DOC
@param pack_info Packet information

@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);

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);

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);

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);

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);

/**
@param cblk
@param index
@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);

/*@}*/

/*@}*/

/* ----------------------------------------------------------------------- */

/* #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);
}

OPJ_UINT32 opj_t2_getcommacode(opj_bio_t *bio) 
{
    OPJ_UINT32 n = 0;
    while (opj_bio_read(bio, 1)) {
	    ++n;
    }
    return n;
}

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);
        }
}

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_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;
        }

        * p_data_written = 0;

        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 (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);

                                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];

                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_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 */
#if 0
#define JAS_FPRINTF fprintf
#else
/* issue 290 */
static void opj_null_jas_fprintf(FILE* file, const char * 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_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_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;
        }
#endif

        /* 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 = (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));

                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)) {
                                        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)) {
                                        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 */
                }
                ++l_current_pi;

                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;
}

/* ----------------------------------------------------------------------- */

/**
 * Creates a Tier 2 handle
 *
 * @param       p_image         Source or destination image
 * @param       p_cp            Image coding parameters.
 * @return              a new T2 handle if successful, NULL otherwise.
*/
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;
        }

        l_t2->image = p_image;
        l_t2->cp = p_cp;

        return l_t2;
}

void opj_t2_destroy(opj_t2_t *t2) {
        if(t2) {
                opj_free(t2);
        }
}

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_BOOL l_read_data;
        OPJ_UINT32 l_nb_bytes_read = 0;
        OPJ_UINT32 l_nb_total_bytes_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)) {
                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)) {
                        return OPJ_FALSE;
                }

                l_nb_total_bytes_read += l_nb_bytes_read;
        }

        *p_data_read = l_nb_total_bytes_read;

        return OPJ_TRUE;
}

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_tcd_tilecomp_t *tilec = &tile->comps[compno];
        opj_tcd_resolution_t *res = &tilec->resolutions[resno];

        opj_bio_t *bio = 00;    /* BIO component */

        /* <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;
#else
                c[4] = (tile->packno >> 8) & 0xff; /* packno is uint32_t */
                c[5] = tile->packno & 0xff;
#endif
                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 */
        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 (!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;
                }

                ++band;
        }

        if (!opj_bio_flush(bio)) {
                opj_bio_destroy(bio);
                return OPJ_FALSE;               /* modified to eliminate longjmp !! */
        }

        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; 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 >> */
                }
                ++band;
        }

        assert( c >= dest );
        * p_data_written += (OPJ_UINT32)(c - dest);

        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_BOOL l_read_data;
        OPJ_UINT32 l_nb_bytes_read = 0;
        OPJ_UINT32 l_nb_total_bytes_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)) {
                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)) {
                        return OPJ_FALSE;
                }

                l_nb_total_bytes_read += l_nb_bytes_read;
        }
        *p_data_read = l_nb_total_bytes_read;

        return OPJ_TRUE;
}


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)

{
        /* 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_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) {
                        /* TODO opj_event_msg(p_t2->cinfo->event_mgr, EVT_WARNING, "Not enough space for expected SOP marker\n"); */
                        fprintf(stderr, "Not enough space for expected SOP marker\n");
                } else if ((*l_current_data) != 0xff || (*(l_current_data + 1) != 0x91)) {
                        /* TODO opj_event_msg(p_t2->cinfo->event_mgr, EVT_WARNING, "Expected SOP marker\n"); */
                        fprintf(stderr, "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) {
                                fprintf(stderr, "Not enough space for expected EPH marker\n");
                        } else if ((*l_header_data) != 0xff || (*(l_header_data + 1) != 0x92)) {
                                fprintf(stderr, "Error : 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;
        }

        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_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;
                }

                ++l_band;
        }

        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) {
                        fprintf(stderr, "Not enough space for expected EPH marker\n");
                } else if ((*l_header_data) != 0xff || (*(l_header_data + 1) != 0x92)) {
                        /* TODO opj_event_msg(t2->cinfo->event_mgr, EVT_ERROR, "Expected EPH marker\n"); */
                        fprintf(stderr, "Error : 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 */
        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;
}

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_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;
                }

                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)) {
                                        fprintf(stderr, "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_t2->cinfo, 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_t2->cinfo, EVT_ERROR, "JPWL: giving up\n");
                                                return OPJ_FALSE;
                                        }
                                        l_seg->newlen = 8192 - l_cblk->len;
                                        opj_event_msg(p_t2->cinfo, 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) {
                                        fprintf(stderr, "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;
        }

        *(p_data_read) = (OPJ_UINT32)(l_current_data - p_src_data);


        return OPJ_TRUE;
}

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_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;
                                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 {
                                if (* p_data_read + l_seg->newlen > p_max_length) {
                                        fprintf(stderr, "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_t2->cinfo, 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_t2->cinfo, EVT_ERROR, "JPWL: giving up\n");
                                                return -999;
                                        }
                                        l_seg->newlen = 8192 - l_cblk->len;
                                        opj_event_msg(p_t2->cinfo, 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;
}


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); */
                        return OPJ_FALSE;
                }
                cblk->segs = new_segs;
        }

        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;
                }
        } else {
                seg->maxpasses = 109;
        }

        return OPJ_TRUE;
}
