From 5cf331d881c9635e3328d71427c47c8be117ad1e Mon Sep 17 00:00:00 2001 From: Mickael Savinaud Date: Wed, 12 Oct 2011 14:30:22 +0000 Subject: [PATCH] [trunk] WIP: add a read MCT marker function (JPEG2000 part 2) --- CHANGES | 3 + libopenjpeg/j2k.c | 141 ++++++++++++++++++++++++++++++++++++++++++++-- libopenjpeg/j2k.h | 52 +++++++++-------- 3 files changed, 167 insertions(+), 29 deletions(-) diff --git a/CHANGES b/CHANGES index 07548624..2e0471e5 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,9 @@ What's New for OpenJPEG ! : changed + : added +October 12, 2011 ++ [mickael] WIP: add a read MCT marker function (part 2) + October 11, 2011 * [mickael] WIP: correct a segfault inside j2k_dump output * [mickael] WIP: correct some segfault with win platform and remove a aligned allocation which produce error when a realloc is done on this pointer. diff --git a/libopenjpeg/j2k.c b/libopenjpeg/j2k.c index bd429af0..7b1a7ff5 100644 --- a/libopenjpeg/j2k.c +++ b/libopenjpeg/j2k.c @@ -699,6 +699,20 @@ static opj_bool j2k_read_unk_v2 ( opj_j2k_v2_t *p_j2k, OPJ_UINT32 *output_marker, struct opj_event_mgr * p_manager ); +/** + * Reads a MCT marker (Multiple Component Transform) + * + * @param p_header_data the data contained in the MCT box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the MCT marker. + * @param p_manager the user event manager. +*/ +static opj_bool j2k_read_mct ( 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 * @@ -735,6 +749,17 @@ j2k_prog_order_t j2k_prog_order_list[] = { {(OPJ_PROG_ORDER)-1, ""} }; +/** + * FIXME DOC + */ +const OPJ_UINT32 MCT_ELEMENT_SIZE [] = +{ + 2, + 4, + 4, + 8 +}; + typedef struct opj_dec_memory_marker_handler { /** marker value */ @@ -791,12 +816,10 @@ const opj_dec_memory_marker_handler_t j2k_memory_marker_handler_tab [] = {J2K_MS_SOP, 0, 0}, {J2K_MS_CRG, J2K_STATE_MH, j2k_read_crg_v2}, {J2K_MS_COM, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_com_v2}, -#ifdef TODO_MS /* FIXME */ {J2K_MS_MCT, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_mct}, - {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_MCO, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_mco}, -#endif + {J2K_MS_MCO, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_mco}, */ #ifdef USE_JPWL #ifdef TODO_MS /* FIXME */ {J2K_MS_EPC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_epc}, @@ -4032,6 +4055,116 @@ static opj_dec_mstabent_t *j2k_dec_mstab_lookup(int id) { return e; } + +/** + * Reads a MCT marker (Multiple Component Transform) + * + * @param p_header_data the data contained in the MCT box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the MCT marker. + * @param p_manager the user event manager. +*/ +opj_bool j2k_read_mct ( 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; + opj_tcp_v2_t *l_tcp = 00; + OPJ_UINT32 l_tmp; + OPJ_UINT32 l_indix; + opj_mct_data_t * l_mct_data; + + /* preconditions */ + assert(p_header_data != 00); + assert(p_j2k != 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 MCT marker\n"); + return OPJ_FALSE; + } + + /* first marker */ + opj_read_bytes(p_header_data,&l_tmp,2); /* Zmct */ + p_header_data += 2; + if (l_tmp != 0) { + opj_event_msg_v2(p_manager, EVT_WARNING, "Cannot take in charge mct data within multiple MCT records\n"); + return OPJ_TRUE; + } + + if(p_header_size <= 6) { + opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading MCT marker\n"); + return OPJ_FALSE; + } + + /* Imct -> no need for other values, take the first, type is double with decorrelation x0000 1101 0000 0000*/ + opj_read_bytes(p_header_data,&l_tmp,2); /* Imct */ + p_header_data += 2; + + l_indix = l_tmp & 0xff; + l_mct_data = l_tcp->m_mct_records; + + for (i=0;im_nb_mct_records;++i) { + if (l_mct_data->m_index == l_indix) { + break; + } + ++l_mct_data; + } + + /* NOT FOUND */ + if (i == l_tcp->m_nb_mct_records) { + if (l_tcp->m_nb_mct_records == l_tcp->m_nb_max_mct_records) { + l_tcp->m_nb_max_mct_records += J2K_MCT_DEFAULT_NB_RECORDS; + + l_tcp->m_mct_records = (opj_mct_data_t*)opj_realloc(l_tcp->m_mct_records,l_tcp->m_nb_max_mct_records * sizeof(opj_mct_data_t)); + if(! l_tcp->m_mct_records) { + opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading MCT marker\n"); + return OPJ_FALSE; + } + + l_mct_data = l_tcp->m_mct_records + l_tcp->m_nb_mct_records; + memset(l_mct_data ,0,(l_tcp->m_nb_max_mct_records - l_tcp->m_nb_mct_records) * sizeof(opj_mct_data_t)); + } + + l_mct_data = l_tcp->m_mct_records + l_tcp->m_nb_mct_records; + } + + if (l_mct_data->m_data) { + opj_free(l_mct_data->m_data); + l_mct_data->m_data = 00; + } + + l_mct_data->m_index = l_indix; + l_mct_data->m_array_type = (J2K_MCT_ARRAY_TYPE)((l_tmp >> 8) & 3); + l_mct_data->m_element_type = (J2K_MCT_ELEMENT_TYPE)((l_tmp >> 10) & 3); + + opj_read_bytes(p_header_data,&l_tmp,2); /* Ymct */ + p_header_data+=2; + if (l_tmp != 0) { + opj_event_msg_v2(p_manager, EVT_WARNING, "Cannot take in charge multiple MCT markers\n"); + return OPJ_TRUE; + } + + p_header_size -= 6; + + l_mct_data->m_data = (OPJ_BYTE*)opj_malloc(p_header_size); + if (! l_mct_data->m_data) { + opj_event_msg_v2(p_manager, EVT_ERROR, "Error reading MCT marker\n"); + return OPJ_FALSE; + } + memcpy(l_mct_data->m_data,p_header_data,p_header_size); + + l_mct_data->m_data_size = p_header_size; + ++l_tcp->m_nb_mct_records; + + return OPJ_TRUE; +} + + /* ----------------------------------------------------------------------- */ /* J2K / JPT decoder interface */ /* ----------------------------------------------------------------------- */ diff --git a/libopenjpeg/j2k.h b/libopenjpeg/j2k.h index 270232aa..c4b09808 100644 --- a/libopenjpeg/j2k.h +++ b/libopenjpeg/j2k.h @@ -77,15 +77,12 @@ The functions in J2K.C have for goal to read/write the several parts of the code #define J2K_MS_EPH 0xff92 /**< EPH marker value */ #define J2K_MS_CRG 0xff63 /**< CRG marker value */ #define J2K_MS_COM 0xff64 /**< COM marker value */ - -#define J2K_MS_UNK 0 /**< UNKNOWN marker value */ - -#ifdef TODO_MS /* FIXME */ #define J2K_MS_CBD 0xff78 /**< CBD marker value */ #define J2K_MS_MCC 0xff75 /**< MCC marker value */ #define J2K_MS_MCT 0xff74 /**< MCT marker value */ #define J2K_MS_MCO 0xff77 /**< MCO marker value */ -#endif + +#define J2K_MS_UNK 0 /**< UNKNOWN marker value */ /* UniPG>> */ #ifdef USE_JPWL @@ -122,6 +119,27 @@ typedef enum J2K_STATUS { J2K_STATE_ERR = 0x8000 /**< the decoding process has encountered an error (FIXME warning V1 = 0x0080)*/ } J2K_STATUS; +/** + * Type of elements storing in the MCT data + */ +typedef enum MCT_ELEMENT_TYPE +{ + MCT_TYPE_INT16 = 0, /** MCT data is stored as signed shorts*/ + MCT_TYPE_INT32 = 1, /** MCT data is stored as signed integers*/ + MCT_TYPE_FLOAT = 2, /** MCT data is stored as floats*/ + MCT_TYPE_DOUBLE = 3 /** MCT data is stored as doubles*/ +} J2K_MCT_ELEMENT_TYPE; + +/** + * Type of MCT array + */ +typedef enum MCT_ARRAY_TYPE +{ + MCT_TYPE_DEPENDENCY = 0, + MCT_TYPE_DECORRELATION = 1, + MCT_TYPE_OFFSET = 2 +} J2K_MCT_ARRAY_TYPE; + /* ----------------------------------------------------------------------- */ /** @@ -247,28 +265,9 @@ typedef struct opj_tcp { opj_tccp_t *tccps; } opj_tcp_t; - /** - * Type of data for storing the MCT data + * FIXME DOC */ -typedef enum MCT_ELEMENT_TYPE -{ - MCT_TYPE_INT16 = 0, /** MCT data is stored as signed shorts*/ - MCT_TYPE_INT32 = 1, /** MCT data is stored as signed integers*/ - MCT_TYPE_FLOAT = 2, /** MCT data is stored as floats*/ - MCT_TYPE_DOUBLE = 3 /** MCT data is stored as doubles*/ -} J2K_MCT_ELEMENT_TYPE; - -/** - * Type of data for storing the MCT data - */ -typedef enum MCT_ARRAY_TYPE -{ - MCT_TYPE_DEPENDENCY = 0, - MCT_TYPE_DECORRELATION = 1, - MCT_TYPE_OFFSET = 2 -} J2K_MCT_ARRAY_TYPE; - typedef struct opj_mct_data { J2K_MCT_ELEMENT_TYPE m_element_type; @@ -279,6 +278,9 @@ typedef struct opj_mct_data } opj_mct_data_t; +/** + * FIXME DOC + */ typedef struct opj_simple_mcc_decorrelation_data { OPJ_UINT32 m_index;