diff options
Diffstat (limited to 'ext/metadata/metadata.c')
-rw-r--r-- | ext/metadata/metadata.c | 186 |
1 files changed, 118 insertions, 68 deletions
diff --git a/ext/metadata/metadata.c b/ext/metadata/metadata.c index 0056a51c..4fcd7c1c 100644 --- a/ext/metadata/metadata.c +++ b/ext/metadata/metadata.c @@ -49,16 +49,26 @@ *static declarations */ -static int +static MetadataParsingReturn metadata_parse_none (MetaData * meta_data, const guint8 * buf, guint32 * bufsize, guint8 ** next_start, guint32 * next_size); /* - * extern implementation + * extern functions implementations */ +/* + * Init metadata handle vars. + * This function must becalled before any other function from this module. + * This functoin must not be called twice without call 'metadata_dispose' + * beteween them. + * meta_data [in]: metadata handler to be inited + * parse [in]: pass TRUE for demuxing and FALSE for muxing + * options [in]: which types of metadata will be processed (EXIF, IPTC and/or XMP). + * Look at 'MetaOption' to see the available options. + */ void -metadata_init (MetaData * meta_data, gboolean parse, guint8 options) +metadata_init (MetaData * meta_data, const gboolean parse, const guint8 options) { meta_data->state = STATE_NULL; meta_data->img_type = IMG_NONE; @@ -70,36 +80,95 @@ metadata_init (MetaData * meta_data, gboolean parse, guint8 options) meta_data->parse = parse; if (parse) { + /* when parsing we will probably strip only 3 chunk (exif, iptc and xmp) + so we use 4 just in case there is more than one chunk of them. + But this is just for convinience, 'cause the chunk_array incriases dinamically */ metadata_chunk_array_init (&meta_data->strip_chunks, 4); + /* at most 1 chunk will be injected (JPEG JFIF) */ metadata_chunk_array_init (&meta_data->inject_chunks, 1); } else { + /* at most 1 chunk will be striped (JPEG JFIF) */ metadata_chunk_array_init (&meta_data->strip_chunks, 1); + /* at most 3 chunk will be injected (EXIF, IPTC, XMP) */ metadata_chunk_array_init (&meta_data->inject_chunks, 3); } } /* - * offset: number of bytes to jump (just a hint to jump a chunk) - * size: number of bytes to read on next call (just a hint to get all chunk) + * Dispose medadata handler data. + * Call this function to free any resource allocated by 'metadata_init' + */ +void +metadata_dispose (MetaData * meta_data) +{ + + switch (meta_data->img_type) { + case IMG_JPEG: + if (G_LIKELY (meta_data->parse)) + metadataparse_jpeg_dispose (&meta_data->format_data.jpeg_parse); + else + metadatamux_jpeg_dispose (&meta_data->format_data.jpeg_mux); + break; + case IMG_PNG: + if (G_LIKELY (meta_data->parse)) + metadataparse_png_dispose (&meta_data->format_data.png_parse); + else + metadatamux_png_dispose (&meta_data->format_data.png_mux); + break; + } + + metadata_chunk_array_free (&meta_data->strip_chunks); + metadata_chunk_array_free (&meta_data->inject_chunks); + + if (meta_data->xmp_adapter) { + gst_object_unref (meta_data->xmp_adapter); + meta_data->xmp_adapter = NULL; + } + + if (meta_data->iptc_adapter) { + gst_object_unref (meta_data->iptc_adapter); + meta_data->iptc_adapter = NULL; + } + + if (meta_data->exif_adapter) { + gst_object_unref (meta_data->exif_adapter); + meta_data->exif_adapter = NULL; + } + +} + +/* + * meta_data [in]: metata handle + * buf [in]: data to be parsed + * bufsize [in]: size of data in bytes + * next_offset [out]: number of bytes to jump from the begining of 'buf' in the next call. + * i.e, 0 (zero) mean that in the next call to function "buf" must have the same + * data (probably resized, see 'size') + * size [out]: number of minimal bytes in buf for the next call to this function * return: - * -1 -> error - * 0 -> done - * 1 -> need more data + * META_PARSING_ERROR + * META_PARSING_DONE + * META_PARSING_NEED_MORE_DATA (look 'next_offset' and 'size') + * when this function returns 0 you have strip and inject chunks ready to use + * If you change the contents of strip and inject chunks, you have to call + * 'metadata_lazy_update' (this is the case when muxing) + * see MetaData->strip_chunks and MetaData->inject_chunks */ -int + +MetadataParsingReturn metadata_parse (MetaData * meta_data, const guint8 * buf, guint32 bufsize, guint32 * next_offset, guint32 * next_size) { - int ret = 0; + int ret = META_PARSING_DONE; guint8 *next_start = (guint8 *) buf; if (meta_data->state == STATE_NULL) { ret = metadata_parse_none (meta_data, buf, &bufsize, &next_start, next_size); - if (ret == 0) + if (ret == META_PARSING_DONE) meta_data->state = STATE_READING; else goto done; @@ -132,7 +201,7 @@ metadata_parse (MetaData * meta_data, const guint8 * buf, break; default: /* unexpected */ - ret = -1; + ret = META_PARSING_ERROR; goto done; break; } @@ -142,63 +211,60 @@ metadata_parse (MetaData * meta_data, const guint8 * buf, done: - if (ret == 0) { + if (ret == META_PARSING_DONE) { meta_data->state = STATE_DONE; } return ret; } +/* + * This function must be called after 'metadata_parse' and after the element has modified the 'segments'. + * This function is really importante in case o muxing 'cause: + * 1- 'cause gives the oportunity to muxers to wrapper new segments with apropriate bytes + * ex: in case of JPEG it can wrap the EXIF chunk (created using tags) with chunk id and chunk size + * 2- 'cause gives the oportunity to muxer to decide if some chunks should still be striped/injected + * ex: if there is no EXIF chunk to be inserted, the muxer decides to not strip JFIF anymore + * see MetaData->strip_chunks and MetaData->inject_chunks + */ + void -metadata_dispose (MetaData * meta_data) +metadata_lazy_update (MetaData * meta_data) { - switch (meta_data->img_type) { case IMG_JPEG: if (G_LIKELY (meta_data->parse)) - metadataparse_jpeg_dispose (&meta_data->format_data.jpeg_parse); + metadataparse_jpeg_lazy_update (&meta_data->format_data.jpeg_parse); else - metadatamux_jpeg_dispose (&meta_data->format_data.jpeg_mux); + metadatamux_jpeg_lazy_update (&meta_data->format_data.jpeg_mux); break; case IMG_PNG: if (G_LIKELY (meta_data->parse)) - metadataparse_png_dispose (&meta_data->format_data.png_parse); + metadataparse_png_lazy_update (&meta_data->format_data.png_parse); else - metadatamux_png_dispose (&meta_data->format_data.png_mux); + metadatamux_png_lazy_update (&meta_data->format_data.png_mux); + break; + default: + /* unexpected */ break; - } - - metadata_chunk_array_free (&meta_data->strip_chunks); - metadata_chunk_array_free (&meta_data->inject_chunks); - - if (meta_data->xmp_adapter) { - gst_object_unref (meta_data->xmp_adapter); - meta_data->xmp_adapter = NULL; - } - - if (meta_data->iptc_adapter) { - gst_object_unref (meta_data->iptc_adapter); - meta_data->iptc_adapter = NULL; - } - - if (meta_data->exif_adapter) { - gst_object_unref (meta_data->exif_adapter); - meta_data->exif_adapter = NULL; } } + /* - * static implementation + * static functions implementation */ -/* find image type */ -static int +/* + * Find out the type of the stream + */ +static MetadataParsingReturn metadata_parse_none (MetaData * meta_data, const guint8 * buf, guint32 * bufsize, guint8 ** next_start, guint32 * next_size) { - int ret = -1; + int ret = META_PARSING_ERROR; GstAdapter **exif = NULL; GstAdapter **iptc = NULL; GstAdapter **xmp = NULL; @@ -207,9 +273,15 @@ metadata_parse_none (MetaData * meta_data, const guint8 * buf, meta_data->img_type = IMG_NONE; + /* + * Be sure of add checking for more types in order from the + * less to more bytes need to detect the stream type. + */ + + /* we need at least 3 bytes to see if it is JPEG */ if (*bufsize < 3) { *next_size = 3; - ret = 1; + ret = META_PARSING_NEED_MORE_DATA; goto done; } @@ -227,14 +299,15 @@ metadata_parse_none (MetaData * meta_data, const guint8 * buf, else metadatamux_jpeg_init (&meta_data->format_data.jpeg_mux, &meta_data->strip_chunks, &meta_data->inject_chunks); - ret = 0; + ret = META_PARSING_DONE; meta_data->img_type = IMG_JPEG; goto done; } + /* we need at least 8 bytes to see if it is PNG */ if (*bufsize < 8) { *next_size = 8; - ret = 1; + ret = META_PARSING_NEED_MORE_DATA; goto done; } @@ -246,7 +319,7 @@ metadata_parse_none (MetaData * meta_data, const guint8 * buf, else metadatamux_png_init (&meta_data->format_data.png_mux, &meta_data->strip_chunks, &meta_data->inject_chunks); - ret = 0; + ret = META_PARSING_DONE; meta_data->img_type = IMG_PNG; goto done; } @@ -255,26 +328,3 @@ done: return ret; } - -void -metadata_lazy_update (MetaData * meta_data) -{ - switch (meta_data->img_type) { - case IMG_JPEG: - if (G_LIKELY (meta_data->parse)) - metadataparse_jpeg_lazy_update (&meta_data->format_data.jpeg_parse); - else - metadatamux_jpeg_lazy_update (&meta_data->format_data.jpeg_mux); - break; - case IMG_PNG: - if (G_LIKELY (meta_data->parse)) - metadataparse_png_lazy_update (&meta_data->format_data.png_parse); - else - metadatamux_png_lazy_update (&meta_data->format_data.png_mux); - break; - default: - /* unexpected */ - break; - } - -} |