summaryrefslogtreecommitdiffstats
path: root/ext/metadata/metadata.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/metadata/metadata.c')
-rw-r--r--ext/metadata/metadata.c186
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;
- }
-
-}