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,
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}
};
@ -1455,6 +1474,59 @@ 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,
@ -3017,6 +3089,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;

View File

@ -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