+ return OPJ_FALSE;
+}
+
+void pi_update_encoding_parameters( const opj_image_t *p_image,
+ opj_cp_v2_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_v2_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 */
+ 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) {
+ 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 {
+ 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);
+ }
+
+}
+
+void get_encoding_parameters( const opj_image_t *p_image,
+ const opj_cp_v2_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_v2_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 = int_max(p_cp->tx0 + p * p_cp->tdx, p_image->x0);
+ *p_tx1 = int_min(p_cp->tx0 + (p + 1) * p_cp->tdx, p_image->x1);
+ *p_ty0 = int_max(p_cp->ty0 + q * p_cp->tdy, p_image->y0);
+ *p_ty1 = int_min(p_cp->ty0 + (q + 1) * p_cp->tdy, 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 = int_ceildiv(*p_tx0, l_img_comp->dx);
+ l_tcy0 = int_ceildiv(*p_ty0, l_img_comp->dy);
+ l_tcx1 = int_ceildiv(*p_tx1, l_img_comp->dx);
+ l_tcy1 = int_ceildiv(*p_ty1, 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 * (1 << (l_pdx + l_tccp->numresolutions - 1 - resno));
+ l_dy = l_img_comp->dy * (1 << (l_pdy + l_tccp->numresolutions - 1 - resno));
+
+ /* take the minimum size for dx for each comp and resolution */
+ *p_dx_min = uint_min(*p_dx_min, l_dx);
+ *p_dy_min = uint_min(*p_dy_min, l_dy);
+
+ /* various calculations of extents */
+ l_level_no = l_tccp->numresolutions - 1 - resno;
+
+ l_rx0 = int_ceildivpow2(l_tcx0, l_level_no);
+ l_ry0 = int_ceildivpow2(l_tcy0, l_level_no);
+ l_rx1 = int_ceildivpow2(l_tcx1, l_level_no);
+ l_ry1 = int_ceildivpow2(l_tcy1, l_level_no);
+
+ l_px0 = int_floordivpow2(l_rx0, l_pdx) << l_pdx;
+ l_py0 = int_floordivpow2(l_ry0, l_pdy) << l_pdy;
+ l_px1 = int_ceildivpow2(l_rx1, l_pdx) << l_pdx;
+
+ py1 = int_ceildivpow2(l_ry1, l_pdy) << l_pdy;
+
+ l_pw = (l_rx0==l_rx1)?0:((l_px1 - l_px0) >> l_pdx);
+ l_ph = (l_ry0==l_ry1)?0:((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;
+ }
+}
+
+/**
+ * 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.
+ */
+void get_all_encoding_parameters(
+ const opj_image_t *p_image,
+ const opj_cp_v2_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_v2_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;
+
+ /* 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 */
+ *p_tx0 = int_max(p_cp->tx0 + p * p_cp->tdx, p_image->x0);
+ *p_tx1 = int_min(p_cp->tx0 + (p + 1) * p_cp->tdx, p_image->x1);
+ *p_ty0 = int_max(p_cp->ty0 + q * p_cp->tdy, p_image->y0);
+ *p_ty1 = int_min(p_cp->ty0 + (q + 1) * 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 = int_ceildiv(*p_tx0, l_img_comp->dx);
+ l_tcy0 = int_ceildiv(*p_ty0, l_img_comp->dy);
+ l_tcx1 = int_ceildiv(*p_tx1, l_img_comp->dx);
+ l_tcy1 = int_ceildiv(*p_ty1, 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 * (1 << (l_pdx + l_level_no));
+ l_dy = l_img_comp->dy * (1 << (l_pdy + l_level_no));
+ /* take the minimum size for l_dx for each comp and resolution*/
+ *p_dx_min = int_min(*p_dx_min, l_dx);
+ *p_dy_min = int_min(*p_dy_min, l_dy);
+ /* various calculations of extents*/
+
+ l_rx0 = int_ceildivpow2(l_tcx0, l_level_no);
+ l_ry0 = int_ceildivpow2(l_tcy0, l_level_no);
+ l_rx1 = int_ceildivpow2(l_tcx1, l_level_no);
+ l_ry1 = int_ceildivpow2(l_tcy1, l_level_no);
+ l_px0 = int_floordivpow2(l_rx0, l_pdx) << l_pdx;
+ l_py0 = int_floordivpow2(l_ry0, l_pdy) << l_pdy;
+ l_px1 = int_ceildivpow2(l_rx1, l_pdx) << l_pdx;
+ py1 = int_ceildivpow2(l_ry1, l_pdy) << l_pdy;
+ l_pw = (l_rx0==l_rx1)?0:((l_px1 - l_px0) >> l_pdx);
+ l_ph = (l_ry0==l_ry1)?0:((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;
+ }
+}
+
+opj_pi_iterator_t * pi_create( const opj_image_t *image,
+ const opj_cp_v2_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_v2_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;
+ }
+ memset(l_pi,0,l_poc_bound * sizeof(opj_pi_iterator_t));
+
+ 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) {
+ pi_destroy_v2(l_pi, l_poc_bound);
+ return NULL;
+ }
+
+ l_current_pi->numcomps = image->numcomps;
+ memset(l_current_pi->comps,0,image->numcomps * sizeof(opj_pi_comp_t));
+
+ 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_malloc(tccp->numresolutions * sizeof(opj_pi_resolution_t));
+ if (!comp->resolutions) {
+ pi_destroy_v2(l_pi, l_poc_bound);
+ return 00;
+ }
+
+ comp->numresolutions = tccp->numresolutions;
+ memset(comp->resolutions,0,tccp->numresolutions * sizeof(opj_pi_resolution_t));
+ }
+ ++l_current_pi;
+ }
+ return l_pi;
+}
+
+void pi_update_encode_poc_and_final (opj_cp_v2_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_v2_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;
+
+ 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 = p_tx0;
+ l_current_poc->txE = p_tx1;
+ l_current_poc->tyS = p_ty0;
+ l_current_poc->tyE = 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 = p_tx0;
+ l_current_poc->txE = p_tx1;
+ l_current_poc->tyS = p_ty0;
+ l_current_poc->tyE = p_ty1;
+ l_current_poc->dx = p_dx_min;
+ l_current_poc->dy = p_dy_min;
+ ++ l_current_poc;
+ }