Fix unsigned int overflow reported by UBSan (#761)
[openjpeg.git] / src / lib / openjp2 / pi.c
index 2606051b030a3c244e6b8ec34a964301799d6f66..cffad6684f0fc1f7521461c15c5135c19fb57bc6 100644 (file)
@@ -1,9 +1,15 @@
 /*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
+ * 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 and Antonin Descampe
+ * 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.
@@ -130,10 +136,10 @@ static void opj_pi_update_encode_not_poc (  opj_cp_t *p_cp,
  * @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_max_prec              pointer that will hold the maximum precision for all the bands of the tile
+ * @param      p_max_res               pointer that will hold the maximum number of resolutions for all the poc inside the tile.
+ * @param      p_dx_min                        pointer that will hold the minimum dx of all the components of all the resolutions for the tile.
+ * @param      p_dy_min                        pointer that will hold 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,
@@ -161,10 +167,10 @@ static void opj_get_encoding_parameters(const opj_image_t *p_image,
  * @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_max_prec              pointer that will hold the maximum precision for all the bands of the tile
+ * @param      p_max_res               pointer that will hold the maximum number of resolutions for all the poc inside the tile.
+ * @param      p_dx_min                pointer that will hold the minimum dx of all the components of all the resolutions for the tile.
+ * @param      p_dy_min                pointer that will hold 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,
@@ -208,7 +214,7 @@ static void opj_pi_update_decode_poc (  opj_pi_iterator_t * p_pi,
 /**
  * FIXME DOC
  */
-OPJ_BOOL opj_pi_check_next_level(      OPJ_INT32 pos,
+static OPJ_BOOL opj_pi_check_next_level(       OPJ_INT32 pos,
                                                                opj_cp_t *cp,
                                                                OPJ_UINT32 tileno,
                                                                OPJ_UINT32 pino,
@@ -224,7 +230,7 @@ OPJ_BOOL opj_pi_check_next_level(   OPJ_INT32 pos,
 ==========================================================
 */
 
-OPJ_BOOL opj_pi_next_lrcp(opj_pi_iterator_t * pi) {
+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;
@@ -264,7 +270,7 @@ LABEL_SKIP:;
        return OPJ_FALSE;
 }
 
-OPJ_BOOL opj_pi_next_rlcp(opj_pi_iterator_t * pi) {
+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;
@@ -303,7 +309,7 @@ LABEL_SKIP:;
        return OPJ_FALSE;
 }
 
-OPJ_BOOL opj_pi_next_rpcl(opj_pi_iterator_t * pi) {
+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;
@@ -386,7 +392,7 @@ LABEL_SKIP:;
        return OPJ_FALSE;
 }
 
-OPJ_BOOL opj_pi_next_pcrl(opj_pi_iterator_t * pi) {
+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;
@@ -467,7 +473,7 @@ LABEL_SKIP:;
        return OPJ_FALSE;
 }
 
-OPJ_BOOL opj_pi_next_cprl(opj_pi_iterator_t * pi) {
+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;
@@ -546,7 +552,7 @@ LABEL_SKIP:;
        return OPJ_FALSE;
 }
 
-void opj_get_encoding_parameters(      const opj_image_t *p_image,
+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,
@@ -660,7 +666,7 @@ void opj_get_encoding_parameters(   const opj_image_t *p_image,
 }
 
 
-void opj_get_all_encoding_parameters(   const opj_image_t *p_image,
+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,
@@ -687,6 +693,9 @@ void opj_get_all_encoding_parameters(   const opj_image_t *p_image,
        /* 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);
@@ -702,10 +711,12 @@ void opj_get_all_encoding_parameters(   const opj_image_t *p_image,
        q = tileno / p_cp->tw;
 
        /* here calculation of tx0, tx1, ty0, ty1, maxprec, l_dx and l_dy */
-       *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);
+       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;
@@ -736,10 +747,12 @@ void opj_get_all_encoding_parameters(   const opj_image_t *p_image,
                }
 
                /* use custom size for precincts*/
-               l_level_no = l_tccp->numresolutions - 1;
+               l_level_no = l_tccp->numresolutions;
                for (resno = 0; resno < l_tccp->numresolutions; ++resno) {
                        OPJ_UINT32 l_dx, l_dy;
 
+                       --l_level_no;
+                       
                        /* precinct width and height*/
                        l_pdx = l_tccp->prcw[resno];
                        l_pdy = l_tccp->prch[resno];
@@ -771,14 +784,13 @@ void opj_get_all_encoding_parameters(   const opj_image_t *p_image,
                                *p_max_prec = l_product;
                        }
 
-                       --l_level_no;
                }
                ++l_tccp;
                ++l_img_comp;
        }
 }
 
-opj_pi_iterator_t * opj_pi_create(     const opj_image_t *image,
+static opj_pi_iterator_t * opj_pi_create(      const opj_image_t *image,
                                     const opj_cp_t *cp,
                                     OPJ_UINT32 tileno )
 {
@@ -809,7 +821,6 @@ opj_pi_iterator_t * opj_pi_create(  const opj_image_t *image,
        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) {
@@ -821,28 +832,26 @@ opj_pi_iterator_t * opj_pi_create(        const opj_image_t *image,
                }
 
                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));
+                       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;
-                       memset(comp->resolutions,0,tccp->numresolutions * sizeof(opj_pi_resolution_t));
                }
                ++l_current_pi;
        }
        return l_pi;
 }
 
-void opj_pi_update_encode_poc_and_final (   opj_cp_t *p_cp,
+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,
@@ -920,7 +929,7 @@ void opj_pi_update_encode_poc_and_final (   opj_cp_t *p_cp,
        }
 }
 
-void opj_pi_update_encode_not_poc (    opj_cp_t *p_cp,
+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,
@@ -975,7 +984,7 @@ void opj_pi_update_encode_not_poc ( opj_cp_t *p_cp,
        }
 }
 
-void opj_pi_update_decode_poc (opj_pi_iterator_t * p_pi,
+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)
@@ -1017,7 +1026,7 @@ void opj_pi_update_decode_poc (opj_pi_iterator_t * p_pi,
        }
 }
 
-void opj_pi_update_decode_not_poc (opj_pi_iterator_t * p_pi,
+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)
@@ -1054,7 +1063,7 @@ void opj_pi_update_decode_not_poc (opj_pi_iterator_t * p_pi,
 
 
 
-OPJ_BOOL opj_pi_check_next_level(      OPJ_INT32 pos,
+static OPJ_BOOL opj_pi_check_next_level(       OPJ_INT32 pos,
                                                                opj_cp_t *cp,
                                                                OPJ_UINT32 tileno,
                                                                OPJ_UINT32 pino,
@@ -1102,7 +1111,8 @@ OPJ_BOOL opj_pi_check_next_level( OPJ_INT32 pos,
                            break;
                    case 'P':
                            switch(tcp->prg){
-                                   case OPJ_LRCP||OPJ_RLCP:
+                    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;
@@ -1236,7 +1246,6 @@ opj_pi_iterator_t *opj_pi_create_decode(opj_image_t *p_image,
                opj_pi_destroy(l_pi, l_bound);
                return 00;
        }
-       memset(l_current_pi->include,0, (l_tcp->numlayers + 1) * l_step_l* sizeof(OPJ_INT16));
 
        /* special treatment for the first packet iterator */
        l_current_comp = l_current_pi->comps;
@@ -1422,7 +1431,7 @@ opj_pi_iterator_t *opj_pi_initialise_encode(const opj_image_t *p_image,
        l_step_l = l_max_res * l_step_r;
 
        /* set values for first packet iterator*/
-       l_pi->tp_on = p_cp->m_specific_param.m_enc.m_tp_on;
+       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*/
@@ -1433,7 +1442,6 @@ opj_pi_iterator_t *opj_pi_initialise_encode(const opj_image_t *p_image,
                opj_pi_destroy(l_pi, l_bound);
                return 00;
        }
-       memset(l_current_pi->include,0,l_tcp->numlayers * l_step_l* sizeof(OPJ_INT16));
 
        /* special treatment for the first packet iterator*/
        l_current_comp = l_current_pi->comps;
@@ -1519,7 +1527,7 @@ opj_pi_iterator_t *opj_pi_initialise_encode(const opj_image_t *p_image,
        opj_free(l_tmp_ptr);
        l_tmp_ptr = 00;
 
-       if (l_tcp->POC && ( p_cp->m_specific_param.m_enc.m_cinema || p_t2_mode == FINAL_PASS)) {
+    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 {
@@ -1548,7 +1556,7 @@ void opj_pi_create_encode(        opj_pi_iterator_t *pi,
        pi[pino].first = 1;
        pi[pino].poc.prg = tcp->prg;
 
-       if(!(cp->m_specific_param.m_enc.m_tp_on && ((!cp->m_specific_param.m_enc.m_cinema && (t2_mode == FINAL_PASS)) || cp->m_specific_param.m_enc.m_cinema))){
+    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;