From 1023be33fb46dd805fc278ebe784bb1f4ace9c19 Mon Sep 17 00:00:00 2001 From: Mickael Savinaud Date: Mon, 14 May 2012 09:37:36 +0000 Subject: [PATCH] add new functions in jp2 codec from v2 branches; solve bug in j2k_setup_encoder_v2 --- applications/codec/image_to_j2k.c | 9 + libopenjpeg/j2k.c | 22 +- libopenjpeg/jp2.c | 472 ++++++++++++++++++++++++++++-- libopenjpeg/jp2.h | 31 +- libopenjpeg/openjpeg.c | 2 +- 5 files changed, 502 insertions(+), 34 deletions(-) diff --git a/applications/codec/image_to_j2k.c b/applications/codec/image_to_j2k.c index f8937252..bdbdf05c 100644 --- a/applications/codec/image_to_j2k.c +++ b/applications/codec/image_to_j2k.c @@ -1818,8 +1818,17 @@ int main(int argc, char **argv) { /* encode the image */ bSuccess = opj_start_compress(l_codec,image,l_stream); + if (!bSuccess) { + fprintf(stderr, "failed to encode image: opj_start_compress\n"); + } bSuccess = bSuccess && opj_encode_v2(l_codec, l_stream); + if (!bSuccess) { + fprintf(stderr, "failed to encode image: opj_encode_v2\n"); + } bSuccess = bSuccess && opj_end_compress(l_codec, l_stream); + if (!bSuccess) { + fprintf(stderr, "failed to encode image: opj_end_compress\n"); + } if (!bSuccess) { opj_stream_destroy(l_stream); diff --git a/libopenjpeg/j2k.c b/libopenjpeg/j2k.c index 9d59259c..9301b294 100644 --- a/libopenjpeg/j2k.c +++ b/libopenjpeg/j2k.c @@ -8487,20 +8487,20 @@ void j2k_setup_encoder_v2( opj_j2k_v2_t *p_j2k, } }else{ if (parameters->csty & J2K_CCP_CSTY_PRT) { - int p = 0; - for (j = tccp->numresolutions - 1; j >= 0; j--) { + OPJ_INT32 p = 0, it_res; + for (it_res = tccp->numresolutions - 1; it_res >= 0; it_res--) { if (p < parameters->res_spec) { if (parameters->prcw_init[p] < 1) { - tccp->prcw[j] = 1; + tccp->prcw[it_res] = 1; } else { - tccp->prcw[j] = int_floorlog2(parameters->prcw_init[p]); + tccp->prcw[it_res] = int_floorlog2(parameters->prcw_init[p]); } if (parameters->prch_init[p] < 1) { - tccp->prch[j] = 1; + tccp->prch[it_res] = 1; }else { - tccp->prch[j] = int_floorlog2(parameters->prch_init[p]); + tccp->prch[it_res] = int_floorlog2(parameters->prch_init[p]); } } else { @@ -8509,19 +8509,19 @@ void j2k_setup_encoder_v2( opj_j2k_v2_t *p_j2k, int size_prch = parameters->prch_init[res_spec - 1] >> (p - (res_spec - 1)); if (size_prcw < 1) { - tccp->prcw[j] = 1; + tccp->prcw[it_res] = 1; } else { - tccp->prcw[j] = int_floorlog2(size_prcw); + tccp->prcw[it_res] = int_floorlog2(size_prcw); } if (size_prch < 1) { - tccp->prch[j] = 1; + tccp->prch[it_res] = 1; } else { - tccp->prch[j] = int_floorlog2(size_prch); + tccp->prch[it_res] = int_floorlog2(size_prch); } } p++; - /*printf("\nsize precinct for level %d : %d,%d\n", j,tccp->prcw[j], tccp->prch[j]); */ + /*printf("\nsize precinct for level %d : %d,%d\n", it_res,tccp->prcw[it_res], tccp->prch[it_res]); */ } //end for } else { for (j = 0; j < tccp->numresolutions; j++) { diff --git a/libopenjpeg/jp2.c b/libopenjpeg/jp2.c index 841640fc..f3e9bd51 100644 --- a/libopenjpeg/jp2.c +++ b/libopenjpeg/jp2.c @@ -74,7 +74,31 @@ static opj_bool jp2_read_ihdr_v2( ); static void jp2_write_ihdr(opj_jp2_t *jp2, opj_cio_t *cio); + +/** + * Writes the Image Header box - Image Header box. + * + * @param jp2 jpeg2000 file codec. + * @param p_nb_bytes_written pointer to store the nb of bytes written by the function. + * + * @return the data being copied. +*/ +static unsigned char * jp2_write_ihdr_v2( opj_jp2_v2_t *jp2, + unsigned int * p_nb_bytes_written ); + static void jp2_write_bpcc(opj_jp2_t *jp2, opj_cio_t *cio); + +/** + * Writes the Bit per Component box. + * + * @param jp2 jpeg2000 file codec. + * @param p_nb_bytes_written pointer to store the nb of bytes written by the function. + * + * @return the data being copied. +*/ +static unsigned char * jp2_write_bpcc_v2( opj_jp2_v2_t *jp2, + unsigned int * p_nb_bytes_written ); + static opj_bool jp2_read_bpcc(opj_jp2_t *jp2, opj_cio_t *cio); /** @@ -106,6 +130,18 @@ Write the FTYP box - File type box @param jp2 JP2 handle @param cio Output buffer stream */ + +/** + * Writes the Colour Specification box. + * + * @param jp2 jpeg2000 file codec. + * @param p_nb_bytes_written pointer to store the nb of bytes written by the function. + * + * @return the data being copied. +*/ +static unsigned char *jp2_write_colr_v2(opj_jp2_v2_t *jp2, + unsigned int * p_nb_bytes_written ); + static void jp2_write_ftyp(opj_jp2_t *jp2, opj_cio_t *cio); /** Read the FTYP box - File type box @@ -115,6 +151,19 @@ Read the FTYP box - File type box */ static opj_bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio); +/** + * Writes a FTYP box - File type box + * + * @param cio the stream to write data to. + * @param jp2 the jpeg2000 file codec. + * @param p_manager the user event manager. + * + * @return true if writting was successful. + */ +static opj_bool jp2_write_ftyp_v2( opj_jp2_v2_t *jp2, + struct opj_stream_private *cio, + struct opj_event_mgr * p_manager ); + /** * Reads a a FTYP box - File type box * @@ -125,12 +174,10 @@ static opj_bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio); * * @return true if the FTYP box is valid. */ -static opj_bool jp2_read_ftyp_v2( - opj_jp2_v2_t *jp2, - unsigned char * p_header_data, - unsigned int p_header_size, - struct opj_event_mgr * p_manager - ); +static opj_bool jp2_read_ftyp_v2( opj_jp2_v2_t *jp2, + unsigned char * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager ); /** * Skips the Jpeg2000 Codestream Header box - JP2C Header box. @@ -673,6 +720,64 @@ static void jp2_write_ihdr(opj_jp2_t *jp2, opj_cio_t *cio) { cio_seek(cio, box.init_pos + box.length); } +/** + * Writes the Image Header box - Image Header box. + * + * @param jp2 jpeg2000 file codec. + * @param p_nb_bytes_written pointer to store the nb of bytes written by the function. + * + * @return the data being copied. +*/ +static unsigned char * jp2_write_ihdr_v2( opj_jp2_v2_t *jp2, + unsigned int * p_nb_bytes_written ) +{ + unsigned char * l_ihdr_data,* l_current_ihdr_ptr; + + // preconditions + assert(jp2 != 00); + assert(p_nb_bytes_written != 00); + + /* default image header is 22 bytes wide */ + l_ihdr_data = (unsigned char *) opj_malloc(22); + if (l_ihdr_data == 00) { + return 00; + } + memset(l_ihdr_data,0,22); + + l_current_ihdr_ptr = l_ihdr_data; + + opj_write_bytes(l_current_ihdr_ptr,22,4); /* write box size */ + l_current_ihdr_ptr+=4; + + opj_write_bytes(l_current_ihdr_ptr,JP2_IHDR, 4); /* IHDR */ + l_current_ihdr_ptr+=4; + + opj_write_bytes(l_current_ihdr_ptr,jp2->h, 4); /* HEIGHT */ + l_current_ihdr_ptr+=4; + + opj_write_bytes(l_current_ihdr_ptr, jp2->w, 4); /* WIDTH */ + l_current_ihdr_ptr+=4; + + opj_write_bytes(l_current_ihdr_ptr, jp2->numcomps, 2); /* NC */ + l_current_ihdr_ptr+=2; + + opj_write_bytes(l_current_ihdr_ptr, jp2->bpc, 1); /* BPC */ + ++l_current_ihdr_ptr; + + opj_write_bytes(l_current_ihdr_ptr, jp2->C, 1); /* C : Always 7 */ + ++l_current_ihdr_ptr; + + opj_write_bytes(l_current_ihdr_ptr, jp2->UnkC, 1); /* UnkC, colorspace unknown */ + ++l_current_ihdr_ptr; + + opj_write_bytes(l_current_ihdr_ptr, jp2->IPR, 1); /* IPR, no intellectual property */ + ++l_current_ihdr_ptr; + + *p_nb_bytes_written = 22; + + return l_ihdr_data; +} + static void jp2_write_bpcc(opj_jp2_t *jp2, opj_cio_t *cio) { unsigned int i; opj_jp2_box_t box; @@ -692,6 +797,52 @@ static void jp2_write_bpcc(opj_jp2_t *jp2, opj_cio_t *cio) { } +/** + * Writes the Bit per Component box. + * + * @param jp2 jpeg2000 file codec. + * @param p_nb_bytes_written pointer to store the nb of bytes written by the function. + * + * @return the data being copied. +*/ +unsigned char * jp2_write_bpcc_v2( opj_jp2_t *jp2, + unsigned int * p_nb_bytes_written ) +{ + unsigned int i; + /* room for 8 bytes for box and 1 byte for each component */ + int l_bpcc_size = 8 + jp2->numcomps; + unsigned char * l_bpcc_data,* l_current_bpcc_ptr; + + // preconditions + assert(jp2 != 00); + assert(p_nb_bytes_written != 00); + + l_bpcc_data = (unsigned char *) opj_malloc(l_bpcc_size); + if (l_bpcc_data == 00) { + return 00; + } + memset(l_bpcc_data,0,l_bpcc_size); + + l_current_bpcc_ptr = l_bpcc_data; + + opj_write_bytes(l_current_bpcc_ptr,l_bpcc_size,4); /* write box size */ + l_current_bpcc_ptr += 4; + + opj_write_bytes(l_current_bpcc_ptr,JP2_BPCC,4); /* BPCC */ + l_current_bpcc_ptr += 4; + + for (i = 0; i < jp2->numcomps; ++i) { + opj_write_bytes(l_current_bpcc_ptr, jp2->comps[i].bpcc, 1); /* write each component information */ + ++l_current_bpcc_ptr; + } + + *p_nb_bytes_written = l_bpcc_size; + + return l_bpcc_data; +} + + + static opj_bool jp2_read_bpcc(opj_jp2_t *jp2, opj_cio_t *cio) { unsigned int i; opj_jp2_box_t box; @@ -781,6 +932,71 @@ static void jp2_write_colr(opj_jp2_t *jp2, opj_cio_t *cio) { cio_seek(cio, box.init_pos + box.length); } +/** + * Writes the Colour Specification box. + * + * @param jp2 jpeg2000 file codec. + * @param p_nb_bytes_written pointer to store the nb of bytes written by the function. + * + * @return the data being copied. +*/ +unsigned char *jp2_write_colr_v2( opj_jp2_v2_t *jp2, + unsigned int * p_nb_bytes_written ) +{ + /* room for 8 bytes for box 3 for common data and variable upon profile*/ + unsigned int l_colr_size = 11; + unsigned char * l_colr_data,* l_current_colr_ptr; + + // preconditions + assert(jp2 != 00); + assert(p_nb_bytes_written != 00); + + switch (jp2->meth) { + case 1 : + l_colr_size += 4; + break; + case 2 : + ++l_colr_size; + break; + default : + return 00; + } + + l_colr_data = (unsigned char *) opj_malloc(l_colr_size); + if (l_colr_data == 00) { + return 00; + } + memset(l_colr_data,0,l_colr_size); + + l_current_colr_ptr = l_colr_data; + + opj_write_bytes(l_current_colr_ptr,l_colr_size,4); /* write box size */ + l_current_colr_ptr += 4; + + opj_write_bytes(l_current_colr_ptr,JP2_COLR,4); /* BPCC */ + l_current_colr_ptr += 4; + + opj_write_bytes(l_current_colr_ptr, jp2->meth,1); /* METH */ + ++l_current_colr_ptr; + + opj_write_bytes(l_current_colr_ptr, jp2->precedence,1); /* PRECEDENCE */ + ++l_current_colr_ptr; + + opj_write_bytes(l_current_colr_ptr, jp2->approx,1); /* APPROX */ + ++l_current_colr_ptr; + + if (jp2->meth == 1) { + opj_write_bytes(l_current_colr_ptr, jp2->enumcs,4); /* EnumCS */ + } + else { + opj_write_bytes(l_current_colr_ptr, 0, 1); /* PROFILE (??) */ + } + + *p_nb_bytes_written = l_colr_size; + + return l_colr_data; +} + static void jp2_free_pclr(opj_jp2_color_t *color) { opj_free(color->jp2_pclr->channel_sign); @@ -1597,6 +1813,112 @@ void jp2_write_jp2h(opj_jp2_t *jp2, opj_cio_t *cio) { cio_seek(cio, box.init_pos + box.length); } +/** + * Writes the Jpeg2000 file Header box - JP2 Header box (warning, this is a super 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_jp2h_v2( opj_jp2_v2_t *jp2, + opj_stream_private_t *cio, + opj_event_mgr_t * p_manager ) +{ + opj_jp2_img_header_writer_handler_t l_writers [3]; + opj_jp2_img_header_writer_handler_t * l_current_writer; + + int i, l_nb_pass; + /* size of data for super box*/ + int l_jp2h_size = 8; + opj_bool l_result = OPJ_TRUE; + + /* to store the data of the super box */ + unsigned char l_jp2h_data [8]; + + // preconditions + assert(cio != 00); + assert(jp2 != 00); + assert(p_manager != 00); + + memset(l_writers,0,sizeof(l_writers)); + + if (jp2->bpc == 255) { + l_nb_pass = 3; + l_writers[0].handler = jp2_write_ihdr_v2; + l_writers[1].handler = jp2_write_bpcc_v2; + l_writers[2].handler = jp2_write_colr_v2; + } + else { + l_nb_pass = 2; + l_writers[0].handler = jp2_write_ihdr_v2; + l_writers[1].handler = jp2_write_colr_v2; + } + + /* write box header */ + /* write JP2H type */ + opj_write_bytes(l_jp2h_data+4,JP2_JP2H,4); + + l_current_writer = l_writers; + for (i=0;im_data = l_current_writer->handler(jp2,&(l_current_writer->m_size)); + if (l_current_writer->m_data == 00) { + opj_event_msg_v2(p_manager, EVT_ERROR, "Not enough memory to hold JP2 Header data\n"); + l_result = OPJ_FALSE; + break; + } + + l_jp2h_size += l_current_writer->m_size; + ++l_current_writer; + } + + if (! l_result) { + l_current_writer = l_writers; + for (i=0;im_data != 00) { + opj_free(l_current_writer->m_data ); + } + ++l_current_writer; + } + + return OPJ_FALSE; + } + + /* write super box size */ + opj_write_bytes(l_jp2h_data,l_jp2h_size,4); + + /* 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"); + l_result = OPJ_FALSE; + } + + if (l_result) { + l_current_writer = l_writers; + for (i=0;im_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"); + l_result = OPJ_FALSE; + break; + } + ++l_current_writer; + } + } + + l_current_writer = l_writers; + + /* cleanup */ + for (i=0;im_data != 00) { + opj_free(l_current_writer->m_data ); + } + ++l_current_writer; + } + + return l_result; +} + static void jp2_write_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) { unsigned int i; opj_jp2_box_t box; @@ -1618,6 +1940,67 @@ static void jp2_write_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) { cio_seek(cio, box.init_pos + box.length); } +/** + * Writes a FTYP box - File type box + * + * @param cio the stream to write data to. + * @param jp2 the jpeg2000 file codec. + * @param p_manager the user event manager. + * + * @return true if writting was successful. + */ +opj_bool jp2_write_ftyp_v2( opj_jp2_v2_t *jp2, + opj_stream_private_t *cio, + opj_event_mgr_t * p_manager ) +{ + unsigned int i; + unsigned int l_ftyp_size = 16 + 4 * jp2->numcl; + unsigned char * l_ftyp_data, * l_current_data_ptr; + opj_bool l_result; + + // preconditions + assert(cio != 00); + assert(jp2 != 00); + assert(p_manager != 00); + + l_ftyp_data = (unsigned char *) opj_malloc(l_ftyp_size); + + if (l_ftyp_data == 00) { + opj_event_msg_v2(p_manager, EVT_ERROR, "Not enough memory to handle ftyp data\n"); + return OPJ_FALSE; + } + + memset(l_ftyp_data,0,l_ftyp_size); + + l_current_data_ptr = l_ftyp_data; + + opj_write_bytes(l_current_data_ptr, l_ftyp_size,4); /* box size */ + l_current_data_ptr += 4; + + opj_write_bytes(l_current_data_ptr, JP2_FTYP,4); /* FTYP */ + l_current_data_ptr += 4; + + opj_write_bytes(l_current_data_ptr, jp2->brand,4); /* BR */ + l_current_data_ptr += 4; + + opj_write_bytes(l_current_data_ptr, jp2->minversion,4); /* MinV */ + l_current_data_ptr += 4; + + for (i = 0; i < jp2->numcl; i++) { + opj_write_bytes(l_current_data_ptr, jp2->cl[i],4); /* CL */ + } + + 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_free(l_ftyp_data); + + return l_result; +} + static opj_bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) { int i; opj_jp2_box_t box; @@ -1710,6 +2093,41 @@ static void jp2_write_jp(opj_cio_t *cio) { cio_seek(cio, box.init_pos + box.length); } +/** + * Writes a jpeg2000 file signature box. + * + * @param cio the stream to write data to. + * @param jp2 the jpeg2000 file codec. + * @param p_manager the user event manager. + * + * @return true if writting was successful. + */ +opj_bool jp2_write_jp_v2( opj_jp2_v2_t *jp2, + opj_stream_private_t *cio, + opj_event_mgr_t * p_manager ) +{ + /* 12 bytes will be read */ + unsigned char l_signature_data [12]; + + // preconditions + assert(cio != 00); + assert(jp2 != 00); + assert(p_manager != 00); + + /* write box length */ + opj_write_bytes(l_signature_data,12,4); + /* writes box type */ + opj_write_bytes(l_signature_data+4,JP2_JP,4); + /* writes magic number*/ + opj_write_bytes(l_signature_data+8,0x0d0a870a,4); + + if (opj_stream_write_data(cio,l_signature_data,12,p_manager) != 12) { + return OPJ_FALSE; + } + + return OPJ_TRUE; +} + static opj_bool jp2_read_jp(opj_jp2_t *jp2, opj_cio_t *cio) { opj_jp2_box_t box; @@ -1891,7 +2309,10 @@ void jp2_destroy_compress(opj_jp2_t *jp2) { } } -void jp2_setup_encoder(opj_jp2_t *jp2, opj_cparameters_t *parameters, opj_image_t *image) { +void jp2_setup_encoder( opj_jp2_v2_t *jp2, + opj_cparameters_t *parameters, + opj_image_t *image, + opj_event_mgr_t * p_manager) { int i; int depth_0, sign; @@ -1903,11 +2324,11 @@ void jp2_setup_encoder(opj_jp2_t *jp2, opj_cparameters_t *parameters, opj_image_ /* Check if number of components respects standard */ if (image->numcomps < 1 || image->numcomps > 16384) { - opj_event_msg(jp2->cinfo, EVT_ERROR, "Invalid number of components specified while setting up JP2 encoder\n"); + opj_event_msg_v2(p_manager, EVT_ERROR, "Invalid number of components specified while setting up JP2 encoder\n"); return; } - j2k_setup_encoder(jp2->j2k, parameters, image); + j2k_setup_encoder_v2(jp2->j2k, parameters, image, p_manager ); /* setup the JP2 codec */ /* ------------------- */ @@ -1941,21 +2362,30 @@ void jp2_setup_encoder(opj_jp2_t *jp2, opj_cparameters_t *parameters, opj_image_ jp2->IPR = 0; /* IPR, no intellectual property */ /* BitsPerComponent box */ - for (i = 0; i < image->numcomps; i++) { jp2->comps[i].bpcc = image->comps[i].prec - 1 + (image->comps[i].sgnd << 7); } - jp2->meth = 1; - if (image->color_space == 1) - jp2->enumcs = 16; /* sRGB as defined by IEC 61966-2.1 */ - else if (image->color_space == 2) - jp2->enumcs = 17; /* greyscale */ - else if (image->color_space == 3) - jp2->enumcs = 18; /* YUV */ + + /* Colour Specification box */ + if ((image->numcomps == 1 || image->numcomps == 3) && (jp2->bpc != 255)) { + jp2->meth = 1; /* METH: Enumerated colourspace */ + } else { + jp2->meth = 2; /* METH: Restricted ICC profile */ + } + if (jp2->meth == 1) { + if (image->color_space == 1) + jp2->enumcs = 16; /* sRGB as defined by IEC 61966𣇻 */ + else if (image->color_space == 2) + jp2->enumcs = 17; /* greyscale */ + else if (image->color_space == 3) + jp2->enumcs = 18; /* YUV */ + } else { + jp2->enumcs = 0; /* PROFILE (??) */ + } jp2->precedence = 0; /* PRECEDENCE */ jp2->approx = 0; /* APPROX */ - jp2->jpip_on = parameters->jpip_on; + // jp2->jpip_on = parameters->jpip_on; } opj_bool opj_jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) { @@ -2719,9 +3149,9 @@ void jp2_setup_header_writting (opj_jp2_v2_t *jp2) /* preconditions */ assert(jp2 != 00); - opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)jp2_write_jp ); - opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)jp2_write_ftyp ); - opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)jp2_write_jp2h ); + opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)jp2_write_jp_v2 ); + opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)jp2_write_ftyp_v2 ); + opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)jp2_write_jp2h_v2 ); opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)jp2_skip_jp2c ); /* DEVELOPER CORNER, insert your custom procedures */ diff --git a/libopenjpeg/jp2.h b/libopenjpeg/jp2.h index 1de72a9b..b44f9b6d 100644 --- a/libopenjpeg/jp2.h +++ b/libopenjpeg/jp2.h @@ -236,6 +236,18 @@ typedef struct opj_jp2_header_handler } opj_jp2_header_handler_t; + +typedef struct opj_jp2_img_header_writer_handler +{ + /* action to perform */ + unsigned char* (*handler) (opj_jp2_v2_t *jp2, unsigned int * p_data_size); + /* result of the action : data */ + unsigned char * m_data; + /* size of data */ + unsigned int m_size; +} +opj_jp2_img_header_writer_handler_t; + /** @name Exported functions */ /*@{*/ /* ----------------------------------------------------------------------- */ @@ -245,6 +257,20 @@ Write the JP2H box - JP2 Header box (used in MJ2) @param cio Output buffer stream */ void jp2_write_jp2h(opj_jp2_t *jp2, opj_cio_t *cio); + +/** + * Writes the Jpeg2000 file Header box - JP2 Header box (warning, this is a super 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_jp2h_v2( opj_jp2_v2_t *jp2, + struct opj_stream_private *cio, + struct opj_event_mgr * p_manager ); + /** Read the JP2H box - JP2 Header box (used in MJ2) @param jp2 JP2 handle @@ -318,7 +344,10 @@ Coding parameters are returned in jp2->j2k->cp. @param parameters compression parameters @param image input filled image */ -void jp2_setup_encoder(opj_jp2_t *jp2, opj_cparameters_t *parameters, opj_image_t *image); +void jp2_setup_encoder( opj_jp2_v2_t *jp2, + opj_cparameters_t *parameters, + opj_image_t *image, + struct opj_event_mgr * p_manager); /** Encode an image into a JPEG-2000 file stream @param jp2 JP2 compressor handle diff --git a/libopenjpeg/openjpeg.c b/libopenjpeg/openjpeg.c index fb0c748c..c03f1478 100644 --- a/libopenjpeg/openjpeg.c +++ b/libopenjpeg/openjpeg.c @@ -826,7 +826,7 @@ void OPJ_CALLCONV opj_setup_encoder(opj_cinfo_t *cinfo, opj_cparameters_t *param j2k_setup_encoder((opj_j2k_t*)cinfo->j2k_handle, parameters, image); break; case CODEC_JP2: - jp2_setup_encoder((opj_jp2_t*)cinfo->jp2_handle, parameters, image); + jp2_setup_encoder((opj_jp2_t*)cinfo->jp2_handle, parameters, image, NULL); break; case CODEC_JPT: case CODEC_UNKNOWN: