add new functions in jp2 codec from v2 branches; solve bug in j2k_setup_encoder_v2
This commit is contained in:
parent
595c00f55c
commit
1023be33fb
|
@ -1818,8 +1818,17 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
/* encode the image */
|
/* encode the image */
|
||||||
bSuccess = opj_start_compress(l_codec,image,l_stream);
|
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);
|
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);
|
bSuccess = bSuccess && opj_end_compress(l_codec, l_stream);
|
||||||
|
if (!bSuccess) {
|
||||||
|
fprintf(stderr, "failed to encode image: opj_end_compress\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (!bSuccess) {
|
if (!bSuccess) {
|
||||||
opj_stream_destroy(l_stream);
|
opj_stream_destroy(l_stream);
|
||||||
|
|
|
@ -8487,20 +8487,20 @@ void j2k_setup_encoder_v2( opj_j2k_v2_t *p_j2k,
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
if (parameters->csty & J2K_CCP_CSTY_PRT) {
|
if (parameters->csty & J2K_CCP_CSTY_PRT) {
|
||||||
int p = 0;
|
OPJ_INT32 p = 0, it_res;
|
||||||
for (j = tccp->numresolutions - 1; j >= 0; j--) {
|
for (it_res = tccp->numresolutions - 1; it_res >= 0; it_res--) {
|
||||||
if (p < parameters->res_spec) {
|
if (p < parameters->res_spec) {
|
||||||
|
|
||||||
if (parameters->prcw_init[p] < 1) {
|
if (parameters->prcw_init[p] < 1) {
|
||||||
tccp->prcw[j] = 1;
|
tccp->prcw[it_res] = 1;
|
||||||
} else {
|
} 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) {
|
if (parameters->prch_init[p] < 1) {
|
||||||
tccp->prch[j] = 1;
|
tccp->prch[it_res] = 1;
|
||||||
}else {
|
}else {
|
||||||
tccp->prch[j] = int_floorlog2(parameters->prch_init[p]);
|
tccp->prch[it_res] = int_floorlog2(parameters->prch_init[p]);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} 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));
|
int size_prch = parameters->prch_init[res_spec - 1] >> (p - (res_spec - 1));
|
||||||
|
|
||||||
if (size_prcw < 1) {
|
if (size_prcw < 1) {
|
||||||
tccp->prcw[j] = 1;
|
tccp->prcw[it_res] = 1;
|
||||||
} else {
|
} else {
|
||||||
tccp->prcw[j] = int_floorlog2(size_prcw);
|
tccp->prcw[it_res] = int_floorlog2(size_prcw);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size_prch < 1) {
|
if (size_prch < 1) {
|
||||||
tccp->prch[j] = 1;
|
tccp->prch[it_res] = 1;
|
||||||
} else {
|
} else {
|
||||||
tccp->prch[j] = int_floorlog2(size_prch);
|
tccp->prch[it_res] = int_floorlog2(size_prch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p++;
|
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
|
} //end for
|
||||||
} else {
|
} else {
|
||||||
for (j = 0; j < tccp->numresolutions; j++) {
|
for (j = 0; j < tccp->numresolutions; j++) {
|
||||||
|
|
|
@ -74,7 +74,31 @@ static opj_bool jp2_read_ihdr_v2(
|
||||||
);
|
);
|
||||||
|
|
||||||
static void jp2_write_ihdr(opj_jp2_t *jp2, opj_cio_t *cio);
|
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);
|
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);
|
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 jp2 JP2 handle
|
||||||
@param cio Output buffer stream
|
@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);
|
static void jp2_write_ftyp(opj_jp2_t *jp2, opj_cio_t *cio);
|
||||||
/**
|
/**
|
||||||
Read the FTYP box - File type box
|
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);
|
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
|
* 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.
|
* @return true if the FTYP box is valid.
|
||||||
*/
|
*/
|
||||||
static opj_bool jp2_read_ftyp_v2(
|
static opj_bool jp2_read_ftyp_v2( opj_jp2_v2_t *jp2,
|
||||||
opj_jp2_v2_t *jp2,
|
|
||||||
unsigned char * p_header_data,
|
unsigned char * p_header_data,
|
||||||
unsigned int p_header_size,
|
OPJ_UINT32 p_header_size,
|
||||||
struct opj_event_mgr * p_manager
|
struct opj_event_mgr * p_manager );
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Skips the Jpeg2000 Codestream Header box - JP2C Header box.
|
* 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);
|
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) {
|
static void jp2_write_bpcc(opj_jp2_t *jp2, opj_cio_t *cio) {
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
opj_jp2_box_t box;
|
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) {
|
static opj_bool jp2_read_bpcc(opj_jp2_t *jp2, opj_cio_t *cio) {
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
opj_jp2_box_t box;
|
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);
|
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)
|
static void jp2_free_pclr(opj_jp2_color_t *color)
|
||||||
{
|
{
|
||||||
opj_free(color->jp2_pclr->channel_sign);
|
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);
|
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;i<l_nb_pass;++i) {
|
||||||
|
l_current_writer->m_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;i<l_nb_pass;++i) {
|
||||||
|
if (l_current_writer->m_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;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");
|
||||||
|
l_result = OPJ_FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++l_current_writer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
l_current_writer = l_writers;
|
||||||
|
|
||||||
|
/* cleanup */
|
||||||
|
for (i=0;i<l_nb_pass;++i) {
|
||||||
|
if (l_current_writer->m_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) {
|
static void jp2_write_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) {
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
opj_jp2_box_t box;
|
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);
|
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) {
|
static opj_bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) {
|
||||||
int i;
|
int i;
|
||||||
opj_jp2_box_t box;
|
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);
|
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) {
|
static opj_bool jp2_read_jp(opj_jp2_t *jp2, opj_cio_t *cio) {
|
||||||
opj_jp2_box_t box;
|
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 i;
|
||||||
int depth_0, sign;
|
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 */
|
/* Check if number of components respects standard */
|
||||||
if (image->numcomps < 1 || image->numcomps > 16384) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
j2k_setup_encoder(jp2->j2k, parameters, image);
|
j2k_setup_encoder_v2(jp2->j2k, parameters, image, p_manager );
|
||||||
|
|
||||||
/* setup the JP2 codec */
|
/* 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 */
|
jp2->IPR = 0; /* IPR, no intellectual property */
|
||||||
|
|
||||||
/* BitsPerComponent box */
|
/* BitsPerComponent box */
|
||||||
|
|
||||||
for (i = 0; i < image->numcomps; i++) {
|
for (i = 0; i < image->numcomps; i++) {
|
||||||
jp2->comps[i].bpcc = image->comps[i].prec - 1 + (image->comps[i].sgnd << 7);
|
jp2->comps[i].bpcc = image->comps[i].prec - 1 + (image->comps[i].sgnd << 7);
|
||||||
}
|
}
|
||||||
jp2->meth = 1;
|
|
||||||
|
/* 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)
|
if (image->color_space == 1)
|
||||||
jp2->enumcs = 16; /* sRGB as defined by IEC 61966-2.1 */
|
jp2->enumcs = 16; /* sRGB as defined by IEC 61966–2–1 */
|
||||||
else if (image->color_space == 2)
|
else if (image->color_space == 2)
|
||||||
jp2->enumcs = 17; /* greyscale */
|
jp2->enumcs = 17; /* greyscale */
|
||||||
else if (image->color_space == 3)
|
else if (image->color_space == 3)
|
||||||
jp2->enumcs = 18; /* YUV */
|
jp2->enumcs = 18; /* YUV */
|
||||||
|
} else {
|
||||||
|
jp2->enumcs = 0; /* PROFILE (??) */
|
||||||
|
}
|
||||||
jp2->precedence = 0; /* PRECEDENCE */
|
jp2->precedence = 0; /* PRECEDENCE */
|
||||||
jp2->approx = 0; /* APPROX */
|
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) {
|
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 */
|
/* preconditions */
|
||||||
assert(jp2 != 00);
|
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_jp_v2 );
|
||||||
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_ftyp_v2 );
|
||||||
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_jp2h_v2 );
|
||||||
opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)jp2_skip_jp2c );
|
opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)jp2_skip_jp2c );
|
||||||
|
|
||||||
/* DEVELOPER CORNER, insert your custom procedures */
|
/* DEVELOPER CORNER, insert your custom procedures */
|
||||||
|
|
|
@ -236,6 +236,18 @@ typedef struct opj_jp2_header_handler
|
||||||
}
|
}
|
||||||
opj_jp2_header_handler_t;
|
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 */
|
/** @name Exported functions */
|
||||||
/*@{*/
|
/*@{*/
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
|
@ -245,6 +257,20 @@ Write the JP2H box - JP2 Header box (used in MJ2)
|
||||||
@param cio Output buffer stream
|
@param cio Output buffer stream
|
||||||
*/
|
*/
|
||||||
void jp2_write_jp2h(opj_jp2_t *jp2, opj_cio_t *cio);
|
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)
|
Read the JP2H box - JP2 Header box (used in MJ2)
|
||||||
@param jp2 JP2 handle
|
@param jp2 JP2 handle
|
||||||
|
@ -318,7 +344,10 @@ Coding parameters are returned in jp2->j2k->cp.
|
||||||
@param parameters compression parameters
|
@param parameters compression parameters
|
||||||
@param image input filled image
|
@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
|
Encode an image into a JPEG-2000 file stream
|
||||||
@param jp2 JP2 compressor handle
|
@param jp2 JP2 compressor handle
|
||||||
|
|
|
@ -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);
|
j2k_setup_encoder((opj_j2k_t*)cinfo->j2k_handle, parameters, image);
|
||||||
break;
|
break;
|
||||||
case CODEC_JP2:
|
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;
|
break;
|
||||||
case CODEC_JPT:
|
case CODEC_JPT:
|
||||||
case CODEC_UNKNOWN:
|
case CODEC_UNKNOWN:
|
||||||
|
|
Loading…
Reference in New Issue