[trunk] WIP: add a read MCC marker function (JPEG2000 part 2)

This commit is contained in:
Mickael Savinaud 2011-10-12 14:32:29 +00:00
parent 5cf331d881
commit f62201ba9d
2 changed files with 231 additions and 1 deletions

View File

@ -6,6 +6,7 @@ What's New for OpenJPEG
+ : added
October 12, 2011
+ [mickael] WIP: add a read MCC marker function (part 2)
+ [mickael] WIP: add a read MCT marker function (part 2)
October 11, 2011

View File

@ -712,6 +712,18 @@ static opj_bool j2k_read_mct ( opj_j2k_v2_t *p_j2k,
OPJ_UINT32 p_header_size,
struct opj_event_mgr * p_manager );
/**
* Reads a MCC marker (Multiple Component Collection)
*
* @param p_header_data the data contained in the MCC box.
* @param p_j2k the jpeg2000 codec.
* @param p_header_size the size of the data contained in the MCC marker.
* @param p_manager the user event manager.
*/
static opj_bool j2k_read_mcc ( opj_j2k_v2_t *p_j2k,
OPJ_BYTE * p_header_data,
OPJ_UINT32 p_header_size,
struct opj_event_mgr * p_manager );
/**
* Copy the image header from the jpeg2000 codec into an external image_header
@ -818,7 +830,7 @@ const opj_dec_memory_marker_handler_t j2k_memory_marker_handler_tab [] =
{J2K_MS_COM, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_com_v2},
{J2K_MS_MCT, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_mct},
/*FIXME MSD {J2K_MS_CBD, J2K_STATE_MH , j2k_read_cbd},
{J2K_MS_MCC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_mcc},
*/{J2K_MS_MCC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_mcc},/*
{J2K_MS_MCO, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_mco}, */
#ifdef USE_JPWL
#ifdef TODO_MS /* FIXME */
@ -4164,6 +4176,223 @@ opj_bool j2k_read_mct ( opj_j2k_v2_t *p_j2k,
return OPJ_TRUE;
}
/**
* Reads a MCC marker (Multiple Component Collection)
*
* @param p_header_data the data contained in the MCC box.
* @param p_j2k the jpeg2000 codec.
* @param p_header_size the size of the data contained in the MCC marker.
* @param p_manager the user event manager.
*/
opj_bool j2k_read_mcc ( opj_j2k_v2_t *p_j2k,
OPJ_BYTE * p_header_data,
OPJ_UINT32 p_header_size,
struct opj_event_mgr * p_manager )
{
OPJ_UINT32 i,j;
OPJ_UINT32 l_tmp;
OPJ_UINT32 l_indix;
opj_tcp_v2_t * l_tcp;
opj_simple_mcc_decorrelation_data_t * l_mcc_record;
opj_mct_data_t * l_mct_data;
OPJ_UINT32 l_nb_collections;
OPJ_UINT32 l_nb_comps;
OPJ_UINT32 l_nb_bytes_by_comp;
/* preconditions */
assert(p_header_data != 00);
assert(p_j2k != 00);
assert(p_manager != 00);
l_tcp = p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH ?
&p_j2k->m_cp.tcps[p_j2k->m_current_tile_number] :
p_j2k->m_specific_param.m_decoder.m_default_tcp;
if (p_header_size < 2) {
opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading MCC marker\n");
return OPJ_FALSE;
}
/* first marker */
opj_read_bytes(p_header_data,&l_tmp,2); /* Zmcc */
p_header_data += 2;
if (l_tmp != 0) {
opj_event_msg_v2(p_manager, EVT_WARNING, "Cannot take in charge multiple data spanning\n");
return OPJ_TRUE;
}
if (p_header_size < 7) {
opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading MCC marker\n");
return OPJ_FALSE;
}
opj_read_bytes(p_header_data,&l_indix,1); /* Imcc -> no need for other values, take the first */
++p_header_data;
l_mcc_record = l_tcp->m_mcc_records;
for(i=0;i<l_tcp->m_nb_mcc_records;++i) {
if (l_mcc_record->m_index == l_indix) {
break;
}
++l_mcc_record;
}
/** NOT FOUND */
if (i == l_tcp->m_nb_mcc_records) {
if (l_tcp->m_nb_mcc_records == l_tcp->m_nb_max_mcc_records) {
l_tcp->m_nb_max_mcc_records += J2K_MCC_DEFAULT_NB_RECORDS;
l_tcp->m_mcc_records = (opj_simple_mcc_decorrelation_data_t*)
opj_realloc(l_tcp->m_mcc_records,l_tcp->m_nb_max_mcc_records * sizeof(opj_simple_mcc_decorrelation_data_t));
if (! l_tcp->m_mcc_records) {
opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading MCC marker\n");
return OPJ_FALSE;
}
l_mcc_record = l_tcp->m_mcc_records + l_tcp->m_nb_mcc_records;
memset(l_mcc_record,0,(l_tcp->m_nb_max_mcc_records-l_tcp->m_nb_mcc_records) * sizeof(opj_simple_mcc_decorrelation_data_t));
}
l_mcc_record = l_tcp->m_mcc_records + l_tcp->m_nb_mcc_records;
}
l_mcc_record->m_index = l_indix;
/* only one marker atm */
opj_read_bytes(p_header_data,&l_tmp,2); /* Ymcc */
p_header_data+=2;
if (l_tmp != 0) {
opj_event_msg_v2(p_manager, EVT_WARNING, "Cannot take in charge multiple data spanning\n");
return OPJ_TRUE;
}
opj_read_bytes(p_header_data,&l_nb_collections,2); /* Qmcc -> number of collections -> 1 */
p_header_data+=2;
if (l_nb_collections > 1) {
opj_event_msg_v2(p_manager, EVT_WARNING, "Cannot take in charge multiple collections\n");
return OPJ_TRUE;
}
p_header_size -= 7;
for (i=0;i<l_nb_collections;++i) {
if (p_header_size < 3) {
opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading MCC marker\n");
return OPJ_FALSE;
}
opj_read_bytes(p_header_data,&l_tmp,1); /* Xmcci type of component transformation -> array based decorrelation */
++p_header_data;
if (l_tmp != 1) {
opj_event_msg_v2(p_manager, EVT_WARNING, "Cannot take in charge collections other than array decorrelation\n");
return OPJ_TRUE;
}
opj_read_bytes(p_header_data,&l_nb_comps,2);
p_header_data+=2;
p_header_size-=3;
l_nb_bytes_by_comp = 1 + (l_nb_comps>>15);
l_mcc_record->m_nb_comps = l_nb_comps & 0x7fff;
if (p_header_size < (l_nb_bytes_by_comp * l_mcc_record->m_nb_comps + 2)) {
opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading MCC marker\n");
return OPJ_FALSE;
}
p_header_size -= (l_nb_bytes_by_comp * l_mcc_record->m_nb_comps + 2);
for (j=0;j<l_mcc_record->m_nb_comps;++j) {
opj_read_bytes(p_header_data,&l_tmp,l_nb_bytes_by_comp); /* Cmccij Component offset*/
p_header_data+=l_nb_bytes_by_comp;
if (l_tmp != j) {
opj_event_msg_v2(p_manager, EVT_WARNING, "Cannot take in charge collections with indix shuffle\n");
return OPJ_TRUE;
}
}
opj_read_bytes(p_header_data,&l_nb_comps,2);
p_header_data+=2;
l_nb_bytes_by_comp = 1 + (l_nb_comps>>15);
l_nb_comps &= 0x7fff;
if (l_nb_comps != l_mcc_record->m_nb_comps) {
opj_event_msg_v2(p_manager, EVT_WARNING, "Cannot take in charge collections without same number of indixes\n");
return OPJ_TRUE;
}
if (p_header_size < (l_nb_bytes_by_comp * l_mcc_record->m_nb_comps + 3)) {
opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading MCC marker\n");
return OPJ_FALSE;
}
p_header_size -= (l_nb_bytes_by_comp * l_mcc_record->m_nb_comps + 3);
for (j=0;j<l_mcc_record->m_nb_comps;++j) {
opj_read_bytes(p_header_data,&l_tmp,l_nb_bytes_by_comp); /* Wmccij Component offset*/
p_header_data+=l_nb_bytes_by_comp;
if (l_tmp != j) {
opj_event_msg_v2(p_manager, EVT_WARNING, "Cannot take in charge collections with indix shuffle\n");
return OPJ_TRUE;
}
}
opj_read_bytes(p_header_data,&l_tmp,3); /* Wmccij Component offset*/
p_header_data += 3;
l_mcc_record->m_is_irreversible = ! ((l_tmp>>16) & 1);
l_mcc_record->m_decorrelation_array = 00;
l_mcc_record->m_offset_array = 00;
l_indix = l_tmp & 0xff;
if (l_indix != 0) {
l_mct_data = l_tcp->m_mct_records;
for (j=0;j<l_tcp->m_nb_mct_records;++j) {
if (l_mct_data->m_index == l_indix) {
l_mcc_record->m_decorrelation_array = l_mct_data;
break;
}
++l_mct_data;
}
if (l_mcc_record->m_decorrelation_array == 00) {
opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading MCC marker\n");
return OPJ_FALSE;
}
}
l_indix = (l_tmp >> 8) & 0xff;
if (l_indix != 0) {
l_mct_data = l_tcp->m_mct_records;
for (j=0;j<l_tcp->m_nb_mct_records;++j) {
if (l_mct_data->m_index == l_indix) {
l_mcc_record->m_offset_array = l_mct_data;
break;
}
++l_mct_data;
}
if (l_mcc_record->m_offset_array == 00) {
opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading MCC marker\n");
return OPJ_FALSE;
}
}
}
if (p_header_size != 0) {
opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading MCC marker\n");
return OPJ_FALSE;
}
++l_tcp->m_nb_mcc_records;
return OPJ_TRUE;
}
/* ----------------------------------------------------------------------- */
/* J2K / JPT decoder interface */