Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add parsing of pxfm boxes #1176

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 82 additions & 1 deletion src/lib/openjp2/jp2.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down Expand Up @@ -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}

};

Expand Down Expand Up @@ -1455,6 +1474,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,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there should be cautious sanitfy checks in that function that p_pxfm_header_size is large enough, otherwise fuzzy testers will trigger crashes with malformed boxes

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(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in the event (likely illegal) that there are 2 PFXM boxes, this will cause a memory leak. An error should likely be emitted if pixel_format is already allocated

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pixel_format should be tested against NULL

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

opj_calloc() should be used so that all members are 0 initialized

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 ||
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

given the above masking, it is not possible to have pixel_format_type being 0 or 4...

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,
Expand Down Expand Up @@ -3017,6 +3093,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;
Expand Down
27 changes: 27 additions & 0 deletions src/lib/openjp2/jp2.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) */
Expand Down Expand Up @@ -143,6 +144,31 @@ typedef struct opj_jp2_comps {
OPJ_UINT32 bpcc;
} opj_jp2_comps_t;


typedef enum {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this enumeration type appears to be unused ?

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
*/
Expand Down Expand Up @@ -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
Expand Down