* @param p_image_header_size the size of the image header
* @param p_manager the user event manager.
*
- * @return true if the image header is valid, fale else.
+ * @return true if the image header is valid, false else.
*/
-static opj_bool jp2_read_ihdr_v2(
- opj_jp2_v2_t *jp2,
- unsigned char * p_image_header_data,
- unsigned int p_image_header_size,
- struct opj_event_mgr * p_manager
- );
+static opj_bool jp2_read_ihdr_v2( opj_jp2_v2_t *jp2,
+ OPJ_BYTE *p_image_header_data,
+ OPJ_INT32 p_image_header_size,
+ opj_event_mgr_t * p_manager );
static void jp2_write_ihdr(opj_jp2_t *jp2, opj_cio_t *cio);
);
static int jp2_write_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info);
+
+
+/**
+ * Writes the Jpeg2000 codestream Header box - JP2C Header box. This function must be called AFTER the coding has been done.
+ *
+ * @param cio the stream to write data to.
+ * @param jp2 the jpeg2000 file codec.
+ * @param p_manager user event manager.
+ *
+ * @return true if writting was successful.
+*/
+static opj_bool jp2_write_jp2c_v2( opj_jp2_v2_t *jp2,
+ struct opj_stream_private *cio,
+ struct opj_event_mgr * p_manager );
+
static opj_bool jp2_read_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, unsigned int *j2k_codestream_length, unsigned int *j2k_codestream_offset);
static void jp2_write_jp(opj_cio_t *cio);
/**
*
* @return true if the image header is valid, fale else.
*/
-opj_bool jp2_read_ihdr_v2(
- opj_jp2_v2_t *jp2,
- unsigned char * p_image_header_data,
- unsigned int p_image_header_size,
- opj_event_mgr_t * p_manager
+opj_bool jp2_read_ihdr_v2( opj_jp2_v2_t *jp2,
+ OPJ_BYTE *p_image_header_data,
+ OPJ_INT32 p_image_header_size,
+ opj_event_mgr_t * p_manager
)
{
/* preconditions */
p_image_header_data += 4;
opj_read_bytes(p_image_header_data,&(jp2->w),4); /* WIDTH */
p_image_header_data += 4;
- opj_read_bytes(p_image_header_data,&(jp2->numcomps),2); /* NC */
+ opj_read_bytes(p_image_header_data,&(jp2->numcomps),2); /* NC */
p_image_header_data += 2;
/* allocate memory for components */
for(i = 0; i < nr_channels; ++i)
{
/* Cji */
- *entries++ = cio_read(cio, channel_size[i]>>3);
+ *entries++ = cio_read(cio, (channel_size[i]+7)>>3);
}
}
assert(p_pclr_header_data != 00);
assert(jp2 != 00);
assert(p_manager != 00);
+ (void)p_pclr_header_size;
if(jp2->color.jp2_pclr)
return OPJ_FALSE;
for(j = 0; j < nr_entries; ++j) {
for(i = 0; i < nr_channels; ++i) {
- /**entries++ = cio_read(cio, channel_size[i]>>3); */
- opj_read_bytes(p_pclr_header_data, &l_value , channel_size[i]>>3); /* Cji */
- p_pclr_header_data += channel_size[i]>>3;
+ int bytes_to_read = (channel_size[i]+7)>>3;
+
+ opj_read_bytes(p_pclr_header_data, &l_value , bytes_to_read); /* Cji */
+ p_pclr_header_data += bytes_to_read;
*entries = (OPJ_UINT32) l_value;
entries++;
}
assert(jp2 != 00);
assert(p_cmap_header_data != 00);
assert(p_manager != 00);
+ (void)p_cmap_header_size;
/* Need nr_channels: */
if(jp2->color.jp2_pclr == NULL) {
assert(jp2 != 00);
assert(p_cdef_header_data != 00);
assert(p_manager != 00);
+ (void)p_cdef_header_size;
/* Part 1, I.5.3.6: 'The shall be at most one Channel Definition box
* inside a JP2 Header box.'*/
/* write super box data on stream */
if (opj_stream_write_data(cio,l_jp2h_data,8,p_manager) != 8) {
- opj_event_msg(p_manager, EVT_ERROR, "Stream error while writting JP2 Header box\n");
+ opj_event_msg_v2(p_manager, EVT_ERROR, "Stream error while writing JP2 Header box\n");
l_result = OPJ_FALSE;
}
l_current_writer = l_writers;
for (i=0;i<l_nb_pass;++i) {
if (opj_stream_write_data(cio,l_current_writer->m_data,l_current_writer->m_size,p_manager) != l_current_writer->m_size) {
- opj_event_msg(p_manager, EVT_ERROR, "Stream error while writting JP2 Header box\n");
+ opj_event_msg_v2(p_manager, EVT_ERROR, "Stream error while writting JP2 Header box\n");
l_result = OPJ_FALSE;
break;
}
l_result = (opj_stream_write_data(cio,l_ftyp_data,l_ftyp_size,p_manager) == l_ftyp_size);
if (! l_result)
{
- opj_event_msg(p_manager, EVT_ERROR, "Error while writting ftyp data to stream\n");
+ opj_event_msg_v2(p_manager, EVT_ERROR, "Error while writting ftyp data to stream\n");
}
opj_free(l_ftyp_data);
return box.length;
}
+/**
+ * Writes the Jpeg2000 codestream Header box - JP2C Header box.
+ *
+ * @param cio the stream to write data to.
+ * @param jp2 the jpeg2000 file codec.
+ * @param p_manager user event manager.
+ *
+ * @return true if writting was successful.
+*/
+opj_bool jp2_write_jp2c_v2( opj_jp2_v2_t *jp2,
+ opj_stream_private_t *cio,
+ opj_event_mgr_t * p_manager )
+{
+ unsigned int j2k_codestream_exit;
+ unsigned char l_data_header [8];
+
+ // preconditions
+ assert(jp2 != 00);
+ assert(cio != 00);
+ assert(p_manager != 00);
+ assert(opj_stream_has_seek(cio));
+
+ j2k_codestream_exit = opj_stream_tell(cio);
+ opj_write_bytes(l_data_header,j2k_codestream_exit - jp2->j2k_codestream_offset,4); /* size of codestream */
+ opj_write_bytes(l_data_header + 4,JP2_JP2C,4); /* JP2C */
+
+ if (! opj_stream_seek(cio,jp2->j2k_codestream_offset,p_manager)) {
+ opj_event_msg_v2(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
+ return OPJ_FALSE;
+ }
+
+ if (opj_stream_write_data(cio,l_data_header,8,p_manager) != 8) {
+ opj_event_msg_v2(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
+ return OPJ_FALSE;
+ }
+
+ if (! opj_stream_seek(cio,j2k_codestream_exit,p_manager)) {
+ opj_event_msg_v2(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
+ return OPJ_FALSE;
+ }
+
+ return OPJ_TRUE;
+}
+
static opj_bool jp2_read_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, unsigned int *j2k_codestream_length, unsigned int *j2k_codestream_offset) {
opj_jp2_box_t box;
/* preconditions */
assert(jp2 != 00);
- opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)jp2_write_jp2c );
+ opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)jp2_write_jp2c_v2 );
/* DEVELOPER CORNER, add your custom procedures */
}
{
opj_jp2_v2_t *jp2 = (opj_jp2_v2_t*)opj_malloc(sizeof(opj_jp2_v2_t));
if (jp2) {
- memset(jp2,0,sizeof(opj_jp2_t));
+ memset(jp2,0,sizeof(opj_jp2_v2_t));
/* create the J2K codec */
if (! p_is_decoder) {