Make sure to allocate on 16bits alignement. Fix issue #624
[openjpeg.git] / src / lib / openjp2 / tcd.c
index e926d4f5bcf2109ec24e0fe6da5b150852411d5d..3feb74cae9d10889c3e8fe81fb8f51d48b575147 100644 (file)
@@ -107,7 +107,7 @@ void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_image_t * img) {
 /**
  * Initializes tile coding/decoding
  */
-static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no, OPJ_BOOL isEncoder, OPJ_FLOAT32 fraction, OPJ_SIZE_T sizeof_block);
+static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no, OPJ_BOOL isEncoder, OPJ_FLOAT32 fraction, OPJ_SIZE_T sizeof_block, opj_event_mgr_t* manager);
 
 /**
 * Allocates memory for a decoding code block.
@@ -146,13 +146,14 @@ static OPJ_BOOL opj_tcd_t2_decode ( opj_tcd_t *p_tcd,
                                     OPJ_BYTE * p_src_data,
                                     OPJ_UINT32 * p_data_read,
                                     OPJ_UINT32 p_max_src_size,
-                                    opj_codestream_index_t *p_cstr_index );
+                                    opj_codestream_index_t *p_cstr_index,
+                                    opj_event_mgr_t *p_manager);
 
 static OPJ_BOOL opj_tcd_t1_decode (opj_tcd_t *p_tcd);
 
 static OPJ_BOOL opj_tcd_dwt_decode (opj_tcd_t *p_tcd);
 
-static OPJ_BOOL opj_tcd_mct_decode (opj_tcd_t *p_tcd);
+static OPJ_BOOL opj_tcd_mct_decode (opj_tcd_t *p_tcd, opj_event_mgr_t *p_manager);
 
 static OPJ_BOOL opj_tcd_dc_level_shift_decode (opj_tcd_t *p_tcd);
 
@@ -267,7 +268,7 @@ void opj_tcd_makelayer( opj_tcd_t *tcd,
                                                                         n = passno + 1;
                                                                 continue;
                                                         }
-                                                        if (dd / dr >= thresh)
+                                                        if (thresh - (dd / dr) < DBL_EPSILON) /* do not rely on float equality, check with DBL_EPSILON margin */
                                                                 n = passno + 1;
                                                 }
 
@@ -625,7 +626,7 @@ void opj_tcd_destroy(opj_tcd_t *tcd) {
 OPJ_BOOL opj_alloc_tile_component_data(opj_tcd_tilecomp_t *l_tilec)
 {
        if ((l_tilec->data == 00) || ((l_tilec->data_size_needed > l_tilec->data_size) && (l_tilec->ownsData == OPJ_FALSE))) {
-               l_tilec->data = (OPJ_INT32 *) opj_malloc(l_tilec->data_size_needed);
+               l_tilec->data = (OPJ_INT32 *) opj_aligned_malloc(l_tilec->data_size_needed);
                if (! l_tilec->data ) {
                        return OPJ_FALSE;
                }
@@ -655,7 +656,7 @@ OPJ_BOOL opj_alloc_tile_component_data(opj_tcd_tilecomp_t *l_tilec)
 
 /* ----------------------------------------------------------------------- */
 
-static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no, OPJ_BOOL isEncoder, OPJ_FLOAT32 fraction, OPJ_SIZE_T sizeof_block)
+static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no, OPJ_BOOL isEncoder, OPJ_FLOAT32 fraction, OPJ_SIZE_T sizeof_block, opj_event_mgr_t* manager)
 {
        OPJ_UINT32 (*l_gain_ptr)(OPJ_UINT32) = 00;
        OPJ_UINT32 compno, resno, bandno, precno, cblkno;
@@ -711,7 +712,7 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
 
        /* testcase 1888.pdf.asan.35.988 */
        if (l_tccp->numresolutions == 0) {
-               fprintf(stderr, "tiles require at least one resolution\n");
+               opj_event_msg(manager, EVT_ERROR, "tiles require at least one resolution\n");
                return OPJ_FALSE;
        }
        /*fprintf(stderr, "Tile border = %d,%d,%d,%d\n", l_tile->x0, l_tile->y0,l_tile->x1,l_tile->y1);*/
@@ -730,13 +731,13 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
                /* 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 */
+                       opj_event_msg(manager, EVT_ERROR, "Not enough memory for tile data\n");
                        return OPJ_FALSE;
                }
                l_data_size = l_data_size * (OPJ_UINT32)(l_tilec->y1 - l_tilec->y0);
                
                if ((((OPJ_UINT32)-1) / (OPJ_UINT32)sizeof(OPJ_UINT32)) < l_data_size) {
-                       /* TODO event */
+                       opj_event_msg(manager, EVT_ERROR, "Not enough memory for tile data\n");
                        return OPJ_FALSE;
                }
                l_data_size = l_data_size * (OPJ_UINT32)sizeof(OPJ_UINT32);
@@ -750,6 +751,7 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
                
                l_tilec->data_size_needed = l_data_size;
                if (p_tcd->m_is_decoder && !opj_alloc_tile_component_data(l_tilec)) {
+                       opj_event_msg(manager, EVT_ERROR, "Not enough memory for tile data\n");
                        return OPJ_FALSE;
                }
                
@@ -767,8 +769,7 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
                else if (l_data_size > l_tilec->resolutions_size) {
                        opj_tcd_resolution_t* new_resolutions = (opj_tcd_resolution_t *) opj_realloc(l_tilec->resolutions, l_data_size);
                        if (! new_resolutions) {
-                               /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to tile resolutions\n");                                                                                         */
-                               fprintf(stderr, "Not enough memory to tile resolutions\n");
+                               opj_event_msg(manager, EVT_ERROR, "Not enough memory for tile resolutions\n");
                                opj_free(l_tilec->resolutions);
                                l_tilec->resolutions = NULL;
                                l_tilec->resolutions_size = 0;
@@ -861,10 +862,10 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
                                        /* y0b = 1 if bandno = 2 or 3 */
                                        l_y0b = (OPJ_INT32)((l_band->bandno)>>1);
                                        /* l_band border (global) */
-                                       l_band->x0 = opj_int_ceildivpow2(l_tilec->x0 - (1 << l_level_no) * l_x0b, (OPJ_INT32)(l_level_no + 1));
-                                       l_band->y0 = opj_int_ceildivpow2(l_tilec->y0 - (1 << l_level_no) * l_y0b, (OPJ_INT32)(l_level_no + 1));
-                                       l_band->x1 = opj_int_ceildivpow2(l_tilec->x1 - (1 << l_level_no) * l_x0b, (OPJ_INT32)(l_level_no + 1));
-                                       l_band->y1 = opj_int_ceildivpow2(l_tilec->y1 - (1 << l_level_no) * l_y0b, (OPJ_INT32)(l_level_no + 1));
+                                       l_band->x0 = opj_int64_ceildivpow2(l_tilec->x0 - ((OPJ_INT64)l_x0b << l_level_no), (OPJ_INT32)(l_level_no + 1));
+                                       l_band->y0 = opj_int64_ceildivpow2(l_tilec->y0 - ((OPJ_INT64)l_y0b << l_level_no), (OPJ_INT32)(l_level_no + 1));
+                                       l_band->x1 = opj_int64_ceildivpow2(l_tilec->x1 - ((OPJ_INT64)l_x0b << l_level_no), (OPJ_INT32)(l_level_no + 1));
+                                       l_band->y1 = opj_int64_ceildivpow2(l_tilec->y1 - ((OPJ_INT64)l_y0b << l_level_no), (OPJ_INT32)(l_level_no + 1));
                                }
                                
                                /** avoid an if with storing function pointer */
@@ -886,8 +887,7 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
                                        
                                        opj_tcd_precinct_t * new_precincts = (opj_tcd_precinct_t *) opj_realloc(l_band->precincts,/*3 * */ l_nb_precinct_size);
                                        if (! new_precincts) {
-                                               /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle band precints\n");                                                                    */
-                                               fprintf(stderr, "Not enough memory to handle band precints\n");
+                                               opj_event_msg(manager, EVT_ERROR, "Not enough memory to handle band precints\n");
                                                opj_free(l_band->precincts);
                                                l_band->precincts = NULL;
                                                l_band->precincts_data_size = 0;
@@ -950,8 +950,7 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
                                                        opj_free(l_current_precinct->cblks.blocks);
                                                        l_current_precinct->cblks.blocks = NULL;
                                                        l_current_precinct->block_size = 0;
-                                                       /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory for current precinct codeblock element\n");                                              */
-                                                       fprintf(stderr, "Not enough memory for current precinct codeblock element\n");
+                                                       opj_event_msg(manager, EVT_ERROR, "Not enough memory for current precinct codeblock element\n");
                                                        return OPJ_FALSE;
                                                }
                                                l_current_precinct->cblks.blocks = new_blocks;
@@ -965,34 +964,26 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
                                        }
                                        
                                        if (! l_current_precinct->incltree) {
-                                               l_current_precinct->incltree = opj_tgt_create(l_current_precinct->cw,
-                                                                                                                                                                                                                                       l_current_precinct->ch);
+                                               l_current_precinct->incltree = opj_tgt_create(l_current_precinct->cw, l_current_precinct->ch, manager);
                                        }
                                        else{
-                                               l_current_precinct->incltree = opj_tgt_init(l_current_precinct->incltree,
-                                                                                                                                                                                                                               l_current_precinct->cw,
-                                                                                                                                                                                                                               l_current_precinct->ch);
+                                               l_current_precinct->incltree = opj_tgt_init(l_current_precinct->incltree, l_current_precinct->cw, l_current_precinct->ch, manager);
                                        }
 
                                        if (! l_current_precinct->incltree)     {
-                                               fprintf(stderr, "WARNING: No incltree created.\n");
+                                               opj_event_msg(manager, EVT_WARNING, "No incltree created.\n");
                                                /*return OPJ_FALSE;*/
                                        }
 
                                        if (! l_current_precinct->imsbtree) {
-                                               l_current_precinct->imsbtree = opj_tgt_create(
-                                                                                                                                                                                                                                       l_current_precinct->cw,
-                                                                                                                                                                                                                                       l_current_precinct->ch);
+                                               l_current_precinct->imsbtree = opj_tgt_create(l_current_precinct->cw, l_current_precinct->ch, manager);
                                        }
                                        else {
-                                               l_current_precinct->imsbtree = opj_tgt_init(
-                                                                                                                                                                                                                               l_current_precinct->imsbtree,
-                                                                                                                                                                                                                               l_current_precinct->cw,
-                                                                                                                                                                                                                               l_current_precinct->ch);
+                                               l_current_precinct->imsbtree = opj_tgt_init(l_current_precinct->imsbtree, l_current_precinct->cw, l_current_precinct->ch, manager);
                                        }
 
                                        if (! l_current_precinct->imsbtree) {
-                                               fprintf(stderr, "WARNING: No imsbtree created.\n");
+                                               opj_event_msg(manager, EVT_WARNING, "No imsbtree created.\n");
                                                /*return OPJ_FALSE;*/
                                        }
 
@@ -1045,14 +1036,14 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
        return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_tcd_init_encode_tile (opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no)
+OPJ_BOOL opj_tcd_init_encode_tile (opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no, opj_event_mgr_t* p_manager)
 {
-       return opj_tcd_init_tile(p_tcd, p_tile_no, OPJ_TRUE, 1.0F, sizeof(opj_tcd_cblk_enc_t));
+       return opj_tcd_init_tile(p_tcd, p_tile_no, OPJ_TRUE, 1.0F, sizeof(opj_tcd_cblk_enc_t), p_manager);
 }
 
-OPJ_BOOL opj_tcd_init_decode_tile (opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no)
+OPJ_BOOL opj_tcd_init_decode_tile (opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no, opj_event_mgr_t* p_manager)
 {
-       return opj_tcd_init_tile(p_tcd, p_tile_no, OPJ_FALSE, 0.5F, sizeof(opj_tcd_cblk_dec_t));
+       return opj_tcd_init_tile(p_tcd, p_tile_no, OPJ_FALSE, 0.5F, sizeof(opj_tcd_cblk_dec_t), p_manager);
 }
 
 /**
@@ -1089,7 +1080,7 @@ static OPJ_BOOL opj_tcd_code_block_enc_allocate_data (opj_tcd_cblk_enc_t * p_cod
                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);
+               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;
@@ -1266,7 +1257,8 @@ OPJ_BOOL opj_tcd_decode_tile(   opj_tcd_t *p_tcd,
                                 OPJ_BYTE *p_src,
                                 OPJ_UINT32 p_max_length,
                                 OPJ_UINT32 p_tile_no,
-                                opj_codestream_index_t *p_cstr_index
+                                opj_codestream_index_t *p_cstr_index,
+                                opj_event_mgr_t *p_manager
                                 )
 {
         OPJ_UINT32 l_data_read;
@@ -1299,7 +1291,7 @@ OPJ_BOOL opj_tcd_decode_tile(   opj_tcd_t *p_tcd,
         /*--------------TIER2------------------*/
         /* FIXME _ProfStart(PGROUP_T2); */
         l_data_read = 0;
-        if (! opj_tcd_t2_decode(p_tcd, p_src, &l_data_read, p_max_length, p_cstr_index))
+        if (! opj_tcd_t2_decode(p_tcd, p_src, &l_data_read, p_max_length, p_cstr_index, p_manager))
         {
                 return OPJ_FALSE;
         }
@@ -1328,7 +1320,7 @@ OPJ_BOOL opj_tcd_decode_tile(   opj_tcd_t *p_tcd,
         /*----------------MCT-------------------*/
         /* FIXME _ProfStart(PGROUP_MCT); */
         if
-                (! opj_tcd_mct_decode(p_tcd))
+                (! opj_tcd_mct_decode(p_tcd, p_manager))
         {
                 return OPJ_FALSE;
         }
@@ -1549,7 +1541,8 @@ static OPJ_BOOL opj_tcd_t2_decode (opj_tcd_t *p_tcd,
                             OPJ_BYTE * p_src_data,
                             OPJ_UINT32 * p_data_read,
                             OPJ_UINT32 p_max_src_size,
-                            opj_codestream_index_t *p_cstr_index
+                            opj_codestream_index_t *p_cstr_index,
+                            opj_event_mgr_t *p_manager
                             )
 {
         opj_t2_t * l_t2;
@@ -1566,7 +1559,8 @@ static OPJ_BOOL opj_tcd_t2_decode (opj_tcd_t *p_tcd,
                                         p_src_data,
                                         p_data_read,
                                         p_max_src_size,
-                                        p_cstr_index)) {
+                                        p_cstr_index,
+                                        p_manager)) {
                 opj_t2_destroy(l_t2);
                 return OPJ_FALSE;
         }
@@ -1647,7 +1641,7 @@ static OPJ_BOOL opj_tcd_dwt_decode ( opj_tcd_t *p_tcd )
 
         return OPJ_TRUE;
 }
-static OPJ_BOOL opj_tcd_mct_decode ( opj_tcd_t *p_tcd )
+static OPJ_BOOL opj_tcd_mct_decode ( opj_tcd_t *p_tcd, opj_event_mgr_t *p_manager)
 {
         opj_tcd_tile_t * l_tile = p_tcd->tcd_image->tiles;
         opj_tcp_t * l_tcp = p_tcd->tcp;
@@ -1665,7 +1659,7 @@ static OPJ_BOOL opj_tcd_mct_decode ( opj_tcd_t *p_tcd )
                 if ((l_tile->comps[0].x1 - l_tile->comps[0].x0) * (l_tile->comps[0].y1 - l_tile->comps[0].y0) < (OPJ_INT32)l_samples ||
                     (l_tile->comps[1].x1 - l_tile->comps[1].x0) * (l_tile->comps[1].y1 - l_tile->comps[1].y0) < (OPJ_INT32)l_samples ||
                     (l_tile->comps[2].x1 - l_tile->comps[2].x0) * (l_tile->comps[2].y1 - l_tile->comps[2].y0) < (OPJ_INT32)l_samples) {
-                        fprintf(stderr, "Tiles don't all have the same dimension. Skip the MCT step.\n");
+                        opj_event_msg(p_manager, EVT_ERROR, "Tiles don't all have the same dimension. Skip the MCT step.\n");
                         return OPJ_FALSE;
                 }
                 else if (l_tcp->mct == 2) {
@@ -1717,8 +1711,7 @@ static OPJ_BOOL opj_tcd_mct_decode ( opj_tcd_t *p_tcd )
                 }
         }
         else {
-                /* FIXME need to use opj_event_msg function */
-                fprintf(stderr,"Number of components (%d) is inconsistent with a MCT. Skip the MCT step.\n",l_tile->numcomps);
+                opj_event_msg(p_manager, EVT_ERROR, "Number of components (%d) is inconsistent with a MCT. Skip the MCT step.\n",l_tile->numcomps);
         }
 
         return OPJ_TRUE;
@@ -1775,7 +1768,7 @@ static 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;