/*
 * 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) 2006-2007, Parvatha Elangovan
 * 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"

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

/* TODO MSD: */
#ifdef TODO_MSD 
void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_image_t * img) {
        int tileno, compno, resno, bandno, precno;/*, cblkno;*/

        fprintf(fd, "image {\n");
        fprintf(fd, "  tw=%d, th=%d x0=%d x1=%d y0=%d y1=%d\n", 
                img->tw, img->th, tcd->image->x0, tcd->image->x1, tcd->image->y0, tcd->image->y1);

        for (tileno = 0; tileno < img->th * img->tw; tileno++) {
                opj_tcd_tile_t *tile = &tcd->tcd_image->tiles[tileno];
                fprintf(fd, "  tile {\n");
                fprintf(fd, "    x0=%d, y0=%d, x1=%d, y1=%d, numcomps=%d\n",
                        tile->x0, tile->y0, tile->x1, tile->y1, tile->numcomps);
                for (compno = 0; compno < tile->numcomps; compno++) {
                        opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
                        fprintf(fd, "    tilec {\n");
                        fprintf(fd,
                                "      x0=%d, y0=%d, x1=%d, y1=%d, numresolutions=%d\n",
                                tilec->x0, tilec->y0, tilec->x1, tilec->y1, tilec->numresolutions);
                        for (resno = 0; resno < tilec->numresolutions; resno++) {
                                opj_tcd_resolution_t *res = &tilec->resolutions[resno];
                                fprintf(fd, "\n   res {\n");
                                fprintf(fd,
                                        "          x0=%d, y0=%d, x1=%d, y1=%d, pw=%d, ph=%d, numbands=%d\n",
                                        res->x0, res->y0, res->x1, res->y1, res->pw, res->ph, res->numbands);
                                for (bandno = 0; bandno < res->numbands; bandno++) {
                                        opj_tcd_band_t *band = &res->bands[bandno];
                                        fprintf(fd, "        band {\n");
                                        fprintf(fd,
                                                "          x0=%d, y0=%d, x1=%d, y1=%d, stepsize=%f, numbps=%d\n",
                                                band->x0, band->y0, band->x1, band->y1, band->stepsize, band->numbps);
                                        for (precno = 0; precno < res->pw * res->ph; precno++) {
                                                opj_tcd_precinct_t *prec = &band->precincts[precno];
                                                fprintf(fd, "          prec {\n");
                                                fprintf(fd,
                                                        "            x0=%d, y0=%d, x1=%d, y1=%d, cw=%d, ch=%d\n",
                                                        prec->x0, prec->y0, prec->x1, prec->y1, prec->cw, prec->ch);
                                                /*
                                                for (cblkno = 0; cblkno < prec->cw * prec->ch; cblkno++) {
                                                        opj_tcd_cblk_t *cblk = &prec->cblks[cblkno];
                                                        fprintf(fd, "            cblk {\n");
                                                        fprintf(fd,
                                                                "              x0=%d, y0=%d, x1=%d, y1=%d\n",
                                                                cblk->x0, cblk->y0, cblk->x1, cblk->y1);
                                                        fprintf(fd, "            }\n");
                                                }
                                                */
                                                fprintf(fd, "          }\n");
                                        }
                                        fprintf(fd, "        }\n");
                                }
                                fprintf(fd, "      }\n");
                        }
                        fprintf(fd, "    }\n");
                }
                fprintf(fd, "  }\n");
        }
        fprintf(fd, "}\n");
}
#endif

/**
 * Initializes tile coding/decoding
 */
static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no, OPJ_BOOL isEncoder, OPJ_FLOAT32 fraction, OPJ_SIZE_T sizeof_block, opj_event_mgr_t* manager);

/**
* Allocates memory for a decoding code block.
*/
static OPJ_BOOL opj_tcd_code_block_dec_allocate (opj_tcd_cblk_dec_t * p_code_block);

/**
 * Deallocates the decoding data of the given precinct.
 */
static void opj_tcd_code_block_dec_deallocate (opj_tcd_precinct_t * p_precinct);

/**
 * Allocates memory for an encoding code block (but not data).
 */
static OPJ_BOOL opj_tcd_code_block_enc_allocate (opj_tcd_cblk_enc_t * p_code_block);

/**
 * Allocates data for an encoding code block
 */
static OPJ_BOOL opj_tcd_code_block_enc_allocate_data (opj_tcd_cblk_enc_t * p_code_block);

/**
 * Deallocates the encoding data of the given precinct.
 */
static void opj_tcd_code_block_enc_deallocate (opj_tcd_precinct_t * p_precinct);


/**
Free the memory allocated for encoding
@param tcd TCD handle
*/
static void opj_tcd_free_tile(opj_tcd_t *tcd);


static OPJ_BOOL opj_tcd_t2_decode ( opj_tcd_t *p_tcd,
                                    OPJ_BYTE * p_src_data,
                                    OPJ_UINT32 * p_data_read,
                                    OPJ_UINT32 p_max_src_size,
                                    opj_codestream_index_t *p_cstr_index,
                                    opj_event_mgr_t *p_manager);

static OPJ_BOOL opj_tcd_t1_decode (opj_tcd_t *p_tcd);

static OPJ_BOOL opj_tcd_dwt_decode (opj_tcd_t *p_tcd);

static OPJ_BOOL opj_tcd_mct_decode (opj_tcd_t *p_tcd, opj_event_mgr_t *p_manager);

static OPJ_BOOL opj_tcd_dc_level_shift_decode (opj_tcd_t *p_tcd);


static OPJ_BOOL opj_tcd_dc_level_shift_encode ( opj_tcd_t *p_tcd );

static OPJ_BOOL opj_tcd_mct_encode ( opj_tcd_t *p_tcd );

static OPJ_BOOL opj_tcd_dwt_encode ( opj_tcd_t *p_tcd );

static OPJ_BOOL opj_tcd_t1_encode ( opj_tcd_t *p_tcd );

static OPJ_BOOL opj_tcd_t2_encode (     opj_tcd_t *p_tcd,
                                                                    OPJ_BYTE * p_dest_data,
                                                                    OPJ_UINT32 * p_data_written,
                                                                    OPJ_UINT32 p_max_dest_size,
                                                                    opj_codestream_info_t *p_cstr_info );

static OPJ_BOOL opj_tcd_rate_allocate_encode(   opj_tcd_t *p_tcd,
                                                                                        OPJ_BYTE * p_dest_data,
                                                                                        OPJ_UINT32 p_max_dest_size,
                                                                                        opj_codestream_info_t *p_cstr_info );

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

/**
Create a new TCD handle
*/
opj_tcd_t* opj_tcd_create(OPJ_BOOL p_is_decoder)
{
        opj_tcd_t *l_tcd = 00;

        /* create the tcd structure */
        l_tcd = (opj_tcd_t*) opj_calloc(1,sizeof(opj_tcd_t));
        if (!l_tcd) {
                return 00;
        }

        l_tcd->m_is_decoder = p_is_decoder ? 1 : 0;

        l_tcd->tcd_image = (opj_tcd_image_t*)opj_calloc(1,sizeof(opj_tcd_image_t));
        if (!l_tcd->tcd_image) {
                opj_free(l_tcd);
                return 00;
        }

        return l_tcd;
}


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

void opj_tcd_rateallocate_fixed(opj_tcd_t *tcd) {
        OPJ_UINT32 layno;

        for (layno = 0; layno < tcd->tcp->numlayers; layno++) {
                opj_tcd_makelayer_fixed(tcd, layno, 1);
        }
}


void opj_tcd_makelayer( opj_tcd_t *tcd,
                                                OPJ_UINT32 layno,
                                                OPJ_FLOAT64 thresh,
                                                OPJ_UINT32 final)
{
        OPJ_UINT32 compno, resno, bandno, precno, cblkno;
        OPJ_UINT32 passno;

        opj_tcd_tile_t *tcd_tile = tcd->tcd_image->tiles;

        tcd_tile->distolayer[layno] = 0;        /* fixed_quality */

        for (compno = 0; compno < tcd_tile->numcomps; compno++) {
                opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno];

                for (resno = 0; resno < tilec->numresolutions; resno++) {
                        opj_tcd_resolution_t *res = &tilec->resolutions[resno];

                        for (bandno = 0; bandno < res->numbands; bandno++) {
                                opj_tcd_band_t *band = &res->bands[bandno];

                                for (precno = 0; precno < res->pw * res->ph; precno++) {
                                        opj_tcd_precinct_t *prc = &band->precincts[precno];

                                        for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
                                                opj_tcd_cblk_enc_t *cblk = &prc->cblks.enc[cblkno];
                                                opj_tcd_layer_t *layer = &cblk->layers[layno];
                                                OPJ_UINT32 n;

                                                if (layno == 0) {
                                                        cblk->numpassesinlayers = 0;
                                                }

                                                n = cblk->numpassesinlayers;

                                                for (passno = cblk->numpassesinlayers; passno < cblk->totalpasses; passno++) {
                                                        OPJ_UINT32 dr;
                                                        OPJ_FLOAT64 dd;
                                                        opj_tcd_pass_t *pass = &cblk->passes[passno];

                                                        if (n == 0) {
                                                                dr = pass->rate;
                                                                dd = pass->distortiondec;
                                                        } else {
                                                                dr = pass->rate - cblk->passes[n - 1].rate;
                                                                dd = pass->distortiondec - cblk->passes[n - 1].distortiondec;
                                                        }

                                                        if (!dr) {
                                                                if (dd != 0)
                                                                        n = passno + 1;
                                                                continue;
                                                        }
                                                        if (thresh - (dd / dr) < DBL_EPSILON) /* do not rely on float equality, check with DBL_EPSILON margin */
                                                                n = passno + 1;
                                                }

                                                layer->numpasses = n - cblk->numpassesinlayers;

                                                if (!layer->numpasses) {
                                                        layer->disto = 0;
                                                        continue;
                                                }

                                                if (cblk->numpassesinlayers == 0) {
                                                        layer->len = cblk->passes[n - 1].rate;
                                                        layer->data = cblk->data;
                                                        layer->disto = cblk->passes[n - 1].distortiondec;
                                                } else {
                                                        layer->len = cblk->passes[n - 1].rate - cblk->passes[cblk->numpassesinlayers - 1].rate;
                                                        layer->data = cblk->data + cblk->passes[cblk->numpassesinlayers - 1].rate;
                                                        layer->disto = cblk->passes[n - 1].distortiondec - cblk->passes[cblk->numpassesinlayers - 1].distortiondec;
                                                }

                                                tcd_tile->distolayer[layno] += layer->disto;    /* fixed_quality */

                                                if (final)
                                                        cblk->numpassesinlayers = n;
                                        }
                                }
                        }
                }
        }
}

void opj_tcd_makelayer_fixed(opj_tcd_t *tcd, OPJ_UINT32 layno, OPJ_UINT32 final) {
        OPJ_UINT32 compno, resno, bandno, precno, cblkno;
        OPJ_INT32 value;                        /*, matrice[tcd_tcp->numlayers][tcd_tile->comps[0].numresolutions][3]; */
        OPJ_INT32 matrice[10][10][3];
        OPJ_UINT32 i, j, k;

        opj_cp_t *cp = tcd->cp;
        opj_tcd_tile_t *tcd_tile = tcd->tcd_image->tiles;
        opj_tcp_t *tcd_tcp = tcd->tcp;

        for (compno = 0; compno < tcd_tile->numcomps; compno++) {
                opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno];

                for (i = 0; i < tcd_tcp->numlayers; i++) {
                        for (j = 0; j < tilec->numresolutions; j++) {
                                for (k = 0; k < 3; k++) {
                                        matrice[i][j][k] =
                                                (OPJ_INT32) ((OPJ_FLOAT32)cp->m_specific_param.m_enc.m_matrice[i * tilec->numresolutions * 3 + j * 3 + k]
                                                * (OPJ_FLOAT32) (tcd->image->comps[compno].prec / 16.0));
                                }
                        }
                }

                for (resno = 0; resno < tilec->numresolutions; resno++) {
                        opj_tcd_resolution_t *res = &tilec->resolutions[resno];

                        for (bandno = 0; bandno < res->numbands; bandno++) {
                                opj_tcd_band_t *band = &res->bands[bandno];

                                for (precno = 0; precno < res->pw * res->ph; precno++) {
                                        opj_tcd_precinct_t *prc = &band->precincts[precno];

                                        for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
                                                opj_tcd_cblk_enc_t *cblk = &prc->cblks.enc[cblkno];
                                                opj_tcd_layer_t *layer = &cblk->layers[layno];
                                                OPJ_UINT32 n;
                                                OPJ_INT32 imsb = (OPJ_INT32)(tcd->image->comps[compno].prec - cblk->numbps); /* number of bit-plan equal to zero */

                                                /* Correction of the matrix of coefficient to include the IMSB information */
                                                if (layno == 0) {
                                                        value = matrice[layno][resno][bandno];
                                                        if (imsb >= value) {
                                                                value = 0;
                                                        } else {
                                                                value -= imsb;
                                                        }
                                                } else {
                                                        value = matrice[layno][resno][bandno] - matrice[layno - 1][resno][bandno];
                                                        if (imsb >= matrice[layno - 1][resno][bandno]) {
                                                                value -= (imsb - matrice[layno - 1][resno][bandno]);
                                                                if (value < 0) {
                                                                        value = 0;
                                                                }
                                                        }
                                                }

                                                if (layno == 0) {
                                                        cblk->numpassesinlayers = 0;
                                                }

                                                n = cblk->numpassesinlayers;
                                                if (cblk->numpassesinlayers == 0) {
                                                        if (value != 0) {
                                                                n = 3 * (OPJ_UINT32)value - 2 + cblk->numpassesinlayers;
                                                        } else {
                                                                n = cblk->numpassesinlayers;
                                                        }
                                                } else {
                                                        n = 3 * (OPJ_UINT32)value + cblk->numpassesinlayers;
                                                }

                                                layer->numpasses = n - cblk->numpassesinlayers;

                                                if (!layer->numpasses)
                                                        continue;

                                                if (cblk->numpassesinlayers == 0) {
                                                        layer->len = cblk->passes[n - 1].rate;
                                                        layer->data = cblk->data;
                                                } else {
                                                        layer->len = cblk->passes[n - 1].rate - cblk->passes[cblk->numpassesinlayers - 1].rate;
                                                        layer->data = cblk->data + cblk->passes[cblk->numpassesinlayers - 1].rate;
                                                }

                                                if (final)
                                                        cblk->numpassesinlayers = n;
                                        }
                                }
                        }
                }
        }
}

OPJ_BOOL opj_tcd_rateallocate(  opj_tcd_t *tcd,
                                                                OPJ_BYTE *dest,
                                                                OPJ_UINT32 * p_data_written,
                                                                OPJ_UINT32 len,
                                                                opj_codestream_info_t *cstr_info)
{
        OPJ_UINT32 compno, resno, bandno, precno, cblkno, layno;
        OPJ_UINT32 passno;
        OPJ_FLOAT64 min, max;
        OPJ_FLOAT64 cumdisto[100];      /* fixed_quality */
        const OPJ_FLOAT64 K = 1;                /* 1.1; fixed_quality */
        OPJ_FLOAT64 maxSE = 0;

        opj_cp_t *cp = tcd->cp;
        opj_tcd_tile_t *tcd_tile = tcd->tcd_image->tiles;
        opj_tcp_t *tcd_tcp = tcd->tcp;

        min = DBL_MAX;
        max = 0;

        tcd_tile->numpix = 0;           /* fixed_quality */

        for (compno = 0; compno < tcd_tile->numcomps; compno++) {
                opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno];
                tilec->numpix = 0;

                for (resno = 0; resno < tilec->numresolutions; resno++) {
                        opj_tcd_resolution_t *res = &tilec->resolutions[resno];

                        for (bandno = 0; bandno < res->numbands; bandno++) {
                                opj_tcd_band_t *band = &res->bands[bandno];

                                for (precno = 0; precno < res->pw * res->ph; precno++) {
                                        opj_tcd_precinct_t *prc = &band->precincts[precno];

                                        for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
                                                opj_tcd_cblk_enc_t *cblk = &prc->cblks.enc[cblkno];

                                                for (passno = 0; passno < cblk->totalpasses; passno++) {
                                                        opj_tcd_pass_t *pass = &cblk->passes[passno];
                                                        OPJ_INT32 dr;
                                                        OPJ_FLOAT64 dd, rdslope;

                                                        if (passno == 0) {
                                                                dr = (OPJ_INT32)pass->rate;
                                                                dd = pass->distortiondec;
                                                        } else {
                                                                dr = (OPJ_INT32)(pass->rate - cblk->passes[passno - 1].rate);
                                                                dd = pass->distortiondec - cblk->passes[passno - 1].distortiondec;
                                                        }

                                                        if (dr == 0) {
                                                                continue;
                                                        }

                                                        rdslope = dd / dr;
                                                        if (rdslope < min) {
                                                                min = rdslope;
                                                        }

                                                        if (rdslope > max) {
                                                                max = rdslope;
                                                        }
                                                } /* passno */

                                                /* fixed_quality */
                                                tcd_tile->numpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0));
                                                tilec->numpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0));
                                        } /* cbklno */
                                } /* precno */
                        } /* bandno */
                } /* resno */

                maxSE += (((OPJ_FLOAT64)(1 << tcd->image->comps[compno].prec) - 1.0)
                        * ((OPJ_FLOAT64)(1 << tcd->image->comps[compno].prec) -1.0))
                        * ((OPJ_FLOAT64)(tilec->numpix));
        } /* compno */

        /* index file */
        if(cstr_info) {
                opj_tile_info_t *tile_info = &cstr_info->tile[tcd->tcd_tileno];
                tile_info->numpix = tcd_tile->numpix;
                tile_info->distotile = tcd_tile->distotile;
                tile_info->thresh = (OPJ_FLOAT64 *) opj_malloc(tcd_tcp->numlayers * sizeof(OPJ_FLOAT64));
                if (!tile_info->thresh) {
                        /* FIXME event manager error callback */
                        return OPJ_FALSE;
                }
        }

        for (layno = 0; layno < tcd_tcp->numlayers; layno++) {
                OPJ_FLOAT64 lo = min;
                OPJ_FLOAT64 hi = max;
                OPJ_BOOL success = OPJ_FALSE;
                OPJ_UINT32 maxlen = tcd_tcp->rates[layno] ? opj_uint_min(((OPJ_UINT32) ceil(tcd_tcp->rates[layno])), len) : len;
                OPJ_FLOAT64 goodthresh = 0;
                OPJ_FLOAT64 stable_thresh = 0;
                OPJ_UINT32 i;
                OPJ_FLOAT64 distotarget;                /* fixed_quality */

                /* fixed_quality */
                distotarget = tcd_tile->distotile - ((K * maxSE) / pow((OPJ_FLOAT32)10, tcd_tcp->distoratio[layno] / 10));

                /* Don't try to find an optimal threshold but rather take everything not included yet, if
                  -r xx,yy,zz,0   (disto_alloc == 1 and rates == 0)
                  -q xx,yy,zz,0   (fixed_quality == 1 and distoratio == 0)
                  ==> possible to have some lossy layers and the last layer for sure lossless */
                if ( ((cp->m_specific_param.m_enc.m_disto_alloc==1) && (tcd_tcp->rates[layno]>0)) || ((cp->m_specific_param.m_enc.m_fixed_quality==1) && (tcd_tcp->distoratio[layno]>0))) {
                        opj_t2_t*t2 = opj_t2_create(tcd->image, cp);
                        OPJ_FLOAT64 thresh = 0;

                        if (t2 == 00) {
                                return OPJ_FALSE;
                        }

                        for     (i = 0; i < 128; ++i) {
                                OPJ_FLOAT64 distoachieved = 0;  /* fixed_quality */

                                thresh = (lo + hi) / 2;

                                opj_tcd_makelayer(tcd, layno, thresh, 0);

                                if (cp->m_specific_param.m_enc.m_fixed_quality) {       /* fixed_quality */
                                        if(OPJ_IS_CINEMA(cp->rsiz)){
                                                if (! opj_t2_encode_packets(t2,tcd->tcd_tileno, tcd_tile, layno + 1, dest, p_data_written, maxlen, cstr_info,tcd->cur_tp_num,tcd->tp_pos,tcd->cur_pino,THRESH_CALC)) {

                                                        lo = thresh;
                                                        continue;
                                                }
                                                else {
                                                        distoachieved = layno == 0 ?
                                                                        tcd_tile->distolayer[0] : cumdisto[layno - 1] + tcd_tile->distolayer[layno];

                                                        if (distoachieved < distotarget) {
                                                                hi=thresh;
                                                                stable_thresh = thresh;
                                                                continue;
                                                        }else{
                                                                lo=thresh;
                                                        }
                                                }
                                        }else{
                                                distoachieved = (layno == 0) ?
                                                                tcd_tile->distolayer[0] : (cumdisto[layno - 1] + tcd_tile->distolayer[layno]);

                                                if (distoachieved < distotarget) {
                                                        hi = thresh;
                                                        stable_thresh = thresh;
                                                        continue;
                                                }
                                                lo = thresh;
                                        }
                                } else {
                                        if (! opj_t2_encode_packets(t2, tcd->tcd_tileno, tcd_tile, layno + 1, dest,p_data_written, maxlen, cstr_info,tcd->cur_tp_num,tcd->tp_pos,tcd->cur_pino,THRESH_CALC))
                                        {
                                                /* TODO: what to do with l ??? seek / tell ??? */
                                                /* opj_event_msg(tcd->cinfo, EVT_INFO, "rate alloc: len=%d, max=%d\n", l, maxlen); */
                                                lo = thresh;
                                                continue;
                                        }

                                        hi = thresh;
                                        stable_thresh = thresh;
                                }
                        }

                        success = OPJ_TRUE;
                        goodthresh = stable_thresh == 0? thresh : stable_thresh;

                        opj_t2_destroy(t2);
                } else {
                        success = OPJ_TRUE;
                        goodthresh = min;
                }

                if (!success) {
                        return OPJ_FALSE;
                }

                if(cstr_info) { /* Threshold for Marcela Index */
                        cstr_info->tile[tcd->tcd_tileno].thresh[layno] = goodthresh;
                }

                opj_tcd_makelayer(tcd, layno, goodthresh, 1);

                /* fixed_quality */
                cumdisto[layno] = (layno == 0) ? tcd_tile->distolayer[0] : (cumdisto[layno - 1] + tcd_tile->distolayer[layno]);
        }

        return OPJ_TRUE;
}

OPJ_BOOL opj_tcd_init( opj_tcd_t *p_tcd,
                                           opj_image_t * p_image,
                                           opj_cp_t * p_cp )
{
        p_tcd->image = p_image;
        p_tcd->cp = p_cp;

        p_tcd->tcd_image->tiles = (opj_tcd_tile_t *) opj_calloc(1,sizeof(opj_tcd_tile_t));
        if (! p_tcd->tcd_image->tiles) {
                return OPJ_FALSE;
        }

        p_tcd->tcd_image->tiles->comps = (opj_tcd_tilecomp_t *) opj_calloc(p_image->numcomps,sizeof(opj_tcd_tilecomp_t));
        if (! p_tcd->tcd_image->tiles->comps ) {
                return OPJ_FALSE;
        }

        p_tcd->tcd_image->tiles->numcomps = p_image->numcomps;
        p_tcd->tp_pos = p_cp->m_specific_param.m_enc.m_tp_pos;

        return OPJ_TRUE;
}

/**
Destroy a previously created TCD handle
*/
void opj_tcd_destroy(opj_tcd_t *tcd) {
        if (tcd) {
                opj_tcd_free_tile(tcd);

                if (tcd->tcd_image) {
                        opj_free(tcd->tcd_image);
                        tcd->tcd_image = 00;
                }
                opj_free(tcd);
        }
}

OPJ_BOOL opj_alloc_tile_component_data(opj_tcd_tilecomp_t *l_tilec)
{
	if ((l_tilec->data == 00) || ((l_tilec->data_size_needed > l_tilec->data_size) && (l_tilec->ownsData == OPJ_FALSE))) {
		l_tilec->data = (OPJ_INT32 *) opj_malloc(l_tilec->data_size_needed);
		if (! l_tilec->data ) {
			return OPJ_FALSE;
		}
		/*fprintf(stderr, "tAllocate data of tilec (int): %d x OPJ_UINT32n",l_data_size);*/
		l_tilec->data_size = l_tilec->data_size_needed;
		l_tilec->ownsData = OPJ_TRUE;
	}
	else if (l_tilec->data_size_needed > l_tilec->data_size) {
		OPJ_INT32 * new_data = (OPJ_INT32 *) opj_realloc(l_tilec->data, l_tilec->data_size_needed);
		/* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle tile datan"); */
		/* fprintf(stderr, "Not enough memory to handle tile data"); */
		if (! new_data) {
			opj_free(l_tilec->data);
			l_tilec->data = NULL;
			l_tilec->data_size = 0;
			l_tilec->data_size_needed = 0;
			l_tilec->ownsData = OPJ_FALSE;
			return OPJ_FALSE;
		}
		l_tilec->data = new_data;
		/*fprintf(stderr, "tReallocate data of tilec (int): from %d to %d x OPJ_UINT32n", l_tilec->data_size, l_data_size);*/
		l_tilec->data_size = l_tilec->data_size_needed;
		l_tilec->ownsData = OPJ_TRUE;
	}
	return OPJ_TRUE;
}

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

static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no, OPJ_BOOL isEncoder, OPJ_FLOAT32 fraction, OPJ_SIZE_T sizeof_block, opj_event_mgr_t* manager)
{
	OPJ_UINT32 (*l_gain_ptr)(OPJ_UINT32) = 00;
	OPJ_UINT32 compno, resno, bandno, precno, cblkno;
	opj_tcp_t * l_tcp = 00;
	opj_cp_t * l_cp = 00;
	opj_tcd_tile_t * l_tile = 00;
	opj_tccp_t *l_tccp = 00;
	opj_tcd_tilecomp_t *l_tilec = 00;
	opj_image_comp_t * l_image_comp = 00;
	opj_tcd_resolution_t *l_res = 00;
	opj_tcd_band_t *l_band = 00;
	opj_stepsize_t * l_step_size = 00;
	opj_tcd_precinct_t *l_current_precinct = 00;
	opj_image_t *l_image = 00;
	OPJ_UINT32 p,q;
	OPJ_UINT32 l_level_no;
	OPJ_UINT32 l_pdx, l_pdy;
	OPJ_UINT32 l_gain;
	OPJ_INT32 l_x0b, l_y0b;
	OPJ_UINT32 l_tx0, l_ty0;
	/* extent of precincts , top left, bottom right**/
	OPJ_INT32 l_tl_prc_x_start, l_tl_prc_y_start, l_br_prc_x_end, l_br_prc_y_end;
	/* number of precinct for a resolution */
	OPJ_UINT32 l_nb_precincts;
	/* room needed to store l_nb_precinct precinct for a resolution */
	OPJ_UINT32 l_nb_precinct_size;
	/* number of code blocks for a precinct*/
	OPJ_UINT32 l_nb_code_blocks;
	/* room needed to store l_nb_code_blocks code blocks for a precinct*/
	OPJ_UINT32 l_nb_code_blocks_size;
	/* size of data for a tile */
	OPJ_UINT32 l_data_size;
	
	l_cp = p_tcd->cp;
	l_tcp = &(l_cp->tcps[p_tile_no]);
	l_tile = p_tcd->tcd_image->tiles;
	l_tccp = l_tcp->tccps;
	l_tilec = l_tile->comps;
	l_image = p_tcd->image;
	l_image_comp = p_tcd->image->comps;
	
	p = p_tile_no % l_cp->tw;       /* tile coordinates */
	q = p_tile_no / l_cp->tw;
	/*fprintf(stderr, "Tile coordinate = %d,%d\n", p, q);*/
	
	/* 4 borders of the tile rescale on the image if necessary */
	l_tx0 = l_cp->tx0 + p * l_cp->tdx; /* can't be greater than l_image->x1 so won't overflow */
	l_tile->x0 = (OPJ_INT32)opj_uint_max(l_tx0, l_image->x0);
	l_tile->x1 = (OPJ_INT32)opj_uint_min(opj_uint_adds(l_tx0, l_cp->tdx), l_image->x1);
	l_ty0 = l_cp->ty0 + q * l_cp->tdy; /* can't be greater than l_image->y1 so won't overflow */
	l_tile->y0 = (OPJ_INT32)opj_uint_max(l_ty0, l_image->y0);
	l_tile->y1 = (OPJ_INT32)opj_uint_min(opj_uint_adds(l_ty0, l_cp->tdy), l_image->y1);

	/* testcase 1888.pdf.asan.35.988 */
	if (l_tccp->numresolutions == 0) {
		opj_event_msg(manager, EVT_ERROR, "tiles require at least one resolution\n");
		return OPJ_FALSE;
	}
	/*fprintf(stderr, "Tile border = %d,%d,%d,%d\n", l_tile->x0, l_tile->y0,l_tile->x1,l_tile->y1);*/
	
	/*tile->numcomps = image->numcomps; */
	for (compno = 0; compno < l_tile->numcomps; ++compno) {
		/*fprintf(stderr, "compno = %d/%d\n", compno, l_tile->numcomps);*/
		l_image_comp->resno_decoded = 0;
		/* border of each l_tile component (global) */
		l_tilec->x0 = opj_int_ceildiv(l_tile->x0, (OPJ_INT32)l_image_comp->dx);
		l_tilec->y0 = opj_int_ceildiv(l_tile->y0, (OPJ_INT32)l_image_comp->dy);
		l_tilec->x1 = opj_int_ceildiv(l_tile->x1, (OPJ_INT32)l_image_comp->dx);
		l_tilec->y1 = opj_int_ceildiv(l_tile->y1, (OPJ_INT32)l_image_comp->dy);
		/*fprintf(stderr, "\tTile compo border = %d,%d,%d,%d\n", l_tilec->x0, l_tilec->y0,l_tilec->x1,l_tilec->y1);*/
		if (l_tilec->x0 >= l_tilec->x1 || l_tilec->y0 >= l_tilec->y1) {
			opj_event_msg(manager, EVT_ERROR, "Invalid tile data\n");
			return OPJ_FALSE;
		}
		/* compute l_data_size with overflow check */
		l_data_size = (OPJ_UINT32)(l_tilec->x1 - l_tilec->x0);
		if ((((OPJ_UINT32)-1) / l_data_size) < (OPJ_UINT32)(l_tilec->y1 - l_tilec->y0)) {
			opj_event_msg(manager, EVT_ERROR, "Not enough memory for tile data\n");
			return OPJ_FALSE;
		}
		l_data_size = l_data_size * (OPJ_UINT32)(l_tilec->y1 - l_tilec->y0);
		
		if ((((OPJ_UINT32)-1) / (OPJ_UINT32)sizeof(OPJ_UINT32)) < l_data_size) {
			opj_event_msg(manager, EVT_ERROR, "Not enough memory for tile data\n");
			return OPJ_FALSE;
		}
		l_data_size = l_data_size * (OPJ_UINT32)sizeof(OPJ_UINT32);
		l_tilec->numresolutions = l_tccp->numresolutions;
		if (l_tccp->numresolutions < l_cp->m_specific_param.m_dec.m_reduce) {
			l_tilec->minimum_num_resolutions = 1;
		}
		else {
			l_tilec->minimum_num_resolutions = l_tccp->numresolutions - l_cp->m_specific_param.m_dec.m_reduce;
		}
		
		l_tilec->data_size_needed = l_data_size;
		if (p_tcd->m_is_decoder && !opj_alloc_tile_component_data(l_tilec)) {
			opj_event_msg(manager, EVT_ERROR, "Not enough memory for tile data\n");
			return OPJ_FALSE;
		}
		
		l_data_size = l_tilec->numresolutions * (OPJ_UINT32)sizeof(opj_tcd_resolution_t);
		
		if (l_tilec->resolutions == 00) {
			l_tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(l_data_size);
			if (! l_tilec->resolutions ) {
				return OPJ_FALSE;
			}
			/*fprintf(stderr, "\tAllocate resolutions of tilec (opj_tcd_resolution_t): %d\n",l_data_size);*/
			l_tilec->resolutions_size = l_data_size;
			memset(l_tilec->resolutions,0,l_data_size);
		}
		else if (l_data_size > l_tilec->resolutions_size) {
			opj_tcd_resolution_t* new_resolutions = (opj_tcd_resolution_t *) opj_realloc(l_tilec->resolutions, l_data_size);
			if (! new_resolutions) {
				opj_event_msg(manager, EVT_ERROR, "Not enough memory for tile resolutions\n");
				opj_free(l_tilec->resolutions);
				l_tilec->resolutions = NULL;
				l_tilec->resolutions_size = 0;
				return OPJ_FALSE;
			}
			l_tilec->resolutions = new_resolutions;
			/*fprintf(stderr, "\tReallocate data of tilec (int): from %d to %d x OPJ_UINT32\n", l_tilec->resolutions_size, l_data_size);*/
			memset(((OPJ_BYTE*) l_tilec->resolutions)+l_tilec->resolutions_size,0,l_data_size - l_tilec->resolutions_size);
			l_tilec->resolutions_size = l_data_size;
		}
		
		l_level_no = l_tilec->numresolutions - 1;
		l_res = l_tilec->resolutions;
		l_step_size = l_tccp->stepsizes;
		if (l_tccp->qmfbid == 0) {
			l_gain_ptr = &opj_dwt_getgain_real;
		}
		else {
			l_gain_ptr  = &opj_dwt_getgain;
		}
		/*fprintf(stderr, "\tlevel_no=%d\n",l_level_no);*/
		
		for (resno = 0; resno < l_tilec->numresolutions; ++resno) {
			/*fprintf(stderr, "\t\tresno = %d/%d\n", resno, l_tilec->numresolutions);*/
			OPJ_INT32 tlcbgxstart, tlcbgystart /*, brcbgxend, brcbgyend*/;
			OPJ_UINT32 cbgwidthexpn, cbgheightexpn;
			OPJ_UINT32 cblkwidthexpn, cblkheightexpn;
			
			/* border for each resolution level (global) */
			l_res->x0 = opj_int_ceildivpow2(l_tilec->x0, (OPJ_INT32)l_level_no);
			l_res->y0 = opj_int_ceildivpow2(l_tilec->y0, (OPJ_INT32)l_level_no);
			l_res->x1 = opj_int_ceildivpow2(l_tilec->x1, (OPJ_INT32)l_level_no);
			l_res->y1 = opj_int_ceildivpow2(l_tilec->y1, (OPJ_INT32)l_level_no);
			/*fprintf(stderr, "\t\t\tres_x0= %d, res_y0 =%d, res_x1=%d, res_y1=%d\n", l_res->x0, l_res->y0, l_res->x1, l_res->y1);*/
			/* p. 35, table A-23, ISO/IEC FDIS154444-1 : 2000 (18 august 2000) */
			l_pdx = l_tccp->prcw[resno];
			l_pdy = l_tccp->prch[resno];
			/*fprintf(stderr, "\t\t\tpdx=%d, pdy=%d\n", l_pdx, l_pdy);*/
			/* p. 64, B.6, ISO/IEC FDIS15444-1 : 2000 (18 august 2000)  */
			l_tl_prc_x_start = opj_int_floordivpow2(l_res->x0, (OPJ_INT32)l_pdx) << l_pdx;
			l_tl_prc_y_start = opj_int_floordivpow2(l_res->y0, (OPJ_INT32)l_pdy) << l_pdy;
			l_br_prc_x_end = opj_int_ceildivpow2(l_res->x1, (OPJ_INT32)l_pdx) << l_pdx;
			l_br_prc_y_end = opj_int_ceildivpow2(l_res->y1, (OPJ_INT32)l_pdy) << l_pdy;
			/*fprintf(stderr, "\t\t\tprc_x_start=%d, prc_y_start=%d, br_prc_x_end=%d, br_prc_y_end=%d \n", l_tl_prc_x_start, l_tl_prc_y_start, l_br_prc_x_end ,l_br_prc_y_end );*/
			
			l_res->pw = (l_res->x0 == l_res->x1) ? 0 : (OPJ_UINT32)((l_br_prc_x_end - l_tl_prc_x_start) >> l_pdx);
			l_res->ph = (l_res->y0 == l_res->y1) ? 0 : (OPJ_UINT32)((l_br_prc_y_end - l_tl_prc_y_start) >> l_pdy);
			/*fprintf(stderr, "\t\t\tres_pw=%d, res_ph=%d\n", l_res->pw, l_res->ph );*/
			
			l_nb_precincts = l_res->pw * l_res->ph;
			l_nb_precinct_size = l_nb_precincts * (OPJ_UINT32)sizeof(opj_tcd_precinct_t);
			if (resno == 0) {
				tlcbgxstart = l_tl_prc_x_start;
				tlcbgystart = l_tl_prc_y_start;
				/*brcbgxend = l_br_prc_x_end;*/
				/* brcbgyend = l_br_prc_y_end;*/
				cbgwidthexpn = l_pdx;
				cbgheightexpn = l_pdy;
				l_res->numbands = 1;
			}
			else {
				tlcbgxstart = opj_int_ceildivpow2(l_tl_prc_x_start, 1);
				tlcbgystart = opj_int_ceildivpow2(l_tl_prc_y_start, 1);
				/*brcbgxend = opj_int_ceildivpow2(l_br_prc_x_end, 1);*/
				/*brcbgyend = opj_int_ceildivpow2(l_br_prc_y_end, 1);*/
				cbgwidthexpn = l_pdx - 1;
				cbgheightexpn = l_pdy - 1;
				l_res->numbands = 3;
			}
			
			cblkwidthexpn = opj_uint_min(l_tccp->cblkw, cbgwidthexpn);
			cblkheightexpn = opj_uint_min(l_tccp->cblkh, cbgheightexpn);
			l_band = l_res->bands;
			
			for (bandno = 0; bandno < l_res->numbands; ++bandno) {
				OPJ_INT32 numbps;
				/*fprintf(stderr, "\t\t\tband_no=%d/%d\n", bandno, l_res->numbands );*/
				
				if (resno == 0) {
					l_band->bandno = 0 ;
					l_band->x0 = opj_int_ceildivpow2(l_tilec->x0, (OPJ_INT32)l_level_no);
					l_band->y0 = opj_int_ceildivpow2(l_tilec->y0, (OPJ_INT32)l_level_no);
					l_band->x1 = opj_int_ceildivpow2(l_tilec->x1, (OPJ_INT32)l_level_no);
					l_band->y1 = opj_int_ceildivpow2(l_tilec->y1, (OPJ_INT32)l_level_no);
				}
				else {
					l_band->bandno = bandno + 1;
					/* x0b = 1 if bandno = 1 or 3 */
					l_x0b = l_band->bandno&1;
					/* y0b = 1 if bandno = 2 or 3 */
					l_y0b = (OPJ_INT32)((l_band->bandno)>>1);
					/* l_band border (global) */
					l_band->x0 = opj_int64_ceildivpow2(l_tilec->x0 - ((OPJ_INT64)l_x0b << l_level_no), (OPJ_INT32)(l_level_no + 1));
					l_band->y0 = opj_int64_ceildivpow2(l_tilec->y0 - ((OPJ_INT64)l_y0b << l_level_no), (OPJ_INT32)(l_level_no + 1));
					l_band->x1 = opj_int64_ceildivpow2(l_tilec->x1 - ((OPJ_INT64)l_x0b << l_level_no), (OPJ_INT32)(l_level_no + 1));
					l_band->y1 = opj_int64_ceildivpow2(l_tilec->y1 - ((OPJ_INT64)l_y0b << l_level_no), (OPJ_INT32)(l_level_no + 1));
				}
				
				/** avoid an if with storing function pointer */
				l_gain = (*l_gain_ptr) (l_band->bandno);
				numbps = (OPJ_INT32)(l_image_comp->prec + l_gain);
				l_band->stepsize = (OPJ_FLOAT32)(((1.0 + l_step_size->mant / 2048.0) * pow(2.0, (OPJ_INT32) (numbps - l_step_size->expn)))) * fraction;
				l_band->numbps = l_step_size->expn + (OPJ_INT32)l_tccp->numgbits - 1;      /* WHY -1 ? */
				
				if (! l_band->precincts) {
					l_band->precincts = (opj_tcd_precinct_t *) opj_malloc( /*3 * */ l_nb_precinct_size);
					if (! l_band->precincts) {
						return OPJ_FALSE;
					}
					/*fprintf(stderr, "\t\t\t\tAllocate precincts of a band (opj_tcd_precinct_t): %d\n",l_nb_precinct_size);     */
					memset(l_band->precincts,0,l_nb_precinct_size);
					l_band->precincts_data_size = l_nb_precinct_size;
				}
				else if (l_band->precincts_data_size < l_nb_precinct_size) {
					
					opj_tcd_precinct_t * new_precincts = (opj_tcd_precinct_t *) opj_realloc(l_band->precincts,/*3 * */ l_nb_precinct_size);
					if (! new_precincts) {
						opj_event_msg(manager, EVT_ERROR, "Not enough memory to handle band precints\n");
						opj_free(l_band->precincts);
						l_band->precincts = NULL;
						l_band->precincts_data_size = 0;
						return OPJ_FALSE;
					}
					l_band->precincts = new_precincts;
					/*fprintf(stderr, "\t\t\t\tReallocate precincts of a band (opj_tcd_precinct_t): from %d to %d\n",l_band->precincts_data_size, l_nb_precinct_size);*/
					memset(((OPJ_BYTE *) l_band->precincts) + l_band->precincts_data_size,0,l_nb_precinct_size - l_band->precincts_data_size);
					l_band->precincts_data_size = l_nb_precinct_size;
				}
				
				l_current_precinct = l_band->precincts;
				for (precno = 0; precno < l_nb_precincts; ++precno) {
					OPJ_INT32 tlcblkxstart, tlcblkystart, brcblkxend, brcblkyend;
					OPJ_INT32 cbgxstart = tlcbgxstart + (OPJ_INT32)(precno % l_res->pw) * (1 << cbgwidthexpn);
					OPJ_INT32 cbgystart = tlcbgystart + (OPJ_INT32)(precno / l_res->pw) * (1 << cbgheightexpn);
					OPJ_INT32 cbgxend = cbgxstart + (1 << cbgwidthexpn);
					OPJ_INT32 cbgyend = cbgystart + (1 << cbgheightexpn);
					/*fprintf(stderr, "\t precno=%d; bandno=%d, resno=%d; compno=%d\n", precno, bandno , resno, compno);*/
					/*fprintf(stderr, "\t tlcbgxstart(=%d) + (precno(=%d) percent res->pw(=%d)) * (1 << cbgwidthexpn(=%d)) \n",tlcbgxstart,precno,l_res->pw,cbgwidthexpn);*/
					
					/* precinct size (global) */
					/*fprintf(stderr, "\t cbgxstart=%d, l_band->x0 = %d \n",cbgxstart, l_band->x0);*/
					
					l_current_precinct->x0 = opj_int_max(cbgxstart, l_band->x0);
					l_current_precinct->y0 = opj_int_max(cbgystart, l_band->y0);
					l_current_precinct->x1 = opj_int_min(cbgxend, l_band->x1);
					l_current_precinct->y1 = opj_int_min(cbgyend, l_band->y1);
					/*fprintf(stderr, "\t prc_x0=%d; prc_y0=%d, prc_x1=%d; prc_y1=%d\n",l_current_precinct->x0, l_current_precinct->y0 ,l_current_precinct->x1, l_current_precinct->y1);*/
					
					tlcblkxstart = opj_int_floordivpow2(l_current_precinct->x0, (OPJ_INT32)cblkwidthexpn) << cblkwidthexpn;
					/*fprintf(stderr, "\t tlcblkxstart =%d\n",tlcblkxstart );*/
					tlcblkystart = opj_int_floordivpow2(l_current_precinct->y0, (OPJ_INT32)cblkheightexpn) << cblkheightexpn;
					/*fprintf(stderr, "\t tlcblkystart =%d\n",tlcblkystart );*/
					brcblkxend = opj_int_ceildivpow2(l_current_precinct->x1, (OPJ_INT32)cblkwidthexpn) << cblkwidthexpn;
					/*fprintf(stderr, "\t brcblkxend =%d\n",brcblkxend );*/
					brcblkyend = opj_int_ceildivpow2(l_current_precinct->y1, (OPJ_INT32)cblkheightexpn) << cblkheightexpn;
					/*fprintf(stderr, "\t brcblkyend =%d\n",brcblkyend );*/
					l_current_precinct->cw = (OPJ_UINT32)((brcblkxend - tlcblkxstart) >> cblkwidthexpn);
					l_current_precinct->ch = (OPJ_UINT32)((brcblkyend - tlcblkystart) >> cblkheightexpn);
					
					l_nb_code_blocks = l_current_precinct->cw * l_current_precinct->ch;
					/*fprintf(stderr, "\t\t\t\t precinct_cw = %d x recinct_ch = %d\n",l_current_precinct->cw, l_current_precinct->ch);      */
					l_nb_code_blocks_size = l_nb_code_blocks * (OPJ_UINT32)sizeof_block;
					
					if (! l_current_precinct->cblks.blocks) {
						l_current_precinct->cblks.blocks = opj_malloc(l_nb_code_blocks_size);
						if (! l_current_precinct->cblks.blocks ) {
							return OPJ_FALSE;
						}
						/*fprintf(stderr, "\t\t\t\tAllocate cblks of a precinct (opj_tcd_cblk_dec_t): %d\n",l_nb_code_blocks_size);*/
						
						memset(l_current_precinct->cblks.blocks,0,l_nb_code_blocks_size);
						
						l_current_precinct->block_size = l_nb_code_blocks_size;
					}
					else if (l_nb_code_blocks_size > l_current_precinct->block_size) {
						void *new_blocks = opj_realloc(l_current_precinct->cblks.blocks, l_nb_code_blocks_size);
						if (! new_blocks) {
							opj_free(l_current_precinct->cblks.blocks);
							l_current_precinct->cblks.blocks = NULL;
							l_current_precinct->block_size = 0;
							opj_event_msg(manager, EVT_ERROR, "Not enough memory for current precinct codeblock element\n");
							return OPJ_FALSE;
						}
						l_current_precinct->cblks.blocks = new_blocks;
						/*fprintf(stderr, "\t\t\t\tReallocate cblks of a precinct (opj_tcd_cblk_dec_t): from %d to %d\n",l_current_precinct->block_size, l_nb_code_blocks_size);     */
						
						memset(((OPJ_BYTE *) l_current_precinct->cblks.blocks) + l_current_precinct->block_size
									 ,0
									 ,l_nb_code_blocks_size - l_current_precinct->block_size);
						
						l_current_precinct->block_size = l_nb_code_blocks_size;
					}
					
					if (! l_current_precinct->incltree) {
						l_current_precinct->incltree = opj_tgt_create(l_current_precinct->cw, l_current_precinct->ch, manager);
					}
					else{
						l_current_precinct->incltree = opj_tgt_init(l_current_precinct->incltree, l_current_precinct->cw, l_current_precinct->ch, manager);
					}

					if (! l_current_precinct->incltree)     {
						opj_event_msg(manager, EVT_WARNING, "No incltree created.\n");
						/*return OPJ_FALSE;*/
					}

					if (! l_current_precinct->imsbtree) {
						l_current_precinct->imsbtree = opj_tgt_create(l_current_precinct->cw, l_current_precinct->ch, manager);
					}
					else {
						l_current_precinct->imsbtree = opj_tgt_init(l_current_precinct->imsbtree, l_current_precinct->cw, l_current_precinct->ch, manager);
					}

					if (! l_current_precinct->imsbtree) {
						opj_event_msg(manager, EVT_WARNING, "No imsbtree created.\n");
						/*return OPJ_FALSE;*/
					}

					for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) {
						OPJ_INT32 cblkxstart = tlcblkxstart + (OPJ_INT32)(cblkno % l_current_precinct->cw) * (1 << cblkwidthexpn);
						OPJ_INT32 cblkystart = tlcblkystart + (OPJ_INT32)(cblkno / l_current_precinct->cw) * (1 << cblkheightexpn);
						OPJ_INT32 cblkxend = cblkxstart + (1 << cblkwidthexpn);
						OPJ_INT32 cblkyend = cblkystart + (1 << cblkheightexpn);
						
						if (isEncoder) {
							opj_tcd_cblk_enc_t* l_code_block = l_current_precinct->cblks.enc + cblkno;
							
							if (! opj_tcd_code_block_enc_allocate(l_code_block)) {
								return OPJ_FALSE;
							}
							/* code-block size (global) */
							l_code_block->x0 = opj_int_max(cblkxstart, l_current_precinct->x0);
							l_code_block->y0 = opj_int_max(cblkystart, l_current_precinct->y0);
							l_code_block->x1 = opj_int_min(cblkxend, l_current_precinct->x1);
							l_code_block->y1 = opj_int_min(cblkyend, l_current_precinct->y1);
							
							if (! opj_tcd_code_block_enc_allocate_data(l_code_block)) {
								return OPJ_FALSE;
							}
						} else {
							opj_tcd_cblk_dec_t* l_code_block = l_current_precinct->cblks.dec + cblkno;
							
							if (! opj_tcd_code_block_dec_allocate(l_code_block)) {
								return OPJ_FALSE;
							}
							/* code-block size (global) */
							l_code_block->x0 = opj_int_max(cblkxstart, l_current_precinct->x0);
							l_code_block->y0 = opj_int_max(cblkystart, l_current_precinct->y0);
							l_code_block->x1 = opj_int_min(cblkxend, l_current_precinct->x1);
							l_code_block->y1 = opj_int_min(cblkyend, l_current_precinct->y1);
						}
					}
					++l_current_precinct;
				} /* precno */
				++l_band;
				++l_step_size;
			} /* bandno */
			++l_res;
			--l_level_no;
		} /* resno */
		++l_tccp;
		++l_tilec;
		++l_image_comp;
	} /* compno */
	return OPJ_TRUE;
}

OPJ_BOOL opj_tcd_init_encode_tile (opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no, opj_event_mgr_t* p_manager)
{
	return opj_tcd_init_tile(p_tcd, p_tile_no, OPJ_TRUE, 1.0F, sizeof(opj_tcd_cblk_enc_t), p_manager);
}

OPJ_BOOL opj_tcd_init_decode_tile (opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no, opj_event_mgr_t* p_manager)
{
	return opj_tcd_init_tile(p_tcd, p_tile_no, OPJ_FALSE, 0.5F, sizeof(opj_tcd_cblk_dec_t), p_manager);
}

/**
 * Allocates memory for an encoding code block (but not data memory).
 */
static OPJ_BOOL opj_tcd_code_block_enc_allocate (opj_tcd_cblk_enc_t * p_code_block)
{
	if (! p_code_block->layers) {
		/* no memset since data */
		p_code_block->layers = (opj_tcd_layer_t*) opj_calloc(100, sizeof(opj_tcd_layer_t));
		if (! p_code_block->layers) {
			return OPJ_FALSE;
		}
	}
	if (! p_code_block->passes) {
		p_code_block->passes = (opj_tcd_pass_t*) opj_calloc(100, sizeof(opj_tcd_pass_t));
		if (! p_code_block->passes) {
			return OPJ_FALSE;
		}
	}
	return OPJ_TRUE;
}

/**
 * Allocates data memory for an encoding code block.
 */
static OPJ_BOOL opj_tcd_code_block_enc_allocate_data (opj_tcd_cblk_enc_t * p_code_block)
{
	OPJ_UINT32 l_data_size;
	
	l_data_size = (OPJ_UINT32)((p_code_block->x1 - p_code_block->x0) * (p_code_block->y1 - p_code_block->y0) * (OPJ_INT32)sizeof(OPJ_UINT32));
	
	if (l_data_size > p_code_block->data_size) {
		if (p_code_block->data) {
			opj_free(p_code_block->data - 1); /* again, why -1 */
		}
		p_code_block->data = (OPJ_BYTE*) opj_malloc(l_data_size+1);
		if(! p_code_block->data) {
			p_code_block->data_size = 0U;
			return OPJ_FALSE;
		}
		p_code_block->data_size = l_data_size;
		
		p_code_block->data[0] = 0;
		p_code_block->data+=1;   /*why +1 ?*/
	}
	return OPJ_TRUE;
}

/**
 * Allocates memory for a decoding code block.
 */
static OPJ_BOOL opj_tcd_code_block_dec_allocate (opj_tcd_cblk_dec_t * p_code_block)
{
        if (! p_code_block->data) {

                p_code_block->data = (OPJ_BYTE*) opj_malloc(OPJ_J2K_DEFAULT_CBLK_DATA_SIZE);
                if (! p_code_block->data) {
                        return OPJ_FALSE;
                }
                p_code_block->data_max_size = OPJ_J2K_DEFAULT_CBLK_DATA_SIZE;
                /*fprintf(stderr, "Allocate 8192 elements of code_block->data\n");*/

                p_code_block->segs = (opj_tcd_seg_t *) opj_calloc(OPJ_J2K_DEFAULT_NB_SEGS,sizeof(opj_tcd_seg_t));
                if (! p_code_block->segs) {
                        return OPJ_FALSE;
                }
                /*fprintf(stderr, "Allocate %d elements of code_block->data\n", OPJ_J2K_DEFAULT_NB_SEGS * sizeof(opj_tcd_seg_t));*/

                p_code_block->m_current_max_segs = OPJ_J2K_DEFAULT_NB_SEGS;
                /*fprintf(stderr, "m_current_max_segs of code_block->data = %d\n", p_code_block->m_current_max_segs);*/
        } else {
					/* sanitize */
					OPJ_BYTE* l_data = p_code_block->data;
					OPJ_UINT32 l_data_max_size = p_code_block->data_max_size;
					opj_tcd_seg_t * l_segs = p_code_block->segs;
					OPJ_UINT32 l_current_max_segs = p_code_block->m_current_max_segs;

					memset(p_code_block, 0, sizeof(opj_tcd_cblk_dec_t));
					p_code_block->data = l_data;
					p_code_block->data_max_size = l_data_max_size;
					p_code_block->segs = l_segs;
					p_code_block->m_current_max_segs = l_current_max_segs;
				}

        return OPJ_TRUE;
}

OPJ_UINT32 opj_tcd_get_decoded_tile_size ( opj_tcd_t *p_tcd )
{
        OPJ_UINT32 i;
        OPJ_UINT32 l_data_size = 0;
        opj_image_comp_t * l_img_comp = 00;
        opj_tcd_tilecomp_t * l_tile_comp = 00;
        opj_tcd_resolution_t * l_res = 00;
        OPJ_UINT32 l_size_comp, l_remaining;

        l_tile_comp = p_tcd->tcd_image->tiles->comps;
        l_img_comp = p_tcd->image->comps;

        for (i=0;i<p_tcd->image->numcomps;++i) {
                l_size_comp = l_img_comp->prec >> 3; /*(/ 8)*/
                l_remaining = l_img_comp->prec & 7;  /* (%8) */

                if(l_remaining) {
                        ++l_size_comp;
                }

                if (l_size_comp == 3) {
                        l_size_comp = 4;
                }

                l_res = l_tile_comp->resolutions + l_tile_comp->minimum_num_resolutions - 1;
                l_data_size += l_size_comp * (OPJ_UINT32)((l_res->x1 - l_res->x0) * (l_res->y1 - l_res->y0));
                ++l_img_comp;
                ++l_tile_comp;
        }

        return l_data_size;
}

OPJ_BOOL opj_tcd_encode_tile(   opj_tcd_t *p_tcd,
                                                        OPJ_UINT32 p_tile_no,
                                                        OPJ_BYTE *p_dest,
                                                        OPJ_UINT32 * p_data_written,
                                                        OPJ_UINT32 p_max_length,
                                                        opj_codestream_info_t *p_cstr_info)
{

        if (p_tcd->cur_tp_num == 0) {

                p_tcd->tcd_tileno = p_tile_no;
                p_tcd->tcp = &p_tcd->cp->tcps[p_tile_no];

                /* INDEX >> "Precinct_nb_X et Precinct_nb_Y" */
                if(p_cstr_info)  {
                        OPJ_UINT32 l_num_packs = 0;
                        OPJ_UINT32 i;
                        opj_tcd_tilecomp_t *l_tilec_idx = &p_tcd->tcd_image->tiles->comps[0];        /* based on component 0 */
                        opj_tccp_t *l_tccp = p_tcd->tcp->tccps; /* based on component 0 */

                        for (i = 0; i < l_tilec_idx->numresolutions; i++) {
                                opj_tcd_resolution_t *l_res_idx = &l_tilec_idx->resolutions[i];

                                p_cstr_info->tile[p_tile_no].pw[i] = (int)l_res_idx->pw;
                                p_cstr_info->tile[p_tile_no].ph[i] = (int)l_res_idx->ph;

                                l_num_packs += l_res_idx->pw * l_res_idx->ph;
                                p_cstr_info->tile[p_tile_no].pdx[i] = (int)l_tccp->prcw[i];
                                p_cstr_info->tile[p_tile_no].pdy[i] = (int)l_tccp->prch[i];
                        }
                        p_cstr_info->tile[p_tile_no].packet = (opj_packet_info_t*) opj_calloc((size_t)p_cstr_info->numcomps * (size_t)p_cstr_info->numlayers * l_num_packs, sizeof(opj_packet_info_t));
                        if (!p_cstr_info->tile[p_tile_no].packet) {
                                /* FIXME event manager error callback */
                                return OPJ_FALSE;
                        }
                }
                /* << INDEX */

                /* FIXME _ProfStart(PGROUP_DC_SHIFT); */
                /*---------------TILE-------------------*/
                if (! opj_tcd_dc_level_shift_encode(p_tcd)) {
                        return OPJ_FALSE;
                }
                /* FIXME _ProfStop(PGROUP_DC_SHIFT); */

                /* FIXME _ProfStart(PGROUP_MCT); */
                if (! opj_tcd_mct_encode(p_tcd)) {
                        return OPJ_FALSE;
                }
                /* FIXME _ProfStop(PGROUP_MCT); */

                /* FIXME _ProfStart(PGROUP_DWT); */
                if (! opj_tcd_dwt_encode(p_tcd)) {
                        return OPJ_FALSE;
                }
                /* FIXME  _ProfStop(PGROUP_DWT); */

                /* FIXME  _ProfStart(PGROUP_T1); */
                if (! opj_tcd_t1_encode(p_tcd)) {
                        return OPJ_FALSE;
                }
                /* FIXME _ProfStop(PGROUP_T1); */

                /* FIXME _ProfStart(PGROUP_RATE); */
                if (! opj_tcd_rate_allocate_encode(p_tcd,p_dest,p_max_length,p_cstr_info)) {
                        return OPJ_FALSE;
                }
                /* FIXME _ProfStop(PGROUP_RATE); */

        }
        /*--------------TIER2------------------*/

        /* INDEX */
        if (p_cstr_info) {
                p_cstr_info->index_write = 1;
        }
        /* FIXME _ProfStart(PGROUP_T2); */

        if (! opj_tcd_t2_encode(p_tcd,p_dest,p_data_written,p_max_length,p_cstr_info)) {
                return OPJ_FALSE;
        }
        /* FIXME _ProfStop(PGROUP_T2); */

        /*---------------CLEAN-------------------*/

        return OPJ_TRUE;
}

OPJ_BOOL opj_tcd_decode_tile(   opj_tcd_t *p_tcd,
                                OPJ_BYTE *p_src,
                                OPJ_UINT32 p_max_length,
                                OPJ_UINT32 p_tile_no,
                                opj_codestream_index_t *p_cstr_index,
                                opj_event_mgr_t *p_manager
                                )
{
        OPJ_UINT32 l_data_read;
        p_tcd->tcd_tileno = p_tile_no;
        p_tcd->tcp = &(p_tcd->cp->tcps[p_tile_no]);

#ifdef TODO_MSD /* FIXME */
        /* INDEX >>  */
        if(p_cstr_info) {
                OPJ_UINT32 resno, compno, numprec = 0;
                for (compno = 0; compno < (OPJ_UINT32) p_cstr_info->numcomps; compno++) {
                        opj_tcp_t *tcp = &p_tcd->cp->tcps[0];
                        opj_tccp_t *tccp = &tcp->tccps[compno];
                        opj_tcd_tilecomp_t *tilec_idx = &p_tcd->tcd_image->tiles->comps[compno];
                        for (resno = 0; resno < tilec_idx->numresolutions; resno++) {
                                opj_tcd_resolution_t *res_idx = &tilec_idx->resolutions[resno];
                                p_cstr_info->tile[p_tile_no].pw[resno] = res_idx->pw;
                                p_cstr_info->tile[p_tile_no].ph[resno] = res_idx->ph;
                                numprec += res_idx->pw * res_idx->ph;
                                p_cstr_info->tile[p_tile_no].pdx[resno] = tccp->prcw[resno];
                                p_cstr_info->tile[p_tile_no].pdy[resno] = tccp->prch[resno];
                        }
                }
                p_cstr_info->tile[p_tile_no].packet = (opj_packet_info_t *) opj_malloc(p_cstr_info->numlayers * numprec * sizeof(opj_packet_info_t));
                p_cstr_info->packno = 0;
        }
        /* << INDEX */
#endif

        /*--------------TIER2------------------*/
        /* FIXME _ProfStart(PGROUP_T2); */
        l_data_read = 0;
        if (! opj_tcd_t2_decode(p_tcd, p_src, &l_data_read, p_max_length, p_cstr_index, p_manager))
        {
                return OPJ_FALSE;
        }
        /* FIXME _ProfStop(PGROUP_T2); */

        /*------------------TIER1-----------------*/

        /* FIXME _ProfStart(PGROUP_T1); */
        if
                (! opj_tcd_t1_decode(p_tcd))
        {
                return OPJ_FALSE;
        }
        /* FIXME _ProfStop(PGROUP_T1); */

        /*----------------DWT---------------------*/

        /* FIXME _ProfStart(PGROUP_DWT); */
        if
                (! opj_tcd_dwt_decode(p_tcd))
        {
                return OPJ_FALSE;
        }
        /* FIXME _ProfStop(PGROUP_DWT); */

        /*----------------MCT-------------------*/
        /* FIXME _ProfStart(PGROUP_MCT); */
        if
                (! opj_tcd_mct_decode(p_tcd, p_manager))
        {
                return OPJ_FALSE;
        }
        /* FIXME _ProfStop(PGROUP_MCT); */

        /* FIXME _ProfStart(PGROUP_DC_SHIFT); */
        if
                (! opj_tcd_dc_level_shift_decode(p_tcd))
        {
                return OPJ_FALSE;
        }
        /* FIXME _ProfStop(PGROUP_DC_SHIFT); */


        /*---------------TILE-------------------*/
        return OPJ_TRUE;
}

OPJ_BOOL opj_tcd_update_tile_data ( opj_tcd_t *p_tcd,
                                    OPJ_BYTE * p_dest,
                                    OPJ_UINT32 p_dest_length
                                    )
{
        OPJ_UINT32 i,j,k,l_data_size = 0;
        opj_image_comp_t * l_img_comp = 00;
        opj_tcd_tilecomp_t * l_tilec = 00;
        opj_tcd_resolution_t * l_res;
        OPJ_UINT32 l_size_comp, l_remaining;
        OPJ_UINT32 l_stride, l_width,l_height;

        l_data_size = opj_tcd_get_decoded_tile_size(p_tcd);
        if (l_data_size > p_dest_length) {
                return OPJ_FALSE;
        }

        l_tilec = p_tcd->tcd_image->tiles->comps;
        l_img_comp = p_tcd->image->comps;

        for (i=0;i<p_tcd->image->numcomps;++i) {
                l_size_comp = l_img_comp->prec >> 3; /*(/ 8)*/
                l_remaining = l_img_comp->prec & 7;  /* (%8) */
                l_res = l_tilec->resolutions + l_img_comp->resno_decoded;
                l_width = (OPJ_UINT32)(l_res->x1 - l_res->x0);
                l_height = (OPJ_UINT32)(l_res->y1 - l_res->y0);
                l_stride = (OPJ_UINT32)(l_tilec->x1 - l_tilec->x0) - l_width;

                if (l_remaining) {
                        ++l_size_comp;
                }

                if (l_size_comp == 3) {
                        l_size_comp = 4;
                }

                switch (l_size_comp)
                        {
                        case 1:
                                {
                                        OPJ_CHAR * l_dest_ptr = (OPJ_CHAR *) p_dest;
                                        const OPJ_INT32 * l_src_ptr = l_tilec->data;

                                        if (l_img_comp->sgnd) {
                                                for (j=0;j<l_height;++j) {
                                                        for (k=0;k<l_width;++k) {
                                                                *(l_dest_ptr++) = (OPJ_CHAR) (*(l_src_ptr++));
                                                        }
                                                        l_src_ptr += l_stride;
                                                }
                                        }
                                        else {
                                                for (j=0;j<l_height;++j) {
                                                        for     (k=0;k<l_width;++k) {
                                                                *(l_dest_ptr++) = (OPJ_CHAR) ((*(l_src_ptr++))&0xff);
                                                        }
                                                        l_src_ptr += l_stride;
                                                }
                                        }

                                        p_dest = (OPJ_BYTE *)l_dest_ptr;
                                }
                                break;
                        case 2:
                                {
                                        const OPJ_INT32 * l_src_ptr = l_tilec->data;
                                        OPJ_INT16 * l_dest_ptr = (OPJ_INT16 *) p_dest;

                                        if (l_img_comp->sgnd) {
                                                for (j=0;j<l_height;++j) {
                                                        for (k=0;k<l_width;++k) {
                                                                *(l_dest_ptr++) = (OPJ_INT16) (*(l_src_ptr++));
                                                        }
                                                        l_src_ptr += l_stride;
                                                }
                                        }
                                        else {
                                                for (j=0;j<l_height;++j) {
                                                        for (k=0;k<l_width;++k) {
                                                                *(l_dest_ptr++) = (OPJ_INT16) ((*(l_src_ptr++))&0xffff);
                                                        }
                                                        l_src_ptr += l_stride;
                                                }
                                        }

                                        p_dest = (OPJ_BYTE*) l_dest_ptr;
                                }
                                break;
                        case 4:
                                {
                                        OPJ_INT32 * l_dest_ptr = (OPJ_INT32 *) p_dest;
                                        OPJ_INT32 * l_src_ptr = l_tilec->data;

                                        for (j=0;j<l_height;++j) {
                                                for (k=0;k<l_width;++k) {
                                                        *(l_dest_ptr++) = (*(l_src_ptr++));
                                                }
                                                l_src_ptr += l_stride;
                                        }

                                        p_dest = (OPJ_BYTE*) l_dest_ptr;
                                }
                                break;
                }

                ++l_img_comp;
                ++l_tilec;
        }

        return OPJ_TRUE;
}




static void opj_tcd_free_tile(opj_tcd_t *p_tcd)
{
        OPJ_UINT32 compno, resno, bandno, precno;
        opj_tcd_tile_t *l_tile = 00;
        opj_tcd_tilecomp_t *l_tile_comp = 00;
        opj_tcd_resolution_t *l_res = 00;
        opj_tcd_band_t *l_band = 00;
        opj_tcd_precinct_t *l_precinct = 00;
        OPJ_UINT32 l_nb_resolutions, l_nb_precincts;
        void (* l_tcd_code_block_deallocate) (opj_tcd_precinct_t *) = 00;

        if (! p_tcd) {
                return;
        }

        if (! p_tcd->tcd_image) {
                return;
        }

        if (p_tcd->m_is_decoder) {
                l_tcd_code_block_deallocate = opj_tcd_code_block_dec_deallocate;
        }
        else {
                l_tcd_code_block_deallocate = opj_tcd_code_block_enc_deallocate;
        }

        l_tile = p_tcd->tcd_image->tiles;
        if (! l_tile) {
                return;
        }

        l_tile_comp = l_tile->comps;

        for (compno = 0; compno < l_tile->numcomps; ++compno) {
                l_res = l_tile_comp->resolutions;
                if (l_res) {

                        l_nb_resolutions = l_tile_comp->resolutions_size / sizeof(opj_tcd_resolution_t);
                        for (resno = 0; resno < l_nb_resolutions; ++resno) {
                                l_band = l_res->bands;
                                for     (bandno = 0; bandno < 3; ++bandno) {
                                        l_precinct = l_band->precincts;
                                        if (l_precinct) {

                                                l_nb_precincts = l_band->precincts_data_size / sizeof(opj_tcd_precinct_t);
                                                for (precno = 0; precno < l_nb_precincts; ++precno) {
                                                        opj_tgt_destroy(l_precinct->incltree);
                                                        l_precinct->incltree = 00;
                                                        opj_tgt_destroy(l_precinct->imsbtree);
                                                        l_precinct->imsbtree = 00;
                                                        (*l_tcd_code_block_deallocate) (l_precinct);
                                                        ++l_precinct;
                                                }

                                                opj_free(l_band->precincts);
                                                l_band->precincts = 00;
                                        }
                                        ++l_band;
                                } /* for (resno */
                                ++l_res;
                        }

                        opj_free(l_tile_comp->resolutions);
                        l_tile_comp->resolutions = 00;
                }

                if (l_tile_comp->ownsData && l_tile_comp->data) {
                        opj_free(l_tile_comp->data);
                        l_tile_comp->data = 00;
                        l_tile_comp->ownsData = 0;
                        l_tile_comp->data_size = 0;
                        l_tile_comp->data_size_needed = 0;
                }
                ++l_tile_comp;
        }

        opj_free(l_tile->comps);
        l_tile->comps = 00;
        opj_free(p_tcd->tcd_image->tiles);
        p_tcd->tcd_image->tiles = 00;
}


static OPJ_BOOL opj_tcd_t2_decode (opj_tcd_t *p_tcd,
                            OPJ_BYTE * p_src_data,
                            OPJ_UINT32 * p_data_read,
                            OPJ_UINT32 p_max_src_size,
                            opj_codestream_index_t *p_cstr_index,
                            opj_event_mgr_t *p_manager
                            )
{
        opj_t2_t * l_t2;

        l_t2 = opj_t2_create(p_tcd->image, p_tcd->cp);
        if (l_t2 == 00) {
                return OPJ_FALSE;
        }

        if (! opj_t2_decode_packets(
                                        l_t2,
                                        p_tcd->tcd_tileno,
                                        p_tcd->tcd_image->tiles,
                                        p_src_data,
                                        p_data_read,
                                        p_max_src_size,
                                        p_cstr_index,
                                        p_manager)) {
                opj_t2_destroy(l_t2);
                return OPJ_FALSE;
        }

        opj_t2_destroy(l_t2);

        /*---------------CLEAN-------------------*/
        return OPJ_TRUE;
}

static OPJ_BOOL opj_tcd_t1_decode ( opj_tcd_t *p_tcd )
{
        OPJ_UINT32 compno;
        opj_t1_t * l_t1;
        opj_tcd_tile_t * l_tile = p_tcd->tcd_image->tiles;
        opj_tcd_tilecomp_t* l_tile_comp = l_tile->comps;
        opj_tccp_t * l_tccp = p_tcd->tcp->tccps;


        l_t1 = opj_t1_create(OPJ_FALSE);
        if (l_t1 == 00) {
                return OPJ_FALSE;
        }

        for (compno = 0; compno < l_tile->numcomps; ++compno) {
                /* The +3 is headroom required by the vectorized DWT */
                if (OPJ_FALSE == opj_t1_decode_cblks(l_t1, l_tile_comp, l_tccp)) {
                        opj_t1_destroy(l_t1);
                        return OPJ_FALSE;
                }
                ++l_tile_comp;
                ++l_tccp;
        }

        opj_t1_destroy(l_t1);

        return OPJ_TRUE;
}


static OPJ_BOOL opj_tcd_dwt_decode ( opj_tcd_t *p_tcd )
{
        OPJ_UINT32 compno;
        opj_tcd_tile_t * l_tile = p_tcd->tcd_image->tiles;
        opj_tcd_tilecomp_t * l_tile_comp = l_tile->comps;
        opj_tccp_t * l_tccp = p_tcd->tcp->tccps;
        opj_image_comp_t * l_img_comp = p_tcd->image->comps;

        for (compno = 0; compno < l_tile->numcomps; compno++) {
                /*
                if (tcd->cp->reduce != 0) {
                        tcd->image->comps[compno].resno_decoded =
                                tile->comps[compno].numresolutions - tcd->cp->reduce - 1;
                        if (tcd->image->comps[compno].resno_decoded < 0)
                        {
                                return false;
                        }
                }
                numres2decode = tcd->image->comps[compno].resno_decoded + 1;
                if(numres2decode > 0){
                */

                if (l_tccp->qmfbid == 1) {
                        if (! opj_dwt_decode(l_tile_comp, l_img_comp->resno_decoded+1)) {
                                return OPJ_FALSE;
                        }
                }
                else {
                        if (! opj_dwt_decode_real(l_tile_comp, l_img_comp->resno_decoded+1)) {
                                return OPJ_FALSE;
                        }
                }

                ++l_tile_comp;
                ++l_img_comp;
                ++l_tccp;
        }

        return OPJ_TRUE;
}
static OPJ_BOOL opj_tcd_mct_decode ( opj_tcd_t *p_tcd, opj_event_mgr_t *p_manager)
{
        opj_tcd_tile_t * l_tile = p_tcd->tcd_image->tiles;
        opj_tcp_t * l_tcp = p_tcd->tcp;
        opj_tcd_tilecomp_t * l_tile_comp = l_tile->comps;
        OPJ_UINT32 l_samples,i;

        if (! l_tcp->mct) {
                return OPJ_TRUE;
        }

        l_samples = (OPJ_UINT32)((l_tile_comp->x1 - l_tile_comp->x0) * (l_tile_comp->y1 - l_tile_comp->y0));

        if (l_tile->numcomps >= 3 ){
                /* testcase 1336.pdf.asan.47.376 */
                if ((l_tile->comps[0].x1 - l_tile->comps[0].x0) * (l_tile->comps[0].y1 - l_tile->comps[0].y0) < (OPJ_INT32)l_samples ||
                    (l_tile->comps[1].x1 - l_tile->comps[1].x0) * (l_tile->comps[1].y1 - l_tile->comps[1].y0) < (OPJ_INT32)l_samples ||
                    (l_tile->comps[2].x1 - l_tile->comps[2].x0) * (l_tile->comps[2].y1 - l_tile->comps[2].y0) < (OPJ_INT32)l_samples) {
                        opj_event_msg(p_manager, EVT_ERROR, "Tiles don't all have the same dimension. Skip the MCT step.\n");
                        return OPJ_FALSE;
                }
                else if (l_tcp->mct == 2) {
                        OPJ_BYTE ** l_data;

                        if (! l_tcp->m_mct_decoding_matrix) {
                                return OPJ_TRUE;
                        }

                        l_data = (OPJ_BYTE **) opj_malloc(l_tile->numcomps*sizeof(OPJ_BYTE*));
                        if (! l_data) {
                                return OPJ_FALSE;
                        }

                        for (i=0;i<l_tile->numcomps;++i) {
                                l_data[i] = (OPJ_BYTE*) l_tile_comp->data;
                                ++l_tile_comp;
                        }

                        if (! opj_mct_decode_custom(/* MCT data */
                                                                        (OPJ_BYTE*) l_tcp->m_mct_decoding_matrix,
                                                                        /* size of components */
                                                                        l_samples,
                                                                        /* components */
                                                                        l_data,
                                                                        /* nb of components (i.e. size of pData) */
                                                                        l_tile->numcomps,
                                                                        /* tells if the data is signed */
                                                                        p_tcd->image->comps->sgnd)) {
                                opj_free(l_data);
                                return OPJ_FALSE;
                        }

                        opj_free(l_data);
                }
                else {
                        if (l_tcp->tccps->qmfbid == 1) {
                                opj_mct_decode(     l_tile->comps[0].data,
                                                        l_tile->comps[1].data,
                                                        l_tile->comps[2].data,
                                                        l_samples);
                        }
                        else {
                            opj_mct_decode_real((OPJ_FLOAT32*)l_tile->comps[0].data,
                                                (OPJ_FLOAT32*)l_tile->comps[1].data,
                                                (OPJ_FLOAT32*)l_tile->comps[2].data,
                                                l_samples);
                        }
                }
        }
        else {
                opj_event_msg(p_manager, EVT_ERROR, "Number of components (%d) is inconsistent with a MCT. Skip the MCT step.\n",l_tile->numcomps);
        }

        return OPJ_TRUE;
}


static OPJ_BOOL opj_tcd_dc_level_shift_decode ( opj_tcd_t *p_tcd )
{
        OPJ_UINT32 compno;
        opj_tcd_tilecomp_t * l_tile_comp = 00;
        opj_tccp_t * l_tccp = 00;
        opj_image_comp_t * l_img_comp = 00;
        opj_tcd_resolution_t* l_res = 00;
        opj_tcd_tile_t * l_tile;
        OPJ_UINT32 l_width,l_height,i,j;
        OPJ_INT32 * l_current_ptr;
        OPJ_INT32 l_min, l_max;
        OPJ_UINT32 l_stride;

        l_tile = p_tcd->tcd_image->tiles;
        l_tile_comp = l_tile->comps;
        l_tccp = p_tcd->tcp->tccps;
        l_img_comp = p_tcd->image->comps;

        for (compno = 0; compno < l_tile->numcomps; compno++) {
                l_res = l_tile_comp->resolutions + l_img_comp->resno_decoded;
                l_width = (OPJ_UINT32)(l_res->x1 - l_res->x0);
                l_height = (OPJ_UINT32)(l_res->y1 - l_res->y0);
                l_stride = (OPJ_UINT32)(l_tile_comp->x1 - l_tile_comp->x0) - l_width;

                assert(l_height == 0 || l_width + l_stride <= l_tile_comp->data_size / l_height); /*MUPDF*/

                if (l_img_comp->sgnd) {
                        l_min = -(1 << (l_img_comp->prec - 1));
                        l_max = (1 << (l_img_comp->prec - 1)) - 1;
                }
                else {
            l_min = 0;
                        l_max = (1 << l_img_comp->prec) - 1;
                }

                l_current_ptr = l_tile_comp->data;

                if (l_tccp->qmfbid == 1) {
                        for (j=0;j<l_height;++j) {
                                for (i = 0; i < l_width; ++i) {
                                        *l_current_ptr = opj_int_clamp(*l_current_ptr + l_tccp->m_dc_level_shift, l_min, l_max);
                                        ++l_current_ptr;
                                }
                                l_current_ptr += l_stride;
                        }
                }
                else {
                        for (j=0;j<l_height;++j) {
                                for (i = 0; i < l_width; ++i) {
                                        OPJ_FLOAT32 l_value = *((OPJ_FLOAT32 *) l_current_ptr);
                                        *l_current_ptr = opj_int_clamp((OPJ_INT32)opj_lrintf(l_value) + l_tccp->m_dc_level_shift, l_min, l_max); ;
                                        ++l_current_ptr;
                                }
                                l_current_ptr += l_stride;
                        }
                }

                ++l_img_comp;
                ++l_tccp;
                ++l_tile_comp;
        }

        return OPJ_TRUE;
}



/**
 * Deallocates the encoding data of the given precinct.
 */
static void opj_tcd_code_block_dec_deallocate (opj_tcd_precinct_t * p_precinct)
{
        OPJ_UINT32 cblkno , l_nb_code_blocks;

        opj_tcd_cblk_dec_t * l_code_block = p_precinct->cblks.dec;
        if (l_code_block) {
                /*fprintf(stderr,"deallocate codeblock:{\n");*/
                /*fprintf(stderr,"\t x0=%d, y0=%d, x1=%d, y1=%d\n",l_code_block->x0, l_code_block->y0, l_code_block->x1, l_code_block->y1);*/
                /*fprintf(stderr,"\t numbps=%d, numlenbits=%d, len=%d, numnewpasses=%d, real_num_segs=%d, m_current_max_segs=%d\n ",
                                l_code_block->numbps, l_code_block->numlenbits, l_code_block->len, l_code_block->numnewpasses, l_code_block->real_num_segs, l_code_block->m_current_max_segs );*/


                l_nb_code_blocks = p_precinct->block_size / sizeof(opj_tcd_cblk_dec_t);
                /*fprintf(stderr,"nb_code_blocks =%d\t}\n", l_nb_code_blocks);*/

                for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) {

                        if (l_code_block->data) {
                                opj_free(l_code_block->data);
                                l_code_block->data = 00;
                        }

                        if (l_code_block->segs) {
                                opj_free(l_code_block->segs );
                                l_code_block->segs = 00;
                        }

                        ++l_code_block;
                }

                opj_free(p_precinct->cblks.dec);
                p_precinct->cblks.dec = 00;
        }
}

/**
 * Deallocates the encoding data of the given precinct.
 */
static void opj_tcd_code_block_enc_deallocate (opj_tcd_precinct_t * p_precinct)
{       
        OPJ_UINT32 cblkno , l_nb_code_blocks;

        opj_tcd_cblk_enc_t * l_code_block = p_precinct->cblks.enc;
        if (l_code_block) {
                l_nb_code_blocks = p_precinct->block_size / sizeof(opj_tcd_cblk_enc_t);
                
                for     (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno)  {
                        if (l_code_block->data) {
                                opj_free(l_code_block->data - 1);
                                l_code_block->data = 00;
                        }

                        if (l_code_block->layers) {
                                opj_free(l_code_block->layers );
                                l_code_block->layers = 00;
                        }

                        if (l_code_block->passes) {
                                opj_free(l_code_block->passes );
                                l_code_block->passes = 00;
                        }
                        ++l_code_block;
                }

                opj_free(p_precinct->cblks.enc);
                
                p_precinct->cblks.enc = 00;
        }
}

OPJ_UINT32 opj_tcd_get_encoded_tile_size ( opj_tcd_t *p_tcd )
{
        OPJ_UINT32 i,l_data_size = 0;
        opj_image_comp_t * l_img_comp = 00;
        opj_tcd_tilecomp_t * l_tilec = 00;
        OPJ_UINT32 l_size_comp, l_remaining;

        l_tilec = p_tcd->tcd_image->tiles->comps;
        l_img_comp = p_tcd->image->comps;
        for (i=0;i<p_tcd->image->numcomps;++i) {
                l_size_comp = l_img_comp->prec >> 3; /*(/ 8)*/
                l_remaining = l_img_comp->prec & 7;  /* (%8) */

                if (l_remaining) {
                        ++l_size_comp;
                }

                if (l_size_comp == 3) {
                        l_size_comp = 4;
                }

                l_data_size += l_size_comp * (OPJ_UINT32)((l_tilec->x1 - l_tilec->x0) * (l_tilec->y1 - l_tilec->y0));
                ++l_img_comp;
                ++l_tilec;
        }

        return l_data_size;
}
                
static OPJ_BOOL opj_tcd_dc_level_shift_encode ( opj_tcd_t *p_tcd )
{
        OPJ_UINT32 compno;
        opj_tcd_tilecomp_t * l_tile_comp = 00;
        opj_tccp_t * l_tccp = 00;
        opj_image_comp_t * l_img_comp = 00;
        opj_tcd_tile_t * l_tile;
        OPJ_UINT32 l_nb_elem,i;
        OPJ_INT32 * l_current_ptr;

        l_tile = p_tcd->tcd_image->tiles;
        l_tile_comp = l_tile->comps;
        l_tccp = p_tcd->tcp->tccps;
        l_img_comp = p_tcd->image->comps;

        for (compno = 0; compno < l_tile->numcomps; compno++) {
                l_current_ptr = l_tile_comp->data;
                l_nb_elem = (OPJ_UINT32)((l_tile_comp->x1 - l_tile_comp->x0) * (l_tile_comp->y1 - l_tile_comp->y0));

                if (l_tccp->qmfbid == 1) {
                        for     (i = 0; i < l_nb_elem; ++i) {
                                *l_current_ptr -= l_tccp->m_dc_level_shift ;
                                ++l_current_ptr;
                        }
                }
                else {
                        for (i = 0; i < l_nb_elem; ++i) {
                                *l_current_ptr = (*l_current_ptr - l_tccp->m_dc_level_shift) << 11 ;
                                ++l_current_ptr;
                        }
                }

                ++l_img_comp;
                ++l_tccp;
                ++l_tile_comp;
        }

        return OPJ_TRUE;
}

static OPJ_BOOL opj_tcd_mct_encode ( opj_tcd_t *p_tcd )
{
        opj_tcd_tile_t * l_tile = p_tcd->tcd_image->tiles;
        opj_tcd_tilecomp_t * l_tile_comp = p_tcd->tcd_image->tiles->comps;
        OPJ_UINT32 samples = (OPJ_UINT32)((l_tile_comp->x1 - l_tile_comp->x0) * (l_tile_comp->y1 - l_tile_comp->y0));
        OPJ_UINT32 i;
        OPJ_BYTE ** l_data = 00;
        opj_tcp_t * l_tcp = p_tcd->tcp;

        if(!p_tcd->tcp->mct) {
                return OPJ_TRUE;
        }

        if (p_tcd->tcp->mct == 2) {
                if (! p_tcd->tcp->m_mct_coding_matrix) {
                        return OPJ_TRUE;
                }

        l_data = (OPJ_BYTE **) opj_malloc(l_tile->numcomps*sizeof(OPJ_BYTE*));
                if (! l_data) {
                        return OPJ_FALSE;
                }

                for (i=0;i<l_tile->numcomps;++i) {
                        l_data[i] = (OPJ_BYTE*) l_tile_comp->data;
                        ++l_tile_comp;
                }

                if (! opj_mct_encode_custom(/* MCT data */
                                        (OPJ_BYTE*) p_tcd->tcp->m_mct_coding_matrix,
                                        /* size of components */
                                        samples,
                                        /* components */
                                        l_data,
                                        /* nb of components (i.e. size of pData) */
                                        l_tile->numcomps,
                                        /* tells if the data is signed */
                                        p_tcd->image->comps->sgnd) )
                {
            opj_free(l_data);
                        return OPJ_FALSE;
                }

                opj_free(l_data);
        }
        else if (l_tcp->tccps->qmfbid == 0) {
                opj_mct_encode_real(l_tile->comps[0].data, l_tile->comps[1].data, l_tile->comps[2].data, samples);
        }
        else {
                opj_mct_encode(l_tile->comps[0].data, l_tile->comps[1].data, l_tile->comps[2].data, samples);
        }

        return OPJ_TRUE;
}

static OPJ_BOOL opj_tcd_dwt_encode ( opj_tcd_t *p_tcd )
{
        opj_tcd_tile_t * l_tile = p_tcd->tcd_image->tiles;
        opj_tcd_tilecomp_t * l_tile_comp = p_tcd->tcd_image->tiles->comps;
        opj_tccp_t * l_tccp = p_tcd->tcp->tccps;
        OPJ_UINT32 compno;

        for (compno = 0; compno < l_tile->numcomps; ++compno) {
                if (l_tccp->qmfbid == 1) {
                        if (! opj_dwt_encode(l_tile_comp)) {
                                return OPJ_FALSE;
                        }
                }
                else if (l_tccp->qmfbid == 0) {
                        if (! opj_dwt_encode_real(l_tile_comp)) {
                                return OPJ_FALSE;
                        }
                }

                ++l_tile_comp;
                ++l_tccp;
        }

        return OPJ_TRUE;
}

static OPJ_BOOL opj_tcd_t1_encode ( opj_tcd_t *p_tcd )
{
        opj_t1_t * l_t1;
        const OPJ_FLOAT64 * l_mct_norms;
        OPJ_UINT32 l_mct_numcomps = 0U;
        opj_tcp_t * l_tcp = p_tcd->tcp;

        l_t1 = opj_t1_create(OPJ_TRUE);
        if (l_t1 == 00) {
                return OPJ_FALSE;
        }

        if (l_tcp->mct == 1) {
                l_mct_numcomps = 3U;
                /* irreversible encoding */
                if (l_tcp->tccps->qmfbid == 0) {
                        l_mct_norms = opj_mct_get_mct_norms_real();
                }
                else {
                        l_mct_norms = opj_mct_get_mct_norms();
                }
        }
        else {
                l_mct_numcomps = p_tcd->image->numcomps;
                l_mct_norms = (const OPJ_FLOAT64 *) (l_tcp->mct_norms);
        }

        if (! opj_t1_encode_cblks(l_t1, p_tcd->tcd_image->tiles , l_tcp, l_mct_norms, l_mct_numcomps)) {
        opj_t1_destroy(l_t1);
                return OPJ_FALSE;
        }

        opj_t1_destroy(l_t1);

        return OPJ_TRUE;
}

static OPJ_BOOL opj_tcd_t2_encode (opj_tcd_t *p_tcd,
                                                OPJ_BYTE * p_dest_data,
                                                OPJ_UINT32 * p_data_written,
                                                OPJ_UINT32 p_max_dest_size,
                                                opj_codestream_info_t *p_cstr_info )
{
        opj_t2_t * l_t2;

        l_t2 = opj_t2_create(p_tcd->image, p_tcd->cp);
        if (l_t2 == 00) {
                return OPJ_FALSE;
        }

        if (! opj_t2_encode_packets(
                                        l_t2,
                                        p_tcd->tcd_tileno,
                                        p_tcd->tcd_image->tiles,
                                        p_tcd->tcp->numlayers,
                                        p_dest_data,
                                        p_data_written,
                                        p_max_dest_size,
                                        p_cstr_info,
                                        p_tcd->tp_num,
                                        p_tcd->tp_pos,
                                        p_tcd->cur_pino,
                                        FINAL_PASS))
        {
                opj_t2_destroy(l_t2);
                return OPJ_FALSE;
        }

        opj_t2_destroy(l_t2);

        /*---------------CLEAN-------------------*/
        return OPJ_TRUE;
}


static OPJ_BOOL opj_tcd_rate_allocate_encode(  opj_tcd_t *p_tcd,
                                                                            OPJ_BYTE * p_dest_data,
                                                                            OPJ_UINT32 p_max_dest_size,
                                                                            opj_codestream_info_t *p_cstr_info )
{
        opj_cp_t * l_cp = p_tcd->cp;
        OPJ_UINT32 l_nb_written = 0;

        if (p_cstr_info)  {
                p_cstr_info->index_write = 0;
        }

        if (l_cp->m_specific_param.m_enc.m_disto_alloc|| l_cp->m_specific_param.m_enc.m_fixed_quality)  {
                /* fixed_quality */
                /* Normal Rate/distortion allocation */
                if (! opj_tcd_rateallocate(p_tcd, p_dest_data,&l_nb_written, p_max_dest_size, p_cstr_info)) {
                        return OPJ_FALSE;
                }
        }
        else {
                /* Fixed layer allocation */
                opj_tcd_rateallocate_fixed(p_tcd);
        }

        return OPJ_TRUE;
}


OPJ_BOOL opj_tcd_copy_tile_data (       opj_tcd_t *p_tcd,
                                                                    OPJ_BYTE * p_src,
                                                                    OPJ_UINT32 p_src_length )
{
        OPJ_UINT32 i,j,l_data_size = 0;
        opj_image_comp_t * l_img_comp = 00;
        opj_tcd_tilecomp_t * l_tilec = 00;
        OPJ_UINT32 l_size_comp, l_remaining;
        OPJ_UINT32 l_nb_elem;

        l_data_size = opj_tcd_get_encoded_tile_size(p_tcd);
        if (l_data_size != p_src_length) {
                return OPJ_FALSE;
        }

        l_tilec = p_tcd->tcd_image->tiles->comps;
        l_img_comp = p_tcd->image->comps;
        for (i=0;i<p_tcd->image->numcomps;++i) {
                l_size_comp = l_img_comp->prec >> 3; /*(/ 8)*/
                l_remaining = l_img_comp->prec & 7;  /* (%8) */
                l_nb_elem = (OPJ_UINT32)((l_tilec->x1 - l_tilec->x0) * (l_tilec->y1 - l_tilec->y0));

                if (l_remaining) {
                        ++l_size_comp;
                }

                if (l_size_comp == 3) {
                        l_size_comp = 4;
                }

                switch (l_size_comp) {
                        case 1:
                                {
                                        OPJ_CHAR * l_src_ptr = (OPJ_CHAR *) p_src;
                                        OPJ_INT32 * l_dest_ptr = l_tilec->data;

                                        if (l_img_comp->sgnd) {
                                                for (j=0;j<l_nb_elem;++j) {
                                                        *(l_dest_ptr++) = (OPJ_INT32) (*(l_src_ptr++));
                                                }
                                        }
                                        else {
                                                for (j=0;j<l_nb_elem;++j) {
                                                        *(l_dest_ptr++) = (*(l_src_ptr++))&0xff;
                                                }
                                        }

                                        p_src = (OPJ_BYTE*) l_src_ptr;
                                }
                                break;
                        case 2:
                                {
                                        OPJ_INT32 * l_dest_ptr = l_tilec->data;
                                        OPJ_INT16 * l_src_ptr = (OPJ_INT16 *) p_src;

                                        if (l_img_comp->sgnd) {
                                                for (j=0;j<l_nb_elem;++j) {
                                                        *(l_dest_ptr++) = (OPJ_INT32) (*(l_src_ptr++));
                                                }
                                        }
                                        else {
                                                for (j=0;j<l_nb_elem;++j) {
                                                        *(l_dest_ptr++) = (*(l_src_ptr++))&0xffff;
                                                }
                                        }

                                        p_src = (OPJ_BYTE*) l_src_ptr;
                                }
                                break;
                        case 4:
                                {
                                        OPJ_INT32 * l_src_ptr = (OPJ_INT32 *) p_src;
                                        OPJ_INT32 * l_dest_ptr = l_tilec->data;

                                        for (j=0;j<l_nb_elem;++j) {
                                                *(l_dest_ptr++) = (OPJ_INT32) (*(l_src_ptr++));
                                        }

                                        p_src = (OPJ_BYTE*) l_src_ptr;
                                }
                                break;
                }

                ++l_img_comp;
                ++l_tilec;
        }

        return OPJ_TRUE;
}
