From 34801b40f4fdd6f52e0834a5ce8449aa93821edd Mon Sep 17 00:00:00 2001 From: hw Date: Mon, 28 May 2018 13:52:03 +0200 Subject: [PATCH] - Moved ASOC data to opj_jp2_metadata_t - Fixed bug in allocation of asoc data (length was set one byte larger than allocated) --- src/bin/jp2/opj_dump.c | 5 ++++- src/lib/openjp2/j2k.c | 9 +++++--- src/lib/openjp2/j2k.h | 9 ++++++++ src/lib/openjp2/jp2.c | 24 ++++++++++++-------- src/lib/openjp2/jp2.h | 11 ++++++++- src/lib/openjp2/openjpeg.c | 45 +++++++++++++++++++++++++++---------- src/lib/openjp2/openjpeg.h | 26 ++++++++++++--------- src/lib/openjp2/opj_codec.h | 1 + 8 files changed, 93 insertions(+), 37 deletions(-) diff --git a/src/bin/jp2/opj_dump.c b/src/bin/jp2/opj_dump.c index d687cc40..22cfd703 100644 --- a/src/bin/jp2/opj_dump.c +++ b/src/bin/jp2/opj_dump.c @@ -456,6 +456,7 @@ int main(int argc, char *argv[]) opj_stream_t *l_stream = NULL; /* Stream */ opj_codestream_info_v2_t* cstr_info = NULL; opj_codestream_index_t* cstr_index = NULL; + opj_jp2_metadata_t *jp2_metadata = NULL; OPJ_INT32 num_images, imageno; img_fol_t img_fol; @@ -603,7 +604,9 @@ int main(int argc, char *argv[]) cstr_info = opj_get_cstr_info(l_codec); /* Dump associated data if there is any */ - opj_dump_associated_data(cstr_info, stdout); + jp2_metadata = opj_get_jp2_metadata(l_codec); + opj_dump_associated_data(jp2_metadata, stdout); + opj_destroy_jp2_metadata(&jp2_metadata); cstr_index = opj_get_cstr_index(l_codec); diff --git a/src/lib/openjp2/j2k.c b/src/lib/openjp2/j2k.c index 15fefaf2..08116139 100644 --- a/src/lib/openjp2/j2k.c +++ b/src/lib/openjp2/j2k.c @@ -10443,9 +10443,6 @@ opj_codestream_info_v2_t* j2k_get_cstr_info(opj_j2k_t* p_j2k) return NULL; } - cstr_info->nbasoc = 0; - cstr_info->asoc_info = 00; - cstr_info->nbcomps = p_j2k->m_private_image->numcomps; cstr_info->tx0 = p_j2k->m_cp.tx0; @@ -10511,6 +10508,12 @@ opj_codestream_info_v2_t* j2k_get_cstr_info(opj_j2k_t* p_j2k) return cstr_info; } +opj_jp2_metadata_t* j2k_get_metadata( opj_j2k_t* p_j2k ) +{ + /* A J2K stream can not contain jp2 meta data */ + return NULL; +} + opj_codestream_index_t* j2k_get_cstr_index(opj_j2k_t* p_j2k) { opj_codestream_index_t* l_cstr_index = (opj_codestream_index_t*) diff --git a/src/lib/openjp2/j2k.h b/src/lib/openjp2/j2k.h index 5d393c98..1253f492 100644 --- a/src/lib/openjp2/j2k.h +++ b/src/lib/openjp2/j2k.h @@ -794,6 +794,15 @@ void j2k_dump_image_comp_header(opj_image_comp_t* comp, OPJ_BOOL dev_dump_flag, */ opj_codestream_info_v2_t* j2k_get_cstr_info(opj_j2k_t* p_j2k); +/** + * Get the metadata from a JPEG2000 codec. + * + *@param p_j2k the component image header to dump. + * + *@return NULL for j2k streams. The metadata extract from the jpg2000 codec + */ + opj_jp2_metadata_t* j2k_get_metadata( opj_j2k_t* p_j2k ); + /** * Get the codestream index from a JPEG2000 codec. * diff --git a/src/lib/openjp2/jp2.c b/src/lib/openjp2/jp2.c index 5f39bbda..9271c0a3 100644 --- a/src/lib/openjp2/jp2.c +++ b/src/lib/openjp2/jp2.c @@ -2713,7 +2713,7 @@ static OPJ_BOOL opj_jp2_read_asoc( opj_jp2_t *jp2, asoc = &(jp2->asoc[jp2->numasoc-1]); asoc->level = jp2->numasoc-1; /* TODO: This is not correct if a parent asoc contains multiple child asocs! */ asoc->label_length = asoc_size+1; - asoc->label = opj_malloc(asoc_size); + asoc->label = opj_malloc(asoc->label_length); memcpy(asoc->label, p_header_data, asoc_size); asoc->label[asoc->label_length-1] = '\0'; /* NULL terminated label string */ asoc->xml_buf = 00; @@ -2742,7 +2742,7 @@ static OPJ_BOOL opj_jp2_read_asoc( opj_jp2_t *jp2, case JP2_XML: { asoc->xml_len = p_header_size+1; - asoc->xml_buf = opj_malloc(p_header_size); + asoc->xml_buf = opj_malloc(asoc->xml_len); memcpy( asoc->xml_buf, p_header_data, p_header_size ); asoc->xml_buf[asoc->xml_len-1] = '\0'; } @@ -2752,7 +2752,7 @@ static OPJ_BOOL opj_jp2_read_asoc( opj_jp2_t *jp2, /* Copy the unknown data for external handling. NOTE: This is not tested, but does the same as if an XML tag was found.*/ asoc->xml_len = p_header_size+1; - asoc->xml_buf = opj_malloc(p_header_size); + asoc->xml_buf = opj_malloc(asoc->xml_len); memcpy( asoc->xml_buf, p_header_data, p_header_size ); asoc->xml_buf[asoc->xml_len-1] = '\0'; } @@ -3378,19 +3378,25 @@ opj_codestream_index_t* jp2_get_cstr_index(opj_jp2_t* p_jp2) opj_codestream_info_v2_t* jp2_get_cstr_info(opj_jp2_t* p_jp2) { opj_codestream_info_v2_t* p_info = j2k_get_cstr_info(p_jp2->j2k); - jp2_copy_asoc_data( p_jp2, p_info ); return p_info; } -OPJ_BOOL jp2_copy_asoc_data( opj_jp2_t* p_jp2, opj_codestream_info_v2_t* p_info ) +opj_jp2_metadata_t* jp2_get_metadata(opj_jp2_t* p_jp2) +{ + opj_jp2_metadata_t* p_metadata = opj_malloc(sizeof(opj_jp2_metadata_t)); + jp2_copy_asoc_data( p_jp2, p_metadata ); + return p_metadata; +} + +OPJ_BOOL jp2_copy_asoc_data( opj_jp2_t* p_jp2, opj_jp2_metadata_t* p_jp2_metadata ) { OPJ_UINT32 i; opj_jp2_asoc_t *asoc, *to_asoc; - p_info->nbasoc = p_jp2->numasoc; - p_info->asoc_info = opj_malloc(p_info->nbasoc * sizeof(opj_jp2_asoc_t)); - for (i=0; inbasoc; i++) { + p_jp2_metadata->nbasoc = p_jp2->numasoc; + p_jp2_metadata->asoc_info = opj_malloc(p_jp2_metadata->nbasoc * sizeof(opj_jp2_asoc_t)); + for (i=0; inbasoc; i++) { asoc = &(p_jp2->asoc[i]); - to_asoc = &(p_info->asoc_info[i]); + to_asoc = &(p_jp2_metadata->asoc_info[i]); to_asoc->level = asoc->level; to_asoc->label_length = asoc->label_length; to_asoc->xml_len = asoc->xml_len; diff --git a/src/lib/openjp2/jp2.h b/src/lib/openjp2/jp2.h index 2d9e3132..e56ae660 100644 --- a/src/lib/openjp2/jp2.h +++ b/src/lib/openjp2/jp2.h @@ -486,10 +486,19 @@ void jp2_dump(opj_jp2_t* p_jp2, OPJ_INT32 flag, FILE* out_stream); */ opj_codestream_info_v2_t* jp2_get_cstr_info(opj_jp2_t* p_jp2); +/** + * Get the metadata from a JPEG2000 codec. + * + *@param p_jp2 jp2 codec. + * + *@return the metadata extract from the jpg2000 codec + */ + opj_jp2_metadata_t* jp2_get_metadata( opj_jp2_t* p_jp2 ); + /** * Copy associated data */ -OPJ_BOOL jp2_copy_asoc_data( opj_jp2_t* p_jp2, opj_codestream_info_v2_t* p_info ); +OPJ_BOOL jp2_copy_asoc_data( opj_jp2_t* p_jp2, opj_jp2_metadata_t* p_jp2_metadata ); /** * Get the codestream index from a JPEG2000 codec. diff --git a/src/lib/openjp2/openjpeg.c b/src/lib/openjp2/openjpeg.c index adcc5622..c57aceea 100644 --- a/src/lib/openjp2/openjpeg.c +++ b/src/lib/openjp2/openjpeg.c @@ -187,6 +187,9 @@ opj_codec_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT p_format) l_codec->opj_get_codec_index = (opj_codestream_index_t* (*)( void*)) j2k_get_cstr_index; + l_codec->opj_get_jp2_metadata = (opj_jp2_metadata_t* (*)( + void*)) j2k_get_metadata; + l_codec->m_codec_data.m_decompression.opj_decode = (OPJ_BOOL(*)(void *, struct opj_stream_private *, @@ -274,6 +277,9 @@ opj_codec_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT p_format) l_codec->opj_get_codec_index = (opj_codestream_index_t* (*)( void*)) jp2_get_cstr_index; + l_codec->opj_get_jp2_metadata = (opj_jp2_metadata_t* (*)( + void*)) jp2_get_metadata; + l_codec->m_codec_data.m_decompression.opj_decode = (OPJ_BOOL(*)(void *, struct opj_stream_private *, @@ -954,16 +960,16 @@ void OPJ_CALLCONV opj_dump_codec(opj_codec_t *p_codec, } void OPJ_CALLCONV opj_dump_associated_data( - opj_codestream_info_v2_t* cstr_info, + opj_jp2_metadata_t* jp2_info, FILE* output_stream ) { OPJ_UINT32 i; - if ( cstr_info->asoc_info ) { + if ( jp2_info && jp2_info->asoc_info ) { fprintf(output_stream, "\n\nAssociated data: {\n"); - for (i=0; inbasoc; i++) { - fprintf(output_stream, "\tlabel=%s, xml/data=", (char*) cstr_info->asoc_info[i].label); - if (cstr_info->asoc_info[i].xml_buf) { - fprintf(output_stream, "%s\n", (char*) cstr_info->asoc_info[i].xml_buf); + for (i=0; inbasoc; i++) { + fprintf(output_stream, "\tlabel=%s, xml/data=", (char*) jp2_info->asoc_info[i].label); + if (jp2_info->asoc_info[i].xml_buf) { + fprintf(output_stream, "%s\n", (char*) jp2_info->asoc_info[i].xml_buf); } else { fprintf(output_stream, "NULL\n"); } @@ -1011,12 +1017,6 @@ void OPJ_CALLCONV opj_destroy_cstr_info(opj_codestream_info_v2_t **cstr_info) /* FIXME not used for the moment*/ } - if ((*cstr_info)->nbasoc) { - opj_asoc_destroy((*cstr_info)->asoc_info, (*cstr_info)->nbasoc); - (*cstr_info)->asoc_info = 00; - (*cstr_info)->nbasoc = 0; - } - opj_free((*cstr_info)); (*cstr_info) = NULL; } @@ -1033,6 +1033,27 @@ opj_codestream_index_t * OPJ_CALLCONV opj_get_cstr_index(opj_codec_t *p_codec) return NULL; } +opj_jp2_metadata_t * OPJ_CALLCONV opj_get_jp2_metadata(opj_codec_t *p_codec) +{ + if (p_codec) { + opj_codec_private_t* l_codec = (opj_codec_private_t*) p_codec; + return l_codec->opj_get_jp2_metadata(l_codec->m_codec); + } + return NULL; +} + +OPJ_API void opj_destroy_jp2_metadata(opj_jp2_metadata_t **p_jp2_meta_data) +{ + if (*p_jp2_meta_data) { + if ((*p_jp2_meta_data)->nbasoc) { + opj_asoc_destroy((*p_jp2_meta_data)->asoc_info, (*p_jp2_meta_data)->nbasoc); + (*p_jp2_meta_data)->asoc_info = 00; + (*p_jp2_meta_data)->nbasoc = 0; + } + (*p_jp2_meta_data) = NULL; + } +} + void OPJ_CALLCONV opj_destroy_cstr_index(opj_codestream_index_t **p_cstr_index) { if (*p_cstr_index) { diff --git a/src/lib/openjp2/openjpeg.h b/src/lib/openjp2/openjpeg.h index 4113ba2c..383e6bf5 100644 --- a/src/lib/openjp2/openjpeg.h +++ b/src/lib/openjp2/openjpeg.h @@ -958,11 +958,6 @@ typedef struct opj_codestream_info_v2 { /** information regarding tiles inside image */ opj_tile_info_v2_t *tile_info; /* FIXME not used for the moment */ - /** Number of associated data boxes*/ - OPJ_UINT32 nbasoc; - - /** Associated data, e.g. GML geoinformation */ - opj_jp2_asoc_t *asoc_info; } opj_codestream_info_v2_t; @@ -1049,11 +1044,15 @@ typedef struct opj_codestream_index { /** * Info structure of the JP2 file - * EXPERIMENTAL FOR THE MOMENT + * Includes associated data (ASOC boxes) if available in JP2 stream. See opj_dump for sample code. */ typedef struct opj_jp2_metadata { - /** */ - OPJ_INT32 not_used; + + /** Number of associated data boxes*/ + OPJ_UINT32 nbasoc; + + /** Associated data, e.g. GML geoinformation */ + opj_jp2_asoc_t *asoc_info; } opj_jp2_metadata_t; @@ -1641,7 +1640,7 @@ OPJ_API opj_codestream_info_v2_t* OPJ_CALLCONV opj_get_cstr_info( * */ OPJ_API void OPJ_CALLCONV opj_dump_associated_data( - opj_codestream_info_v2_t* cstr_info, + opj_jp2_metadata_t* cstr_info, FILE* output_stream ); /** @@ -1660,16 +1659,21 @@ OPJ_API void OPJ_CALLCONV opj_destroy_cstr_index(opj_codestream_index_t /** - * Get the JP2 file information from the codec FIXME + * Get the JP2 metadata file information from the codec * * @param p_codec the jpeg2000 codec. * - * @return a pointer to a JP2 metadata structure. + * @return a pointer to a JP2 metadata structure or NULL if no metadata available. The metadata structure will contain associated data (ASOC tag) such as GML geoinfo-data if available. * */ OPJ_API opj_jp2_metadata_t* OPJ_CALLCONV opj_get_jp2_metadata( opj_codec_t *p_codec); +/** + * Destroy the JP2 metadata file information + */ +OPJ_API void opj_destroy_jp2_metadata(opj_jp2_metadata_t **p_jp2_meta_data); + /** * Get the JP2 file index from the codec FIXME * diff --git a/src/lib/openjp2/opj_codec.h b/src/lib/openjp2/opj_codec.h index b962b121..2d050075 100644 --- a/src/lib/openjp2/opj_codec.h +++ b/src/lib/openjp2/opj_codec.h @@ -160,6 +160,7 @@ typedef struct opj_codec_private { FILE* output_stream); opj_codestream_info_v2_t* (*opj_get_codec_info)(void* p_codec); opj_codestream_index_t* (*opj_get_codec_index)(void* p_codec); + opj_jp2_metadata_t* (*opj_get_jp2_metadata)(void* p_codec); /** Set number of threads */ OPJ_BOOL(*opj_set_threads)(void * p_codec, OPJ_UINT32 num_threads);