/*
 * 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
 * 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 <limits.h>
#include "opj_includes.h"

/** @defgroup PI PI - Implementation of a packet iterator */
/*@{*/

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

/**
Get next packet in layer-resolution-component-precinct order.
@param pi packet iterator to modify
@return returns false if pi pointed to the last packet or else returns true
*/
static OPJ_BOOL opj_pi_next_lrcp(opj_pi_iterator_t * pi);
/**
Get next packet in resolution-layer-component-precinct order.
@param pi packet iterator to modify
@return returns false if pi pointed to the last packet or else returns true
*/
static OPJ_BOOL opj_pi_next_rlcp(opj_pi_iterator_t * pi);
/**
Get next packet in resolution-precinct-component-layer order.
@param pi packet iterator to modify
@return returns false if pi pointed to the last packet or else returns true
*/
static OPJ_BOOL opj_pi_next_rpcl(opj_pi_iterator_t * pi);
/**
Get next packet in precinct-component-resolution-layer order.
@param pi packet iterator to modify
@return returns false if pi pointed to the last packet or else returns true
*/
static OPJ_BOOL opj_pi_next_pcrl(opj_pi_iterator_t * pi);
/**
Get next packet in component-precinct-resolution-layer order.
@param pi packet iterator to modify
@return returns false if pi pointed to the last packet or else returns true
*/
static OPJ_BOOL opj_pi_next_cprl(opj_pi_iterator_t * pi);

/**
 * Updates the coding parameters if the encoding is used with Progression order changes and final (or cinema parameters are used).
 *
 * @param	p_cp		the coding parameters to modify
 * @param	p_tileno	the tile index being concerned.
 * @param	p_tx0		X0 parameter for the tile
 * @param	p_tx1		X1 parameter for the tile
 * @param	p_ty0		Y0 parameter for the tile
 * @param	p_ty1		Y1 parameter for the tile
 * @param	p_max_prec	the maximum precision for all the bands of the tile
 * @param	p_max_res	the maximum number of resolutions for all the poc inside the tile.
 * @param	p_dx_min		the minimum dx of all the components of all the resolutions for the tile.
 * @param	p_dy_min		the minimum dy of all the components of all the resolutions for the tile.
 */
static void opj_pi_update_encode_poc_and_final ( opj_cp_t *p_cp,
                                                 OPJ_UINT32 p_tileno,
                                                 OPJ_INT32 p_tx0,
                                                 OPJ_INT32 p_tx1,
                                                 OPJ_INT32 p_ty0,
                                                 OPJ_INT32 p_ty1,
                                                 OPJ_UINT32 p_max_prec,
                                                 OPJ_UINT32 p_max_res,
                                                 OPJ_UINT32 p_dx_min,
                                                 OPJ_UINT32 p_dy_min);

/**
 * Updates the coding parameters if the encoding is not used with Progression order changes and final (and cinema parameters are used).
 *
 * @param	p_cp		the coding parameters to modify
 * @param	p_num_comps		the number of components
 * @param	p_tileno	the tile index being concerned.
 * @param	p_tx0		X0 parameter for the tile
 * @param	p_tx1		X1 parameter for the tile
 * @param	p_ty0		Y0 parameter for the tile
 * @param	p_ty1		Y1 parameter for the tile
 * @param	p_max_prec	the maximum precision for all the bands of the tile
 * @param	p_max_res	the maximum number of resolutions for all the poc inside the tile.
 * @param	p_dx_min		the minimum dx of all the components of all the resolutions for the tile.
 * @param	p_dy_min		the minimum dy of all the components of all the resolutions for the tile.
 */
static void opj_pi_update_encode_not_poc (  opj_cp_t *p_cp,
                                            OPJ_UINT32 p_num_comps,
                                            OPJ_UINT32 p_tileno,
                                            OPJ_INT32 p_tx0,
                                            OPJ_INT32 p_tx1,
                                            OPJ_INT32 p_ty0,
                                            OPJ_INT32 p_ty1,
                                            OPJ_UINT32 p_max_prec,
                                            OPJ_UINT32 p_max_res,
                                            OPJ_UINT32 p_dx_min,
                                            OPJ_UINT32 p_dy_min);
/**
 * Gets the encoding parameters needed to update the coding parameters and all the pocs.
 * 
 * @param	p_image			the image being encoded.
 * @param	p_cp			the coding parameters.
 * @param	tileno			the tile index of the tile being encoded.
 * @param	p_tx0			pointer that will hold the X0 parameter for the tile
 * @param	p_tx1			pointer that will hold the X1 parameter for the tile
 * @param	p_ty0			pointer that will hold the Y0 parameter for the tile
 * @param	p_ty1			pointer that will hold the Y1 parameter for the tile
 * @param	p_max_prec		pointer that will hold the the maximum precision for all the bands of the tile
 * @param	p_max_res		pointer that will hold the the maximum number of resolutions for all the poc inside the tile.
 * @param	p_dx_min			pointer that will hold the the minimum dx of all the components of all the resolutions for the tile.
 * @param	p_dy_min			pointer that will hold the the minimum dy of all the components of all the resolutions for the tile.
 */
static void opj_get_encoding_parameters(const opj_image_t *p_image,
                                        const opj_cp_t *p_cp,
                                        OPJ_UINT32  tileno,
                                        OPJ_INT32  * p_tx0,
                                        OPJ_INT32 * p_tx1,
                                        OPJ_INT32 * p_ty0,
                                        OPJ_INT32 * p_ty1,
                                        OPJ_UINT32 * p_dx_min,
                                        OPJ_UINT32 * p_dy_min,
                                        OPJ_UINT32 * p_max_prec,
                                        OPJ_UINT32 * p_max_res );

/**
 * Gets the encoding parameters needed to update the coding parameters and all the pocs.
 * The precinct widths, heights, dx and dy for each component at each resolution will be stored as well.
 * the last parameter of the function should be an array of pointers of size nb components, each pointer leading
 * to an area of size 4 * max_res. The data is stored inside this area with the following pattern :
 * dx_compi_res0 , dy_compi_res0 , w_compi_res0, h_compi_res0 , dx_compi_res1 , dy_compi_res1 , w_compi_res1, h_compi_res1 , ...
 *
 * @param	p_image			the image being encoded.
 * @param	p_cp			the coding parameters.
 * @param	tileno			the tile index of the tile being encoded.
 * @param	p_tx0			pointer that will hold the X0 parameter for the tile
 * @param	p_tx1			pointer that will hold the X1 parameter for the tile
 * @param	p_ty0			pointer that will hold the Y0 parameter for the tile
 * @param	p_ty1			pointer that will hold the Y1 parameter for the tile
 * @param	p_max_prec		pointer that will hold the the maximum precision for all the bands of the tile
 * @param	p_max_res		pointer that will hold the the maximum number of resolutions for all the poc inside the tile.
 * @param	p_dx_min		pointer that will hold the the minimum dx of all the components of all the resolutions for the tile.
 * @param	p_dy_min		pointer that will hold the the minimum dy of all the components of all the resolutions for the tile.
 * @param	p_resolutions	pointer to an area corresponding to the one described above.
 */
static void opj_get_all_encoding_parameters(const opj_image_t *p_image,
                                            const opj_cp_t *p_cp,
                                            OPJ_UINT32 tileno,
                                            OPJ_INT32 * p_tx0,
                                            OPJ_INT32 * p_tx1,
                                            OPJ_INT32 * p_ty0,
                                            OPJ_INT32 * p_ty1,
                                            OPJ_UINT32 * p_dx_min,
                                            OPJ_UINT32 * p_dy_min,
                                            OPJ_UINT32 * p_max_prec,
                                            OPJ_UINT32 * p_max_res,
                                            OPJ_UINT32 ** p_resolutions );
/**
 * Allocates memory for a packet iterator. Data and data sizes are set by this operation.
 * No other data is set. The include section of the packet  iterator is not allocated.
 * 
 * @param	p_image		the image used to initialize the packet iterator (in fact only the number of components is relevant.
 * @param	p_cp		the coding parameters.
 * @param	tileno	the index of the tile from which creating the packet iterator.
 */
static opj_pi_iterator_t * opj_pi_create(	const opj_image_t *p_image,
                                            const opj_cp_t *p_cp,
                                            OPJ_UINT32 tileno );
/**
 * FIXME DOC
 */
static void opj_pi_update_decode_not_poc (opj_pi_iterator_t * p_pi,
                                          opj_tcp_t * p_tcp,
                                          OPJ_UINT32 p_max_precision,
                                          OPJ_UINT32 p_max_res);
/**
 * FIXME DOC
 */
static void opj_pi_update_decode_poc (  opj_pi_iterator_t * p_pi,
                                        opj_tcp_t * p_tcp,
                                        OPJ_UINT32 p_max_precision,
                                        OPJ_UINT32 p_max_res);

/**
 * FIXME DOC
 */
static OPJ_BOOL opj_pi_check_next_level(	OPJ_INT32 pos,
								opj_cp_t *cp,
								OPJ_UINT32 tileno,
								OPJ_UINT32 pino,
								const OPJ_CHAR *prog);

/*@}*/

/*@}*/

/*
==========================================================
   local functions
==========================================================
*/

static OPJ_BOOL opj_pi_next_lrcp(opj_pi_iterator_t * pi) {
	opj_pi_comp_t *comp = NULL;
	opj_pi_resolution_t *res = NULL;
	OPJ_UINT32 index = 0;
	
	if (!pi->first) {
		comp = &pi->comps[pi->compno];
		res = &comp->resolutions[pi->resno];
		goto LABEL_SKIP;
	} else {
		pi->first = 0;
	}

	for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) {
		for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1;
		pi->resno++) {
			for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
				comp = &pi->comps[pi->compno];
				if (pi->resno >= comp->numresolutions) {
					continue;
				}
				res = &comp->resolutions[pi->resno];
				if (!pi->tp_on){
					pi->poc.precno1 = res->pw * res->ph;
				}
				for (pi->precno = pi->poc.precno0; pi->precno < pi->poc.precno1; pi->precno++) {
					index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
					if (!pi->include[index]) {
						pi->include[index] = 1;
						return OPJ_TRUE;
					}
LABEL_SKIP:;
				}
			}
		}
	}
	
	return OPJ_FALSE;
}

static OPJ_BOOL opj_pi_next_rlcp(opj_pi_iterator_t * pi) {
	opj_pi_comp_t *comp = NULL;
	opj_pi_resolution_t *res = NULL;
	OPJ_UINT32 index = 0;

	if (!pi->first) {
		comp = &pi->comps[pi->compno];
		res = &comp->resolutions[pi->resno];
		goto LABEL_SKIP;
	} else {
		pi->first = 0;
	}

	for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) {
		for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) {
			for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
				comp = &pi->comps[pi->compno];
				if (pi->resno >= comp->numresolutions) {
					continue;
				}
				res = &comp->resolutions[pi->resno];
				if(!pi->tp_on){
					pi->poc.precno1 = res->pw * res->ph;
				}
				for (pi->precno = pi->poc.precno0; pi->precno < pi->poc.precno1; pi->precno++) {
					index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
					if (!pi->include[index]) {
						pi->include[index] = 1;
						return OPJ_TRUE;
					}
LABEL_SKIP:;
				}
			}
		}
	}
	
	return OPJ_FALSE;
}

static OPJ_BOOL opj_pi_next_rpcl(opj_pi_iterator_t * pi) {
	opj_pi_comp_t *comp = NULL;
	opj_pi_resolution_t *res = NULL;
	OPJ_UINT32 index = 0;

	if (!pi->first) {
		goto LABEL_SKIP;
	} else {
		OPJ_UINT32 compno, resno;
		pi->first = 0;
		pi->dx = 0;
		pi->dy = 0;
		for (compno = 0; compno < pi->numcomps; compno++) {
			comp = &pi->comps[compno];
			for (resno = 0; resno < comp->numresolutions; resno++) {
				OPJ_UINT32 dx, dy;
				res = &comp->resolutions[resno];
				dx = comp->dx * (1u << (res->pdx + comp->numresolutions - 1 - resno));
				dy = comp->dy * (1u << (res->pdy + comp->numresolutions - 1 - resno));
				pi->dx = !pi->dx ? dx : opj_uint_min(pi->dx, dx);
				pi->dy = !pi->dy ? dy : opj_uint_min(pi->dy, dy);
			}
		}
	}
if (!pi->tp_on){
			pi->poc.ty0 = pi->ty0;
			pi->poc.tx0 = pi->tx0;
			pi->poc.ty1 = pi->ty1;
			pi->poc.tx1 = pi->tx1;
		}
	for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) {
		for (pi->y = pi->poc.ty0; pi->y < pi->poc.ty1; pi->y += (OPJ_INT32)(pi->dy - (OPJ_UINT32)(pi->y % (OPJ_INT32)pi->dy))) {
			for (pi->x = pi->poc.tx0; pi->x < pi->poc.tx1; pi->x += (OPJ_INT32)(pi->dx - (OPJ_UINT32)(pi->x % (OPJ_INT32)pi->dx))) {
				for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
					OPJ_UINT32 levelno;
					OPJ_INT32 trx0, try0;
					OPJ_INT32  trx1, try1;
					OPJ_UINT32  rpx, rpy;
					OPJ_INT32  prci, prcj;
					comp = &pi->comps[pi->compno];
					if (pi->resno >= comp->numresolutions) {
						continue;
					}
					res = &comp->resolutions[pi->resno];
					levelno = comp->numresolutions - 1 - pi->resno;
					trx0 = opj_int_ceildiv(pi->tx0, (OPJ_INT32)(comp->dx << levelno));
					try0 = opj_int_ceildiv(pi->ty0, (OPJ_INT32)(comp->dy << levelno));
					trx1 = opj_int_ceildiv(pi->tx1, (OPJ_INT32)(comp->dx << levelno));
					try1 = opj_int_ceildiv(pi->ty1, (OPJ_INT32)(comp->dy << levelno));
					rpx = res->pdx + levelno;
					rpy = res->pdy + levelno;
					if (!((pi->y % (OPJ_INT32)(comp->dy << rpy) == 0) || ((pi->y == pi->ty0) && ((try0 << levelno) % (1 << rpy))))){
						continue;	
					}
					if (!((pi->x % (OPJ_INT32)(comp->dx << rpx) == 0) || ((pi->x == pi->tx0) && ((trx0 << levelno) % (1 << rpx))))){
						continue;
					}
					
					if ((res->pw==0)||(res->ph==0)) continue;
					
					if ((trx0==trx1)||(try0==try1)) continue;
					
					prci = opj_int_floordivpow2(opj_int_ceildiv(pi->x, (OPJ_INT32)(comp->dx << levelno)), (OPJ_INT32)res->pdx)
						 - opj_int_floordivpow2(trx0, (OPJ_INT32)res->pdx);
					prcj = opj_int_floordivpow2(opj_int_ceildiv(pi->y, (OPJ_INT32)(comp->dy << levelno)), (OPJ_INT32)res->pdy)
						 - opj_int_floordivpow2(try0, (OPJ_INT32)res->pdy);
					pi->precno = (OPJ_UINT32)(prci + prcj * (OPJ_INT32)res->pw);
					if (pi->precno >= res->pw * res->ph) {
						return OPJ_FALSE;
					}
					for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) {
						index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
						if (!pi->include[index]) {
							pi->include[index] = 1;
							return OPJ_TRUE;
						}
LABEL_SKIP:;
					}
				}
			}
		}
	}
	
	return OPJ_FALSE;
}

static OPJ_BOOL opj_pi_next_pcrl(opj_pi_iterator_t * pi) {
	opj_pi_comp_t *comp = NULL;
	opj_pi_resolution_t *res = NULL;
	OPJ_UINT32 index = 0;

	if (!pi->first) {
		comp = &pi->comps[pi->compno];
		goto LABEL_SKIP;
	} else {
		OPJ_UINT32 compno, resno;
		pi->first = 0;
		pi->dx = 0;
		pi->dy = 0;
		for (compno = 0; compno < pi->numcomps; compno++) {
			comp = &pi->comps[compno];
			for (resno = 0; resno < comp->numresolutions; resno++) {
				OPJ_UINT32 dx, dy;
				res = &comp->resolutions[resno];
				dx = comp->dx * (1u << (res->pdx + comp->numresolutions - 1 - resno));
				dy = comp->dy * (1u << (res->pdy + comp->numresolutions - 1 - resno));
				pi->dx = !pi->dx ? dx : opj_uint_min(pi->dx, dx);
				pi->dy = !pi->dy ? dy : opj_uint_min(pi->dy, dy);
			}
		}
	}
	if (!pi->tp_on){
			pi->poc.ty0 = pi->ty0;
			pi->poc.tx0 = pi->tx0;
			pi->poc.ty1 = pi->ty1;
			pi->poc.tx1 = pi->tx1;
		}
	for (pi->y = pi->poc.ty0; pi->y < pi->poc.ty1; pi->y += (OPJ_INT32)(pi->dy - (OPJ_UINT32)(pi->y % (OPJ_INT32)pi->dy))) {
		for (pi->x = pi->poc.tx0; pi->x < pi->poc.tx1; pi->x += (OPJ_INT32)(pi->dx - (OPJ_UINT32)(pi->x % (OPJ_INT32)pi->dx))) {
			for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
				comp = &pi->comps[pi->compno];
				for (pi->resno = pi->poc.resno0; pi->resno < opj_uint_min(pi->poc.resno1, comp->numresolutions); pi->resno++) {
					OPJ_UINT32 levelno;
					OPJ_INT32 trx0, try0;
					OPJ_INT32 trx1, try1;
					OPJ_UINT32 rpx, rpy;
					OPJ_INT32 prci, prcj;
					res = &comp->resolutions[pi->resno];
					levelno = comp->numresolutions - 1 - pi->resno;
					trx0 = opj_int_ceildiv(pi->tx0, (OPJ_INT32)(comp->dx << levelno));
					try0 = opj_int_ceildiv(pi->ty0, (OPJ_INT32)(comp->dy << levelno));
					trx1 = opj_int_ceildiv(pi->tx1, (OPJ_INT32)(comp->dx << levelno));
					try1 = opj_int_ceildiv(pi->ty1, (OPJ_INT32)(comp->dy << levelno));
					rpx = res->pdx + levelno;
					rpy = res->pdy + levelno;
					if (!((pi->y % (OPJ_INT32)(comp->dy << rpy) == 0) || ((pi->y == pi->ty0) && ((try0 << levelno) % (1 << rpy))))){
						continue;	
					}
					if (!((pi->x % (OPJ_INT32)(comp->dx << rpx) == 0) || ((pi->x == pi->tx0) && ((trx0 << levelno) % (1 << rpx))))){
						continue;
					}
					
					if ((res->pw==0)||(res->ph==0)) continue;
					
					if ((trx0==trx1)||(try0==try1)) continue;
					
					prci = opj_int_floordivpow2(opj_int_ceildiv(pi->x, (OPJ_INT32)(comp->dx << levelno)), (OPJ_INT32)res->pdx)
						 - opj_int_floordivpow2(trx0, (OPJ_INT32)res->pdx);
					prcj = opj_int_floordivpow2(opj_int_ceildiv(pi->y, (OPJ_INT32)(comp->dy << levelno)), (OPJ_INT32)res->pdy)
						 - opj_int_floordivpow2(try0, (OPJ_INT32)res->pdy);
					pi->precno = (OPJ_UINT32)(prci + prcj * (OPJ_INT32)res->pw);
					if (pi->precno >= res->pw * res->ph) {
						return OPJ_FALSE;
					}
					for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) {
						index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
						if (!pi->include[index]) {
							pi->include[index] = 1;
							return OPJ_TRUE;
						}	
LABEL_SKIP:;
					}
				}
			}
		}
	}
	
	return OPJ_FALSE;
}

static OPJ_BOOL opj_pi_next_cprl(opj_pi_iterator_t * pi) {
	opj_pi_comp_t *comp = NULL;
	opj_pi_resolution_t *res = NULL;
	OPJ_UINT32 index = 0;

	if (!pi->first) {
		comp = &pi->comps[pi->compno];
		goto LABEL_SKIP;
	} else {
		pi->first = 0;
	}

	for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
		OPJ_UINT32 resno;
		comp = &pi->comps[pi->compno];
		pi->dx = 0;
		pi->dy = 0;
		for (resno = 0; resno < comp->numresolutions; resno++) {
			OPJ_UINT32 dx, dy;
			res = &comp->resolutions[resno];
			dx = comp->dx * (1u << (res->pdx + comp->numresolutions - 1 - resno));
			dy = comp->dy * (1u << (res->pdy + comp->numresolutions - 1 - resno));
			pi->dx = !pi->dx ? dx : opj_uint_min(pi->dx, dx);
			pi->dy = !pi->dy ? dy : opj_uint_min(pi->dy, dy);
		}
		if (!pi->tp_on){
			pi->poc.ty0 = pi->ty0;
			pi->poc.tx0 = pi->tx0;
			pi->poc.ty1 = pi->ty1;
			pi->poc.tx1 = pi->tx1;
		}
		for (pi->y = pi->poc.ty0; pi->y < pi->poc.ty1; pi->y += (OPJ_INT32)(pi->dy - (OPJ_UINT32)(pi->y % (OPJ_INT32)pi->dy))) {
			for (pi->x = pi->poc.tx0; pi->x < pi->poc.tx1; pi->x += (OPJ_INT32)(pi->dx - (OPJ_UINT32)(pi->x % (OPJ_INT32)pi->dx))) {
				for (pi->resno = pi->poc.resno0; pi->resno < opj_uint_min(pi->poc.resno1, comp->numresolutions); pi->resno++) {
					OPJ_UINT32 levelno;
					OPJ_INT32 trx0, try0;
					OPJ_INT32 trx1, try1;
					OPJ_UINT32 rpx, rpy;
					OPJ_INT32 prci, prcj;
					res = &comp->resolutions[pi->resno];
					levelno = comp->numresolutions - 1 - pi->resno;
					trx0 = opj_int_ceildiv(pi->tx0, (OPJ_INT32)(comp->dx << levelno));
					try0 = opj_int_ceildiv(pi->ty0, (OPJ_INT32)(comp->dy << levelno));
					trx1 = opj_int_ceildiv(pi->tx1, (OPJ_INT32)(comp->dx << levelno));
					try1 = opj_int_ceildiv(pi->ty1, (OPJ_INT32)(comp->dy << levelno));
					rpx = res->pdx + levelno;
					rpy = res->pdy + levelno;
					if (!((pi->y % (OPJ_INT32)(comp->dy << rpy) == 0) || ((pi->y == pi->ty0) && ((try0 << levelno) % (1 << rpy))))){
						continue;	
					}
					if (!((pi->x % (OPJ_INT32)(comp->dx << rpx) == 0) || ((pi->x == pi->tx0) && ((trx0 << levelno) % (1 << rpx))))){
						continue;
					}
					
					if ((res->pw==0)||(res->ph==0)) continue;
					
					if ((trx0==trx1)||(try0==try1)) continue;
					
					prci = opj_int_floordivpow2(opj_int_ceildiv(pi->x, (OPJ_INT32)(comp->dx << levelno)), (OPJ_INT32)res->pdx)
						 - opj_int_floordivpow2(trx0, (OPJ_INT32)res->pdx);
					prcj = opj_int_floordivpow2(opj_int_ceildiv(pi->y, (OPJ_INT32)(comp->dy << levelno)), (OPJ_INT32)res->pdy)
						 - opj_int_floordivpow2(try0, (OPJ_INT32)res->pdy);
					pi->precno = (OPJ_UINT32)(prci + prcj * (OPJ_INT32)res->pw);
					if (pi->precno >= res->pw * res->ph) {
						return OPJ_FALSE;
					}
					for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) {
						index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
						if (!pi->include[index]) {
							pi->include[index] = 1;
							return OPJ_TRUE;
						}
LABEL_SKIP:;
					}
				}
			}
		}
	}
	
	return OPJ_FALSE;
}

static void opj_get_encoding_parameters(	const opj_image_t *p_image,
                                    const opj_cp_t *p_cp,
                                    OPJ_UINT32 p_tileno,
                                    OPJ_INT32 * p_tx0,
                                    OPJ_INT32  * p_tx1,
                                    OPJ_INT32  * p_ty0,
                                    OPJ_INT32  * p_ty1,
                                    OPJ_UINT32 * p_dx_min,
                                    OPJ_UINT32 * p_dy_min,
                                    OPJ_UINT32 * p_max_prec,
                                    OPJ_UINT32 * p_max_res )
{
	/* loop */
	OPJ_UINT32  compno, resno;
	/* pointers */
	const opj_tcp_t *l_tcp = 00;
	const opj_tccp_t * l_tccp = 00;
	const opj_image_comp_t * l_img_comp = 00;

	/* position in x and y of tile */
	OPJ_UINT32 p, q;

	/* preconditions */
	assert(p_cp != 00);
	assert(p_image != 00);
	assert(p_tileno < p_cp->tw * p_cp->th);

	/* initializations */
	l_tcp = &p_cp->tcps [p_tileno];
	l_img_comp = p_image->comps;
	l_tccp = l_tcp->tccps;

	/* here calculation of tx0, tx1, ty0, ty1, maxprec, dx and dy */
	p = p_tileno % p_cp->tw;
	q = p_tileno / p_cp->tw;

	/* find extent of tile */
	*p_tx0 = opj_int_max((OPJ_INT32)(p_cp->tx0 + p * p_cp->tdx), (OPJ_INT32)p_image->x0);
	*p_tx1 = opj_int_min((OPJ_INT32)(p_cp->tx0 + (p + 1) * p_cp->tdx), (OPJ_INT32)p_image->x1);
	*p_ty0 = opj_int_max((OPJ_INT32)(p_cp->ty0 + q * p_cp->tdy), (OPJ_INT32)p_image->y0);
	*p_ty1 = opj_int_min((OPJ_INT32)(p_cp->ty0 + (q + 1) * p_cp->tdy), (OPJ_INT32)p_image->y1);

	/* max precision is 0 (can only grow) */
	*p_max_prec = 0;
	*p_max_res = 0;

	/* take the largest value for dx_min and dy_min */
	*p_dx_min = 0x7fffffff;
	*p_dy_min  = 0x7fffffff;

	for (compno = 0; compno < p_image->numcomps; ++compno) {
		/* arithmetic variables to calculate */
		OPJ_UINT32 l_level_no;
		OPJ_INT32 l_rx0, l_ry0, l_rx1, l_ry1;
		OPJ_INT32 l_px0, l_py0, l_px1, py1;
		OPJ_UINT32 l_pdx, l_pdy;
		OPJ_UINT32 l_pw, l_ph;
		OPJ_UINT32 l_product;
		OPJ_INT32 l_tcx0, l_tcy0, l_tcx1, l_tcy1;

		l_tcx0 = opj_int_ceildiv(*p_tx0, (OPJ_INT32)l_img_comp->dx);
		l_tcy0 = opj_int_ceildiv(*p_ty0, (OPJ_INT32)l_img_comp->dy);
		l_tcx1 = opj_int_ceildiv(*p_tx1, (OPJ_INT32)l_img_comp->dx);
		l_tcy1 = opj_int_ceildiv(*p_ty1, (OPJ_INT32)l_img_comp->dy);

		if (l_tccp->numresolutions > *p_max_res) {
			*p_max_res = l_tccp->numresolutions;
		}

		/* use custom size for precincts */
		for (resno = 0; resno < l_tccp->numresolutions; ++resno) {
			OPJ_UINT32 l_dx, l_dy;

			/* precinct width and height */
			l_pdx = l_tccp->prcw[resno];
			l_pdy = l_tccp->prch[resno];

			l_dx = l_img_comp->dx * (1u << (l_pdx + l_tccp->numresolutions - 1 - resno));
			l_dy = l_img_comp->dy * (1u << (l_pdy + l_tccp->numresolutions - 1 - resno));

			/* take the minimum size for dx for each comp and resolution */
			*p_dx_min = opj_uint_min(*p_dx_min, l_dx);
			*p_dy_min = opj_uint_min(*p_dy_min, l_dy);

			/* various calculations of extents */
			l_level_no = l_tccp->numresolutions - 1 - resno;

			l_rx0 = opj_int_ceildivpow2(l_tcx0, (OPJ_INT32)l_level_no);
			l_ry0 = opj_int_ceildivpow2(l_tcy0, (OPJ_INT32)l_level_no);
			l_rx1 = opj_int_ceildivpow2(l_tcx1, (OPJ_INT32)l_level_no);
			l_ry1 = opj_int_ceildivpow2(l_tcy1, (OPJ_INT32)l_level_no);

			l_px0 = opj_int_floordivpow2(l_rx0, (OPJ_INT32)l_pdx) << l_pdx;
			l_py0 = opj_int_floordivpow2(l_ry0, (OPJ_INT32)l_pdy) << l_pdy;
			l_px1 = opj_int_ceildivpow2(l_rx1, (OPJ_INT32)l_pdx) << l_pdx;

			py1 = opj_int_ceildivpow2(l_ry1, (OPJ_INT32)l_pdy) << l_pdy;

			l_pw = (l_rx0==l_rx1)?0:(OPJ_UINT32)((l_px1 - l_px0) >> l_pdx);
			l_ph = (l_ry0==l_ry1)?0:(OPJ_UINT32)((py1 - l_py0) >> l_pdy);

			l_product = l_pw * l_ph;

			/* update precision */
			if (l_product > *p_max_prec) {
				*p_max_prec = l_product;
			}
		}
		++l_img_comp;
		++l_tccp;
	}
}


static void opj_get_all_encoding_parameters(   const opj_image_t *p_image,
                                        const opj_cp_t *p_cp,
                                        OPJ_UINT32 tileno,
                                        OPJ_INT32 * p_tx0,
                                        OPJ_INT32 * p_tx1,
                                        OPJ_INT32 * p_ty0,
                                        OPJ_INT32 * p_ty1,
                                        OPJ_UINT32 * p_dx_min,
                                        OPJ_UINT32 * p_dy_min,
                                        OPJ_UINT32 * p_max_prec,
                                        OPJ_UINT32 * p_max_res,
                                        OPJ_UINT32 ** p_resolutions )
{
	/* loop*/
	OPJ_UINT32 compno, resno;

	/* pointers*/
	const opj_tcp_t *tcp = 00;
	const opj_tccp_t * l_tccp = 00;
	const opj_image_comp_t * l_img_comp = 00;

	/* to store l_dx, l_dy, w and h for each resolution and component.*/
	OPJ_UINT32 * lResolutionPtr;

	/* position in x and y of tile*/
	OPJ_UINT32 p, q;

	/* non-corrected (in regard to image offset) tile offset */
	OPJ_UINT32 l_tx0, l_ty0;

	/* preconditions in debug*/
	assert(p_cp != 00);
	assert(p_image != 00);
	assert(tileno < p_cp->tw * p_cp->th);

	/* initializations*/
	tcp = &p_cp->tcps [tileno];
	l_tccp = tcp->tccps;
	l_img_comp = p_image->comps;

	/* position in x and y of tile*/
	p = tileno % p_cp->tw;
	q = tileno / p_cp->tw;

	/* here calculation of tx0, tx1, ty0, ty1, maxprec, l_dx and l_dy */
	l_tx0 = p_cp->tx0 + p * p_cp->tdx; /* can't be greater than p_image->x1 so won't overflow */
	*p_tx0 = (OPJ_INT32)opj_uint_max(l_tx0, p_image->x0);
	*p_tx1 = (OPJ_INT32)opj_uint_min(opj_uint_adds(l_tx0, p_cp->tdx), p_image->x1);
	l_ty0 = p_cp->ty0 + q * p_cp->tdy; /* can't be greater than p_image->y1 so won't overflow */
	*p_ty0 = (OPJ_INT32)opj_uint_max(l_ty0, p_image->y0);
	*p_ty1 = (OPJ_INT32)opj_uint_min(opj_uint_adds(l_ty0, p_cp->tdy), p_image->y1);

	/* max precision and resolution is 0 (can only grow)*/
	*p_max_prec = 0;
	*p_max_res = 0;

	/* take the largest value for dx_min and dy_min*/
	*p_dx_min = 0x7fffffff;
	*p_dy_min = 0x7fffffff;

	for (compno = 0; compno < p_image->numcomps; ++compno) {
		/* aritmetic variables to calculate*/
		OPJ_UINT32 l_level_no;
		OPJ_INT32 l_rx0, l_ry0, l_rx1, l_ry1;
		OPJ_INT32 l_px0, l_py0, l_px1, py1;
		OPJ_UINT32 l_product;
		OPJ_INT32 l_tcx0, l_tcy0, l_tcx1, l_tcy1;
		OPJ_UINT32 l_pdx, l_pdy , l_pw , l_ph;

		lResolutionPtr = p_resolutions[compno];

		l_tcx0 = opj_int_ceildiv(*p_tx0, (OPJ_INT32)l_img_comp->dx);
		l_tcy0 = opj_int_ceildiv(*p_ty0, (OPJ_INT32)l_img_comp->dy);
		l_tcx1 = opj_int_ceildiv(*p_tx1, (OPJ_INT32)l_img_comp->dx);
		l_tcy1 = opj_int_ceildiv(*p_ty1, (OPJ_INT32)l_img_comp->dy);

		if (l_tccp->numresolutions > *p_max_res) {
			*p_max_res = l_tccp->numresolutions;
		}

		/* use custom size for precincts*/
		l_level_no = l_tccp->numresolutions - 1;
		for (resno = 0; resno < l_tccp->numresolutions; ++resno) {
			OPJ_UINT32 l_dx, l_dy;

			/* precinct width and height*/
			l_pdx = l_tccp->prcw[resno];
			l_pdy = l_tccp->prch[resno];
			*lResolutionPtr++ = l_pdx;
			*lResolutionPtr++ = l_pdy;
			l_dx = l_img_comp->dx * (1u << (l_pdx + l_level_no));
			l_dy = l_img_comp->dy * (1u << (l_pdy + l_level_no));
			/* take the minimum size for l_dx for each comp and resolution*/
			*p_dx_min = (OPJ_UINT32)opj_int_min((OPJ_INT32)*p_dx_min, (OPJ_INT32)l_dx);
			*p_dy_min = (OPJ_UINT32)opj_int_min((OPJ_INT32)*p_dy_min, (OPJ_INT32)l_dy);

			/* various calculations of extents*/
			l_rx0 = opj_int_ceildivpow2(l_tcx0, (OPJ_INT32)l_level_no);
			l_ry0 = opj_int_ceildivpow2(l_tcy0, (OPJ_INT32)l_level_no);
			l_rx1 = opj_int_ceildivpow2(l_tcx1, (OPJ_INT32)l_level_no);
			l_ry1 = opj_int_ceildivpow2(l_tcy1, (OPJ_INT32)l_level_no);
			l_px0 = opj_int_floordivpow2(l_rx0, (OPJ_INT32)l_pdx) << l_pdx;
			l_py0 = opj_int_floordivpow2(l_ry0, (OPJ_INT32)l_pdy) << l_pdy;
			l_px1 = opj_int_ceildivpow2(l_rx1, (OPJ_INT32)l_pdx) << l_pdx;
			py1 = opj_int_ceildivpow2(l_ry1, (OPJ_INT32)l_pdy) << l_pdy;
			l_pw = (l_rx0==l_rx1)?0:(OPJ_UINT32)((l_px1 - l_px0) >> l_pdx);
			l_ph = (l_ry0==l_ry1)?0:(OPJ_UINT32)((py1 - l_py0) >> l_pdy);
			*lResolutionPtr++ = l_pw;
			*lResolutionPtr++ = l_ph;
			l_product = l_pw * l_ph;
			
            /* update precision*/
			if (l_product > *p_max_prec) {
				*p_max_prec = l_product;
			}

			--l_level_no;
		}
		++l_tccp;
		++l_img_comp;
	}
}

static opj_pi_iterator_t * opj_pi_create(	const opj_image_t *image,
                                    const opj_cp_t *cp,
                                    OPJ_UINT32 tileno )
{
	/* loop*/
	OPJ_UINT32 pino, compno;
	/* number of poc in the p_pi*/
	OPJ_UINT32 l_poc_bound;

	/* pointers to tile coding parameters and components.*/
	opj_pi_iterator_t *l_pi = 00;
	opj_tcp_t *tcp = 00;
	const opj_tccp_t *tccp = 00;

	/* current packet iterator being allocated*/
	opj_pi_iterator_t *l_current_pi = 00;

	/* preconditions in debug*/
	assert(cp != 00);
	assert(image != 00);
	assert(tileno < cp->tw * cp->th);

	/* initializations*/
	tcp = &cp->tcps[tileno];
	l_poc_bound = tcp->numpocs+1;

	/* memory allocations*/
	l_pi = (opj_pi_iterator_t*) opj_calloc((l_poc_bound), sizeof(opj_pi_iterator_t));
	if (!l_pi) {
		return NULL;
	}

	l_current_pi = l_pi;
	for (pino = 0; pino < l_poc_bound ; ++pino) {

		l_current_pi->comps = (opj_pi_comp_t*) opj_calloc(image->numcomps, sizeof(opj_pi_comp_t));
		if (! l_current_pi->comps) {
			opj_pi_destroy(l_pi, l_poc_bound);
			return NULL;
		}

		l_current_pi->numcomps = image->numcomps;

		for (compno = 0; compno < image->numcomps; ++compno) {
			opj_pi_comp_t *comp = &l_current_pi->comps[compno];

			tccp = &tcp->tccps[compno];

			comp->resolutions = (opj_pi_resolution_t*) opj_calloc(tccp->numresolutions, sizeof(opj_pi_resolution_t));
			if (!comp->resolutions) {
				opj_pi_destroy(l_pi, l_poc_bound);
				return 00;
			}

			comp->numresolutions = tccp->numresolutions;
		}
		++l_current_pi;
	}
	return l_pi;
}

static void opj_pi_update_encode_poc_and_final (   opj_cp_t *p_cp,
                                            OPJ_UINT32 p_tileno,
                                            OPJ_INT32 p_tx0,
                                            OPJ_INT32 p_tx1,
                                            OPJ_INT32 p_ty0,
                                            OPJ_INT32 p_ty1,
                                            OPJ_UINT32 p_max_prec,
                                            OPJ_UINT32 p_max_res,
                                            OPJ_UINT32 p_dx_min,
                                            OPJ_UINT32 p_dy_min)
{
	/* loop*/
	OPJ_UINT32 pino;
	/* tile coding parameter*/
	opj_tcp_t *l_tcp = 00;
	/* current poc being updated*/
	opj_poc_t * l_current_poc = 00;

	/* number of pocs*/
	OPJ_UINT32 l_poc_bound;

    OPJ_ARG_NOT_USED(p_max_res);

	/* preconditions in debug*/
	assert(p_cp != 00);
	assert(p_tileno < p_cp->tw * p_cp->th);

	/* initializations*/
	l_tcp = &p_cp->tcps [p_tileno];
	/* number of iterations in the loop */
	l_poc_bound = l_tcp->numpocs+1;

	/* start at first element, and to make sure the compiler will not make a calculation each time in the loop
	   store a pointer to the current element to modify rather than l_tcp->pocs[i]*/
	l_current_poc = l_tcp->pocs;

	l_current_poc->compS = l_current_poc->compno0;
	l_current_poc->compE = l_current_poc->compno1;
	l_current_poc->resS = l_current_poc->resno0;
	l_current_poc->resE = l_current_poc->resno1;
	l_current_poc->layE = l_current_poc->layno1;

	/* special treatment for the first element*/
	l_current_poc->layS = 0;
	l_current_poc->prg  = l_current_poc->prg1;
	l_current_poc->prcS = 0;

	l_current_poc->prcE = p_max_prec;
	l_current_poc->txS = (OPJ_UINT32)p_tx0;
	l_current_poc->txE = (OPJ_UINT32)p_tx1;
	l_current_poc->tyS = (OPJ_UINT32)p_ty0;
	l_current_poc->tyE = (OPJ_UINT32)p_ty1;
	l_current_poc->dx = p_dx_min;
	l_current_poc->dy = p_dy_min;

	++ l_current_poc;
	for (pino = 1;pino < l_poc_bound ; ++pino) {
		l_current_poc->compS = l_current_poc->compno0;
		l_current_poc->compE= l_current_poc->compno1;
		l_current_poc->resS = l_current_poc->resno0;
		l_current_poc->resE = l_current_poc->resno1;
		l_current_poc->layE = l_current_poc->layno1;
		l_current_poc->prg  = l_current_poc->prg1;
		l_current_poc->prcS = 0;
		/* special treatment here different from the first element*/
		l_current_poc->layS = (l_current_poc->layE > (l_current_poc-1)->layE) ? l_current_poc->layE : 0;

		l_current_poc->prcE = p_max_prec;
		l_current_poc->txS = (OPJ_UINT32)p_tx0;
		l_current_poc->txE = (OPJ_UINT32)p_tx1;
		l_current_poc->tyS = (OPJ_UINT32)p_ty0;
		l_current_poc->tyE = (OPJ_UINT32)p_ty1;
		l_current_poc->dx = p_dx_min;
		l_current_poc->dy = p_dy_min;
		++ l_current_poc;
	}
}

static void opj_pi_update_encode_not_poc (	opj_cp_t *p_cp,
                                    OPJ_UINT32 p_num_comps,
                                    OPJ_UINT32 p_tileno,
                                    OPJ_INT32 p_tx0,
                                    OPJ_INT32 p_tx1,
                                    OPJ_INT32 p_ty0,
                                    OPJ_INT32 p_ty1,
                                    OPJ_UINT32 p_max_prec,
                                    OPJ_UINT32 p_max_res,
                                    OPJ_UINT32 p_dx_min,
                                    OPJ_UINT32 p_dy_min)
{
	/* loop*/
	OPJ_UINT32 pino;
	/* tile coding parameter*/
	opj_tcp_t *l_tcp = 00;
	/* current poc being updated*/
	opj_poc_t * l_current_poc = 00;
	/* number of pocs*/
	OPJ_UINT32 l_poc_bound;

	/* preconditions in debug*/
	assert(p_cp != 00);
	assert(p_tileno < p_cp->tw * p_cp->th);

	/* initializations*/
	l_tcp = &p_cp->tcps [p_tileno];

	/* number of iterations in the loop */
	l_poc_bound = l_tcp->numpocs+1;

	/* start at first element, and to make sure the compiler will not make a calculation each time in the loop
	   store a pointer to the current element to modify rather than l_tcp->pocs[i]*/
	l_current_poc = l_tcp->pocs;

	for (pino = 0; pino < l_poc_bound ; ++pino) {
		l_current_poc->compS = 0;
		l_current_poc->compE = p_num_comps;/*p_image->numcomps;*/
		l_current_poc->resS = 0;
		l_current_poc->resE = p_max_res;
		l_current_poc->layS = 0;
		l_current_poc->layE = l_tcp->numlayers;
		l_current_poc->prg  = l_tcp->prg;
		l_current_poc->prcS = 0;
		l_current_poc->prcE = p_max_prec;
		l_current_poc->txS = (OPJ_UINT32)p_tx0;
		l_current_poc->txE = (OPJ_UINT32)p_tx1;
		l_current_poc->tyS = (OPJ_UINT32)p_ty0;
		l_current_poc->tyE = (OPJ_UINT32)p_ty1;
		l_current_poc->dx = p_dx_min;
		l_current_poc->dy = p_dy_min;
		++ l_current_poc;
	}
}

static void opj_pi_update_decode_poc (opj_pi_iterator_t * p_pi,
                               opj_tcp_t * p_tcp,
                               OPJ_UINT32 p_max_precision,
                               OPJ_UINT32 p_max_res)
{
	/* loop*/
	OPJ_UINT32 pino;

	/* encoding prameters to set*/
	OPJ_UINT32 l_bound;

	opj_pi_iterator_t * l_current_pi = 00;
	opj_poc_t* l_current_poc = 0;

    OPJ_ARG_NOT_USED(p_max_res);

	/* preconditions in debug*/
	assert(p_pi != 00);
	assert(p_tcp != 00);

	/* initializations*/
	l_bound = p_tcp->numpocs+1;
	l_current_pi = p_pi;
	l_current_poc = p_tcp->pocs;

	for	(pino = 0;pino<l_bound;++pino) {
		l_current_pi->poc.prg = l_current_poc->prg; /* Progression Order #0 */
		l_current_pi->first = 1;

		l_current_pi->poc.resno0 = l_current_poc->resno0; /* Resolution Level Index #0 (Start) */
		l_current_pi->poc.compno0 = l_current_poc->compno0; /* Component Index #0 (Start) */
		l_current_pi->poc.layno0 = 0;
		l_current_pi->poc.precno0 = 0;
		l_current_pi->poc.resno1 = l_current_poc->resno1; /* Resolution Level Index #0 (End) */
		l_current_pi->poc.compno1 = l_current_poc->compno1; /* Component Index #0 (End) */
		l_current_pi->poc.layno1 = opj_uint_min(l_current_poc->layno1, p_tcp->numlayers); /* Layer Index #0 (End) */
		l_current_pi->poc.precno1 = p_max_precision;
		++l_current_pi;
		++l_current_poc;
	}
}

static void opj_pi_update_decode_not_poc (opj_pi_iterator_t * p_pi,
                                   opj_tcp_t * p_tcp,
                                   OPJ_UINT32 p_max_precision,
                                   OPJ_UINT32 p_max_res)
{
	/* loop*/
	OPJ_UINT32 pino;

	/* encoding prameters to set*/
	OPJ_UINT32 l_bound;

	opj_pi_iterator_t * l_current_pi = 00;
	/* preconditions in debug*/
	assert(p_tcp != 00);
	assert(p_pi != 00);

	/* initializations*/
	l_bound = p_tcp->numpocs+1;
	l_current_pi = p_pi;

	for (pino = 0;pino<l_bound;++pino) {
		l_current_pi->poc.prg = p_tcp->prg;
		l_current_pi->first = 1;
		l_current_pi->poc.resno0 = 0;
		l_current_pi->poc.compno0 = 0;
		l_current_pi->poc.layno0 = 0;
		l_current_pi->poc.precno0 = 0;
		l_current_pi->poc.resno1 = p_max_res;
		l_current_pi->poc.compno1 = l_current_pi->numcomps;
		l_current_pi->poc.layno1 = p_tcp->numlayers;
		l_current_pi->poc.precno1 = p_max_precision;
		++l_current_pi;
	}
}



static OPJ_BOOL opj_pi_check_next_level(	OPJ_INT32 pos,
								opj_cp_t *cp,
								OPJ_UINT32 tileno,
								OPJ_UINT32 pino,
								const OPJ_CHAR *prog)
{
	OPJ_INT32 i;
	opj_tcp_t *tcps =&cp->tcps[tileno];
	opj_poc_t *tcp = &tcps->pocs[pino];

	if(pos>=0){
		for(i=pos;pos>=0;i--){
			switch(prog[i]){
		    case 'R':
			    if(tcp->res_t==tcp->resE){
				    if(opj_pi_check_next_level(pos-1,cp,tileno,pino,prog)){
					    return OPJ_TRUE;
				    }else{
					    return OPJ_FALSE;
				    }
			    }else{
				    return OPJ_TRUE;
			    }
			    break;
		    case 'C':
			    if(tcp->comp_t==tcp->compE){
				    if(opj_pi_check_next_level(pos-1,cp,tileno,pino,prog)){
					    return OPJ_TRUE;
				    }else{
					    return OPJ_FALSE;
				    }
			    }else{
				    return OPJ_TRUE;
			    }
			    break;
		    case 'L':
			    if(tcp->lay_t==tcp->layE){
				    if(opj_pi_check_next_level(pos-1,cp,tileno,pino,prog)){
					    return OPJ_TRUE;
				    }else{
					    return OPJ_FALSE;
				    }
			    }else{
				    return OPJ_TRUE;
			    }
			    break;
		    case 'P':
			    switch(tcp->prg){
                    case OPJ_LRCP: /* fall through */
                    case OPJ_RLCP:
					    if(tcp->prc_t == tcp->prcE){
						    if(opj_pi_check_next_level(i-1,cp,tileno,pino,prog)){
							    return OPJ_TRUE;
						    }else{
							    return OPJ_FALSE;
						    }
					    }else{
						    return OPJ_TRUE;
					    }
					    break;
			    default:
				    if(tcp->tx0_t == tcp->txE){
					    /*TY*/
					    if(tcp->ty0_t == tcp->tyE){
						    if(opj_pi_check_next_level(i-1,cp,tileno,pino,prog)){
							    return OPJ_TRUE;
						    }else{
							    return OPJ_FALSE;
						    }
					    }else{
						    return OPJ_TRUE;
					    }/*TY*/
				    }else{
					    return OPJ_TRUE;
				    }
				    break;
			    }/*end case P*/
		    }/*end switch*/
		}/*end for*/
	}/*end if*/
	return OPJ_FALSE;
}


/*
==========================================================
   Packet iterator interface
==========================================================
*/
opj_pi_iterator_t *opj_pi_create_decode(opj_image_t *p_image,
										opj_cp_t *p_cp,
										OPJ_UINT32 p_tile_no)
{
	/* loop */
	OPJ_UINT32 pino;
	OPJ_UINT32 compno, resno;

	/* to store w, h, dx and dy fro all components and resolutions */
	OPJ_UINT32 * l_tmp_data;
	OPJ_UINT32 ** l_tmp_ptr;

	/* encoding prameters to set */
	OPJ_UINT32 l_max_res;
	OPJ_UINT32 l_max_prec;
	OPJ_INT32 l_tx0,l_tx1,l_ty0,l_ty1;
	OPJ_UINT32 l_dx_min,l_dy_min;
	OPJ_UINT32 l_bound;
	OPJ_UINT32 l_step_p , l_step_c , l_step_r , l_step_l ;
	OPJ_UINT32 l_data_stride;

	/* pointers */
	opj_pi_iterator_t *l_pi = 00;
	opj_tcp_t *l_tcp = 00;
	const opj_tccp_t *l_tccp = 00;
	opj_pi_comp_t *l_current_comp = 00;
	opj_image_comp_t * l_img_comp = 00;
	opj_pi_iterator_t * l_current_pi = 00;
	OPJ_UINT32 * l_encoding_value_ptr = 00;

	/* preconditions in debug */
	assert(p_cp != 00);
	assert(p_image != 00);
	assert(p_tile_no < p_cp->tw * p_cp->th);

	/* initializations */
	l_tcp = &p_cp->tcps[p_tile_no];
	l_bound = l_tcp->numpocs+1;

	l_data_stride = 4 * OPJ_J2K_MAXRLVLS;
	l_tmp_data = (OPJ_UINT32*)opj_malloc(
		l_data_stride * p_image->numcomps * sizeof(OPJ_UINT32));
	if
		(! l_tmp_data)
	{
		return 00;
	}
	l_tmp_ptr = (OPJ_UINT32**)opj_malloc(
		p_image->numcomps * sizeof(OPJ_UINT32 *));
	if
		(! l_tmp_ptr)
	{
		opj_free(l_tmp_data);
		return 00;
	}

	/* memory allocation for pi */
	l_pi = opj_pi_create(p_image, p_cp, p_tile_no);
	if (!l_pi) {
		opj_free(l_tmp_data);
		opj_free(l_tmp_ptr);
		return 00;
	}

	l_encoding_value_ptr = l_tmp_data;
	/* update pointer array */
	for
		(compno = 0; compno < p_image->numcomps; ++compno)
	{
		l_tmp_ptr[compno] = l_encoding_value_ptr;
		l_encoding_value_ptr += l_data_stride;
	}
	/* get encoding parameters */
	opj_get_all_encoding_parameters(p_image,p_cp,p_tile_no,&l_tx0,&l_tx1,&l_ty0,&l_ty1,&l_dx_min,&l_dy_min,&l_max_prec,&l_max_res,l_tmp_ptr);

	/* step calculations */
	l_step_p = 1;
	l_step_c = l_max_prec * l_step_p;
	l_step_r = p_image->numcomps * l_step_c;
	l_step_l = l_max_res * l_step_r;

	/* set values for first packet iterator */
	l_current_pi = l_pi;

	/* memory allocation for include */
	l_current_pi->include = 00;
	if
		(l_step_l && l_tcp->numlayers < UINT_MAX / l_step_l - 1)
	{
		l_current_pi->include = (OPJ_INT16*)opj_calloc((l_tcp->numlayers + 1) * l_step_l, sizeof(OPJ_INT16));
	}

	if
		(!l_current_pi->include)
	{
		opj_free(l_tmp_data);
		opj_free(l_tmp_ptr);
		opj_pi_destroy(l_pi, l_bound);
		return 00;
	}

	/* special treatment for the first packet iterator */
	l_current_comp = l_current_pi->comps;
	l_img_comp = p_image->comps;
	l_tccp = l_tcp->tccps;

	l_current_pi->tx0 = l_tx0;
	l_current_pi->ty0 = l_ty0;
	l_current_pi->tx1 = l_tx1;
	l_current_pi->ty1 = l_ty1;

	/*l_current_pi->dx = l_img_comp->dx;*/
	/*l_current_pi->dy = l_img_comp->dy;*/

	l_current_pi->step_p = l_step_p;
	l_current_pi->step_c = l_step_c;
	l_current_pi->step_r = l_step_r;
	l_current_pi->step_l = l_step_l;

	/* allocation for components and number of components has already been calculated by opj_pi_create */
	for
		(compno = 0; compno < l_current_pi->numcomps; ++compno)
	{
		opj_pi_resolution_t *l_res = l_current_comp->resolutions;
		l_encoding_value_ptr = l_tmp_ptr[compno];

		l_current_comp->dx = l_img_comp->dx;
		l_current_comp->dy = l_img_comp->dy;
		/* resolutions have already been initialized */
		for
			(resno = 0; resno < l_current_comp->numresolutions; resno++)
		{
			l_res->pdx = *(l_encoding_value_ptr++);
			l_res->pdy = *(l_encoding_value_ptr++);
			l_res->pw =  *(l_encoding_value_ptr++);
			l_res->ph =  *(l_encoding_value_ptr++);
			++l_res;
		}
		++l_current_comp;
		++l_img_comp;
		++l_tccp;
	}
	++l_current_pi;

	for (pino = 1 ; pino<l_bound ; ++pino )
	{
		l_current_comp = l_current_pi->comps;
		l_img_comp = p_image->comps;
		l_tccp = l_tcp->tccps;

		l_current_pi->tx0 = l_tx0;
		l_current_pi->ty0 = l_ty0;
		l_current_pi->tx1 = l_tx1;
		l_current_pi->ty1 = l_ty1;
		/*l_current_pi->dx = l_dx_min;*/
		/*l_current_pi->dy = l_dy_min;*/
		l_current_pi->step_p = l_step_p;
		l_current_pi->step_c = l_step_c;
		l_current_pi->step_r = l_step_r;
		l_current_pi->step_l = l_step_l;

		/* allocation for components and number of components has already been calculated by opj_pi_create */
		for
			(compno = 0; compno < l_current_pi->numcomps; ++compno)
		{
			opj_pi_resolution_t *l_res = l_current_comp->resolutions;
			l_encoding_value_ptr = l_tmp_ptr[compno];

			l_current_comp->dx = l_img_comp->dx;
			l_current_comp->dy = l_img_comp->dy;
			/* resolutions have already been initialized */
			for
				(resno = 0; resno < l_current_comp->numresolutions; resno++)
			{
				l_res->pdx = *(l_encoding_value_ptr++);
				l_res->pdy = *(l_encoding_value_ptr++);
				l_res->pw =  *(l_encoding_value_ptr++);
				l_res->ph =  *(l_encoding_value_ptr++);
				++l_res;
			}
			++l_current_comp;
			++l_img_comp;
			++l_tccp;
		}
		/* special treatment*/
		l_current_pi->include = (l_current_pi-1)->include;
		++l_current_pi;
	}
	opj_free(l_tmp_data);
	l_tmp_data = 00;
	opj_free(l_tmp_ptr);
	l_tmp_ptr = 00;
	if
		(l_tcp->POC)
	{
		opj_pi_update_decode_poc (l_pi,l_tcp,l_max_prec,l_max_res);
	}
	else
	{
		opj_pi_update_decode_not_poc(l_pi,l_tcp,l_max_prec,l_max_res);
	}
	return l_pi;
}



opj_pi_iterator_t *opj_pi_initialise_encode(const opj_image_t *p_image,
                                            opj_cp_t *p_cp,
                                            OPJ_UINT32 p_tile_no,
                                            J2K_T2_MODE p_t2_mode )
{
	/* loop*/
	OPJ_UINT32 pino;
	OPJ_UINT32 compno, resno;

	/* to store w, h, dx and dy fro all components and resolutions*/
	OPJ_UINT32 * l_tmp_data;
	OPJ_UINT32 ** l_tmp_ptr;

	/* encoding prameters to set*/
	OPJ_UINT32 l_max_res;
	OPJ_UINT32 l_max_prec;
	OPJ_INT32 l_tx0,l_tx1,l_ty0,l_ty1;
	OPJ_UINT32 l_dx_min,l_dy_min;
	OPJ_UINT32 l_bound;
	OPJ_UINT32 l_step_p , l_step_c , l_step_r , l_step_l ;
	OPJ_UINT32 l_data_stride;

	/* pointers*/
	opj_pi_iterator_t *l_pi = 00;
	opj_tcp_t *l_tcp = 00;
	const opj_tccp_t *l_tccp = 00;
	opj_pi_comp_t *l_current_comp = 00;
	opj_image_comp_t * l_img_comp = 00;
	opj_pi_iterator_t * l_current_pi = 00;
	OPJ_UINT32 * l_encoding_value_ptr = 00;

	/* preconditions in debug*/
	assert(p_cp != 00);
	assert(p_image != 00);
	assert(p_tile_no < p_cp->tw * p_cp->th);

	/* initializations*/
	l_tcp = &p_cp->tcps[p_tile_no];
	l_bound = l_tcp->numpocs+1;

	l_data_stride = 4 * OPJ_J2K_MAXRLVLS;
	l_tmp_data = (OPJ_UINT32*)opj_malloc(
		l_data_stride * p_image->numcomps * sizeof(OPJ_UINT32));
	if (! l_tmp_data) {
		return 00;
	}

	l_tmp_ptr = (OPJ_UINT32**)opj_malloc(
		p_image->numcomps * sizeof(OPJ_UINT32 *));
	if (! l_tmp_ptr) {
		opj_free(l_tmp_data);
		return 00;
	}

	/* memory allocation for pi*/
	l_pi = opj_pi_create(p_image,p_cp,p_tile_no);
	if (!l_pi) {
		opj_free(l_tmp_data);
		opj_free(l_tmp_ptr);
		return 00;
	}

	l_encoding_value_ptr = l_tmp_data;
	/* update pointer array*/
	for (compno = 0; compno < p_image->numcomps; ++compno) {
		l_tmp_ptr[compno] = l_encoding_value_ptr;
		l_encoding_value_ptr += l_data_stride;
	}

	/* get encoding parameters*/
	opj_get_all_encoding_parameters(p_image,p_cp,p_tile_no,&l_tx0,&l_tx1,&l_ty0,&l_ty1,&l_dx_min,&l_dy_min,&l_max_prec,&l_max_res,l_tmp_ptr);

	/* step calculations*/
	l_step_p = 1;
	l_step_c = l_max_prec * l_step_p;
	l_step_r = p_image->numcomps * l_step_c;
	l_step_l = l_max_res * l_step_r;

	/* set values for first packet iterator*/
	l_pi->tp_on = (OPJ_BYTE)p_cp->m_specific_param.m_enc.m_tp_on;
	l_current_pi = l_pi;

	/* memory allocation for include*/
	l_current_pi->include = (OPJ_INT16*) opj_calloc(l_tcp->numlayers * l_step_l, sizeof(OPJ_INT16));
	if (!l_current_pi->include) {
		opj_free(l_tmp_data);
		opj_free(l_tmp_ptr);
		opj_pi_destroy(l_pi, l_bound);
		return 00;
	}

	/* special treatment for the first packet iterator*/
	l_current_comp = l_current_pi->comps;
	l_img_comp = p_image->comps;
	l_tccp = l_tcp->tccps;
	l_current_pi->tx0 = l_tx0;
	l_current_pi->ty0 = l_ty0;
	l_current_pi->tx1 = l_tx1;
	l_current_pi->ty1 = l_ty1;
	l_current_pi->dx = l_dx_min;
	l_current_pi->dy = l_dy_min;
	l_current_pi->step_p = l_step_p;
	l_current_pi->step_c = l_step_c;
	l_current_pi->step_r = l_step_r;
	l_current_pi->step_l = l_step_l;

	/* allocation for components and number of components has already been calculated by opj_pi_create */
	for (compno = 0; compno < l_current_pi->numcomps; ++compno) {
		opj_pi_resolution_t *l_res = l_current_comp->resolutions;
		l_encoding_value_ptr = l_tmp_ptr[compno];

		l_current_comp->dx = l_img_comp->dx;
		l_current_comp->dy = l_img_comp->dy;

		/* resolutions have already been initialized */
		for (resno = 0; resno < l_current_comp->numresolutions; resno++) {
			l_res->pdx = *(l_encoding_value_ptr++);
			l_res->pdy = *(l_encoding_value_ptr++);
			l_res->pw =  *(l_encoding_value_ptr++);
			l_res->ph =  *(l_encoding_value_ptr++);
			++l_res;
		}

		++l_current_comp;
		++l_img_comp;
		++l_tccp;
	}
	++l_current_pi;

	for (pino = 1 ; pino<l_bound ; ++pino ) {
		l_current_comp = l_current_pi->comps;
		l_img_comp = p_image->comps;
		l_tccp = l_tcp->tccps;

		l_current_pi->tx0 = l_tx0;
		l_current_pi->ty0 = l_ty0;
		l_current_pi->tx1 = l_tx1;
		l_current_pi->ty1 = l_ty1;
		l_current_pi->dx = l_dx_min;
		l_current_pi->dy = l_dy_min;
		l_current_pi->step_p = l_step_p;
		l_current_pi->step_c = l_step_c;
		l_current_pi->step_r = l_step_r;
		l_current_pi->step_l = l_step_l;

		/* allocation for components and number of components has already been calculated by opj_pi_create */
		for (compno = 0; compno < l_current_pi->numcomps; ++compno) {
			opj_pi_resolution_t *l_res = l_current_comp->resolutions;
			l_encoding_value_ptr = l_tmp_ptr[compno];

			l_current_comp->dx = l_img_comp->dx;
			l_current_comp->dy = l_img_comp->dy;
			/* resolutions have already been initialized */
			for (resno = 0; resno < l_current_comp->numresolutions; resno++) {
				l_res->pdx = *(l_encoding_value_ptr++);
				l_res->pdy = *(l_encoding_value_ptr++);
				l_res->pw =  *(l_encoding_value_ptr++);
				l_res->ph =  *(l_encoding_value_ptr++);
				++l_res;
			}
			++l_current_comp;
			++l_img_comp;
			++l_tccp;
		}

		/* special treatment*/
		l_current_pi->include = (l_current_pi-1)->include;
		++l_current_pi;
	}

	opj_free(l_tmp_data);
	l_tmp_data = 00;
	opj_free(l_tmp_ptr);
	l_tmp_ptr = 00;

    if (l_tcp->POC && (OPJ_IS_CINEMA(p_cp->rsiz) || p_t2_mode == FINAL_PASS)) {
		opj_pi_update_encode_poc_and_final(p_cp,p_tile_no,l_tx0,l_tx1,l_ty0,l_ty1,l_max_prec,l_max_res,l_dx_min,l_dy_min);
	}
	else {
		opj_pi_update_encode_not_poc(p_cp,p_image->numcomps,p_tile_no,l_tx0,l_tx1,l_ty0,l_ty1,l_max_prec,l_max_res,l_dx_min,l_dy_min);
	}

	return l_pi;
}

void opj_pi_create_encode( 	opj_pi_iterator_t *pi,
							opj_cp_t *cp,
							OPJ_UINT32 tileno,
							OPJ_UINT32 pino,
							OPJ_UINT32 tpnum,
							OPJ_INT32 tppos,
							J2K_T2_MODE t2_mode)
{
	const OPJ_CHAR *prog;
	OPJ_INT32 i;
	OPJ_UINT32 incr_top=1,resetX=0;
	opj_tcp_t *tcps =&cp->tcps[tileno];
	opj_poc_t *tcp= &tcps->pocs[pino];

	prog = opj_j2k_convert_progression_order(tcp->prg);

	pi[pino].first = 1;
	pi[pino].poc.prg = tcp->prg;

    if(!(cp->m_specific_param.m_enc.m_tp_on && ((!OPJ_IS_CINEMA(cp->rsiz) && (t2_mode == FINAL_PASS)) || OPJ_IS_CINEMA(cp->rsiz)))){
		pi[pino].poc.resno0 = tcp->resS;
		pi[pino].poc.resno1 = tcp->resE;
		pi[pino].poc.compno0 = tcp->compS;
		pi[pino].poc.compno1 = tcp->compE;
		pi[pino].poc.layno0 = tcp->layS;
		pi[pino].poc.layno1 = tcp->layE;
		pi[pino].poc.precno0 = tcp->prcS;
		pi[pino].poc.precno1 = tcp->prcE;
		pi[pino].poc.tx0 = (OPJ_INT32)tcp->txS;
		pi[pino].poc.ty0 = (OPJ_INT32)tcp->tyS;
		pi[pino].poc.tx1 = (OPJ_INT32)tcp->txE;
		pi[pino].poc.ty1 = (OPJ_INT32)tcp->tyE;
	}else {
		for(i=tppos+1;i<4;i++){
			switch(prog[i]){
			case 'R':
				pi[pino].poc.resno0 = tcp->resS;
				pi[pino].poc.resno1 = tcp->resE;
				break;
			case 'C':
				pi[pino].poc.compno0 = tcp->compS;
				pi[pino].poc.compno1 = tcp->compE;
				break;
			case 'L':
				pi[pino].poc.layno0 = tcp->layS;
				pi[pino].poc.layno1 = tcp->layE;
				break;
			case 'P':
				switch(tcp->prg){
				case OPJ_LRCP:
				case OPJ_RLCP:
					pi[pino].poc.precno0 = tcp->prcS;
					pi[pino].poc.precno1 = tcp->prcE;
					break;
				default:
					pi[pino].poc.tx0 = (OPJ_INT32)tcp->txS;
					pi[pino].poc.ty0 = (OPJ_INT32)tcp->tyS;
					pi[pino].poc.tx1 = (OPJ_INT32)tcp->txE;
					pi[pino].poc.ty1 = (OPJ_INT32)tcp->tyE;
					break;
				}
				break;
			}
		}

		if(tpnum==0){
			for(i=tppos;i>=0;i--){
				switch(prog[i]){
				case 'C':
					tcp->comp_t = tcp->compS;
					pi[pino].poc.compno0 = tcp->comp_t;
					pi[pino].poc.compno1 = tcp->comp_t+1;
					tcp->comp_t+=1;
					break;
				case 'R':
					tcp->res_t = tcp->resS;
					pi[pino].poc.resno0 = tcp->res_t;
					pi[pino].poc.resno1 = tcp->res_t+1;
					tcp->res_t+=1;
					break;
				case 'L':
					tcp->lay_t = tcp->layS;
					pi[pino].poc.layno0 = tcp->lay_t;
					pi[pino].poc.layno1 = tcp->lay_t+1;
					tcp->lay_t+=1;
					break;
				case 'P':
					switch(tcp->prg){
					case OPJ_LRCP:
					case OPJ_RLCP:
						tcp->prc_t = tcp->prcS;
						pi[pino].poc.precno0 = tcp->prc_t;
						pi[pino].poc.precno1 = tcp->prc_t+1;
						tcp->prc_t+=1;
						break;
					default:
						tcp->tx0_t = tcp->txS;
						tcp->ty0_t = tcp->tyS;
						pi[pino].poc.tx0 = (OPJ_INT32)tcp->tx0_t;
						pi[pino].poc.tx1 = (OPJ_INT32)(tcp->tx0_t + tcp->dx - (tcp->tx0_t % tcp->dx));
						pi[pino].poc.ty0 = (OPJ_INT32)tcp->ty0_t;
						pi[pino].poc.ty1 = (OPJ_INT32)(tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy));
						tcp->tx0_t = (OPJ_UINT32)pi[pino].poc.tx1;
						tcp->ty0_t = (OPJ_UINT32)pi[pino].poc.ty1;
						break;
					}
					break;
				}
			}
			incr_top=1;
		}else{
			for(i=tppos;i>=0;i--){
				switch(prog[i]){
				case 'C':
					pi[pino].poc.compno0 = tcp->comp_t-1;
					pi[pino].poc.compno1 = tcp->comp_t;
					break;
				case 'R':
					pi[pino].poc.resno0 = tcp->res_t-1;
					pi[pino].poc.resno1 = tcp->res_t;
					break;
				case 'L':
					pi[pino].poc.layno0 = tcp->lay_t-1;
					pi[pino].poc.layno1 = tcp->lay_t;
					break;
				case 'P':
					switch(tcp->prg){
					case OPJ_LRCP:
					case OPJ_RLCP:
						pi[pino].poc.precno0 = tcp->prc_t-1;
						pi[pino].poc.precno1 = tcp->prc_t;
						break;
					default:
						pi[pino].poc.tx0 = (OPJ_INT32)(tcp->tx0_t - tcp->dx - (tcp->tx0_t % tcp->dx));
						pi[pino].poc.tx1 = (OPJ_INT32)tcp->tx0_t ;
						pi[pino].poc.ty0 = (OPJ_INT32)(tcp->ty0_t - tcp->dy - (tcp->ty0_t % tcp->dy));
						pi[pino].poc.ty1 = (OPJ_INT32)tcp->ty0_t ;
						break;
					}
					break;
				}
				if(incr_top==1){
					switch(prog[i]){
					case 'R':
						if(tcp->res_t==tcp->resE){
							if(opj_pi_check_next_level(i-1,cp,tileno,pino,prog)){
								tcp->res_t = tcp->resS;
								pi[pino].poc.resno0 = tcp->res_t;
								pi[pino].poc.resno1 = tcp->res_t+1;
								tcp->res_t+=1;
								incr_top=1;
							}else{
								incr_top=0;
							}
						}else{
							pi[pino].poc.resno0 = tcp->res_t;
							pi[pino].poc.resno1 = tcp->res_t+1;
							tcp->res_t+=1;
							incr_top=0;
						}
						break;
					case 'C':
						if(tcp->comp_t ==tcp->compE){
							if(opj_pi_check_next_level(i-1,cp,tileno,pino,prog)){
								tcp->comp_t = tcp->compS;
								pi[pino].poc.compno0 = tcp->comp_t;
								pi[pino].poc.compno1 = tcp->comp_t+1;
								tcp->comp_t+=1;
								incr_top=1;
							}else{
								incr_top=0;
							}
						}else{
							pi[pino].poc.compno0 = tcp->comp_t;
							pi[pino].poc.compno1 = tcp->comp_t+1;
							tcp->comp_t+=1;
							incr_top=0;
						}
						break;
					case 'L':
						if(tcp->lay_t == tcp->layE){
							if(opj_pi_check_next_level(i-1,cp,tileno,pino,prog)){
								tcp->lay_t = tcp->layS;
								pi[pino].poc.layno0 = tcp->lay_t;
								pi[pino].poc.layno1 = tcp->lay_t+1;
								tcp->lay_t+=1;
								incr_top=1;
							}else{
								incr_top=0;
							}
						}else{
							pi[pino].poc.layno0 = tcp->lay_t;
							pi[pino].poc.layno1 = tcp->lay_t+1;
							tcp->lay_t+=1;
							incr_top=0;
						}
						break;
					case 'P':
						switch(tcp->prg){
						case OPJ_LRCP:
						case OPJ_RLCP:
							if(tcp->prc_t == tcp->prcE){
								if(opj_pi_check_next_level(i-1,cp,tileno,pino,prog)){
									tcp->prc_t = tcp->prcS;
									pi[pino].poc.precno0 = tcp->prc_t;
									pi[pino].poc.precno1 = tcp->prc_t+1;
									tcp->prc_t+=1;
									incr_top=1;
								}else{
									incr_top=0;
								}
							}else{
								pi[pino].poc.precno0 = tcp->prc_t;
								pi[pino].poc.precno1 = tcp->prc_t+1;
								tcp->prc_t+=1;
								incr_top=0;
							}
							break;
						default:
							if(tcp->tx0_t >= tcp->txE){
								if(tcp->ty0_t >= tcp->tyE){
									if(opj_pi_check_next_level(i-1,cp,tileno,pino,prog)){
										tcp->ty0_t = tcp->tyS;
										pi[pino].poc.ty0 = (OPJ_INT32)tcp->ty0_t;
										pi[pino].poc.ty1 = (OPJ_INT32)(tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy));
										tcp->ty0_t = (OPJ_UINT32)pi[pino].poc.ty1;
										incr_top=1;resetX=1;
									}else{
										incr_top=0;resetX=0;
									}
								}else{
									pi[pino].poc.ty0 = (OPJ_INT32)tcp->ty0_t;
									pi[pino].poc.ty1 = (OPJ_INT32)(tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy));
									tcp->ty0_t = (OPJ_UINT32)pi[pino].poc.ty1;
									incr_top=0;resetX=1;
								}
								if(resetX==1){
									tcp->tx0_t = tcp->txS;
									pi[pino].poc.tx0 = (OPJ_INT32)tcp->tx0_t;
									pi[pino].poc.tx1 = (OPJ_INT32)(tcp->tx0_t + tcp->dx- (tcp->tx0_t % tcp->dx));
									tcp->tx0_t = (OPJ_UINT32)pi[pino].poc.tx1;
								}
							}else{
								pi[pino].poc.tx0 = (OPJ_INT32)tcp->tx0_t;
								pi[pino].poc.tx1 = (OPJ_INT32)(tcp->tx0_t + tcp->dx- (tcp->tx0_t % tcp->dx));
								tcp->tx0_t = (OPJ_UINT32)pi[pino].poc.tx1;
								incr_top=0;
							}
							break;
						}
						break;
					}
				}
			}
		}
	}
}

void opj_pi_destroy(opj_pi_iterator_t *p_pi,
                    OPJ_UINT32 p_nb_elements)
{
	OPJ_UINT32 compno, pino;
	opj_pi_iterator_t *l_current_pi = p_pi;
    if (p_pi) {
		if (p_pi->include) {
			opj_free(p_pi->include);
			p_pi->include = 00;
		}
		for (pino = 0; pino < p_nb_elements; ++pino){
			if(l_current_pi->comps) {
				opj_pi_comp_t *l_current_component = l_current_pi->comps;
                for (compno = 0; compno < l_current_pi->numcomps; compno++){
                    if(l_current_component->resolutions) {
						opj_free(l_current_component->resolutions);
						l_current_component->resolutions = 00;
					}

					++l_current_component;
				}
				opj_free(l_current_pi->comps);
				l_current_pi->comps = 0;
			}
			++l_current_pi;
		}
		opj_free(p_pi);
	}
}



void opj_pi_update_encoding_parameters(	const opj_image_t *p_image,
                                        opj_cp_t *p_cp,
                                        OPJ_UINT32 p_tile_no )
{
	/* encoding parameters to set */
	OPJ_UINT32 l_max_res;
	OPJ_UINT32 l_max_prec;
	OPJ_INT32 l_tx0,l_tx1,l_ty0,l_ty1;
	OPJ_UINT32 l_dx_min,l_dy_min;

	/* pointers */
	opj_tcp_t *l_tcp = 00;

	/* preconditions */
	assert(p_cp != 00);
	assert(p_image != 00);
	assert(p_tile_no < p_cp->tw * p_cp->th);

	l_tcp = &(p_cp->tcps[p_tile_no]);

	/* get encoding parameters */
	opj_get_encoding_parameters(p_image,p_cp,p_tile_no,&l_tx0,&l_tx1,&l_ty0,&l_ty1,&l_dx_min,&l_dy_min,&l_max_prec,&l_max_res);

	if (l_tcp->POC) {
		opj_pi_update_encode_poc_and_final(p_cp,p_tile_no,l_tx0,l_tx1,l_ty0,l_ty1,l_max_prec,l_max_res,l_dx_min,l_dy_min);
	}
	else {
		opj_pi_update_encode_not_poc(p_cp,p_image->numcomps,p_tile_no,l_tx0,l_tx1,l_ty0,l_ty1,l_max_prec,l_max_res,l_dx_min,l_dy_min);
	}
}

OPJ_BOOL opj_pi_next(opj_pi_iterator_t * pi) {
	switch (pi->poc.prg) {
		case OPJ_LRCP:
			return opj_pi_next_lrcp(pi);
		case OPJ_RLCP:
			return opj_pi_next_rlcp(pi);
		case OPJ_RPCL:
			return opj_pi_next_rpcl(pi);
		case OPJ_PCRL:
			return opj_pi_next_pcrl(pi);
		case OPJ_CPRL:
			return opj_pi_next_cprl(pi);
		case OPJ_PROG_UNKNOWN:
			return OPJ_FALSE;
	}
	
	return OPJ_FALSE;
}
