Add parsing of pxfm boxes

This commit is contained in:
Nicolas Derouineau 2019-01-09 18:17:15 +01:00
parent 51f097e6d5
commit 4b88e35371
2 changed files with 105 additions and 1 deletions

View File

@ -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, static void opj_jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color,
opj_event_mgr_t *); 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. * 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_BPCC, opj_jp2_read_bpcc},
{JP2_PCLR, opj_jp2_read_pclr}, {JP2_PCLR, opj_jp2_read_pclr},
{JP2_CMAP, opj_jp2_read_cmap}, {JP2_CMAP, opj_jp2_read_cmap},
{JP2_CDEF, opj_jp2_read_cdef} {JP2_CDEF, opj_jp2_read_cdef},
{JP2_PXFM, opj_jp2_read_pxfm}
}; };
@ -1455,6 +1474,59 @@ static OPJ_BOOL opj_jp2_read_cdef(opj_jp2_t * jp2,
return OPJ_TRUE; 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, static OPJ_BOOL opj_jp2_read_colr(opj_jp2_t *jp2,
OPJ_BYTE * p_colr_header_data, OPJ_BYTE * p_colr_header_data,
OPJ_UINT32 p_colr_header_size, OPJ_UINT32 p_colr_header_size,
@ -3017,6 +3089,11 @@ void opj_jp2_destroy(opj_jp2_t *jp2)
jp2->comps = 00; jp2->comps = 00;
} }
if (jp2->pixel_format) {
opj_free(jp2->pixel_format);
jp2->pixel_format = 00;
}
if (jp2->cl) { if (jp2->cl) {
opj_free(jp2->cl); opj_free(jp2->cl);
jp2->cl = 00; jp2->cl = 00;

View File

@ -59,6 +59,7 @@
#define JP2_DTBL 0x6474626c /**< Data Reference box */ #define JP2_DTBL 0x6474626c /**< Data Reference box */
#define JP2_BPCC 0x62706363 /**< Bits per component box */ #define JP2_BPCC 0x62706363 /**< Bits per component box */
#define JP2_JP2 0x6a703220 /**< File type fields */ #define JP2_JP2 0x6a703220 /**< File type fields */
#define JP2_PXFM 0x7078666d /**< Pixel Format box */
/* For the future */ /* For the future */
/* #define JP2_RES 0x72657320 */ /**< Resolution box (super-box) */ /* #define JP2_RES 0x72657320 */ /**< Resolution box (super-box) */
@ -143,6 +144,31 @@ typedef struct opj_jp2_comps {
OPJ_UINT32 bpcc; OPJ_UINT32 bpcc;
} opj_jp2_comps_t; } 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 JPEG-2000 file format reader/writer
*/ */
@ -173,6 +199,7 @@ typedef struct opj_jp2 {
OPJ_UINT32 numcl; OPJ_UINT32 numcl;
OPJ_UINT32 *cl; OPJ_UINT32 *cl;
opj_jp2_comps_t *comps; opj_jp2_comps_t *comps;
opj_jp2_pixel_format_t *pixel_format;
/* FIXME: The following two variables are used to save offset /* 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 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 as codec writers will need to extand those fields as new part