diff --git a/src/lib/openjp2/cio.c b/src/lib/openjp2/cio.c index 57d4ccd2..f7f1bc72 100644 --- a/src/lib/openjp2/cio.c +++ b/src/lib/openjp2/cio.c @@ -189,6 +189,9 @@ void OPJ_CALLCONV opj_stream_destroy(opj_stream_t* p_stream) opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream; if (l_stream) { + if (l_stream->m_free_user_data_fn) { + l_stream->m_free_user_data_fn(l_stream->m_user_data); + } opj_free(l_stream->m_stored_data); l_stream->m_stored_data = 00; opj_free(l_stream); @@ -197,17 +200,7 @@ void OPJ_CALLCONV opj_stream_destroy(opj_stream_t* p_stream) void OPJ_CALLCONV opj_stream_destroy_v3(opj_stream_t* p_stream) { - opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream; - - if (l_stream) { - FILE *fp = (FILE*)l_stream->m_user_data; - if(fp) - fclose(fp); - - opj_free(l_stream->m_stored_data); - l_stream->m_stored_data = 00; - opj_free(l_stream); - } + opj_stream_destroy(p_stream); } void OPJ_CALLCONV opj_stream_set_read_function(opj_stream_t* p_stream, opj_stream_read_fn p_function) @@ -253,12 +246,13 @@ void OPJ_CALLCONV opj_stream_set_skip_function(opj_stream_t* p_stream, opj_strea l_stream->m_skip_fn = p_function; } -void OPJ_CALLCONV opj_stream_set_user_data(opj_stream_t* p_stream, void * p_data) +void OPJ_CALLCONV opj_stream_set_user_data(opj_stream_t* p_stream, void * p_data, opj_stream_free_user_data_fn p_function) { opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream; if (!l_stream) return; l_stream->m_user_data = p_data; + l_stream->m_free_user_data_fn = p_function; } void OPJ_CALLCONV opj_stream_set_user_data_length(opj_stream_t* p_stream, OPJ_UINT64 data_length) diff --git a/src/lib/openjp2/cio.h b/src/lib/openjp2/cio.h index 8e162a16..edbc2009 100644 --- a/src/lib/openjp2/cio.h +++ b/src/lib/openjp2/cio.h @@ -85,6 +85,13 @@ typedef struct opj_stream_private */ void * m_user_data; + /** + * Pointer to function to free m_user_data (NULL at initialization) + * when destroying the stream. If pointer is NULL the function is not + * called and the m_user_data is not freed (even if non-NULL). + */ + opj_stream_free_user_data_fn m_free_user_data_fn; + /** * User data length */ diff --git a/src/lib/openjp2/openjpeg.c b/src/lib/openjp2/openjpeg.c index 08610c8c..05a9938d 100644 --- a/src/lib/openjp2/openjpeg.c +++ b/src/lib/openjp2/openjpeg.c @@ -944,7 +944,7 @@ opj_stream_t* OPJ_CALLCONV opj_stream_create_file_stream_v3 ( return NULL; } - opj_stream_set_user_data(l_stream, p_file); + opj_stream_set_user_data(l_stream, p_file, (opj_stream_free_user_data_fn) fclose); opj_stream_set_user_data_length(l_stream, opj_get_data_length_from_file(p_file)); opj_stream_set_read_function(l_stream, (opj_stream_read_fn) opj_read_from_file); opj_stream_set_write_function(l_stream, (opj_stream_write_fn) opj_write_from_file); diff --git a/src/lib/openjp2/openjpeg.h b/src/lib/openjp2/openjpeg.h index 8170f7a4..d3339954 100644 --- a/src/lib/openjp2/openjpeg.h +++ b/src/lib/openjp2/openjpeg.h @@ -500,6 +500,11 @@ typedef OPJ_OFF_T (* opj_stream_skip_fn) (OPJ_OFF_T p_nb_bytes, void * p_user_da */ typedef OPJ_BOOL (* opj_stream_seek_fn) (OPJ_OFF_T p_nb_bytes, void * p_user_data) ; +/* + * Callback function prototype for free user data function + */ +typedef void (* opj_stream_free_user_data_fn) (void * p_user_data) ; + /* * JPEG2000 Stream. */ @@ -1007,7 +1012,7 @@ OPJ_API opj_stream_t* OPJ_CALLCONV opj_stream_create(OPJ_SIZE_T p_buffer_size, O * * @param p_stream the stream to destroy. */ -OPJ_DEPRECATED(OPJ_API void OPJ_CALLCONV opj_stream_destroy(opj_stream_t* p_stream)); +OPJ_API void OPJ_CALLCONV opj_stream_destroy(opj_stream_t* p_stream); /** * Destroys a stream created by opj_create_stream. This function does NOT close the abstract stream. @@ -1049,8 +1054,9 @@ OPJ_API void OPJ_CALLCONV opj_stream_set_seek_function(opj_stream_t* p_stream, o * Sets the given data to be used as a user data for the stream. * @param p_stream the stream to modify * @param p_data the data to set. + * @param p_function the function to free p_data when opj_stream_destroy() is called. */ -OPJ_API void OPJ_CALLCONV opj_stream_set_user_data (opj_stream_t* p_stream, void * p_data); +OPJ_API void OPJ_CALLCONV opj_stream_set_user_data (opj_stream_t* p_stream, void * p_data, opj_stream_free_user_data_fn p_function); /** * Sets the length of the user data for the stream.