solve problem with input of image_to_j2k; using the right return type comparison for opj_stream_flush; add j2k_write_com_v2, j2k_write_poc_v2, j2k_write_eoc_v2 and j2k_write_tlm_v2

This commit is contained in:
Mickael Savinaud 2012-05-13 22:13:58 +00:00
parent 821d7a8941
commit 80c23d4519
4 changed files with 322 additions and 31 deletions

View File

@ -1776,7 +1776,7 @@ int main(int argc, char **argv) {
/* encode the destination image */
/* ---------------------------- */
switch(parameters.decod_format) {
switch(parameters.cod_format) {
case J2K_CFMT: /* JPEG-2000 codestream */
{
/* Get a decoder handle */

View File

@ -640,47 +640,48 @@ OPJ_SIZE_T opj_stream_read_data (opj_stream_private_t * p_stream,OPJ_BYTE * p_bu
* @param p_event_mgr the user event manager to be notified of special events.
* @return the number of bytes writtent, or -1 if an error occured.
*/
OPJ_SIZE_T opj_stream_write_data (opj_stream_private_t * p_stream,const OPJ_BYTE * p_buffer,OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
OPJ_SIZE_T opj_stream_write_data (opj_stream_private_t * p_stream,
const OPJ_BYTE * p_buffer,
OPJ_SIZE_T p_size,
opj_event_mgr_t * p_event_mgr)
{
OPJ_SIZE_T l_remaining_bytes = 0;
OPJ_SIZE_T l_write_nb_bytes = 0;
if
(p_stream->m_status & opj_stream_e_error)
{
if (p_stream->m_status & opj_stream_e_error) {
return (OPJ_SIZE_T)-1;
}
while(1)
{
while(1) {
l_remaining_bytes = p_stream->m_buffer_size - p_stream->m_bytes_in_buffer;
/* we have more memory than required */
if
(l_remaining_bytes >= p_size)
{
memcpy(p_stream->m_current_data,p_buffer,p_size);
if (l_remaining_bytes >= p_size) {
memcpy(p_stream->m_current_data, p_buffer, p_size);
p_stream->m_current_data += p_size;
p_stream->m_bytes_in_buffer += p_size;
l_write_nb_bytes += p_size;
p_stream->m_byte_offset += (OPJ_OFF_T)p_size;
return l_write_nb_bytes;
}
/* we copy data and then do an actual read on the stream */
if
(l_remaining_bytes)
{
if (l_remaining_bytes) {
l_write_nb_bytes += l_remaining_bytes;
memcpy(p_stream->m_current_data,p_buffer,l_remaining_bytes);
p_stream->m_current_data = p_stream->m_stored_data;
p_buffer += l_remaining_bytes;
p_size -= l_remaining_bytes;
p_stream->m_bytes_in_buffer += l_remaining_bytes;
p_stream->m_byte_offset += (OPJ_OFF_T)l_remaining_bytes;
}
if
(! opj_stream_flush(p_stream, p_event_mgr))
{
if (opj_stream_flush(p_stream, p_event_mgr) == EXIT_FAILURE) {
return (OPJ_SIZE_T)-1;
}
}
@ -697,25 +698,28 @@ opj_bool opj_stream_flush (opj_stream_private_t * p_stream, opj_event_mgr_t * p_
{
/* the number of bytes written on the media. */
OPJ_SIZE_T l_current_write_nb_bytes = 0;
p_stream->m_current_data = p_stream->m_stored_data;
while
(p_stream->m_bytes_in_buffer)
{
while (p_stream->m_bytes_in_buffer) {
/* we should do an actual write on the media */
l_current_write_nb_bytes = p_stream->m_write_fn(p_stream->m_current_data,p_stream->m_bytes_in_buffer,p_stream->m_user_data);
if
(l_current_write_nb_bytes == (OPJ_SIZE_T)-1)
{
l_current_write_nb_bytes = p_stream->m_write_fn(p_stream->m_current_data,
p_stream->m_bytes_in_buffer,
p_stream->m_user_data);
if (l_current_write_nb_bytes == (OPJ_SIZE_T)-1) {
p_stream->m_status |= opj_stream_e_error;
opj_event_msg_v2(p_event_mgr, EVT_INFO, "Error on writting stream!\n");
return EXIT_FAILURE;
}
p_stream->m_current_data += l_current_write_nb_bytes;
p_stream->m_bytes_in_buffer -= l_current_write_nb_bytes;
}
p_stream->m_current_data = p_stream->m_stored_data;
return EXIT_SUCCESS;
}

View File

@ -467,6 +467,18 @@ Write the COM marker (comment)
@param j2k J2K handle
*/
static void j2k_write_com(opj_j2k_t *j2k);
/**
* Writes the COM marker (comment)
*
* @param p_stream the stream to write data to.
* @param p_j2k J2K codec.
* @param p_manager the user event manager.
*/
static opj_bool j2k_write_com_v2( opj_j2k_v2_t *p_j2k,
struct opj_stream_private *p_stream,
struct opj_event_mgr * p_manager );
/**
Read the COM marker (comment)
@param j2k J2K handle
@ -709,6 +721,17 @@ Write the POC marker (progression order change)
*/
static void j2k_write_poc(opj_j2k_t *j2k);
/**
* Writes the POC marker (Progression Order Change)
*
* @param p_stream the stream to write data to.
* @param p_j2k J2K codec.
* @param p_manager the user event manager.
*/
static opj_bool j2k_write_poc_v2( opj_j2k_v2_t *p_j2k,
struct opj_stream_private *p_stream,
struct opj_event_mgr * p_manager );
/**
* Writes the POC marker (Progression Order Change)
*
@ -900,6 +923,18 @@ Write the TLM marker (Mainheader)
@param j2k J2K handle
*/
static void j2k_write_tlm(opj_j2k_t *j2k);
/**
* Writes the TLM marker (Tile Length Marker)
*
* @param p_stream the stream to write data to.
* @param p_j2k J2K codec.
* @param p_manager the user event manager.
*/
static opj_bool j2k_write_tlm_v2( opj_j2k_v2_t *p_j2k,
struct opj_stream_private *p_stream,
struct opj_event_mgr * p_manager );
/**
Write the SOT marker (start of tile-part)
@param j2k J2K handle
@ -1036,6 +1071,17 @@ static opj_bool j2k_read_rgn_v2 (
struct opj_event_mgr * p_manager
) ;
/**
* Writes the EOC marker (End of Codestream)
*
* @param p_stream the stream to write data to.
* @param p_j2k J2K codec.
* @param p_manager the user event manager.
*/
static opj_bool j2k_write_eoc_v2( opj_j2k_t *p_j2k,
struct opj_stream_private *p_stream,
struct opj_event_mgr * p_manager );
/**
Write the EOC marker (end of codestream)
@param j2k J2K handle
@ -2830,6 +2876,63 @@ static void j2k_write_com(opj_j2k_t *j2k) {
}
}
/**
* Writes the COM marker (comment)
*
* @param p_stream the stream to write data to.
* @param p_j2k J2K codec.
* @param p_manager the user event manager.
*/
opj_bool j2k_write_com_v2( opj_j2k_v2_t *p_j2k,
struct opj_stream_private *p_stream,
struct opj_event_mgr * p_manager )
{
OPJ_UINT32 l_comment_size;
OPJ_UINT32 l_total_com_size;
const OPJ_CHAR *l_comment;
OPJ_BYTE * l_current_ptr = 00;
// preconditions
assert(p_j2k != 00);
assert(p_stream != 00);
assert(p_manager != 00);
l_comment = p_j2k->m_cp.comment;
l_comment_size = strlen(l_comment);
l_total_com_size = l_comment_size + 6;
if (l_total_com_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
p_j2k->m_specific_param.m_encoder.m_header_tile_data
= (OPJ_BYTE*)opj_realloc( p_j2k->m_specific_param.m_encoder.m_header_tile_data,
l_total_com_size);
if(! p_j2k->m_specific_param.m_encoder.m_header_tile_data) {
return OPJ_FALSE;
}
p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_total_com_size;
}
l_current_ptr = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
opj_write_bytes(l_current_ptr,J2K_MS_COM , 2); /* COM */
l_current_ptr+=2;
opj_write_bytes(l_current_ptr,l_total_com_size - 2 , 2); /* L_COM */
l_current_ptr+=2;
opj_write_bytes(l_current_ptr,1 , 2); /* General use (IS 8859-15:1999 (Latin) values) */
l_current_ptr+=2;
memcpy( l_current_ptr,l_comment,l_comment_size);
if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_total_com_size,p_manager) != l_total_com_size) {
return OPJ_FALSE;
}
return OPJ_TRUE;
}
static void j2k_read_com(opj_j2k_t *j2k) {
int len;
@ -3887,6 +3990,66 @@ static void j2k_write_poc(opj_j2k_t *j2k) {
}
}
/**
* Writes the POC marker (Progression Order Change)
*
* @param p_stream the stream to write data to.
* @param p_j2k J2K codec.
* @param p_manager the user event manager.
*/
opj_bool j2k_write_poc_v2( opj_j2k_v2_t *p_j2k,
struct opj_stream_private *p_stream,
struct opj_event_mgr * p_manager )
{
OPJ_UINT32 l_nb_comp;
OPJ_UINT32 l_nb_poc;
OPJ_UINT32 l_poc_size;
OPJ_UINT32 l_written_size = 0;
opj_tcp_v2_t *l_tcp = 00;
opj_tccp_t *l_tccp = 00;
OPJ_UINT32 l_poc_room;
// preconditions
assert(p_j2k != 00);
assert(p_manager != 00);
assert(p_stream != 00);
l_tcp = &p_j2k->m_cp.tcps[p_j2k->m_current_tile_number];
l_tccp = &l_tcp->tccps[0];
l_nb_comp = p_j2k->m_private_image->numcomps;
l_nb_poc = 1 + l_tcp->numpocs;
if (l_nb_comp <= 256) {
l_poc_room = 1;
}
else {
l_poc_room = 2;
}
l_poc_size = 4 + (5 + 2 * l_poc_room) * l_nb_poc;
if (l_poc_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
p_j2k->m_specific_param.m_encoder.m_header_tile_data
= (OPJ_BYTE*)opj_realloc(
p_j2k->m_specific_param.m_encoder.m_header_tile_data,
l_poc_size);
if (! p_j2k->m_specific_param.m_encoder.m_header_tile_data) {
return OPJ_FALSE;
}
p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_poc_size;
}
j2k_write_poc_in_memory(p_j2k,p_j2k->m_specific_param.m_encoder.m_header_tile_data,&l_written_size,p_manager);
if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_poc_size,p_manager) != l_poc_size) {
return OPJ_FALSE;
}
return OPJ_TRUE;
}
/**
* Writes the POC marker (Progression Order Change)
*
@ -4906,6 +5069,66 @@ opj_bool j2k_read_ppt_v2 ( opj_j2k_v2_t *p_j2k,
return OPJ_TRUE;
}
/**
* Writes the TLM marker (Tile Length Marker)
*
* @param p_stream the stream to write data to.
* @param p_j2k J2K codec.
* @param p_manager the user event manager.
*/
opj_bool j2k_write_tlm_v2( opj_j2k_v2_t *p_j2k,
struct opj_stream_private *p_stream,
struct opj_event_mgr * p_manager )
{
OPJ_BYTE * l_current_data = 00;
OPJ_UINT32 l_tlm_size;
// preconditions
assert(p_j2k != 00);
assert(p_manager != 00);
assert(p_stream != 00);
l_tlm_size = 6 + (5*p_j2k->m_specific_param.m_encoder.m_total_tile_parts);
if (l_tlm_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
p_j2k->m_specific_param.m_encoder.m_header_tile_data
= (OPJ_BYTE*)opj_realloc(
p_j2k->m_specific_param.m_encoder.m_header_tile_data,
l_tlm_size);
if (! p_j2k->m_specific_param.m_encoder.m_header_tile_data) {
return OPJ_FALSE;
}
p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_tlm_size;
}
l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
/* change the way data is written to avoid seeking if possible */
// TODO
p_j2k->m_specific_param.m_encoder.m_tlm_start = opj_stream_tell(p_stream);
opj_write_bytes(l_current_data,J2K_MS_TLM,2); /* TLM */
l_current_data += 2;
opj_write_bytes(l_current_data,l_tlm_size-2,2); /* Lpoc */
l_current_data += 2;
opj_write_bytes(l_current_data,0,1); /* Ztlm=0*/
++l_current_data;
opj_write_bytes(l_current_data,0x50,1); /* Stlm ST=1(8bits-255 tiles max),SP=1(Ptlm=32bits) */
++l_current_data;
/* do nothing on the 5 * l_j2k->m_specific_param.m_encoder.m_total_tile_parts remaining data */
if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_tlm_size,p_manager) != l_tlm_size) {
return OPJ_FALSE;
}
return OPJ_TRUE;
}
static void j2k_write_tlm(opj_j2k_t *j2k){
int lenp;
opj_cio_t *cio = j2k->cio;
@ -5788,6 +6011,43 @@ static void j2k_write_eoc(opj_j2k_t *j2k) {
/* <<UniPG */
}
/**
* Writes the EOC marker (End of Codestream)
*
* @param p_stream the stream to write data to.
* @param p_j2k J2K codec.
* @param p_manager the user event manager.
*/
opj_bool j2k_write_eoc_v2( opj_j2k_v2_t *p_j2k,
struct opj_stream_private *p_stream,
struct opj_event_mgr * p_manager )
{
/* preconditions */
assert(p_j2k != 00);
assert(p_manager != 00);
assert(p_stream != 00);
opj_write_bytes(p_j2k->m_specific_param.m_encoder.m_header_tile_data,J2K_MS_EOC,2); /* EOC */
/* UniPG>> */
#ifdef USE_JPWL
/* update markers struct */
j2k_add_marker(p_j2k->cstr_info, J2K_MS_EOC, p_stream_tell(p_stream) - 2, 2);
#endif /* USE_JPWL */
if ( opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,2,p_manager) != 2) {
return OPJ_FALSE;
}
if ( opj_stream_flush(p_stream,p_manager) == EXIT_FAILURE) {
return OPJ_FALSE;
}
return OPJ_TRUE;
}
/**
* Reads a RGN marker (Region Of Interest)
*
@ -11829,7 +12089,20 @@ opj_bool j2k_start_compress(opj_j2k_v2_t *p_j2k,
assert(p_stream != 00);
assert(p_manager != 00);
p_j2k->m_private_image = p_image;
p_j2k->m_private_image = opj_image_create0();
opj_copy_image_header(p_image, p_j2k->m_private_image);
// TODO_MSD: Find a better way
if (p_image->comps) {
OPJ_UINT32 it_comp;
for (it_comp = 0 ; it_comp < p_image->numcomps; it_comp++) {
if (p_image->comps[it_comp].data) {
p_j2k->m_private_image->comps[it_comp].data =p_image->comps[it_comp].data;
p_image->comps[it_comp].data = NULL;
}
}
}
/* customization of the validation */
j2k_setup_encoding_validation (p_j2k);
@ -12036,7 +12309,9 @@ opj_bool j2k_post_write_tile ( opj_j2k_v2_t * p_j2k,
l_available_data -= l_nb_bytes_written;
l_nb_bytes_written = l_tile_size - l_available_data;
if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_encoded_tile_data,l_nb_bytes_written,p_manager) != l_nb_bytes_written) {
if ( opj_stream_write_data( p_stream,
p_j2k->m_specific_param.m_encoder.m_encoded_tile_data,
l_nb_bytes_written,p_manager) != l_nb_bytes_written) {
return OPJ_FALSE;
}
@ -12056,7 +12331,7 @@ void j2k_setup_end_compress (opj_j2k_v2_t *p_j2k)
assert(p_j2k != 00);
/* DEVELOPER CORNER, insert your custom procedures */
opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_write_eoc );
opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_write_eoc_v2 );
if (p_j2k->m_cp.m_specific_param.m_enc.m_cinema) {
opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_write_updated_tlm);
@ -12102,17 +12377,17 @@ void j2k_setup_header_writting (opj_j2k_v2_t *p_j2k)
if (p_j2k->m_cp.m_specific_param.m_enc.m_cinema) {
opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_write_image_components );
opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_write_tlm );
opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_write_tlm_v2 );
if (p_j2k->m_cp.m_specific_param.m_enc.m_cinema == CINEMA4K_24) {
opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_write_poc );
opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_write_poc_v2 );
}
}
opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_write_regions);
if (p_j2k->m_cp.comment != 00) {
opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_write_com);
opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)j2k_write_com_v2);
}
/* DEVELOPER CORNER, insert your custom procedures */
@ -12526,8 +12801,15 @@ opj_bool j2k_write_tile (opj_j2k_v2_t * p_j2k,
opj_event_mgr_t * p_manager )
{
if (! j2k_pre_write_tile(p_j2k,p_tile_index,p_stream,p_manager)) {
opj_event_msg_v2(p_manager, EVT_ERROR, "Error while j2k_pre_write_tile with tile index = %d\n", p_tile_index);
return OPJ_FALSE;
}
else {
if (! j2k_post_write_tile(p_j2k,p_data,p_data_size,p_stream,p_manager)) {
opj_event_msg_v2(p_manager, EVT_ERROR, "Error while j2k_post_write_tile with tile index = %d\n", p_tile_index);
return OPJ_FALSE;
}
}
return j2k_post_write_tile(p_j2k,p_data,p_data_size,p_stream,p_manager);
return OPJ_TRUE;
}

View File

@ -242,6 +242,7 @@ int main ()
l_image->color_space = CLRSPC_SRGB;
if (! opj_setup_encoder_v2(l_codec,&l_param,l_image)) {
fprintf(stderr, "ERROR -> test_tile_encoder: failed to setup the codec!\n");
opj_destroy_codec(l_codec);
opj_image_destroy(l_image);
return 1;
@ -249,6 +250,7 @@ int main ()
l_file = fopen(OUTPUT_FILE,"wb");
if (! l_file) {
fprintf(stderr, "ERROR -> test_tile_encoder: failed to create the output file!\n");
opj_destroy_codec(l_codec);
opj_image_destroy(l_image);
return 1;
@ -257,6 +259,7 @@ int main ()
l_stream = opj_stream_create_default_file_stream(l_file, OPJ_FALSE);
if (! opj_start_compress(l_codec,l_image,l_stream)) {
fprintf(stderr, "ERROR -> test_tile_encoder: failed to start compress!\n");
opj_stream_destroy(l_stream);
fclose(l_file);
opj_destroy_codec(l_codec);
@ -266,6 +269,7 @@ int main ()
for (i=0;i<l_nb_tiles;++i) {
if (! opj_write_tile(l_codec,i,l_data,l_data_size,l_stream)) {
fprintf(stderr, "ERROR -> test_tile_encoder: failed to write the tile %d!\n",i);
opj_stream_destroy(l_stream);
fclose(l_file);
opj_destroy_codec(l_codec);
@ -275,6 +279,7 @@ int main ()
}
if (! opj_end_compress(l_codec,l_stream)) {
fprintf(stderr, "ERROR -> test_tile_encoder: failed to end compress!\n");
opj_stream_destroy(l_stream);
fclose(l_file);
opj_destroy_codec(l_codec);