Defines three new functions
[openjpeg.git] / src / lib / openjp2 / tcd.c
index 19a0e1724f5634c746c074dc70f0febf421c602e..08d97c78ab34c308a62cc26240c5d78be1e8003e 100644 (file)
@@ -120,10 +120,15 @@ static OPJ_BOOL opj_tcd_code_block_dec_allocate (opj_tcd_cblk_dec_t * p_code_blo
 static void opj_tcd_code_block_dec_deallocate (opj_tcd_precinct_t * p_precinct);
 
 /**
- * Allocates memory for an encoding code block.
+ * 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.
  */
@@ -670,6 +675,7 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_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 */
@@ -696,10 +702,13 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
        /*fprintf(stderr, "Tile coordinate = %d,%d\n", p, q);*/
        
        /* 4 borders of the tile rescale on the image if necessary */
-       l_tile->x0 = opj_int_max((OPJ_INT32)(l_cp->tx0 + p * l_cp->tdx), (OPJ_INT32)l_image->x0);
-       l_tile->y0 = opj_int_max((OPJ_INT32)(l_cp->ty0 + q * l_cp->tdy), (OPJ_INT32)l_image->y0);
-       l_tile->x1 = opj_int_min((OPJ_INT32)(l_cp->tx0 + (p + 1) * l_cp->tdx), (OPJ_INT32)l_image->x1);
-       l_tile->y1 = opj_int_min((OPJ_INT32)(l_cp->ty0 + (q + 1) * l_cp->tdy), (OPJ_INT32)l_image->y1);
+       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) {
                fprintf(stderr, "tiles require at least one resolution\n");
@@ -718,7 +727,19 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
                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);*/
                
-               l_data_size = (OPJ_UINT32)(l_tilec->x1 - l_tilec->x0) * (OPJ_UINT32)(l_tilec->y1 - l_tilec->y0) * (OPJ_UINT32)sizeof(OPJ_UINT32 );
+               /* 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)) {
+                       /* TODO event */
+                       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) {
+                       /* TODO event */
+                       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;
@@ -992,6 +1013,10 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
                                                        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;
                                                        
@@ -1031,39 +1056,56 @@ OPJ_BOOL opj_tcd_init_decode_tile (opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no)
 }
 
 /**
- * Allocates memory for an encoding code block.
+ * Allocates memory for an encoding code block (but not data memory).
  */
-OPJ_BOOL opj_tcd_code_block_enc_allocate (opj_tcd_cblk_enc_t * p_code_block)
+static OPJ_BOOL opj_tcd_code_block_enc_allocate (opj_tcd_cblk_enc_t * p_code_block)
 {
-        if (! p_code_block->data) {
-
-                p_code_block->data = (OPJ_BYTE*) opj_malloc(OPJ_J2K_DEFAULT_CBLK_DATA_SIZE*2); /*why +1 ?*/
-                if(! p_code_block->data) {
-                        return OPJ_FALSE;
-                }
-
-                p_code_block->data[0] = 0;
-                p_code_block->data+=1;
-
-                /* 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;
-                }
-
-                p_code_block->passes = (opj_tcd_pass_t*) opj_calloc(100, sizeof(opj_tcd_pass_t));
-                if (! p_code_block->passes) {
-                        return OPJ_FALSE;
-                }
-        }
+       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;
+}
 
-        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.
  */
-OPJ_BOOL opj_tcd_code_block_dec_allocate (opj_tcd_cblk_dec_t * p_code_block)
+static OPJ_BOOL opj_tcd_code_block_dec_allocate (opj_tcd_cblk_dec_t * p_code_block)
 {
         if (! p_code_block->data) {
 
@@ -1420,7 +1462,7 @@ OPJ_BOOL opj_tcd_update_tile_data ( opj_tcd_t *p_tcd,
 
 
 
-void opj_tcd_free_tile(opj_tcd_t *p_tcd)
+static void opj_tcd_free_tile(opj_tcd_t *p_tcd)
 {
         OPJ_UINT32 compno, resno, bandno, precno;
         opj_tcd_tile_t *l_tile = 00;
@@ -1503,7 +1545,7 @@ void opj_tcd_free_tile(opj_tcd_t *p_tcd)
 }
 
 
-OPJ_BOOL opj_tcd_t2_decode (opj_tcd_t *p_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,
@@ -1535,7 +1577,7 @@ OPJ_BOOL opj_tcd_t2_decode (opj_tcd_t *p_tcd,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_tcd_t1_decode ( opj_tcd_t *p_tcd )
+static OPJ_BOOL opj_tcd_t1_decode ( opj_tcd_t *p_tcd )
 {
         OPJ_UINT32 compno;
         opj_t1_t * l_t1;
@@ -1565,7 +1607,7 @@ OPJ_BOOL opj_tcd_t1_decode ( opj_tcd_t *p_tcd )
 }
 
 
-OPJ_BOOL opj_tcd_dwt_decode ( opj_tcd_t *p_tcd )
+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;
@@ -1605,7 +1647,7 @@ OPJ_BOOL opj_tcd_dwt_decode ( opj_tcd_t *p_tcd )
 
         return OPJ_TRUE;
 }
-OPJ_BOOL opj_tcd_mct_decode ( opj_tcd_t *p_tcd )
+static OPJ_BOOL opj_tcd_mct_decode ( opj_tcd_t *p_tcd )
 {
         opj_tcd_tile_t * l_tile = p_tcd->tcd_image->tiles;
         opj_tcp_t * l_tcp = p_tcd->tcp;
@@ -1683,7 +1725,7 @@ OPJ_BOOL opj_tcd_mct_decode ( opj_tcd_t *p_tcd )
 }
 
 
-OPJ_BOOL opj_tcd_dc_level_shift_decode ( opj_tcd_t *p_tcd )
+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;
@@ -1733,7 +1775,7 @@ OPJ_BOOL opj_tcd_dc_level_shift_decode ( opj_tcd_t *p_tcd )
                         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)lrintf(l_value) + l_tccp->m_dc_level_shift, l_min, l_max); ;
+                                        *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;
@@ -1753,7 +1795,7 @@ OPJ_BOOL opj_tcd_dc_level_shift_decode ( opj_tcd_t *p_tcd )
 /**
  * Deallocates the encoding data of the given precinct.
  */
-void opj_tcd_code_block_dec_deallocate (opj_tcd_precinct_t * p_precinct)
+static void opj_tcd_code_block_dec_deallocate (opj_tcd_precinct_t * p_precinct)
 {
         OPJ_UINT32 cblkno , l_nb_code_blocks;
 
@@ -1791,7 +1833,7 @@ void opj_tcd_code_block_dec_deallocate (opj_tcd_precinct_t * p_precinct)
 /**
  * Deallocates the encoding data of the given precinct.
  */
-void opj_tcd_code_block_enc_deallocate (opj_tcd_precinct_t * p_precinct)
+static void opj_tcd_code_block_enc_deallocate (opj_tcd_precinct_t * p_precinct)
 {       
         OPJ_UINT32 cblkno , l_nb_code_blocks;
 
@@ -1852,7 +1894,7 @@ OPJ_UINT32 opj_tcd_get_encoded_tile_size ( opj_tcd_t *p_tcd )
         return l_data_size;
 }
                 
-OPJ_BOOL opj_tcd_dc_level_shift_encode ( opj_tcd_t *p_tcd )
+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;
@@ -1892,7 +1934,7 @@ OPJ_BOOL opj_tcd_dc_level_shift_encode ( opj_tcd_t *p_tcd )
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_tcd_mct_encode ( opj_tcd_t *p_tcd )
+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;
@@ -1947,7 +1989,7 @@ OPJ_BOOL opj_tcd_mct_encode ( opj_tcd_t *p_tcd )
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_tcd_dwt_encode ( opj_tcd_t *p_tcd )
+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;
@@ -1973,10 +2015,11 @@ OPJ_BOOL opj_tcd_dwt_encode ( opj_tcd_t *p_tcd )
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_tcd_t1_encode ( opj_tcd_t *p_tcd )
+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);
@@ -1985,6 +2028,7 @@ OPJ_BOOL opj_tcd_t1_encode ( opj_tcd_t *p_tcd )
         }
 
         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();
@@ -1994,10 +2038,11 @@ OPJ_BOOL opj_tcd_t1_encode ( opj_tcd_t *p_tcd )
                 }
         }
         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)) {
+        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;
         }
@@ -2007,7 +2052,7 @@ OPJ_BOOL opj_tcd_t1_encode ( opj_tcd_t *p_tcd )
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_tcd_t2_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,
@@ -2045,7 +2090,7 @@ OPJ_BOOL opj_tcd_t2_encode (opj_tcd_t *p_tcd,
 }
 
 
-OPJ_BOOL opj_tcd_rate_allocate_encode(  opj_tcd_t *p_tcd,
+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 )