diff --git a/src/lib/openjp2/jp2.c b/src/lib/openjp2/jp2.c index ec202272..589a52c1 100644 --- a/src/lib/openjp2/jp2.c +++ b/src/lib/openjp2/jp2.c @@ -111,6 +111,24 @@ static OPJ_BOOL opj_jp2_read_cdef(opj_jp2_t * jp2, static void opj_jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color, opj_event_mgr_t *); + +/** + * Reads a pixel format box. + * + * @param p_pxfm_header_data pointer to actual data (already read from file) + * @param jp2 the jpeg2000 file codec. + * @param p_pxfm_header_size the size of the pxfm header + * @param p_manager the user event manager. + * + * @return true if the bpc header is valid, false else. + */ + +static OPJ_BOOL opj_jp2_read_pxfm(opj_jp2_t * jp2, + OPJ_BYTE * p_pxfm_header_data, + OPJ_UINT32 p_pxfm_header_size, + opj_event_mgr_t * p_manager); + + /** * Writes the Channel Definition box. * @@ -434,7 +452,8 @@ static const opj_jp2_header_handler_t jp2_img_header [] = { {JP2_BPCC, opj_jp2_read_bpcc}, {JP2_PCLR, opj_jp2_read_pclr}, {JP2_CMAP, opj_jp2_read_cmap}, - {JP2_CDEF, opj_jp2_read_cdef} + {JP2_CDEF, opj_jp2_read_cdef}, + {JP2_PXFM, opj_jp2_read_pxfm} }; @@ -1461,6 +1480,63 @@ static OPJ_BOOL opj_jp2_read_cdef(opj_jp2_t * jp2, return OPJ_TRUE; } + +static OPJ_BOOL opj_jp2_read_pxfm(opj_jp2_t * jp2, + OPJ_BYTE * p_pxfm_header_data, + OPJ_UINT32 p_pxfm_header_size, + opj_event_mgr_t * p_manager + ) +{ + opj_jp2_cdef_info_t *cdef_info; + OPJ_UINT16 i; + OPJ_UINT32 l_value; + OPJ_UINT16 num_channel; + OPJ_UINT8 Channel_index; + + assert(jp2 != 00); + assert(p_pxfm_header_data != 00); + assert(p_manager != 00); + (void)p_pxfm_header_size; + + opj_read_bytes(p_pxfm_header_data, &l_value, + 2); + + num_channel = (OPJ_UINT16) l_value; + + p_pxfm_header_data += 2; + + if (jp2->numcomps != num_channel) { + opj_event_msg(p_manager, EVT_ERROR, + "Mismatch between num comps and PXFM number of channel \n"); + return OPJ_FALSE; + } + jp2->pixel_format = (opj_jp2_pixel_format_t*) opj_malloc(jp2->numcomps * sizeof( + opj_jp2_pixel_format_t)); + + for (i = 0; i < jp2->numcomps; ++i) { + opj_read_bytes(p_pxfm_header_data, &l_value, + 2); + p_pxfm_header_data += 2; + Channel_index = (OPJ_UINT16) l_value; + opj_read_bytes(p_pxfm_header_data, &l_value, + 2); + p_pxfm_header_data += 2; + if (Channel_index < jp2->numcomps) { + jp2->pixel_format[Channel_index].pixel_format_type = ((OPJ_UINT16) l_value) & + 0xF000; + + if (jp2->pixel_format[Channel_index].pixel_format_type == 0 || + jp2->pixel_format[Channel_index].pixel_format_type == 4 + ) { + jp2->pixel_format[Channel_index].pixel_format_values.mentissa = (( + OPJ_UINT16) l_value) & 0x0FFF; + } + } + } + + return OPJ_TRUE; +} + static OPJ_BOOL opj_jp2_read_colr(opj_jp2_t *jp2, OPJ_BYTE * p_colr_header_data, OPJ_UINT32 p_colr_header_size, @@ -3026,6 +3102,11 @@ void opj_jp2_destroy(opj_jp2_t *jp2) jp2->comps = 00; } + if (jp2->pixel_format) { + opj_free(jp2->pixel_format); + jp2->pixel_format = 00; + } + if (jp2->cl) { opj_free(jp2->cl); jp2->cl = 00; diff --git a/src/lib/openjp2/jp2.h b/src/lib/openjp2/jp2.h index 173f2511..3eed520a 100644 --- a/src/lib/openjp2/jp2.h +++ b/src/lib/openjp2/jp2.h @@ -59,6 +59,7 @@ #define JP2_DTBL 0x6474626c /**< Data Reference box */ #define JP2_BPCC 0x62706363 /**< Bits per component box */ #define JP2_JP2 0x6a703220 /**< File type fields */ +#define JP2_PXFM 0x7078666d /**< Pixel Format box */ /* For the future */ /* #define JP2_RES 0x72657320 */ /**< Resolution box (super-box) */ @@ -143,6 +144,31 @@ typedef struct opj_jp2_comps { OPJ_UINT32 bpcc; } opj_jp2_comps_t; + +typedef enum { + JP2_TRANSFORM_TYPE_BINARY_TWO_COMPLEMENT = 0x0, + JP2_TRANSFORM_TYPE_MANTISSA_ONLY = 0x1, + JP2_TRANSFORM_TYPE_EXPONENT_ONLY = 0x2, + JP2_TRANSFORM_TYPE_FIXED_POINT = 0x3, + JP2_TRANSFORM_TYPE_MANTISSA_EXPONENT = 0x4, + +} +JP2_TRANSFORM_TYPE; + +typedef struct opj_jp2_pixel_format_values_t { + OPJ_UINT8 exponent; + OPJ_UINT8 mentissa; + OPJ_UINT8 fractional_bits; +} opj_jp2_pixel_format_values_t; + +/** + Non Linear Transform +*/ +typedef struct opj_jp2_pixel_format_t { + OPJ_UINT8 pixel_format_type; + opj_jp2_pixel_format_values_t pixel_format_values; +} opj_jp2_pixel_format_t; + /** JPEG-2000 file format reader/writer */ @@ -173,6 +199,7 @@ typedef struct opj_jp2 { OPJ_UINT32 numcl; OPJ_UINT32 *cl; opj_jp2_comps_t *comps; + opj_jp2_pixel_format_t *pixel_format; /* FIXME: The following two variables are used to save offset as we write out a JP2 file to disk. This mechanism is not flexible as codec writers will need to extand those fields as new part