[trunk] WIP: add a read MCC marker function (JPEG2000 part 2)
This commit is contained in:
parent
5cf331d881
commit
f62201ba9d
1
CHANGES
1
CHANGES
|
@ -6,6 +6,7 @@ What's New for OpenJPEG
|
||||||
+ : added
|
+ : added
|
||||||
|
|
||||||
October 12, 2011
|
October 12, 2011
|
||||||
|
+ [mickael] WIP: add a read MCC marker function (part 2)
|
||||||
+ [mickael] WIP: add a read MCT marker function (part 2)
|
+ [mickael] WIP: add a read MCT marker function (part 2)
|
||||||
|
|
||||||
October 11, 2011
|
October 11, 2011
|
||||||
|
|
|
@ -712,6 +712,18 @@ static opj_bool j2k_read_mct ( opj_j2k_v2_t *p_j2k,
|
||||||
OPJ_UINT32 p_header_size,
|
OPJ_UINT32 p_header_size,
|
||||||
struct opj_event_mgr * p_manager );
|
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
|
* 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_COM, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_com_v2},
|
||||||
{J2K_MS_MCT, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_mct},
|
{J2K_MS_MCT, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_mct},
|
||||||
/*FIXME MSD {J2K_MS_CBD, J2K_STATE_MH , j2k_read_cbd},
|
/*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}, */
|
{J2K_MS_MCO, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_mco}, */
|
||||||
#ifdef USE_JPWL
|
#ifdef USE_JPWL
|
||||||
#ifdef TODO_MS /* FIXME */
|
#ifdef TODO_MS /* FIXME */
|
||||||
|
@ -4164,6 +4176,223 @@ opj_bool j2k_read_mct ( opj_j2k_v2_t *p_j2k,
|
||||||
return OPJ_TRUE;
|
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 */
|
/* J2K / JPT decoder interface */
|
||||||
|
|
Loading…
Reference in New Issue