From 4643533ca3dabe945fd174caf892a3ccb6cf2fd6 Mon Sep 17 00:00:00 2001 From: Bo Xu Date: Mon, 24 Nov 2014 13:58:10 -0800 Subject: Update to openjpeg r2944 BUG=429139,430566,431288 R=tsepez@chromium.org Review URL: https://codereview.chromium.org/758593002 --- .../fx_libopenjpeg/libopenjpeg20/CMakeLists.txt | 10 + .../src/fxcodec/fx_libopenjpeg/libopenjpeg20/j2k.c | 197 +++-- .../src/fxcodec/fx_libopenjpeg/libopenjpeg20/jp2.c | 237 +++++- core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/pi.c | 2 +- core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t1.c | 62 +- core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t1.h | 6 +- core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t2.c | 15 +- .../src/fxcodec/fx_libopenjpeg/libopenjpeg20/tcd.c | 826 +++++++++++---------- .../src/fxcodec/fx_libopenjpeg/libopenjpeg20/tcd.h | 26 +- 9 files changed, 845 insertions(+), 536 deletions(-) diff --git a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/CMakeLists.txt b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/CMakeLists.txt index fcf60ecf01..7f16834660 100644 --- a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/CMakeLists.txt +++ b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/CMakeLists.txt @@ -98,3 +98,13 @@ if(OPENJPEG_CPPCHECK) COMMAND ${CPPCHECK_EXECUTABLE} -DWIN32 ${f}) endforeach() endif() + +if(OPJ_USE_DSYMUTIL) + if(BUILD_SHARED_LIBS) + GET_TARGET_PROPERTY(OPENJPEG_LIBRARY_LOCATION ${OPENJPEG_LIBRARY_NAME} LOCATION) + add_custom_command(TARGET ${OPENJPEG_LIBRARY_NAME} POST_BUILD + COMMAND "dsymutil" "${OPENJPEG_LIBRARY_LOCATION}" + COMMENT "dsymutil ${OPENJPEG_LIBRARY_LOCATION}" + DEPENDS ${OPENJPEG_LIBRARY_NAME}) + endif() +endif() diff --git a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/j2k.c b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/j2k.c index 46f50eeb8a..4a1c103f4b 100644 --- a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/j2k.c +++ b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/j2k.c @@ -338,11 +338,21 @@ static OPJ_BOOL opj_j2k_pre_write_tile ( opj_j2k_t * p_j2k, static OPJ_BOOL opj_j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data, opj_image_t* p_output_image); +static void opj_get_tile_dimensions(opj_image_t * l_image, + opj_tcd_tilecomp_t * l_tilec, + opj_image_comp_t * l_img_comp, + OPJ_UINT32* l_size_comp, + OPJ_UINT32* l_width, + OPJ_UINT32* l_height, + OPJ_UINT32* l_offset_x, + OPJ_UINT32* l_offset_y, + OPJ_UINT32* l_image_width, + OPJ_UINT32* l_stride, + OPJ_UINT32* l_tile_offset); + static void opj_j2k_get_tile_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data); static OPJ_BOOL opj_j2k_post_write_tile (opj_j2k_t * p_j2k, - OPJ_BYTE * p_data, - OPJ_UINT32 p_data_size, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ); @@ -9756,50 +9766,82 @@ OPJ_BOOL opj_j2k_encode(opj_j2k_t * p_j2k, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ) { - OPJ_UINT32 i; + OPJ_UINT32 i, j; OPJ_UINT32 l_nb_tiles; - OPJ_UINT32 l_max_tile_size, l_current_tile_size; - OPJ_BYTE * l_current_data; + OPJ_UINT32 l_max_tile_size = 0, l_current_tile_size; + OPJ_BYTE * l_current_data = 00; + opj_tcd_t* p_tcd = 00; /* preconditions */ assert(p_j2k != 00); assert(p_stream != 00); assert(p_manager != 00); - l_current_data = (OPJ_BYTE*)opj_malloc(1000); - if (! l_current_data) { - opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to encode all tiles\n"); - return OPJ_FALSE; - } - l_max_tile_size = 1000; + p_tcd = p_j2k->m_tcd; l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw; for (i=0;im_tcd); - if (l_current_tile_size > l_max_tile_size) { - OPJ_BYTE *l_new_current_data = (OPJ_BYTE *) opj_realloc(l_current_data, l_current_tile_size); - if (! l_new_current_data) { - opj_free(l_current_data); - opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to encode all tiles\n"); - return OPJ_FALSE; + /* if we only have one tile, then simply set tile component data equal to image component data */ + /* otherwise, allocate the data */ + for (j=0;jm_tcd->image->numcomps;++j) { + opj_tcd_tilecomp_t* l_tilec = p_tcd->tcd_image->tiles->comps + j; + if (l_nb_tiles == 1) { + opj_image_comp_t * l_img_comp = p_tcd->image->comps + j; + l_tilec->data = l_img_comp->data; + l_tilec->ownsData = OPJ_FALSE; + } else { + if(! opj_alloc_tile_component_data(l_tilec)) { + opj_event_msg(p_manager, EVT_ERROR, "Error allocating tile component data." ); + if (l_current_data) { + opj_free(l_current_data); + } + return OPJ_FALSE; + } + opj_alloc_tile_component_data(l_tilec); } - l_current_data = l_new_current_data; - l_max_tile_size = l_current_tile_size; } + l_current_tile_size = opj_tcd_get_encoded_tile_size(p_j2k->m_tcd); + if (l_nb_tiles > 1) { + if (l_current_tile_size > l_max_tile_size) { + OPJ_BYTE *l_new_current_data = (OPJ_BYTE *) opj_realloc(l_current_data, l_current_tile_size); + if (! l_new_current_data) { + if (l_current_data) { + opj_free(l_current_data); + } + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to encode all tiles\n"); + return OPJ_FALSE; + } + l_current_data = l_new_current_data; + l_max_tile_size = l_current_tile_size; + } + + /* copy image data (32 bit) to l_current_data as contiguous, all-component, zero offset buffer */ + /* 32 bit components @ 8 bit precision get converted to 8 bit */ + /* 32 bit components @ 16 bit precision get converted to 16 bit */ + opj_j2k_get_tile_data(p_j2k->m_tcd,l_current_data); - opj_j2k_get_tile_data(p_j2k->m_tcd,l_current_data); + /* now copy this data into the tile component */ + if (! opj_tcd_copy_tile_data(p_j2k->m_tcd,l_current_data,l_current_tile_size)) { + opj_event_msg(p_manager, EVT_ERROR, "Size mismatch between tile data and sent data." ); + return OPJ_FALSE; + } + } - if (! opj_j2k_post_write_tile (p_j2k,l_current_data,l_current_tile_size,p_stream,p_manager)) { + if (! opj_j2k_post_write_tile (p_j2k,p_stream,p_manager)) { return OPJ_FALSE; } } - opj_free(l_current_data); + if (l_current_data) { + opj_free(l_current_data); + } return OPJ_TRUE; } @@ -9891,37 +9933,61 @@ OPJ_BOOL opj_j2k_pre_write_tile ( opj_j2k_t * p_j2k, return OPJ_TRUE; } +void opj_get_tile_dimensions(opj_image_t * l_image, + opj_tcd_tilecomp_t * l_tilec, + opj_image_comp_t * l_img_comp, + OPJ_UINT32* l_size_comp, + OPJ_UINT32* l_width, + OPJ_UINT32* l_height, + OPJ_UINT32* l_offset_x, + OPJ_UINT32* l_offset_y, + OPJ_UINT32* l_image_width, + OPJ_UINT32* l_stride, + OPJ_UINT32* l_tile_offset) { + OPJ_UINT32 l_remaining; + *l_size_comp = l_img_comp->prec >> 3; /* (/8) */ + l_remaining = l_img_comp->prec & 7; /* (%8) */ + if (l_remaining) { + *l_size_comp += 1; + } + + if (*l_size_comp == 3) { + *l_size_comp = 4; + } + + *l_width = (OPJ_UINT32)(l_tilec->x1 - l_tilec->x0); + *l_height = (OPJ_UINT32)(l_tilec->y1 - l_tilec->y0); + *l_offset_x = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->x0, (OPJ_INT32)l_img_comp->dx); + *l_offset_y = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->y0, (OPJ_INT32)l_img_comp->dy); + *l_image_width = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->x1 - (OPJ_INT32)l_image->x0, (OPJ_INT32)l_img_comp->dx); + *l_stride = *l_image_width - *l_width; + *l_tile_offset = ((OPJ_UINT32)l_tilec->x0 - *l_offset_x) + ((OPJ_UINT32)l_tilec->y0 - *l_offset_y) * *l_image_width; +} + void opj_j2k_get_tile_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data) { OPJ_UINT32 i,j,k = 0; - OPJ_UINT32 l_width,l_height,l_stride, l_offset_x,l_offset_y, l_image_width; - opj_image_comp_t * l_img_comp = 00; - opj_tcd_tilecomp_t * l_tilec = 00; - opj_image_t * l_image = 00; - OPJ_UINT32 l_size_comp, l_remaining; - OPJ_INT32 * l_src_ptr; - l_tilec = p_tcd->tcd_image->tiles->comps; - l_image = p_tcd->image; - l_img_comp = l_image->comps; for (i=0;iimage->numcomps;++i) { - l_size_comp = l_img_comp->prec >> 3; /* (/8) */ - l_remaining = l_img_comp->prec & 7; /* (%8) */ - if (l_remaining) { - ++l_size_comp; - } - - if (l_size_comp == 3) { - l_size_comp = 4; - } - - l_width = (OPJ_UINT32)(l_tilec->x1 - l_tilec->x0); - l_height = (OPJ_UINT32)(l_tilec->y1 - l_tilec->y0); - l_offset_x = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->x0, (OPJ_INT32)l_img_comp->dx); - l_offset_y = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->y0, (OPJ_INT32)l_img_comp->dy); - l_image_width = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->x1 - (OPJ_INT32)l_image->x0, (OPJ_INT32)l_img_comp->dx); - l_stride = l_image_width - l_width; - l_src_ptr = l_img_comp->data + ((OPJ_UINT32)l_tilec->x0 - l_offset_x) + ((OPJ_UINT32)l_tilec->y0 - l_offset_y) * l_image_width; + opj_image_t * l_image = p_tcd->image; + OPJ_INT32 * l_src_ptr; + opj_tcd_tilecomp_t * l_tilec = p_tcd->tcd_image->tiles->comps + i; + opj_image_comp_t * l_img_comp = l_image->comps + i; + OPJ_UINT32 l_size_comp,l_width,l_height,l_offset_x,l_offset_y, l_image_width,l_stride,l_tile_offset; + + opj_get_tile_dimensions(l_image, + l_tilec, + l_img_comp, + &l_size_comp, + &l_width, + &l_height, + &l_offset_x, + &l_offset_y, + &l_image_width, + &l_stride, + &l_tile_offset); + + l_src_ptr = l_img_comp->data + l_tile_offset; switch (l_size_comp) { case 1: @@ -9988,19 +10054,13 @@ void opj_j2k_get_tile_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data) } break; } - - ++l_img_comp; - ++l_tilec; } } OPJ_BOOL opj_j2k_post_write_tile ( opj_j2k_t * p_j2k, - OPJ_BYTE * p_data, - OPJ_UINT32 p_data_size, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ) { - opj_tcd_t * l_tcd = 00; OPJ_UINT32 l_nb_bytes_written; OPJ_BYTE * l_current_data = 00; OPJ_UINT32 l_tile_size = 0; @@ -10009,17 +10069,10 @@ OPJ_BOOL opj_j2k_post_write_tile ( opj_j2k_t * p_j2k, /* preconditions */ assert(p_j2k->m_specific_param.m_encoder.m_encoded_tile_data); - l_tcd = p_j2k->m_tcd; - l_tile_size = p_j2k->m_specific_param.m_encoder.m_encoded_tile_size; l_available_data = l_tile_size; l_current_data = p_j2k->m_specific_param.m_encoder.m_encoded_tile_data; - if (! opj_tcd_copy_tile_data(l_tcd,p_data,p_data_size)) { - opj_event_msg(p_manager, EVT_ERROR, "Size mismatch between tile data and sent data." ); - return OPJ_FALSE; - } - l_nb_bytes_written = 0; if (! opj_j2k_write_first_tile_part(p_j2k,l_current_data,&l_nb_bytes_written,l_available_data,p_stream,p_manager)) { return OPJ_FALSE; @@ -10490,7 +10543,23 @@ OPJ_BOOL opj_j2k_write_tile (opj_j2k_t * p_j2k, return OPJ_FALSE; } else { - if (! opj_j2k_post_write_tile(p_j2k,p_data,p_data_size,p_stream,p_manager)) { + OPJ_UINT32 j; + /* Allocate data */ + for (j=0;jm_tcd->image->numcomps;++j) { + opj_tcd_tilecomp_t* l_tilec = p_j2k->m_tcd->tcd_image->tiles->comps + j; + + if(! opj_alloc_tile_component_data(l_tilec)) { + opj_event_msg(p_manager, EVT_ERROR, "Error allocating tile component data." ); + return OPJ_FALSE; + } + } + + /* now copy data into the the tile component */ + if (! opj_tcd_copy_tile_data(p_j2k->m_tcd,p_data,p_data_size)) { + opj_event_msg(p_manager, EVT_ERROR, "Size mismatch between tile data and sent data." ); + return OPJ_FALSE; + } + if (! opj_j2k_post_write_tile(p_j2k,p_stream,p_manager)) { opj_event_msg(p_manager, EVT_ERROR, "Error while opj_j2k_post_write_tile with tile index = %d\n", p_tile_index); return OPJ_FALSE; } diff --git a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/jp2.c b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/jp2.c index 78a15026a9..1830c11a19 100644 --- a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/jp2.c +++ b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/jp2.c @@ -108,6 +108,17 @@ static OPJ_BOOL opj_jp2_read_cdef( opj_jp2_t * jp2, static void opj_jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color); +/** + * Writes the Channel Definition box. + * + * @param jp2 jpeg2000 file codec. + * @param p_nb_bytes_written pointer to store the nb of bytes written by the function. + * + * @return the data being copied. + */ +static OPJ_BYTE * opj_jp2_write_cdef( opj_jp2_t *jp2, + OPJ_UINT32 * p_nb_bytes_written ); + /** * Writes the Colour Specification box. * @@ -680,6 +691,55 @@ OPJ_BOOL opj_jp2_read_bpcc( opj_jp2_t *jp2, return OPJ_TRUE; } +static OPJ_BYTE * opj_jp2_write_cdef(opj_jp2_t *jp2, OPJ_UINT32 * p_nb_bytes_written) +{ + /* room for 8 bytes for box, 2 for n */ + OPJ_UINT32 l_cdef_size = 10; + OPJ_BYTE * l_cdef_data,* l_current_cdef_ptr; + OPJ_UINT32 l_value; + OPJ_UINT16 i; + + /* preconditions */ + assert(jp2 != 00); + assert(p_nb_bytes_written != 00); + assert(jp2->color.jp2_cdef != 00); + assert(jp2->color.jp2_cdef->info != 00); + assert(jp2->color.jp2_cdef->n > 0U); + + l_cdef_size += 6 * jp2->color.jp2_cdef->n; + + l_cdef_data = (OPJ_BYTE *) opj_malloc(l_cdef_size); + if (l_cdef_data == 00) { + return 00; + } + + l_current_cdef_ptr = l_cdef_data; + + opj_write_bytes(l_current_cdef_ptr,l_cdef_size,4); /* write box size */ + l_current_cdef_ptr += 4; + + opj_write_bytes(l_current_cdef_ptr,JP2_CDEF,4); /* BPCC */ + l_current_cdef_ptr += 4; + + l_value = jp2->color.jp2_cdef->n; + opj_write_bytes(l_current_cdef_ptr,l_value,2); /* N */ + l_current_cdef_ptr += 2; + + for (i = 0U; i < jp2->color.jp2_cdef->n; ++i) { + l_value = jp2->color.jp2_cdef->info[i].cn; + opj_write_bytes(l_current_cdef_ptr,l_value,2); /* Cni */ + l_current_cdef_ptr += 2; + l_value = jp2->color.jp2_cdef->info[i].typ; + opj_write_bytes(l_current_cdef_ptr,l_value,2); /* Typi */ + l_current_cdef_ptr += 2; + l_value = jp2->color.jp2_cdef->info[i].asoc; + opj_write_bytes(l_current_cdef_ptr,l_value,2); /* Asoci */ + l_current_cdef_ptr += 2; + } + *p_nb_bytes_written = l_cdef_size; + + return l_cdef_data; +} OPJ_BYTE * opj_jp2_write_colr( opj_jp2_t *jp2, OPJ_UINT32 * p_nb_bytes_written @@ -688,7 +748,7 @@ OPJ_BYTE * opj_jp2_write_colr( opj_jp2_t *jp2, /* room for 8 bytes for box 3 for common data and variable upon profile*/ OPJ_UINT32 l_colr_size = 11; OPJ_BYTE * l_colr_data,* l_current_colr_ptr; - + /* preconditions */ assert(jp2 != 00); assert(p_nb_bytes_written != 00); @@ -772,12 +832,12 @@ static OPJ_BOOL opj_jp2_check_color(opj_image_t *image, opj_jp2_color_t *color, } for (i = 0; i < n; i++) { - if (info[i].cn >= image->numcomps) { - opj_event_msg(p_manager, EVT_ERROR, "Invalid component index %d (>= %d).\n", info[i].cn, image->numcomps); + if (info[i].cn >= nr_channels) { + opj_event_msg(p_manager, EVT_ERROR, "Invalid component index %d (>= %d).\n", info[i].cn, nr_channels); return OPJ_FALSE; } - if (info[i].asoc > 0 && (OPJ_UINT32)(info[i].asoc - 1) >= image->numcomps) { - opj_event_msg(p_manager, EVT_ERROR, "Invalid component index %d (>= %d).\n", info[i].asoc - 1, image->numcomps); + if (info[i].asoc > 0 && (OPJ_UINT32)(info[i].asoc - 1) >= nr_channels) { + opj_event_msg(p_manager, EVT_ERROR, "Invalid component index %d (>= %d).\n", info[i].asoc - 1, nr_channels); return OPJ_FALSE; } } @@ -982,12 +1042,20 @@ OPJ_BOOL opj_jp2_read_pclr( opj_jp2_t *jp2, opj_read_bytes(p_pclr_header_data, &l_value , 2); /* NE */ p_pclr_header_data += 2; nr_entries = (OPJ_UINT16) l_value; + if ((nr_entries == 0U) || (nr_entries > 1024U)) { + opj_event_msg(p_manager, EVT_ERROR, "Invalid PCLR box. Reports %d entries\n", (int)nr_entries); + return OPJ_FALSE; + } opj_read_bytes(p_pclr_header_data, &l_value , 1); /* NPC */ ++p_pclr_header_data; nr_channels = (OPJ_UINT16) l_value; + if (nr_channels == 0U) { + opj_event_msg(p_manager, EVT_ERROR, "Invalid PCLR box. Reports 0 palette columns\n"); + return OPJ_FALSE; + } - if (p_pclr_header_size < 3 + (OPJ_UINT32)nr_channels || nr_channels == 0 || nr_entries >= (OPJ_UINT32)-1 / nr_channels) + if (p_pclr_header_size < 3 + (OPJ_UINT32)nr_channels) return OPJ_FALSE; entries = (OPJ_UINT32*) opj_malloc((size_t)nr_channels * nr_entries * sizeof(OPJ_UINT32)); @@ -1120,35 +1188,51 @@ void opj_jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color) info = color->jp2_cdef->info; n = color->jp2_cdef->n; - for(i = 0; i < n; ++i) - { - /* WATCH: acn = asoc - 1 ! */ - asoc = info[i].asoc; - if(asoc == 0 || asoc == 65535) - { - if (i < image->numcomps) - image->comps[i].alpha = info[i].typ; - continue; - } + for(i = 0; i < n; ++i) + { + /* WATCH: acn = asoc - 1 ! */ + asoc = info[i].asoc; + cn = info[i].cn; - cn = info[i].cn; - acn = (OPJ_UINT16)(asoc - 1); - if( cn >= image->numcomps || acn >= image->numcomps ) - { - fprintf(stderr, "cn=%d, acn=%d, numcomps=%d\n", cn, acn, image->numcomps); - continue; - } + if( cn >= image->numcomps) + { + fprintf(stderr, "cn=%d, numcomps=%d\n", cn, image->numcomps); + continue; + } + if(asoc == 0 || asoc == 65535) + { + image->comps[cn].alpha = info[i].typ; + continue; + } + + acn = (OPJ_UINT16)(asoc - 1); + if( acn >= image->numcomps ) + { + fprintf(stderr, "acn=%d, numcomps=%d\n", acn, image->numcomps); + continue; + } - if(cn != acn) + /* Swap only if color channel */ + if((cn != acn) && (info[i].typ == 0)) { opj_image_comp_t saved; + OPJ_UINT16 j; memcpy(&saved, &image->comps[cn], sizeof(opj_image_comp_t)); memcpy(&image->comps[cn], &image->comps[acn], sizeof(opj_image_comp_t)); memcpy(&image->comps[acn], &saved, sizeof(opj_image_comp_t)); - info[i].asoc = (OPJ_UINT16)(cn + 1); - info[acn].asoc = (OPJ_UINT16)(info[acn].cn + 1); + /* Swap channels in following channel definitions, don't bother with j <= i that are already processed */ + for (j = i + 1; j < n ; ++j) + { + if (info[j].cn == cn) { + info[j].cn = acn; + } + else if (info[j].cn == acn) { + info[j].cn = cn; + } + /* asoc is related to color index. Do not update. */ + } } image->comps[cn].alpha = info[i].typ; @@ -1341,11 +1425,6 @@ OPJ_BOOL opj_jp2_decode(opj_jp2_t *jp2, else p_image->color_space = OPJ_CLRSPC_UNKNOWN; - /* Apply the color space if needed */ - if(jp2->color.jp2_cdef) { - opj_jp2_apply_cdef(p_image, &(jp2->color)); - } - if(jp2->color.jp2_pclr) { /* Part 1, I.5.3.4: Either both or none : */ if( !jp2->color.jp2_pclr->cmap) @@ -1354,6 +1433,11 @@ OPJ_BOOL opj_jp2_decode(opj_jp2_t *jp2, opj_jp2_apply_pclr(p_image, &(jp2->color)); } + /* Apply the color space if needed */ + if(jp2->color.jp2_cdef) { + opj_jp2_apply_cdef(p_image, &(jp2->color)); + } + if(jp2->color.icc_profile_buf) { p_image->icc_profile_buf = jp2->color.icc_profile_buf; p_image->icc_profile_len = jp2->color.icc_profile_len; @@ -1369,7 +1453,7 @@ OPJ_BOOL opj_jp2_write_jp2h(opj_jp2_t *jp2, opj_event_mgr_t * p_manager ) { - opj_jp2_img_header_writer_handler_t l_writers [3]; + opj_jp2_img_header_writer_handler_t l_writers [4]; opj_jp2_img_header_writer_handler_t * l_current_writer; OPJ_INT32 i, l_nb_pass; @@ -1399,6 +1483,11 @@ OPJ_BOOL opj_jp2_write_jp2h(opj_jp2_t *jp2, l_writers[1].handler = opj_jp2_write_colr; } + if (jp2->color.jp2_cdef != NULL) { + l_writers[l_nb_pass].handler = opj_jp2_write_cdef; + l_nb_pass++; + } + /* write box header */ /* write JP2H type */ opj_write_bytes(l_jp2h_data+4,JP2_JP2H,4); @@ -1598,9 +1687,13 @@ OPJ_BOOL opj_jp2_setup_encoder( opj_jp2_t *jp2, opj_image_t *image, opj_event_mgr_t * p_manager) { - OPJ_UINT32 i; + OPJ_UINT32 i; OPJ_UINT32 depth_0; OPJ_UINT32 sign; + OPJ_UINT32 alpha_count; + OPJ_UINT32 color_channels = 0U; + OPJ_UINT32 alpha_channel = 0U; + if(!jp2 || !parameters || !image) return OPJ_FALSE; @@ -1681,6 +1774,74 @@ OPJ_BOOL opj_jp2_setup_encoder( opj_jp2_t *jp2, jp2->enumcs = 18; /* YUV */ } + /* Channel Definition box */ + /* FIXME not provided by parameters */ + /* We try to do what we can... */ + alpha_count = 0U; + for (i = 0; i < image->numcomps; i++) { + if (image->comps[i].alpha != 0) { + alpha_count++; + alpha_channel = i; + } + } + if (alpha_count == 1U) { /* no way to deal with more than 1 alpha channel */ + switch (jp2->enumcs) { + case 16: + case 18: + color_channels = 3; + break; + case 17: + color_channels = 1; + break; + default: + alpha_count = 0U; + break; + } + if (alpha_count == 0U) { + opj_event_msg(p_manager, EVT_WARNING, "Alpha channel specified but unknown enumcs. No cdef box will be created.\n"); + } else if (image->numcomps < (color_channels+1)) { + opj_event_msg(p_manager, EVT_WARNING, "Alpha channel specified but not enough image components for an automatic cdef box creation.\n"); + alpha_count = 0U; + } else if ((OPJ_UINT32)alpha_channel < color_channels) { + opj_event_msg(p_manager, EVT_WARNING, "Alpha channel position conflicts with color channel. No cdef box will be created.\n"); + alpha_count = 0U; + } + } else if (alpha_count > 1) { + opj_event_msg(p_manager, EVT_WARNING, "Multiple alpha channels specified. No cdef box will be created.\n"); + } + if (alpha_count == 1U) { /* if here, we know what we can do */ + jp2->color.jp2_cdef = (opj_jp2_cdef_t*)opj_malloc(sizeof(opj_jp2_cdef_t)); + if(!jp2->color.jp2_cdef) { + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to setup the JP2 encoder\n"); + return OPJ_FALSE; + } + /* no memset needed, all values will be overwritten except if jp2->color.jp2_cdef->info allocation fails, */ + /* in which case jp2->color.jp2_cdef->info will be NULL => valid for destruction */ + jp2->color.jp2_cdef->info = (opj_jp2_cdef_info_t*) opj_malloc(image->numcomps * sizeof(opj_jp2_cdef_info_t)); + if (!jp2->color.jp2_cdef->info) { + /* memory will be freed by opj_jp2_destroy */ + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to setup the JP2 encoder\n"); + return OPJ_FALSE; + } + jp2->color.jp2_cdef->n = (OPJ_UINT16) image->numcomps; /* cast is valid : image->numcomps [1,16384] */ + for (i = 0U; i < color_channels; i++) { + jp2->color.jp2_cdef->info[i].cn = (OPJ_UINT16)i; /* cast is valid : image->numcomps [1,16384] */ + jp2->color.jp2_cdef->info[i].typ = 0U; + jp2->color.jp2_cdef->info[i].asoc = (OPJ_UINT16)(i+1U); /* No overflow + cast is valid : image->numcomps [1,16384] */ + } + for (; i < image->numcomps; i++) { + if (image->comps[i].alpha != 0) { /* we'll be here exactly once */ + jp2->color.jp2_cdef->info[i].cn = (OPJ_UINT16)i; /* cast is valid : image->numcomps [1,16384] */ + jp2->color.jp2_cdef->info[i].typ = 1U; /* Opacity channel */ + jp2->color.jp2_cdef->info[i].asoc = 0U; /* Apply alpha channel to the whole image */ + } else { + /* Unknown channel */ + jp2->color.jp2_cdef->info[i].cn = (OPJ_UINT16)i; /* cast is valid : image->numcomps [1,16384] */ + jp2->color.jp2_cdef->info[i].typ = 65535U; + jp2->color.jp2_cdef->info[i].asoc = 65535U; + } + } + } jp2->precedence = 0; /* PRECEDENCE */ jp2->approx = 0; /* APPROX */ @@ -2551,11 +2712,6 @@ OPJ_BOOL opj_jp2_get_tile( opj_jp2_t *p_jp2, else p_image->color_space = OPJ_CLRSPC_UNKNOWN; - /* Apply the color space if needed */ - if(p_jp2->color.jp2_cdef) { - opj_jp2_apply_cdef(p_image, &(p_jp2->color)); - } - if(p_jp2->color.jp2_pclr) { /* Part 1, I.5.3.4: Either both or none : */ if( !p_jp2->color.jp2_pclr->cmap) @@ -2564,6 +2720,11 @@ OPJ_BOOL opj_jp2_get_tile( opj_jp2_t *p_jp2, opj_jp2_apply_pclr(p_image, &(p_jp2->color)); } + /* Apply the color space if needed */ + if(p_jp2->color.jp2_cdef) { + opj_jp2_apply_cdef(p_image, &(p_jp2->color)); + } + if(p_jp2->color.icc_profile_buf) { p_image->icc_profile_buf = p_jp2->color.icc_profile_buf; p_image->icc_profile_len = p_jp2->color.icc_profile_len; diff --git a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/pi.c b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/pi.c index b3fe9af18a..65ff6263e0 100644 --- a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/pi.c +++ b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/pi.c @@ -1105,7 +1105,7 @@ OPJ_BOOL opj_pi_check_next_level( OPJ_INT32 pos, break; case 'P': switch(tcp->prg){ - case OPJ_LRCP: // fall through + 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)){ diff --git a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t1.c b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t1.c index 5646896315..11b72a33ff 100644 --- a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t1.c +++ b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t1.c @@ -496,7 +496,7 @@ void opj_t1_enc_sigpass(opj_t1_t *t1, opj_t1_enc_sigpass_step( t1, &t1->flags[((j+1) * t1->flags_stride) + i + 1], - &t1->data[(j * t1->w) + i], + &t1->data[(j * t1->data_stride) + i], orient, bpno, one, @@ -718,7 +718,7 @@ void opj_t1_enc_refpass( opj_t1_enc_refpass_step( t1, &t1->flags[((j+1) * t1->flags_stride) + i + 1], - &t1->data[(j * t1->w) + i], + &t1->data[(j * t1->data_stride) + i], bpno, one, nmsedec, @@ -970,7 +970,7 @@ void opj_t1_enc_clnpass( } if (agg) { for (runlen = 0; runlen < 4; ++runlen) { - if (opj_int_abs(t1->data[((k + runlen)*t1->w) + i]) & one) + if (opj_int_abs(t1->data[((k + runlen)*t1->data_stride) + i]) & one) break; } opj_mqc_setcurctx(mqc, T1_CTXNO_AGG); @@ -989,7 +989,7 @@ void opj_t1_enc_clnpass( opj_t1_enc_clnpass_step( t1, &t1->flags[((j+1) * t1->flags_stride) + i + 1], - &t1->data[(j * t1->w) + i], + &t1->data[(j * t1->data_stride) + i], orient, bpno, one, @@ -1166,17 +1166,19 @@ OPJ_BOOL opj_t1_allocate_buffers( OPJ_UINT32 datasize=w * h; OPJ_UINT32 flagssize; - if(datasize > t1->datasize){ - opj_aligned_free(t1->data); - t1->data = (OPJ_INT32*) opj_aligned_malloc(datasize * sizeof(OPJ_INT32)); - if(!t1->data){ - /* FIXME event manager error callback */ - return OPJ_FALSE; + /* encoder uses tile buffer, so no need to allocate */ + if (!t1->encoder) { + if(datasize > t1->datasize){ + opj_aligned_free(t1->data); + t1->data = (OPJ_INT32*) opj_aligned_malloc(datasize * sizeof(OPJ_INT32)); + if(!t1->data){ + /* FIXME event manager error callback */ + return OPJ_FALSE; + } + t1->datasize=datasize; } - t1->datasize=datasize; + memset(t1->data,0,datasize * sizeof(OPJ_INT32)); } - memset(t1->data,0,datasize * sizeof(OPJ_INT32)); - t1->flags_stride=w+2; flagssize=t1->flags_stride * (h+2); @@ -1205,7 +1207,7 @@ OPJ_BOOL opj_t1_allocate_buffers( * and initializes the look-up tables of the Tier-1 coder/decoder * @return a new T1 handle if successful, returns NULL otherwise */ -opj_t1_t* opj_t1_create() +opj_t1_t* opj_t1_create(OPJ_BOOL isEncoder) { opj_t1_t *l_t1 = 00; @@ -1226,6 +1228,7 @@ opj_t1_t* opj_t1_create() opj_t1_destroy(l_t1); return 00; } + l_t1->encoder = isEncoder; return l_t1; } @@ -1248,7 +1251,8 @@ void opj_t1_destroy(opj_t1_t *p_t1) opj_raw_destroy(p_t1->raw); p_t1->raw = 00; - if (p_t1->data) { + /* encoder uses tile buffer, so no need to free */ + if (!p_t1->encoder && p_t1->data) { opj_aligned_free(p_t1->data); p_t1->data = 00; } @@ -1482,11 +1486,10 @@ OPJ_BOOL opj_t1_encode_cblks( opj_t1_t *t1, for (cblkno = 0; cblkno < prc->cw * prc->ch; ++cblkno) { opj_tcd_cblk_enc_t* cblk = &prc->cblks.enc[cblkno]; - OPJ_INT32 * restrict datap; OPJ_INT32* restrict tiledp; OPJ_UINT32 cblk_w; OPJ_UINT32 cblk_h; - OPJ_UINT32 i, j; + OPJ_UINT32 i, j, tileIndex=0, tileLineAdvance; OPJ_INT32 x = cblk->x0 - band->x0; OPJ_INT32 y = cblk->y0 - band->y0; @@ -1507,27 +1510,32 @@ OPJ_BOOL opj_t1_encode_cblks( opj_t1_t *t1, return OPJ_FALSE; } - datap=t1->data; cblk_w = t1->w; cblk_h = t1->h; + tileLineAdvance = tile_w - cblk_w; tiledp=&tilec->data[(OPJ_UINT32)y * tile_w + (OPJ_UINT32)x]; + t1->data = tiledp; + t1->data_stride = tile_w; if (tccp->qmfbid == 1) { for (j = 0; j < cblk_h; ++j) { for (i = 0; i < cblk_w; ++i) { - OPJ_INT32 tmp = tiledp[(j * tile_w) + i]; - datap[(j * cblk_w) + i] = tmp << T1_NMSEDEC_FRACBITS; + tiledp[tileIndex] <<= T1_NMSEDEC_FRACBITS; + tileIndex++; } + tileIndex += tileLineAdvance; } } else { /* if (tccp->qmfbid == 0) */ for (j = 0; j < cblk_h; ++j) { for (i = 0; i < cblk_w; ++i) { - OPJ_INT32 tmp = tiledp[(j * tile_w) + i]; - datap[(j * cblk_w) + i] = + OPJ_INT32 tmp = tiledp[tileIndex]; + tiledp[tileIndex] = opj_int_fix_mul( tmp, bandconst) >> (11 - T1_NMSEDEC_FRACBITS); + tileIndex++; } + tileIndex += tileLineAdvance; } } @@ -1574,14 +1582,16 @@ void opj_t1_encode_cblk(opj_t1_t *t1, OPJ_UINT32 passtype; OPJ_INT32 nmsedec = 0; OPJ_INT32 max; - OPJ_UINT32 i; + OPJ_UINT32 i, j; OPJ_BYTE type = T1_TYPE_MQ; OPJ_FLOAT64 tempwmsedec; max = 0; - for (i = 0; i < t1->w * t1->h; ++i) { - OPJ_INT32 tmp = abs(t1->data[i]); - max = opj_int_max(max, tmp); + for (i = 0; i < t1->w; ++i) { + for (j = 0; j < t1->h; ++j) { + OPJ_INT32 tmp = abs(t1->data[i + j*t1->data_stride]); + max = opj_int_max(max, tmp); + } } cblk->numbps = max ? (OPJ_UINT32)((opj_int_floorlog2(max) + 1) - T1_NMSEDEC_FRACBITS) : 0; diff --git a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t1.h b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t1.h index e5be70ed5b..e1d41ed56f 100644 --- a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t1.h +++ b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t1.h @@ -103,13 +103,15 @@ typedef struct opj_t1 { /** RAW component */ opj_raw_t *raw; - OPJ_INT32 *data; + OPJ_INT32 *data; opj_flag_t *flags; OPJ_UINT32 w; OPJ_UINT32 h; OPJ_UINT32 datasize; OPJ_UINT32 flagssize; OPJ_UINT32 flags_stride; + OPJ_UINT32 data_stride; + OPJ_BOOL encoder; } opj_t1_t; #define MACRO_t1_flags(x,y) t1->flags[((x)*(t1->flags_stride))+(y)] @@ -147,7 +149,7 @@ OPJ_BOOL opj_t1_decode_cblks( opj_t1_t* t1, * and initializes the look-up tables of the Tier-1 coder/decoder * @return a new T1 handle if successful, returns NULL otherwise */ -opj_t1_t* opj_t1_create(void); +opj_t1_t* opj_t1_create(OPJ_BOOL isEncoder); /** * Destroys a previously created T1 handle diff --git a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t2.c b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t2.c index 1a29cccfc6..d0d63d2bd0 100644 --- a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t2.c +++ b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t2.c @@ -387,7 +387,15 @@ OPJ_BOOL opj_t2_decode_packets( opj_t2_t *p_t2, * l_current_pi->resno is always >= p_tile->comps[l_current_pi->compno].minimum_num_resolutions * and no l_img_comp->resno_decoded are computed */ - OPJ_BOOL* first_pass_failed = (OPJ_BOOL*)opj_malloc(l_image->numcomps * sizeof(OPJ_BOOL)); + OPJ_BOOL* first_pass_failed = NULL; + + if (l_current_pi->poc.prg == OPJ_PROG_UNKNOWN) { + /* TODO ADE : add an error */ + opj_pi_destroy(l_pi, l_nb_pocs); + return OPJ_FALSE; + } + + first_pass_failed = (OPJ_BOOL*)opj_malloc(l_image->numcomps * sizeof(OPJ_BOOL)); if (!first_pass_failed) { opj_pi_destroy(l_pi,l_nb_pocs); @@ -395,11 +403,6 @@ OPJ_BOOL opj_t2_decode_packets( opj_t2_t *p_t2, } memset(first_pass_failed, OPJ_TRUE, l_image->numcomps * sizeof(OPJ_BOOL)); - if (l_current_pi->poc.prg == OPJ_PROG_UNKNOWN) { - /* TODO ADE : add an error */ - opj_pi_destroy(l_pi, l_nb_pocs); - return OPJ_FALSE; - } while (opj_pi_next(l_current_pi)) { JAS_FPRINTF( stderr, "packet offset=00000166 prg=%d cmptno=%02d rlvlno=%02d prcno=%03d lyrno=%02d\n\n", l_current_pi->poc.prg1, l_current_pi->compno, l_current_pi->resno, l_current_pi->precno, l_current_pi->layno ); diff --git a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/tcd.c b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/tcd.c index 1720b8efa5..6c04f3d8b7 100644 --- a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/tcd.c +++ b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/tcd.c @@ -103,6 +103,12 @@ void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_image_t * img) { fprintf(fd, "}\n"); } #endif + +/** + * 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); + /** * Allocates memory for a decoding code block. */ @@ -611,395 +617,430 @@ 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); + if (! l_tilec->data ) { + return OPJ_FALSE; + } + /*fprintf(stderr, "tAllocate data of tilec (int): %d x OPJ_UINT32n",l_data_size);*/ + l_tilec->data_size = l_tilec->data_size_needed; + l_tilec->ownsData = OPJ_TRUE; + } + else if (l_tilec->data_size_needed > l_tilec->data_size) { + OPJ_INT32 * new_data = (OPJ_INT32 *) opj_realloc(l_tilec->data, l_tilec->data_size_needed); + /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle tile datan"); */ + /* fprintf(stderr, "Not enough memory to handle tile data"); */ + if (! new_data) { + opj_free(l_tilec->data); + l_tilec->data = NULL; + l_tilec->data_size = 0; + l_tilec->data_size_needed = 0; + l_tilec->ownsData = OPJ_FALSE; + return OPJ_FALSE; + } + l_tilec->data = new_data; + /*fprintf(stderr, "tReallocate data of tilec (int): from %d to %d x OPJ_UINT32n", l_tilec->data_size, l_data_size);*/ + l_tilec->data_size = l_tilec->data_size_needed; + l_tilec->ownsData = OPJ_TRUE; + } + return OPJ_TRUE; +} + /* ----------------------------------------------------------------------- */ -#define OPJ_MACRO_TCD_ALLOCATE(FUNCTION,TYPE,FRACTION,ELEMENT,FUNCTION_ELEMENT) \ -OPJ_BOOL FUNCTION ( opj_tcd_t *p_tcd, \ - OPJ_UINT32 p_tile_no \ - ) \ -{ \ - OPJ_UINT32 (*l_gain_ptr)(OPJ_UINT32) = 00; \ - OPJ_UINT32 compno, resno, bandno, precno, cblkno; \ - opj_tcp_t * l_tcp = 00; \ - opj_cp_t * l_cp = 00; \ - opj_tcd_tile_t * l_tile = 00; \ - opj_tccp_t *l_tccp = 00; \ - opj_tcd_tilecomp_t *l_tilec = 00; \ - opj_image_comp_t * l_image_comp = 00; \ - opj_tcd_resolution_t *l_res = 00; \ - opj_tcd_band_t *l_band = 00; \ - opj_stepsize_t * l_step_size = 00; \ - opj_tcd_precinct_t *l_current_precinct = 00; \ - TYPE* l_code_block = 00; \ - opj_image_t *l_image = 00; \ - OPJ_UINT32 p,q; \ - OPJ_UINT32 l_level_no; \ - OPJ_UINT32 l_pdx, l_pdy; \ - OPJ_UINT32 l_gain; \ - OPJ_INT32 l_x0b, l_y0b; \ - /* 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 */ \ - OPJ_UINT32 l_nb_precincts; \ - /* room needed to store l_nb_precinct precinct for a resolution */ \ - OPJ_UINT32 l_nb_precinct_size; \ - /* number of code blocks for a precinct*/ \ - OPJ_UINT32 l_nb_code_blocks; \ - /* room needed to store l_nb_code_blocks code blocks for a precinct*/ \ - OPJ_UINT32 l_nb_code_blocks_size; \ - /* size of data for a tile */ \ - OPJ_UINT32 l_data_size; \ - \ - l_cp = p_tcd->cp; \ - l_tcp = &(l_cp->tcps[p_tile_no]); \ - l_tile = p_tcd->tcd_image->tiles; \ - l_tccp = l_tcp->tccps; \ - l_tilec = l_tile->comps; \ - l_image = p_tcd->image; \ - l_image_comp = p_tcd->image->comps; \ - \ - p = p_tile_no % l_cp->tw; /* tile coordinates */ \ - q = p_tile_no / l_cp->tw; \ - /*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); \ - /* testcase 1888.pdf.asan.35.988 */ \ - if (l_tccp->numresolutions == 0) { \ - fprintf(stderr, "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);*/ \ - \ - /*tile->numcomps = image->numcomps; */ \ - for(compno = 0; compno < l_tile->numcomps; ++compno) { \ - /*fprintf(stderr, "compno = %d/%d\n", compno, l_tile->numcomps);*/ \ - l_image_comp->resno_decoded = 0; \ - /* border of each l_tile component (global) */ \ - l_tilec->x0 = opj_int_ceildiv(l_tile->x0, (OPJ_INT32)l_image_comp->dx); \ - l_tilec->y0 = opj_int_ceildiv(l_tile->y0, (OPJ_INT32)l_image_comp->dy); \ - l_tilec->x1 = opj_int_ceildiv(l_tile->x1, (OPJ_INT32)l_image_comp->dx); \ - 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 );\ - 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; \ - } \ - else { \ - l_tilec->minimum_num_resolutions = l_tccp->numresolutions \ - - l_cp->m_specific_param.m_dec.m_reduce; \ - } \ - \ - if (l_tilec->data == 00) { \ - l_tilec->data = (OPJ_INT32 *) opj_malloc(l_data_size); \ - if (! l_tilec->data ) { \ - return OPJ_FALSE; \ - } \ - /*fprintf(stderr, "\tAllocate data of tilec (int): %d x OPJ_UINT32\n",l_data_size);*/ \ - \ - l_tilec->data_size = l_data_size; \ - } \ - else if (l_data_size > l_tilec->data_size) { \ - OPJ_INT32 * new_data = (OPJ_INT32 *) opj_realloc(l_tilec->data, l_data_size); \ - /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle tile data\n"); */ \ - fprintf(stderr, "Not enough memory to handle tile data\n"); \ - if (! new_data) { \ - opj_free(l_tilec->data); \ - l_tilec->data = NULL; \ - l_tilec->data_size = 0; \ - return OPJ_FALSE; \ - } \ - l_tilec->data = new_data; \ - /*fprintf(stderr, "\tReallocate data of tilec (int): from %d to %d x OPJ_UINT32\n", l_tilec->data_size, l_data_size);*/ \ - l_tilec->data_size = l_data_size; \ - } \ - \ - l_data_size = l_tilec->numresolutions * (OPJ_UINT32)sizeof(opj_tcd_resolution_t); \ - \ - if (l_tilec->resolutions == 00) { \ - l_tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(l_data_size); \ - if (! l_tilec->resolutions ) { \ - return OPJ_FALSE; \ - } \ - /*fprintf(stderr, "\tAllocate resolutions of tilec (opj_tcd_resolution_t): %d\n",l_data_size);*/ \ - l_tilec->resolutions_size = l_data_size; \ - memset(l_tilec->resolutions,0,l_data_size); \ - } \ - 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_free(l_tilec->resolutions); \ - l_tilec->resolutions = NULL; \ - l_tilec->resolutions_size = 0; \ - return OPJ_FALSE; \ - } \ - l_tilec->resolutions = new_resolutions; \ - /*fprintf(stderr, "\tReallocate data of tilec (int): from %d to %d x OPJ_UINT32\n", l_tilec->resolutions_size, l_data_size);*/ \ - memset(((OPJ_BYTE*) l_tilec->resolutions)+l_tilec->resolutions_size,0,l_data_size - l_tilec->resolutions_size); \ - l_tilec->resolutions_size = l_data_size; \ - } \ - \ - l_level_no = l_tilec->numresolutions - 1; \ - l_res = l_tilec->resolutions; \ - l_step_size = l_tccp->stepsizes; \ - if (l_tccp->qmfbid == 0) { \ - l_gain_ptr = &opj_dwt_getgain_real; \ - } \ - else { \ - l_gain_ptr = &opj_dwt_getgain; \ - } \ - /*fprintf(stderr, "\tlevel_no=%d\n",l_level_no);*/ \ - \ - for(resno = 0; resno < l_tilec->numresolutions; ++resno) { \ - /*fprintf(stderr, "\t\tresno = %d/%d\n", resno, l_tilec->numresolutions);*/ \ - OPJ_INT32 tlcbgxstart, tlcbgystart /*, brcbgxend, brcbgyend*/; \ - OPJ_UINT32 cbgwidthexpn, cbgheightexpn; \ - OPJ_UINT32 cblkwidthexpn, cblkheightexpn; \ - \ - /* border for each resolution level (global) */ \ - l_res->x0 = opj_int_ceildivpow2(l_tilec->x0, (OPJ_INT32)l_level_no); \ - l_res->y0 = opj_int_ceildivpow2(l_tilec->y0, (OPJ_INT32)l_level_no); \ - l_res->x1 = opj_int_ceildivpow2(l_tilec->x1, (OPJ_INT32)l_level_no); \ - l_res->y1 = opj_int_ceildivpow2(l_tilec->y1, (OPJ_INT32)l_level_no); \ - /*fprintf(stderr, "\t\t\tres_x0= %d, res_y0 =%d, res_x1=%d, res_y1=%d\n", l_res->x0, l_res->y0, l_res->x1, l_res->y1);*/ \ - /* p. 35, table A-23, ISO/IEC FDIS154444-1 : 2000 (18 august 2000) */ \ - l_pdx = l_tccp->prcw[resno]; \ - l_pdy = l_tccp->prch[resno]; \ - /*fprintf(stderr, "\t\t\tpdx=%d, pdy=%d\n", l_pdx, l_pdy);*/ \ - /* p. 64, B.6, ISO/IEC FDIS15444-1 : 2000 (18 august 2000) */ \ - l_tl_prc_x_start = opj_int_floordivpow2(l_res->x0, (OPJ_INT32)l_pdx) << l_pdx; \ - l_tl_prc_y_start = opj_int_floordivpow2(l_res->y0, (OPJ_INT32)l_pdy) << l_pdy; \ - l_br_prc_x_end = opj_int_ceildivpow2(l_res->x1, (OPJ_INT32)l_pdx) << l_pdx; \ - l_br_prc_y_end = opj_int_ceildivpow2(l_res->y1, (OPJ_INT32)l_pdy) << l_pdy; \ - /*fprintf(stderr, "\t\t\tprc_x_start=%d, prc_y_start=%d, br_prc_x_end=%d, br_prc_y_end=%d \n", l_tl_prc_x_start, l_tl_prc_y_start, l_br_prc_x_end ,l_br_prc_y_end );*/ \ - \ - l_res->pw = (l_res->x0 == l_res->x1) ? 0 : (OPJ_UINT32)((l_br_prc_x_end - l_tl_prc_x_start) >> l_pdx); \ - l_res->ph = (l_res->y0 == l_res->y1) ? 0 : (OPJ_UINT32)((l_br_prc_y_end - l_tl_prc_y_start) >> l_pdy); \ - /*fprintf(stderr, "\t\t\tres_pw=%d, res_ph=%d\n", l_res->pw, l_res->ph );*/ \ - \ - l_nb_precincts = l_res->pw * l_res->ph; \ - l_nb_precinct_size = l_nb_precincts * (OPJ_UINT32)sizeof(opj_tcd_precinct_t); \ - if (resno == 0) { \ - tlcbgxstart = l_tl_prc_x_start; \ - tlcbgystart = l_tl_prc_y_start; \ - /*brcbgxend = l_br_prc_x_end;*/ \ - /* brcbgyend = l_br_prc_y_end;*/ \ - cbgwidthexpn = l_pdx; \ - cbgheightexpn = l_pdy; \ - l_res->numbands = 1; \ - } \ - else { \ - tlcbgxstart = opj_int_ceildivpow2(l_tl_prc_x_start, 1); \ - tlcbgystart = opj_int_ceildivpow2(l_tl_prc_y_start, 1); \ - /*brcbgxend = opj_int_ceildivpow2(l_br_prc_x_end, 1);*/ \ - /*brcbgyend = opj_int_ceildivpow2(l_br_prc_y_end, 1);*/ \ - cbgwidthexpn = l_pdx - 1; \ - cbgheightexpn = l_pdy - 1; \ - l_res->numbands = 3; \ - } \ - \ - cblkwidthexpn = opj_uint_min(l_tccp->cblkw, cbgwidthexpn); \ - cblkheightexpn = opj_uint_min(l_tccp->cblkh, cbgheightexpn); \ - l_band = l_res->bands; \ - \ - for (bandno = 0; bandno < l_res->numbands; ++bandno) { \ - OPJ_INT32 numbps; \ - /*fprintf(stderr, "\t\t\tband_no=%d/%d\n", bandno, l_res->numbands );*/ \ - \ - if (resno == 0) { \ - l_band->bandno = 0 ; \ - l_band->x0 = opj_int_ceildivpow2(l_tilec->x0, (OPJ_INT32)l_level_no); \ - l_band->y0 = opj_int_ceildivpow2(l_tilec->y0, (OPJ_INT32)l_level_no); \ - l_band->x1 = opj_int_ceildivpow2(l_tilec->x1, (OPJ_INT32)l_level_no); \ - l_band->y1 = opj_int_ceildivpow2(l_tilec->y1, (OPJ_INT32)l_level_no); \ - } \ - else { \ - l_band->bandno = bandno + 1; \ - /* x0b = 1 if bandno = 1 or 3 */ \ - l_x0b = l_band->bandno&1; \ - /* 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)); \ - } \ - \ - /** avoid an if with storing function pointer */ \ - l_gain = (*l_gain_ptr) (l_band->bandno); \ - numbps = (OPJ_INT32)(l_image_comp->prec + l_gain); \ - l_band->stepsize = (OPJ_FLOAT32)(((1.0 + l_step_size->mant / 2048.0) * pow(2.0, (OPJ_INT32) (numbps - l_step_size->expn)))) * FRACTION; \ - l_band->numbps = l_step_size->expn + (OPJ_INT32)l_tccp->numgbits - 1; /* WHY -1 ? */ \ - \ - if (! l_band->precincts) { \ - l_band->precincts = (opj_tcd_precinct_t *) opj_malloc( /*3 * */ l_nb_precinct_size); \ - if (! l_band->precincts) { \ - return OPJ_FALSE; \ - } \ - /*fprintf(stderr, "\t\t\t\tAllocate precincts of a band (opj_tcd_precinct_t): %d\n",l_nb_precinct_size); */ \ - memset(l_band->precincts,0,l_nb_precinct_size); \ - l_band->precincts_data_size = l_nb_precinct_size; \ - } \ - else if (l_band->precincts_data_size < l_nb_precinct_size) { \ - \ - 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_free(l_band->precincts); \ - l_band->precincts = NULL; \ - l_band->precincts_data_size = 0; \ - return OPJ_FALSE; \ - } \ - l_band->precincts = new_precincts; \ - /*fprintf(stderr, "\t\t\t\tReallocate precincts of a band (opj_tcd_precinct_t): from %d to %d\n",l_band->precincts_data_size, l_nb_precinct_size);*/ \ - memset(((OPJ_BYTE *) l_band->precincts) + l_band->precincts_data_size,0,l_nb_precinct_size - l_band->precincts_data_size); \ - l_band->precincts_data_size = l_nb_precinct_size; \ - } \ - \ - l_current_precinct = l_band->precincts; \ - for (precno = 0; precno < l_nb_precincts; ++precno) { \ - OPJ_INT32 tlcblkxstart, tlcblkystart, brcblkxend, brcblkyend; \ - OPJ_INT32 cbgxstart = tlcbgxstart + (OPJ_INT32)(precno % l_res->pw) * (1 << cbgwidthexpn); \ - OPJ_INT32 cbgystart = tlcbgystart + (OPJ_INT32)(precno / l_res->pw) * (1 << cbgheightexpn); \ - OPJ_INT32 cbgxend = cbgxstart + (1 << cbgwidthexpn); \ - OPJ_INT32 cbgyend = cbgystart + (1 << cbgheightexpn); \ - /*fprintf(stderr, "\t precno=%d; bandno=%d, resno=%d; compno=%d\n", precno, bandno , resno, compno);*/ \ - /*fprintf(stderr, "\t tlcbgxstart(=%d) + (precno(=%d) percent res->pw(=%d)) * (1 << cbgwidthexpn(=%d)) \n",tlcbgxstart,precno,l_res->pw,cbgwidthexpn);*/ \ - \ - /* precinct size (global) */ \ - /*fprintf(stderr, "\t cbgxstart=%d, l_band->x0 = %d \n",cbgxstart, l_band->x0);*/ \ - \ - l_current_precinct->x0 = opj_int_max(cbgxstart, l_band->x0); \ - l_current_precinct->y0 = opj_int_max(cbgystart, l_band->y0); \ - l_current_precinct->x1 = opj_int_min(cbgxend, l_band->x1); \ - l_current_precinct->y1 = opj_int_min(cbgyend, l_band->y1); \ - /*fprintf(stderr, "\t prc_x0=%d; prc_y0=%d, prc_x1=%d; prc_y1=%d\n",l_current_precinct->x0, l_current_precinct->y0 ,l_current_precinct->x1, l_current_precinct->y1);*/ \ - \ - tlcblkxstart = opj_int_floordivpow2(l_current_precinct->x0, (OPJ_INT32)cblkwidthexpn) << cblkwidthexpn; \ - /*fprintf(stderr, "\t tlcblkxstart =%d\n",tlcblkxstart );*/ \ - tlcblkystart = opj_int_floordivpow2(l_current_precinct->y0, (OPJ_INT32)cblkheightexpn) << cblkheightexpn; \ - /*fprintf(stderr, "\t tlcblkystart =%d\n",tlcblkystart );*/ \ - brcblkxend = opj_int_ceildivpow2(l_current_precinct->x1, (OPJ_INT32)cblkwidthexpn) << cblkwidthexpn; \ - /*fprintf(stderr, "\t brcblkxend =%d\n",brcblkxend );*/ \ - brcblkyend = opj_int_ceildivpow2(l_current_precinct->y1, (OPJ_INT32)cblkheightexpn) << cblkheightexpn; \ - /*fprintf(stderr, "\t brcblkyend =%d\n",brcblkyend );*/ \ - l_current_precinct->cw = (OPJ_UINT32)((brcblkxend - tlcblkxstart) >> cblkwidthexpn); \ - l_current_precinct->ch = (OPJ_UINT32)((brcblkyend - tlcblkystart) >> cblkheightexpn); \ - \ - l_nb_code_blocks = l_current_precinct->cw * l_current_precinct->ch; \ - /*fprintf(stderr, "\t\t\t\t precinct_cw = %d x recinct_ch = %d\n",l_current_precinct->cw, l_current_precinct->ch); */ \ - l_nb_code_blocks_size = l_nb_code_blocks * (OPJ_UINT32)sizeof(TYPE); \ - \ - if (! l_current_precinct->cblks.ELEMENT) { \ - l_current_precinct->cblks.ELEMENT = (TYPE*) opj_malloc(l_nb_code_blocks_size); \ - if (! l_current_precinct->cblks.ELEMENT ) { \ - return OPJ_FALSE; \ - } \ - /*fprintf(stderr, "\t\t\t\tAllocate cblks of a precinct (opj_tcd_cblk_dec_t): %d\n",l_nb_code_blocks_size);*/ \ - \ - memset(l_current_precinct->cblks.ELEMENT,0,l_nb_code_blocks_size); \ - \ - l_current_precinct->block_size = l_nb_code_blocks_size; \ - } \ - else if (l_nb_code_blocks_size > l_current_precinct->block_size) { \ - TYPE *new_ELEMENT = (TYPE*) opj_realloc(l_current_precinct->cblks.ELEMENT, l_nb_code_blocks_size); \ - if (! new_ELEMENT) { \ - opj_free(l_current_precinct->cblks.ELEMENT); \ - l_current_precinct->cblks.ELEMENT = 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"); \ - return OPJ_FALSE; \ - } \ - l_current_precinct->cblks.ELEMENT = new_ELEMENT; \ - /*fprintf(stderr, "\t\t\t\tReallocate cblks of a precinct (opj_tcd_cblk_dec_t): from %d to %d\n",l_current_precinct->block_size, l_nb_code_blocks_size); */\ - \ - memset(((OPJ_BYTE *) l_current_precinct->cblks.ELEMENT) + l_current_precinct->block_size \ - ,0 \ - ,l_nb_code_blocks_size - l_current_precinct->block_size); \ - \ - l_current_precinct->block_size = l_nb_code_blocks_size; \ - } \ - \ - if (! l_current_precinct->incltree) { \ - l_current_precinct->incltree = opj_tgt_create(l_current_precinct->cw, \ - l_current_precinct->ch); \ - } \ - else{ \ - l_current_precinct->incltree = opj_tgt_init(l_current_precinct->incltree, \ - l_current_precinct->cw, \ - l_current_precinct->ch); \ - } \ - \ - if (! l_current_precinct->incltree) { \ - fprintf(stderr, "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); \ - } \ - else { \ - l_current_precinct->imsbtree = opj_tgt_init( \ - l_current_precinct->imsbtree, \ - l_current_precinct->cw, \ - l_current_precinct->ch); \ - } \ - \ - if (! l_current_precinct->imsbtree) { \ - fprintf(stderr, "WARNING: No imsbtree created.\n"); \ - /*return OPJ_FALSE;*/ \ - } \ - \ - l_code_block = l_current_precinct->cblks.ELEMENT; \ - \ - for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) { \ - OPJ_INT32 cblkxstart = tlcblkxstart + (OPJ_INT32)(cblkno % l_current_precinct->cw) * (1 << cblkwidthexpn); \ - OPJ_INT32 cblkystart = tlcblkystart + (OPJ_INT32)(cblkno / l_current_precinct->cw) * (1 << cblkheightexpn); \ - OPJ_INT32 cblkxend = cblkxstart + (1 << cblkwidthexpn); \ - OPJ_INT32 cblkyend = cblkystart + (1 << cblkheightexpn); \ - \ - if (! FUNCTION_ELEMENT(l_code_block)) { \ - return OPJ_FALSE; \ - } \ - /* code-block size (global) */ \ - l_code_block->x0 = opj_int_max(cblkxstart, l_current_precinct->x0); \ - 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); \ - ++l_code_block; \ - } \ - ++l_current_precinct; \ - } /* precno */ \ - ++l_band; \ - ++l_step_size; \ - } /* bandno */ \ - ++l_res; \ - --l_level_no; \ - } /* resno */ \ - ++l_tccp; \ - ++l_tilec; \ - ++l_image_comp; \ - } /* compno */ \ - return OPJ_TRUE; \ -} \ - - -OPJ_MACRO_TCD_ALLOCATE(opj_tcd_init_encode_tile, opj_tcd_cblk_enc_t, 1.f, enc, opj_tcd_code_block_enc_allocate) -OPJ_MACRO_TCD_ALLOCATE(opj_tcd_init_decode_tile, opj_tcd_cblk_dec_t, 0.5f, dec, opj_tcd_code_block_dec_allocate) - -#undef OPJ_MACRO_TCD_ALLOCATE + +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_UINT32 (*l_gain_ptr)(OPJ_UINT32) = 00; + OPJ_UINT32 compno, resno, bandno, precno, cblkno; + opj_tcp_t * l_tcp = 00; + opj_cp_t * l_cp = 00; + opj_tcd_tile_t * l_tile = 00; + opj_tccp_t *l_tccp = 00; + opj_tcd_tilecomp_t *l_tilec = 00; + opj_image_comp_t * l_image_comp = 00; + opj_tcd_resolution_t *l_res = 00; + opj_tcd_band_t *l_band = 00; + opj_stepsize_t * l_step_size = 00; + opj_tcd_precinct_t *l_current_precinct = 00; + opj_image_t *l_image = 00; + OPJ_UINT32 p,q; + OPJ_UINT32 l_level_no; + OPJ_UINT32 l_pdx, l_pdy; + OPJ_UINT32 l_gain; + OPJ_INT32 l_x0b, l_y0b; + /* 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 */ + OPJ_UINT32 l_nb_precincts; + /* room needed to store l_nb_precinct precinct for a resolution */ + OPJ_UINT32 l_nb_precinct_size; + /* number of code blocks for a precinct*/ + OPJ_UINT32 l_nb_code_blocks; + /* room needed to store l_nb_code_blocks code blocks for a precinct*/ + OPJ_UINT32 l_nb_code_blocks_size; + /* size of data for a tile */ + OPJ_UINT32 l_data_size; + + l_cp = p_tcd->cp; + l_tcp = &(l_cp->tcps[p_tile_no]); + l_tile = p_tcd->tcd_image->tiles; + l_tccp = l_tcp->tccps; + l_tilec = l_tile->comps; + l_image = p_tcd->image; + l_image_comp = p_tcd->image->comps; + + p = p_tile_no % l_cp->tw; /* tile coordinates */ + q = p_tile_no / l_cp->tw; + /*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); + /* testcase 1888.pdf.asan.35.988 */ + if (l_tccp->numresolutions == 0) { + fprintf(stderr, "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);*/ + + /*tile->numcomps = image->numcomps; */ + for (compno = 0; compno < l_tile->numcomps; ++compno) { + /*fprintf(stderr, "compno = %d/%d\n", compno, l_tile->numcomps);*/ + l_image_comp->resno_decoded = 0; + /* border of each l_tile component (global) */ + l_tilec->x0 = opj_int_ceildiv(l_tile->x0, (OPJ_INT32)l_image_comp->dx); + l_tilec->y0 = opj_int_ceildiv(l_tile->y0, (OPJ_INT32)l_image_comp->dy); + l_tilec->x1 = opj_int_ceildiv(l_tile->x1, (OPJ_INT32)l_image_comp->dx); + 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);*/ + + /* 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; + } + else { + l_tilec->minimum_num_resolutions = l_tccp->numresolutions - l_cp->m_specific_param.m_dec.m_reduce; + } + + l_tilec->data_size_needed = l_data_size; + if (p_tcd->m_is_decoder && !opj_alloc_tile_component_data(l_tilec)) { + return OPJ_FALSE; + } + + l_data_size = l_tilec->numresolutions * (OPJ_UINT32)sizeof(opj_tcd_resolution_t); + + if (l_tilec->resolutions == 00) { + l_tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(l_data_size); + if (! l_tilec->resolutions ) { + return OPJ_FALSE; + } + /*fprintf(stderr, "\tAllocate resolutions of tilec (opj_tcd_resolution_t): %d\n",l_data_size);*/ + l_tilec->resolutions_size = l_data_size; + memset(l_tilec->resolutions,0,l_data_size); + } + 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_free(l_tilec->resolutions); + l_tilec->resolutions = NULL; + l_tilec->resolutions_size = 0; + return OPJ_FALSE; + } + l_tilec->resolutions = new_resolutions; + /*fprintf(stderr, "\tReallocate data of tilec (int): from %d to %d x OPJ_UINT32\n", l_tilec->resolutions_size, l_data_size);*/ + memset(((OPJ_BYTE*) l_tilec->resolutions)+l_tilec->resolutions_size,0,l_data_size - l_tilec->resolutions_size); + l_tilec->resolutions_size = l_data_size; + } + + l_level_no = l_tilec->numresolutions - 1; + l_res = l_tilec->resolutions; + l_step_size = l_tccp->stepsizes; + if (l_tccp->qmfbid == 0) { + l_gain_ptr = &opj_dwt_getgain_real; + } + else { + l_gain_ptr = &opj_dwt_getgain; + } + /*fprintf(stderr, "\tlevel_no=%d\n",l_level_no);*/ + + for (resno = 0; resno < l_tilec->numresolutions; ++resno) { + /*fprintf(stderr, "\t\tresno = %d/%d\n", resno, l_tilec->numresolutions);*/ + OPJ_INT32 tlcbgxstart, tlcbgystart /*, brcbgxend, brcbgyend*/; + OPJ_UINT32 cbgwidthexpn, cbgheightexpn; + OPJ_UINT32 cblkwidthexpn, cblkheightexpn; + + /* border for each resolution level (global) */ + l_res->x0 = opj_int_ceildivpow2(l_tilec->x0, (OPJ_INT32)l_level_no); + l_res->y0 = opj_int_ceildivpow2(l_tilec->y0, (OPJ_INT32)l_level_no); + l_res->x1 = opj_int_ceildivpow2(l_tilec->x1, (OPJ_INT32)l_level_no); + l_res->y1 = opj_int_ceildivpow2(l_tilec->y1, (OPJ_INT32)l_level_no); + /*fprintf(stderr, "\t\t\tres_x0= %d, res_y0 =%d, res_x1=%d, res_y1=%d\n", l_res->x0, l_res->y0, l_res->x1, l_res->y1);*/ + /* p. 35, table A-23, ISO/IEC FDIS154444-1 : 2000 (18 august 2000) */ + l_pdx = l_tccp->prcw[resno]; + l_pdy = l_tccp->prch[resno]; + /*fprintf(stderr, "\t\t\tpdx=%d, pdy=%d\n", l_pdx, l_pdy);*/ + /* p. 64, B.6, ISO/IEC FDIS15444-1 : 2000 (18 august 2000) */ + l_tl_prc_x_start = opj_int_floordivpow2(l_res->x0, (OPJ_INT32)l_pdx) << l_pdx; + l_tl_prc_y_start = opj_int_floordivpow2(l_res->y0, (OPJ_INT32)l_pdy) << l_pdy; + l_br_prc_x_end = opj_int_ceildivpow2(l_res->x1, (OPJ_INT32)l_pdx) << l_pdx; + l_br_prc_y_end = opj_int_ceildivpow2(l_res->y1, (OPJ_INT32)l_pdy) << l_pdy; + /*fprintf(stderr, "\t\t\tprc_x_start=%d, prc_y_start=%d, br_prc_x_end=%d, br_prc_y_end=%d \n", l_tl_prc_x_start, l_tl_prc_y_start, l_br_prc_x_end ,l_br_prc_y_end );*/ + + l_res->pw = (l_res->x0 == l_res->x1) ? 0 : (OPJ_UINT32)((l_br_prc_x_end - l_tl_prc_x_start) >> l_pdx); + l_res->ph = (l_res->y0 == l_res->y1) ? 0 : (OPJ_UINT32)((l_br_prc_y_end - l_tl_prc_y_start) >> l_pdy); + /*fprintf(stderr, "\t\t\tres_pw=%d, res_ph=%d\n", l_res->pw, l_res->ph );*/ + + l_nb_precincts = l_res->pw * l_res->ph; + l_nb_precinct_size = l_nb_precincts * (OPJ_UINT32)sizeof(opj_tcd_precinct_t); + if (resno == 0) { + tlcbgxstart = l_tl_prc_x_start; + tlcbgystart = l_tl_prc_y_start; + /*brcbgxend = l_br_prc_x_end;*/ + /* brcbgyend = l_br_prc_y_end;*/ + cbgwidthexpn = l_pdx; + cbgheightexpn = l_pdy; + l_res->numbands = 1; + } + else { + tlcbgxstart = opj_int_ceildivpow2(l_tl_prc_x_start, 1); + tlcbgystart = opj_int_ceildivpow2(l_tl_prc_y_start, 1); + /*brcbgxend = opj_int_ceildivpow2(l_br_prc_x_end, 1);*/ + /*brcbgyend = opj_int_ceildivpow2(l_br_prc_y_end, 1);*/ + cbgwidthexpn = l_pdx - 1; + cbgheightexpn = l_pdy - 1; + l_res->numbands = 3; + } + + cblkwidthexpn = opj_uint_min(l_tccp->cblkw, cbgwidthexpn); + cblkheightexpn = opj_uint_min(l_tccp->cblkh, cbgheightexpn); + l_band = l_res->bands; + + for (bandno = 0; bandno < l_res->numbands; ++bandno) { + OPJ_INT32 numbps; + /*fprintf(stderr, "\t\t\tband_no=%d/%d\n", bandno, l_res->numbands );*/ + + if (resno == 0) { + l_band->bandno = 0 ; + l_band->x0 = opj_int_ceildivpow2(l_tilec->x0, (OPJ_INT32)l_level_no); + l_band->y0 = opj_int_ceildivpow2(l_tilec->y0, (OPJ_INT32)l_level_no); + l_band->x1 = opj_int_ceildivpow2(l_tilec->x1, (OPJ_INT32)l_level_no); + l_band->y1 = opj_int_ceildivpow2(l_tilec->y1, (OPJ_INT32)l_level_no); + } + else { + l_band->bandno = bandno + 1; + /* x0b = 1 if bandno = 1 or 3 */ + l_x0b = l_band->bandno&1; + /* 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)); + } + + /** avoid an if with storing function pointer */ + l_gain = (*l_gain_ptr) (l_band->bandno); + numbps = (OPJ_INT32)(l_image_comp->prec + l_gain); + l_band->stepsize = (OPJ_FLOAT32)(((1.0 + l_step_size->mant / 2048.0) * pow(2.0, (OPJ_INT32) (numbps - l_step_size->expn)))) * fraction; + l_band->numbps = l_step_size->expn + (OPJ_INT32)l_tccp->numgbits - 1; /* WHY -1 ? */ + + if (! l_band->precincts) { + l_band->precincts = (opj_tcd_precinct_t *) opj_malloc( /*3 * */ l_nb_precinct_size); + if (! l_band->precincts) { + return OPJ_FALSE; + } + /*fprintf(stderr, "\t\t\t\tAllocate precincts of a band (opj_tcd_precinct_t): %d\n",l_nb_precinct_size); */ + memset(l_band->precincts,0,l_nb_precinct_size); + l_band->precincts_data_size = l_nb_precinct_size; + } + else if (l_band->precincts_data_size < l_nb_precinct_size) { + + 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_free(l_band->precincts); + l_band->precincts = NULL; + l_band->precincts_data_size = 0; + return OPJ_FALSE; + } + l_band->precincts = new_precincts; + /*fprintf(stderr, "\t\t\t\tReallocate precincts of a band (opj_tcd_precinct_t): from %d to %d\n",l_band->precincts_data_size, l_nb_precinct_size);*/ + memset(((OPJ_BYTE *) l_band->precincts) + l_band->precincts_data_size,0,l_nb_precinct_size - l_band->precincts_data_size); + l_band->precincts_data_size = l_nb_precinct_size; + } + + l_current_precinct = l_band->precincts; + for (precno = 0; precno < l_nb_precincts; ++precno) { + OPJ_INT32 tlcblkxstart, tlcblkystart, brcblkxend, brcblkyend; + OPJ_INT32 cbgxstart = tlcbgxstart + (OPJ_INT32)(precno % l_res->pw) * (1 << cbgwidthexpn); + OPJ_INT32 cbgystart = tlcbgystart + (OPJ_INT32)(precno / l_res->pw) * (1 << cbgheightexpn); + OPJ_INT32 cbgxend = cbgxstart + (1 << cbgwidthexpn); + OPJ_INT32 cbgyend = cbgystart + (1 << cbgheightexpn); + /*fprintf(stderr, "\t precno=%d; bandno=%d, resno=%d; compno=%d\n", precno, bandno , resno, compno);*/ + /*fprintf(stderr, "\t tlcbgxstart(=%d) + (precno(=%d) percent res->pw(=%d)) * (1 << cbgwidthexpn(=%d)) \n",tlcbgxstart,precno,l_res->pw,cbgwidthexpn);*/ + + /* precinct size (global) */ + /*fprintf(stderr, "\t cbgxstart=%d, l_band->x0 = %d \n",cbgxstart, l_band->x0);*/ + + l_current_precinct->x0 = opj_int_max(cbgxstart, l_band->x0); + l_current_precinct->y0 = opj_int_max(cbgystart, l_band->y0); + l_current_precinct->x1 = opj_int_min(cbgxend, l_band->x1); + l_current_precinct->y1 = opj_int_min(cbgyend, l_band->y1); + /*fprintf(stderr, "\t prc_x0=%d; prc_y0=%d, prc_x1=%d; prc_y1=%d\n",l_current_precinct->x0, l_current_precinct->y0 ,l_current_precinct->x1, l_current_precinct->y1);*/ + + tlcblkxstart = opj_int_floordivpow2(l_current_precinct->x0, (OPJ_INT32)cblkwidthexpn) << cblkwidthexpn; + /*fprintf(stderr, "\t tlcblkxstart =%d\n",tlcblkxstart );*/ + tlcblkystart = opj_int_floordivpow2(l_current_precinct->y0, (OPJ_INT32)cblkheightexpn) << cblkheightexpn; + /*fprintf(stderr, "\t tlcblkystart =%d\n",tlcblkystart );*/ + brcblkxend = opj_int_ceildivpow2(l_current_precinct->x1, (OPJ_INT32)cblkwidthexpn) << cblkwidthexpn; + /*fprintf(stderr, "\t brcblkxend =%d\n",brcblkxend );*/ + brcblkyend = opj_int_ceildivpow2(l_current_precinct->y1, (OPJ_INT32)cblkheightexpn) << cblkheightexpn; + /*fprintf(stderr, "\t brcblkyend =%d\n",brcblkyend );*/ + l_current_precinct->cw = (OPJ_UINT32)((brcblkxend - tlcblkxstart) >> cblkwidthexpn); + l_current_precinct->ch = (OPJ_UINT32)((brcblkyend - tlcblkystart) >> cblkheightexpn); + + l_nb_code_blocks = l_current_precinct->cw * l_current_precinct->ch; + /*fprintf(stderr, "\t\t\t\t precinct_cw = %d x recinct_ch = %d\n",l_current_precinct->cw, l_current_precinct->ch); */ + l_nb_code_blocks_size = l_nb_code_blocks * (OPJ_UINT32)sizeof_block; + + if (! l_current_precinct->cblks.blocks) { + l_current_precinct->cblks.blocks = opj_malloc(l_nb_code_blocks_size); + if (! l_current_precinct->cblks.blocks ) { + return OPJ_FALSE; + } + /*fprintf(stderr, "\t\t\t\tAllocate cblks of a precinct (opj_tcd_cblk_dec_t): %d\n",l_nb_code_blocks_size);*/ + + memset(l_current_precinct->cblks.blocks,0,l_nb_code_blocks_size); + + l_current_precinct->block_size = l_nb_code_blocks_size; + } + else if (l_nb_code_blocks_size > l_current_precinct->block_size) { + void *new_blocks = opj_realloc(l_current_precinct->cblks.blocks, l_nb_code_blocks_size); + if (! new_blocks) { + 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"); + return OPJ_FALSE; + } + l_current_precinct->cblks.blocks = new_blocks; + /*fprintf(stderr, "\t\t\t\tReallocate cblks of a precinct (opj_tcd_cblk_dec_t): from %d to %d\n",l_current_precinct->block_size, l_nb_code_blocks_size); */ + + memset(((OPJ_BYTE *) l_current_precinct->cblks.blocks) + l_current_precinct->block_size + ,0 + ,l_nb_code_blocks_size - l_current_precinct->block_size); + + l_current_precinct->block_size = l_nb_code_blocks_size; + } + + if (! l_current_precinct->incltree) { + l_current_precinct->incltree = opj_tgt_create(l_current_precinct->cw, + l_current_precinct->ch); + } + else{ + l_current_precinct->incltree = opj_tgt_init(l_current_precinct->incltree, + l_current_precinct->cw, + l_current_precinct->ch); + } + + if (! l_current_precinct->incltree) { + fprintf(stderr, "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); + } + else { + l_current_precinct->imsbtree = opj_tgt_init( + l_current_precinct->imsbtree, + l_current_precinct->cw, + l_current_precinct->ch); + } + + if (! l_current_precinct->imsbtree) { + fprintf(stderr, "WARNING: No imsbtree created.\n"); + /*return OPJ_FALSE;*/ + } + + for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) { + OPJ_INT32 cblkxstart = tlcblkxstart + (OPJ_INT32)(cblkno % l_current_precinct->cw) * (1 << cblkwidthexpn); + OPJ_INT32 cblkystart = tlcblkystart + (OPJ_INT32)(cblkno / l_current_precinct->cw) * (1 << cblkheightexpn); + OPJ_INT32 cblkxend = cblkxstart + (1 << cblkwidthexpn); + OPJ_INT32 cblkyend = cblkystart + (1 << cblkheightexpn); + + if (isEncoder) { + opj_tcd_cblk_enc_t* l_code_block = l_current_precinct->cblks.enc + cblkno; + + if (! opj_tcd_code_block_enc_allocate(l_code_block)) { + return OPJ_FALSE; + } + /* code-block size (global) */ + l_code_block->x0 = opj_int_max(cblkxstart, l_current_precinct->x0); + 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); + } else { + opj_tcd_cblk_dec_t* l_code_block = l_current_precinct->cblks.dec + cblkno; + + if (! opj_tcd_code_block_dec_allocate(l_code_block)) { + return OPJ_FALSE; + } + /* code-block size (global) */ + l_code_block->x0 = opj_int_max(cblkxstart, l_current_precinct->x0); + 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); + } + } + ++l_current_precinct; + } /* precno */ + ++l_band; + ++l_step_size; + } /* bandno */ + ++l_res; + --l_level_no; + } /* resno */ + ++l_tccp; + ++l_tilec; + ++l_image_comp; + } /* compno */ + return OPJ_TRUE; +} + +OPJ_BOOL opj_tcd_init_encode_tile (opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no) +{ + return opj_tcd_init_tile(p_tcd, p_tile_no, OPJ_TRUE, 1.0F, sizeof(opj_tcd_cblk_enc_t)); +} + +OPJ_BOOL opj_tcd_init_decode_tile (opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no) +{ + return opj_tcd_init_tile(p_tcd, p_tile_no, OPJ_FALSE, 0.5F, sizeof(opj_tcd_cblk_dec_t)); +} /** * Allocates memory for an encoding code block. @@ -1457,9 +1498,12 @@ void opj_tcd_free_tile(opj_tcd_t *p_tcd) l_tile_comp->resolutions = 00; } - if (l_tile_comp->data) { + if (l_tile_comp->ownsData && l_tile_comp->data) { opj_free(l_tile_comp->data); l_tile_comp->data = 00; + l_tile_comp->ownsData = 0; + l_tile_comp->data_size = 0; + l_tile_comp->data_size_needed = 0; } ++l_tile_comp; } @@ -1512,7 +1556,7 @@ OPJ_BOOL opj_tcd_t1_decode ( opj_tcd_t *p_tcd ) opj_tccp_t * l_tccp = p_tcd->tcp->tccps; - l_t1 = opj_t1_create(); + l_t1 = opj_t1_create(OPJ_FALSE); if (l_t1 == 00) { return OPJ_FALSE; } @@ -1947,7 +1991,7 @@ OPJ_BOOL opj_tcd_t1_encode ( opj_tcd_t *p_tcd ) const OPJ_FLOAT64 * l_mct_norms; opj_tcp_t * l_tcp = p_tcd->tcp; - l_t1 = opj_t1_create(); + l_t1 = opj_t1_create(OPJ_TRUE); if (l_t1 == 00) { return OPJ_FALSE; } diff --git a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/tcd.h b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/tcd.h index 360923b151..3cb38d26c5 100644 --- a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/tcd.h +++ b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/tcd.h @@ -122,6 +122,7 @@ typedef struct opj_tcd_precinct { union{ /* code-blocks information */ opj_tcd_cblk_enc_t* enc; opj_tcd_cblk_dec_t* dec; + void* blocks; } cblks; OPJ_UINT32 block_size; /* size taken by cblks (in bytes) */ opj_tgt_tree_t *incltree; /* inclusion tree */ @@ -155,14 +156,16 @@ FIXME DOC */ typedef struct opj_tcd_tilecomp { - OPJ_INT32 x0, y0, x1, y1; /* dimension of component : left upper corner (x0, y0) right low corner (x1,y1) */ - OPJ_UINT32 numresolutions; /* number of resolutions level */ - OPJ_UINT32 minimum_num_resolutions; /* number of resolutions level to decode (at max)*/ - opj_tcd_resolution_t *resolutions; /* resolutions information */ - OPJ_UINT32 resolutions_size; /* size of data for resolutions (in bytes) */ - OPJ_INT32 *data; /* data of the component */ - OPJ_UINT32 data_size; /* size of the data of the component */ - OPJ_INT32 numpix; /* add fixed_quality */ + OPJ_INT32 x0, y0, x1, y1; /* dimension of component : left upper corner (x0, y0) right low corner (x1,y1) */ + OPJ_UINT32 numresolutions; /* number of resolutions level */ + OPJ_UINT32 minimum_num_resolutions; /* number of resolutions level to decode (at max)*/ + opj_tcd_resolution_t *resolutions; /* resolutions information */ + OPJ_UINT32 resolutions_size; /* size of data for resolutions (in bytes) */ + OPJ_INT32 *data; /* data of the component */ + OPJ_BOOL ownsData; /* if true, then need to free after usage, otherwise do not free */ + OPJ_UINT32 data_size_needed; /* we may either need to allocate this amount of data, or re-use image data and ignore this value */ + OPJ_UINT32 data_size; /* size of the data of the component */ + OPJ_INT32 numpix; /* add fixed_quality */ } opj_tcd_tilecomp_t; @@ -346,6 +349,13 @@ OPJ_BOOL opj_tcd_copy_tile_data (opj_tcd_t *p_tcd, OPJ_BYTE * p_src, OPJ_UINT32 p_src_length ); +/** + * Allocates tile component data + * + * + */ +OPJ_BOOL opj_alloc_tile_component_data(opj_tcd_tilecomp_t *l_tilec); + /* ----------------------------------------------------------------------- */ /*@}*/ -- cgit v1.2.3