Index: core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/j2k.c |
diff --git a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/j2k.c b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/j2k.c |
index 46f50eeb8a9406f17de14240381f479a91abc9bd..4a1c103f4b14435b8f6bca454539a90a3c0a96d5 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;i<l_nb_tiles;++i) { |
if (! opj_j2k_pre_write_tile(p_j2k,i,p_stream,p_manager)) { |
- opj_free(l_current_data); |
+ if (l_current_data) { |
+ opj_free(l_current_data); |
+ } |
return OPJ_FALSE; |
} |
- l_current_tile_size = opj_tcd_get_encoded_tile_size(p_j2k->m_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;j<p_j2k->m_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;i<p_tcd->image->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;j<p_j2k->m_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; |
} |